2 * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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
36 RCSID("$Id: socket.c,v 1.11 2005/09/01 18:48:17 lha Exp $");
43 * Set `sa' to the unitialized address of address family `af'
46 void ROKEN_LIB_FUNCTION
47 socket_set_any (struct sockaddr
*sa
, int af
)
51 struct sockaddr_in
*sin4
= (struct sockaddr_in
*)sa
;
53 memset (sin4
, 0, sizeof(*sin4
));
54 sin4
->sin_family
= AF_INET
;
56 sin4
->sin_addr
.s_addr
= INADDR_ANY
;
61 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)sa
;
63 memset (sin6
, 0, sizeof(*sin6
));
64 sin6
->sin6_family
= AF_INET6
;
66 sin6
->sin6_addr
= in6addr_any
;
71 errx (1, "unknown address family %d", sa
->sa_family
);
77 * set `sa' to (`ptr', `port')
80 void ROKEN_LIB_FUNCTION
81 socket_set_address_and_port (struct sockaddr
*sa
, const void *ptr
, int port
)
83 switch (sa
->sa_family
) {
85 struct sockaddr_in
*sin4
= (struct sockaddr_in
*)sa
;
87 memset (sin4
, 0, sizeof(*sin4
));
88 sin4
->sin_family
= AF_INET
;
89 sin4
->sin_port
= port
;
90 memcpy (&sin4
->sin_addr
, ptr
, sizeof(struct in_addr
));
95 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)sa
;
97 memset (sin6
, 0, sizeof(*sin6
));
98 sin6
->sin6_family
= AF_INET6
;
99 sin6
->sin6_port
= port
;
100 memcpy (&sin6
->sin6_addr
, ptr
, sizeof(struct in6_addr
));
105 errx (1, "unknown address family %d", sa
->sa_family
);
111 * Return the size of an address of the type in `sa'
114 size_t ROKEN_LIB_FUNCTION
115 socket_addr_size (const struct sockaddr
*sa
)
117 switch (sa
->sa_family
) {
119 return sizeof(struct in_addr
);
122 return sizeof(struct in6_addr
);
125 errx (1, "unknown address family %d", sa
->sa_family
);
131 * Return the size of a `struct sockaddr' in `sa'.
134 size_t ROKEN_LIB_FUNCTION
135 socket_sockaddr_size (const struct sockaddr
*sa
)
137 switch (sa
->sa_family
) {
139 return sizeof(struct sockaddr_in
);
142 return sizeof(struct sockaddr_in6
);
145 errx (1, "unknown address family %d", sa
->sa_family
);
151 * Return the binary address of `sa'.
154 void * ROKEN_LIB_FUNCTION
155 socket_get_address (struct sockaddr
*sa
)
157 switch (sa
->sa_family
) {
159 struct sockaddr_in
*sin4
= (struct sockaddr_in
*)sa
;
160 return &sin4
->sin_addr
;
164 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)sa
;
165 return &sin6
->sin6_addr
;
169 errx (1, "unknown address family %d", sa
->sa_family
);
175 * Return the port number from `sa'.
178 int ROKEN_LIB_FUNCTION
179 socket_get_port (const struct sockaddr
*sa
)
181 switch (sa
->sa_family
) {
183 const struct sockaddr_in
*sin4
= (const struct sockaddr_in
*)sa
;
184 return sin4
->sin_port
;
188 const struct sockaddr_in6
*sin6
= (const struct sockaddr_in6
*)sa
;
189 return sin6
->sin6_port
;
193 errx (1, "unknown address family %d", sa
->sa_family
);
199 * Set the port in `sa' to `port'.
202 void ROKEN_LIB_FUNCTION
203 socket_set_port (struct sockaddr
*sa
, int port
)
205 switch (sa
->sa_family
) {
207 struct sockaddr_in
*sin4
= (struct sockaddr_in
*)sa
;
208 sin4
->sin_port
= port
;
213 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)sa
;
214 sin6
->sin6_port
= port
;
219 errx (1, "unknown address family %d", sa
->sa_family
);
225 * Set the range of ports to use when binding with port = 0.
227 void ROKEN_LIB_FUNCTION
228 socket_set_portrange (int sock
, int restr
, int af
)
230 #if defined(IP_PORTRANGE)
232 int on
= restr
? IP_PORTRANGE_HIGH
: IP_PORTRANGE_DEFAULT
;
233 if (setsockopt (sock
, IPPROTO_IP
, IP_PORTRANGE
, &on
,
235 warn ("setsockopt IP_PORTRANGE (ignored)");
238 #if defined(IPV6_PORTRANGE)
239 if (af
== AF_INET6
) {
240 int on
= restr
? IPV6_PORTRANGE_HIGH
:
241 IPV6_PORTRANGE_DEFAULT
;
242 if (setsockopt (sock
, IPPROTO_IPV6
, IPV6_PORTRANGE
, &on
,
244 warn ("setsockopt IPV6_PORTRANGE (ignored)");
250 * Enable debug on `sock'.
253 void ROKEN_LIB_FUNCTION
254 socket_set_debug (int sock
)
256 #if defined(SO_DEBUG) && defined(HAVE_SETSOCKOPT)
259 if (setsockopt (sock
, SOL_SOCKET
, SO_DEBUG
, (void *) &on
, sizeof (on
)) < 0)
260 warn ("setsockopt SO_DEBUG (ignored)");
265 * Set the type-of-service of `sock' to `tos'.
268 void ROKEN_LIB_FUNCTION
269 socket_set_tos (int sock
, int tos
)
271 #if defined(IP_TOS) && defined(HAVE_SETSOCKOPT)
272 if (setsockopt (sock
, IPPROTO_IP
, IP_TOS
, (void *) &tos
, sizeof (int)) < 0)
274 warn ("setsockopt TOS (ignored)");
279 * set the reuse of addresses on `sock' to `val'.
282 void ROKEN_LIB_FUNCTION
283 socket_set_reuseaddr (int sock
, int val
)
285 #if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT)
286 if(setsockopt(sock
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&val
,
288 err (1, "setsockopt SO_REUSEADDR");
293 * Set the that the `sock' should bind to only IPv6 addresses.
296 void ROKEN_LIB_FUNCTION
297 socket_set_ipv6only (int sock
, int val
)
299 #if defined(IPV6_V6ONLY) && defined(HAVE_SETSOCKOPT)
300 setsockopt(sock
, IPPROTO_IPV6
, IPV6_V6ONLY
, (void *)&val
, sizeof(val
));