LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/roken - socket.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 11 120 9.2 %
Date: 2024-04-21 15:09:00 Functions: 2 16 12.5 %

          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 */

Generated by: LCOV version 1.14