155682Smarkm/* 2233294Sstas * Copyright (c) 1999 - 2000 Kungliga Tekniska H��gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 5233294Sstas * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 9233294Sstas * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 12233294Sstas * 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. 16233294Sstas * 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. 20233294Sstas * 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#include <config.h> 3555682Smarkm 36178825Sdfr#include "roken.h" 3755682Smarkm#include <err.h> 3855682Smarkm 3955682Smarkm/* 4055682Smarkm * Set `sa' to the unitialized address of address family `af' 4155682Smarkm */ 4255682Smarkm 43233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 4455682Smarkmsocket_set_any (struct sockaddr *sa, int af) 4555682Smarkm{ 4655682Smarkm switch (af) { 4755682Smarkm case AF_INET : { 48178825Sdfr struct sockaddr_in *sin4 = (struct sockaddr_in *)sa; 4955682Smarkm 50178825Sdfr memset (sin4, 0, sizeof(*sin4)); 51178825Sdfr sin4->sin_family = AF_INET; 52178825Sdfr sin4->sin_port = 0; 53178825Sdfr sin4->sin_addr.s_addr = INADDR_ANY; 5455682Smarkm break; 5555682Smarkm } 5655682Smarkm#ifdef HAVE_IPV6 5755682Smarkm case AF_INET6 : { 5855682Smarkm struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; 5955682Smarkm 6055682Smarkm memset (sin6, 0, sizeof(*sin6)); 6155682Smarkm sin6->sin6_family = AF_INET6; 6255682Smarkm sin6->sin6_port = 0; 6355682Smarkm sin6->sin6_addr = in6addr_any; 6455682Smarkm break; 6555682Smarkm } 6655682Smarkm#endif 6755682Smarkm default : 6855682Smarkm errx (1, "unknown address family %d", sa->sa_family); 6955682Smarkm break; 7055682Smarkm } 7155682Smarkm} 7255682Smarkm 7355682Smarkm/* 7455682Smarkm * set `sa' to (`ptr', `port') 7555682Smarkm */ 7655682Smarkm 77233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 7855682Smarkmsocket_set_address_and_port (struct sockaddr *sa, const void *ptr, int port) 7955682Smarkm{ 8055682Smarkm switch (sa->sa_family) { 8155682Smarkm case AF_INET : { 82178825Sdfr struct sockaddr_in *sin4 = (struct sockaddr_in *)sa; 8355682Smarkm 84178825Sdfr memset (sin4, 0, sizeof(*sin4)); 85178825Sdfr sin4->sin_family = AF_INET; 86178825Sdfr sin4->sin_port = port; 87178825Sdfr memcpy (&sin4->sin_addr, ptr, sizeof(struct in_addr)); 8855682Smarkm break; 8955682Smarkm } 9055682Smarkm#ifdef HAVE_IPV6 9155682Smarkm case AF_INET6 : { 9255682Smarkm struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; 9355682Smarkm 9455682Smarkm memset (sin6, 0, sizeof(*sin6)); 9555682Smarkm sin6->sin6_family = AF_INET6; 9655682Smarkm sin6->sin6_port = port; 9755682Smarkm memcpy (&sin6->sin6_addr, ptr, sizeof(struct in6_addr)); 9855682Smarkm break; 9955682Smarkm } 10055682Smarkm#endif 10155682Smarkm default : 10255682Smarkm errx (1, "unknown address family %d", sa->sa_family); 10355682Smarkm break; 10455682Smarkm } 10555682Smarkm} 10655682Smarkm 10755682Smarkm/* 10855682Smarkm * Return the size of an address of the type in `sa' 10955682Smarkm */ 11055682Smarkm 111233294SstasROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL 11255682Smarkmsocket_addr_size (const struct sockaddr *sa) 11355682Smarkm{ 11455682Smarkm switch (sa->sa_family) { 11555682Smarkm case AF_INET : 11655682Smarkm return sizeof(struct in_addr); 11755682Smarkm#ifdef HAVE_IPV6 11855682Smarkm case AF_INET6 : 11955682Smarkm return sizeof(struct in6_addr); 12055682Smarkm#endif 12155682Smarkm default : 122233294Sstas return 0; 12355682Smarkm } 12455682Smarkm} 12555682Smarkm 12655682Smarkm/* 12755682Smarkm * Return the size of a `struct sockaddr' in `sa'. 12855682Smarkm */ 12955682Smarkm 130233294SstasROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL 13155682Smarkmsocket_sockaddr_size (const struct sockaddr *sa) 13255682Smarkm{ 13355682Smarkm switch (sa->sa_family) { 13455682Smarkm case AF_INET : 13555682Smarkm return sizeof(struct sockaddr_in); 13655682Smarkm#ifdef HAVE_IPV6 13755682Smarkm case AF_INET6 : 13855682Smarkm return sizeof(struct sockaddr_in6); 13955682Smarkm#endif 140233294Sstas default: 141233294Sstas return 0; 14255682Smarkm } 14355682Smarkm} 14455682Smarkm 14555682Smarkm/* 14655682Smarkm * Return the binary address of `sa'. 14755682Smarkm */ 14855682Smarkm 149233294SstasROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL 150233294Sstassocket_get_address (const struct sockaddr *sa) 15155682Smarkm{ 15255682Smarkm switch (sa->sa_family) { 15355682Smarkm case AF_INET : { 154233294Sstas const struct sockaddr_in *sin4 = (const struct sockaddr_in *)sa; 155233294Sstas return rk_UNCONST(&sin4->sin_addr); 15655682Smarkm } 15755682Smarkm#ifdef HAVE_IPV6 15855682Smarkm case AF_INET6 : { 159233294Sstas const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa; 160233294Sstas return rk_UNCONST(&sin6->sin6_addr); 16155682Smarkm } 16255682Smarkm#endif 163233294Sstas default: 164233294Sstas return NULL; 16555682Smarkm } 16655682Smarkm} 16755682Smarkm 16855682Smarkm/* 16955682Smarkm * Return the port number from `sa'. 17055682Smarkm */ 17155682Smarkm 172233294SstasROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 17355682Smarkmsocket_get_port (const struct sockaddr *sa) 17455682Smarkm{ 17555682Smarkm switch (sa->sa_family) { 17655682Smarkm case AF_INET : { 177178825Sdfr const struct sockaddr_in *sin4 = (const struct sockaddr_in *)sa; 178178825Sdfr return sin4->sin_port; 17955682Smarkm } 18055682Smarkm#ifdef HAVE_IPV6 18155682Smarkm case AF_INET6 : { 18255682Smarkm const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa; 18355682Smarkm return sin6->sin6_port; 18455682Smarkm } 18555682Smarkm#endif 18655682Smarkm default : 187233294Sstas return 0; 18855682Smarkm } 18955682Smarkm} 19055682Smarkm 19155682Smarkm/* 19255682Smarkm * Set the port in `sa' to `port'. 19355682Smarkm */ 19455682Smarkm 195233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 19655682Smarkmsocket_set_port (struct sockaddr *sa, int port) 19755682Smarkm{ 19855682Smarkm switch (sa->sa_family) { 19955682Smarkm case AF_INET : { 200178825Sdfr struct sockaddr_in *sin4 = (struct sockaddr_in *)sa; 201178825Sdfr sin4->sin_port = port; 20255682Smarkm break; 20355682Smarkm } 20455682Smarkm#ifdef HAVE_IPV6 20555682Smarkm case AF_INET6 : { 20655682Smarkm struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; 20755682Smarkm sin6->sin6_port = port; 20855682Smarkm break; 20955682Smarkm } 21055682Smarkm#endif 21155682Smarkm default : 21255682Smarkm errx (1, "unknown address family %d", sa->sa_family); 21355682Smarkm break; 21455682Smarkm } 21555682Smarkm} 21655682Smarkm 21755682Smarkm/* 21890926Snectar * Set the range of ports to use when binding with port = 0. 21990926Snectar */ 220233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 221233294Sstassocket_set_portrange (rk_socket_t sock, int restr, int af) 22290926Snectar{ 22390926Snectar#if defined(IP_PORTRANGE) 22490926Snectar if (af == AF_INET) { 22590926Snectar int on = restr ? IP_PORTRANGE_HIGH : IP_PORTRANGE_DEFAULT; 226233294Sstas setsockopt (sock, IPPROTO_IP, IP_PORTRANGE, &on, sizeof(on)); 22790926Snectar } 22890926Snectar#endif 22990926Snectar#if defined(IPV6_PORTRANGE) 23090926Snectar if (af == AF_INET6) { 231233294Sstas int on = restr ? IPV6_PORTRANGE_HIGH : IPV6_PORTRANGE_DEFAULT; 232233294Sstas setsockopt (sock, IPPROTO_IPV6, IPV6_PORTRANGE, &on, sizeof(on)); 23390926Snectar } 23490926Snectar#endif 23590926Snectar} 236233294Sstas 23790926Snectar/* 23855682Smarkm * Enable debug on `sock'. 23955682Smarkm */ 24055682Smarkm 241233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 242233294Sstassocket_set_debug (rk_socket_t sock) 24355682Smarkm{ 24472445Sassar#if defined(SO_DEBUG) && defined(HAVE_SETSOCKOPT) 24555682Smarkm int on = 1; 246233294Sstas setsockopt (sock, SOL_SOCKET, SO_DEBUG, (void *) &on, sizeof (on)); 24755682Smarkm#endif 24855682Smarkm} 24955682Smarkm 25055682Smarkm/* 25155682Smarkm * Set the type-of-service of `sock' to `tos'. 25255682Smarkm */ 25355682Smarkm 254233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 255233294Sstassocket_set_tos (rk_socket_t sock, int tos) 25655682Smarkm{ 25755682Smarkm#if defined(IP_TOS) && defined(HAVE_SETSOCKOPT) 258233294Sstas setsockopt (sock, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(int)); 25955682Smarkm#endif 26055682Smarkm} 26155682Smarkm 26255682Smarkm/* 26355682Smarkm * set the reuse of addresses on `sock' to `val'. 26455682Smarkm */ 26555682Smarkm 266233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 267233294Sstassocket_set_reuseaddr (rk_socket_t sock, int val) 26855682Smarkm{ 26955682Smarkm#if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT) 270233294Sstas setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(val)); 27155682Smarkm#endif 27255682Smarkm} 273178825Sdfr 274178825Sdfr/* 275178825Sdfr * Set the that the `sock' should bind to only IPv6 addresses. 276178825Sdfr */ 277178825Sdfr 278233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 279233294Sstassocket_set_ipv6only (rk_socket_t sock, int val) 280178825Sdfr{ 281178825Sdfr#if defined(IPV6_V6ONLY) && defined(HAVE_SETSOCKOPT) 282178825Sdfr setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&val, sizeof(val)); 283178825Sdfr#endif 284178825Sdfr} 285233294Sstas 286233294Sstas/** 287233294Sstas * Create a file descriptor from a socket 288233294Sstas * 289233294Sstas * While the socket handle in \a sock can be used with WinSock 290233294Sstas * functions after calling socket_to_fd(), it should not be closed 291233294Sstas * with rk_closesocket(). The socket will be closed when the associated 292233294Sstas * file descriptor is closed. 293233294Sstas */ 294233294SstasROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 295233294Sstassocket_to_fd(rk_socket_t sock, int flags) 296233294Sstas{ 297233294Sstas#ifndef _WIN32 298233294Sstas return sock; 299233294Sstas#else 300233294Sstas return _open_osfhandle((intptr_t) sock, flags); 301233294Sstas#endif 302233294Sstas} 303233294Sstas 304233294Sstas#ifdef HAVE_WINSOCK 305233294SstasROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 306233294Sstasrk_SOCK_IOCTL(SOCKET s, long cmd, int * argp) { 307233294Sstas u_long ul = (argp)? *argp : 0; 308233294Sstas int rv; 309233294Sstas 310233294Sstas rv = ioctlsocket(s, cmd, &ul); 311233294Sstas if (argp) 312233294Sstas *argp = (int) ul; 313233294Sstas return rv; 314233294Sstas} 315233294Sstas#endif 316233294Sstas 317233294Sstas#ifndef HEIMDAL_SMALLER 318233294Sstas#undef socket 319233294Sstas 320233294Sstasint rk_socket(int, int, int); 321233294Sstas 322233294Sstasint 323233294Sstasrk_socket(int domain, int type, int protocol) 324233294Sstas{ 325233294Sstas int s; 326233294Sstas s = socket (domain, type, protocol); 327233294Sstas#ifdef SOCK_CLOEXEC 328233294Sstas if ((SOCK_CLOEXEC & type) && s < 0 && errno == EINVAL) { 329233294Sstas type &= ~SOCK_CLOEXEC; 330233294Sstas s = socket (domain, type, protocol); 331233294Sstas } 332233294Sstas#endif 333233294Sstas return s; 334233294Sstas} 335233294Sstas 336233294Sstas#endif /* HEIMDAL_SMALLER */ 337