LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/roken - socket.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 10 116 8.6 %
Date: 2024-06-13 04:01:37 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             :         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             :         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             :         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       28929 : socket_set_nonblocking(rk_socket_t sock, int nonblock)
     268             : {
     269             : #if defined(O_NONBLOCK)
     270       28929 :     int flags = fcntl(sock, F_GETFL, 0);
     271       28929 :     if (flags == -1)
     272           0 :         return;
     273       28929 :     if (nonblock)
     274       28929 :         flags |= O_NONBLOCK;
     275             :     else
     276           0 :         flags &= ~O_NONBLOCK;
     277       28929 :     fcntl(sock, F_SETFL, flags);
     278             : #elif defined(FIOBIO)
     279             :     int flags = !!nonblock;
     280             :     return ioctl(sock, FIOBIO, &flags);
     281             : #endif
     282             : }
     283             : 
     284             : /*
     285             :  * set the reuse of addresses on `sock' to `val'.
     286             :  */
     287             : 
     288             : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
     289           0 : socket_set_reuseaddr (rk_socket_t sock, int val)
     290             : {
     291             : #if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT)
     292             :     (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val,
     293             :                       sizeof(val));
     294             : #endif
     295           0 : }
     296             : 
     297             : /*
     298             :  * Set the that the `sock' should bind to only IPv6 addresses.
     299             :  */
     300             : 
     301             : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
     302           0 : socket_set_ipv6only (rk_socket_t sock, int val)
     303             : {
     304             : #if defined(IPV6_V6ONLY) && defined(HAVE_SETSOCKOPT)
     305             :     (void) setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&val,
     306             :                       sizeof(val));
     307             : #endif
     308           0 : }
     309             : 
     310             : /*
     311             :  * Set the that the `sock' keepalive setting.
     312             :  */
     313             : 
     314             : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
     315           0 : socket_set_keepalive(rk_socket_t sock, int val)
     316             : {
     317           0 :     (void) setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&val,
     318             :                       sizeof(val));
     319           0 : }
     320             : 
     321             : /**
     322             :  * Create a file descriptor from a socket
     323             :  *
     324             :  * While the socket handle in \a sock can be used with WinSock
     325             :  * functions after calling socket_to_fd(), it should not be closed
     326             :  * with rk_closesocket().  The socket will be closed when the associated
     327             :  * file descriptor is closed.
     328             :  */
     329             : ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
     330           0 : socket_to_fd(rk_socket_t sock, int flags)
     331             : {
     332             : #ifndef _WIN32
     333           0 :     return sock;
     334             : #else
     335             :     return _open_osfhandle((intptr_t) sock, flags);
     336             : #endif
     337             : }
     338             : 
     339             : #ifdef HAVE_WINSOCK
     340             : ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
     341             : rk_SOCK_IOCTL(SOCKET s, long cmd, int * argp) {
     342             :     u_long ul = (argp)? *argp : 0;
     343             :     int rv;
     344             : 
     345             :     rv = ioctlsocket(s, cmd, &ul);
     346             :     if (argp)
     347             :         *argp = (int) ul;
     348             :     return rv;
     349             : }
     350             : #endif
     351             : 
     352             : #ifndef HEIMDAL_SMALLER
     353             : #undef socket
     354             : 
     355             : int rk_socket(int, int, int);
     356             : 
     357             : int
     358       28960 : rk_socket(int domain, int type, int protocol)
     359             : {
     360             :     int s;
     361       28960 :     s = socket (domain, type, protocol);
     362             : #ifdef SOCK_CLOEXEC
     363       28960 :     if ((SOCK_CLOEXEC & type) && s < 0 && errno == EINVAL) {
     364           0 :         type &= ~SOCK_CLOEXEC;
     365           0 :         s = socket (domain, type, protocol);
     366             :     }
     367             : #endif
     368       28960 :     return s;
     369             : }
     370             : 
     371             : #endif /* HEIMDAL_SMALLER */

Generated by: LCOV version 1.13