socket.c revision 72445
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#ifdef HAVE_CONFIG_H 35#include <config.h> 36RCSID("$Id: socket.c,v 1.5 2000/07/27 04:41:06 assar Exp $"); 37#endif 38 39#include <roken.h> 40#include <err.h> 41 42/* 43 * Set `sa' to the unitialized address of address family `af' 44 */ 45 46void 47socket_set_any (struct sockaddr *sa, int af) 48{ 49 switch (af) { 50 case AF_INET : { 51 struct sockaddr_in *sin = (struct sockaddr_in *)sa; 52 53 memset (sin, 0, sizeof(*sin)); 54 sin->sin_family = AF_INET; 55 sin->sin_port = 0; 56 sin->sin_addr.s_addr = INADDR_ANY; 57 break; 58 } 59#ifdef HAVE_IPV6 60 case AF_INET6 : { 61 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; 62 63 memset (sin6, 0, sizeof(*sin6)); 64 sin6->sin6_family = AF_INET6; 65 sin6->sin6_port = 0; 66 sin6->sin6_addr = in6addr_any; 67 break; 68 } 69#endif 70 default : 71 errx (1, "unknown address family %d", sa->sa_family); 72 break; 73 } 74} 75 76/* 77 * set `sa' to (`ptr', `port') 78 */ 79 80void 81socket_set_address_and_port (struct sockaddr *sa, const void *ptr, int port) 82{ 83 switch (sa->sa_family) { 84 case AF_INET : { 85 struct sockaddr_in *sin = (struct sockaddr_in *)sa; 86 87 memset (sin, 0, sizeof(*sin)); 88 sin->sin_family = AF_INET; 89 sin->sin_port = port; 90 memcpy (&sin->sin_addr, ptr, sizeof(struct in_addr)); 91 break; 92 } 93#ifdef HAVE_IPV6 94 case AF_INET6 : { 95 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; 96 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)); 101 break; 102 } 103#endif 104 default : 105 errx (1, "unknown address family %d", sa->sa_family); 106 break; 107 } 108} 109 110/* 111 * Return the size of an address of the type in `sa' 112 */ 113 114size_t 115socket_addr_size (const struct sockaddr *sa) 116{ 117 switch (sa->sa_family) { 118 case AF_INET : 119 return sizeof(struct in_addr); 120#ifdef HAVE_IPV6 121 case AF_INET6 : 122 return sizeof(struct in6_addr); 123#endif 124 default : 125 errx (1, "unknown address family %d", sa->sa_family); 126 break; 127 } 128} 129 130/* 131 * Return the size of a `struct sockaddr' in `sa'. 132 */ 133 134size_t 135socket_sockaddr_size (const struct sockaddr *sa) 136{ 137 switch (sa->sa_family) { 138 case AF_INET : 139 return sizeof(struct sockaddr_in); 140#ifdef HAVE_IPV6 141 case AF_INET6 : 142 return sizeof(struct sockaddr_in6); 143#endif 144 default : 145 errx (1, "unknown address family %d", sa->sa_family); 146 break; 147 } 148} 149 150/* 151 * Return the binary address of `sa'. 152 */ 153 154void * 155socket_get_address (struct sockaddr *sa) 156{ 157 switch (sa->sa_family) { 158 case AF_INET : { 159 struct sockaddr_in *sin = (struct sockaddr_in *)sa; 160 return &sin->sin_addr; 161 } 162#ifdef HAVE_IPV6 163 case AF_INET6 : { 164 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; 165 return &sin6->sin6_addr; 166 } 167#endif 168 default : 169 errx (1, "unknown address family %d", sa->sa_family); 170 break; 171 } 172} 173 174/* 175 * Return the port number from `sa'. 176 */ 177 178int 179socket_get_port (const struct sockaddr *sa) 180{ 181 switch (sa->sa_family) { 182 case AF_INET : { 183 const struct sockaddr_in *sin = (const struct sockaddr_in *)sa; 184 return sin->sin_port; 185 } 186#ifdef HAVE_IPV6 187 case AF_INET6 : { 188 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa; 189 return sin6->sin6_port; 190 } 191#endif 192 default : 193 errx (1, "unknown address family %d", sa->sa_family); 194 break; 195 } 196} 197 198/* 199 * Set the port in `sa' to `port'. 200 */ 201 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