socket.c revision 72445
155682Smarkm/*
2120945Snectar * Copyright (c) 1999 - 2000 Kungliga Tekniska H�gskolan
355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden).
455682Smarkm * All rights reserved.
555682Smarkm *
655682Smarkm * Redistribution and use in source and binary forms, with or without
755682Smarkm * modification, are permitted provided that the following conditions
855682Smarkm * are met:
955682Smarkm *
1055682Smarkm * 1. Redistributions of source code must retain the above copyright
1155682Smarkm *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1455682Smarkm *    notice, this list of conditions and the following disclaimer in the
1555682Smarkm *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors
1855682Smarkm *    may be used to endorse or promote products derived from this software
1955682Smarkm *    without specific prior written permission.
2055682Smarkm *
2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155682Smarkm * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#ifdef HAVE_CONFIG_H
3555682Smarkm#include <config.h>
3655682SmarkmRCSID("$Id: socket.c,v 1.5 2000/07/27 04:41:06 assar Exp $");
37178825Sdfr#endif
3855682Smarkm
3955682Smarkm#include <roken.h>
4055682Smarkm#include <err.h>
4155682Smarkm
4255682Smarkm/*
4355682Smarkm * Set `sa' to the unitialized address of address family `af'
4455682Smarkm */
45120945Snectar
4655682Smarkmvoid
4755682Smarkmsocket_set_any (struct sockaddr *sa, int af)
4855682Smarkm{
4955682Smarkm    switch (af) {
5055682Smarkm    case AF_INET : {
5155682Smarkm	struct sockaddr_in *sin = (struct sockaddr_in *)sa;
5255682Smarkm
5355682Smarkm	memset (sin, 0, sizeof(*sin));
5455682Smarkm	sin->sin_family = AF_INET;
5555682Smarkm	sin->sin_port   = 0;
5655682Smarkm	sin->sin_addr.s_addr = INADDR_ANY;
5755682Smarkm	break;
5855682Smarkm    }
5955682Smarkm#ifdef HAVE_IPV6
6055682Smarkm    case AF_INET6 : {
6155682Smarkm	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
6255682Smarkm
6355682Smarkm	memset (sin6, 0, sizeof(*sin6));
6455682Smarkm	sin6->sin6_family = AF_INET6;
6555682Smarkm	sin6->sin6_port   = 0;
6655682Smarkm	sin6->sin6_addr   = in6addr_any;
6755682Smarkm	break;
6855682Smarkm    }
6955682Smarkm#endif
7055682Smarkm    default :
7155682Smarkm	errx (1, "unknown address family %d", sa->sa_family);
7255682Smarkm	break;
73178825Sdfr    }
7455682Smarkm}
7555682Smarkm
7655682Smarkm/*
77178825Sdfr * set `sa' to (`ptr', `port')
7855682Smarkm */
7955682Smarkm
80120945Snectarvoid
81178825Sdfrsocket_set_address_and_port (struct sockaddr *sa, const void *ptr, int port)
82178825Sdfr{
83178825Sdfr    switch (sa->sa_family) {
84178825Sdfr    case AF_INET : {
85178825Sdfr	struct sockaddr_in *sin = (struct sockaddr_in *)sa;
86178825Sdfr
87178825Sdfr	memset (sin, 0, sizeof(*sin));
88120945Snectar	sin->sin_family = AF_INET;
89120945Snectar	sin->sin_port   = port;
9055682Smarkm	memcpy (&sin->sin_addr, ptr, sizeof(struct in_addr));
9155682Smarkm	break;
9255682Smarkm    }
9355682Smarkm#ifdef HAVE_IPV6
94178825Sdfr    case AF_INET6 : {
9555682Smarkm	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
9655682Smarkm
9755682Smarkm	memset (sin6, 0, sizeof(*sin6));
9855682Smarkm	sin6->sin6_family = AF_INET6;
9955682Smarkm	sin6->sin6_port   = port;
10055682Smarkm	memcpy (&sin6->sin6_addr, ptr, sizeof(struct in6_addr));
10155682Smarkm	break;
10255682Smarkm    }
103178825Sdfr#endif
10455682Smarkm    default :
10555682Smarkm	errx (1, "unknown address family %d", sa->sa_family);
10655682Smarkm	break;
10755682Smarkm    }
108178825Sdfr}
10955682Smarkm
11055682Smarkm/*
11155682Smarkm * Return the size of an address of the type in `sa'
11255682Smarkm */
11355682Smarkm
11455682Smarkmsize_t
11555682Smarkmsocket_addr_size (const struct sockaddr *sa)
11655682Smarkm{
11755682Smarkm    switch (sa->sa_family) {
118178825Sdfr    case AF_INET :
119178825Sdfr	return sizeof(struct in_addr);
12055682Smarkm#ifdef HAVE_IPV6
12155682Smarkm    case AF_INET6 :
12255682Smarkm	return sizeof(struct in6_addr);
12355682Smarkm#endif
12455682Smarkm    default :
12555682Smarkm	errx (1, "unknown address family %d", sa->sa_family);
12655682Smarkm	break;
12755682Smarkm    }
12855682Smarkm}
12955682Smarkm
130120945Snectar/*
131120945Snectar * Return the size of a `struct sockaddr' in `sa'.
132178825Sdfr */
13355682Smarkm
134120945Snectarsize_t
135120945Snectarsocket_sockaddr_size (const struct sockaddr *sa)
136120945Snectar{
137120945Snectar    switch (sa->sa_family) {
138120945Snectar    case AF_INET :
139120945Snectar	return sizeof(struct sockaddr_in);
140120945Snectar#ifdef HAVE_IPV6
141120945Snectar    case AF_INET6 :
142178825Sdfr	return sizeof(struct sockaddr_in6);
143178825Sdfr#endif
144120945Snectar    default :
145120945Snectar	errx (1, "unknown address family %d", sa->sa_family);
14655682Smarkm	break;
14755682Smarkm    }
14855682Smarkm}
14955682Smarkm
15055682Smarkm/*
151120945Snectar * Return the binary address of `sa'.
152120945Snectar */
153120945Snectar
154120945Snectarvoid *
155120945Snectarsocket_get_address (struct sockaddr *sa)
156120945Snectar{
157120945Snectar    switch (sa->sa_family) {
158120945Snectar    case AF_INET : {
15955682Smarkm	struct sockaddr_in *sin = (struct sockaddr_in *)sa;
16055682Smarkm	return &sin->sin_addr;
16155682Smarkm    }
16255682Smarkm#ifdef HAVE_IPV6
16355682Smarkm    case AF_INET6 : {
164178825Sdfr	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
16555682Smarkm	return &sin6->sin6_addr;
16655682Smarkm    }
16755682Smarkm#endif
16855682Smarkm    default :
16955682Smarkm	errx (1, "unknown address family %d", sa->sa_family);
17055682Smarkm	break;
171178825Sdfr    }
17255682Smarkm}
17355682Smarkm
17455682Smarkm/*
17555682Smarkm * Return the port number from `sa'.
17655682Smarkm */
177178825Sdfr
17855682Smarkmint
17955682Smarkmsocket_get_port (const struct sockaddr *sa)
18055682Smarkm{
18155682Smarkm    switch (sa->sa_family) {
18255682Smarkm    case AF_INET : {
18355682Smarkm	const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
18455682Smarkm	return sin->sin_port;
185120945Snectar    }
18655682Smarkm#ifdef HAVE_IPV6
18755682Smarkm    case AF_INET6 : {
18855682Smarkm	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
18955682Smarkm	return sin6->sin6_port;
19055682Smarkm    }
19155682Smarkm#endif
192120945Snectar    default :
19355682Smarkm	errx (1, "unknown address family %d", sa->sa_family);
19455682Smarkm	break;
19555682Smarkm    }
19655682Smarkm}
19755682Smarkm
198120945Snectar/*
19955682Smarkm * Set the port in `sa' to `port'.
20055682Smarkm */
20155682Smarkm
202void
203socket_set_port (struct sockaddr *sa, int port)
204{
205    switch (sa->sa_family) {
206    case AF_INET : {
207	struct sockaddr_in *sin = (struct sockaddr_in *)sa;
208	sin->sin_port = port;
209	break;
210    }
211#ifdef HAVE_IPV6
212    case AF_INET6 : {
213	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
214	sin6->sin6_port = port;
215	break;
216    }
217#endif
218    default :
219	errx (1, "unknown address family %d", sa->sa_family);
220	break;
221    }
222}
223
224/*
225 * Enable debug on `sock'.
226 */
227
228void
229socket_set_debug (int sock)
230{
231#if defined(SO_DEBUG) && defined(HAVE_SETSOCKOPT)
232    int on = 1;
233
234    if (setsockopt (sock, SOL_SOCKET, SO_DEBUG, (void *) &on, sizeof (on)) < 0)
235	warn ("setsockopt SO_DEBUG (ignored)");
236#endif
237}
238
239/*
240 * Set the type-of-service of `sock' to `tos'.
241 */
242
243void
244socket_set_tos (int sock, int tos)
245{
246#if defined(IP_TOS) && defined(HAVE_SETSOCKOPT)
247    if (setsockopt (sock, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof (int)) < 0)
248	warn ("setsockopt TOS (ignored)");
249#endif
250}
251
252/*
253 * set the reuse of addresses on `sock' to `val'.
254 */
255
256void
257socket_set_reuseaddr (int sock, int val)
258{
259#if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT)
260    if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val,
261		  sizeof(val)) < 0)
262	err (1, "setsockopt SO_REUSEADDR");
263#endif
264}
265