Home | History | Annotate | Line # | Download | only in isc
      1 /*	$NetBSD: net.h,v 1.1 2024/02/18 20:57:57 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #ifndef ISC_NET_H
     17 #define ISC_NET_H 1
     18 
     19 /*****
     20 ***** Module Info
     21 *****/
     22 
     23 /*! \file
     24  * \brief
     25  * Basic Networking Types
     26  *
     27  * This module is responsible for defining the following basic networking
     28  * types:
     29  *
     30  *\li		struct in_addr
     31  *\li		struct in6_addr
     32  *\li		struct in6_pktinfo
     33  *\li		struct sockaddr
     34  *\li		struct sockaddr_in
     35  *\li		struct sockaddr_in6
     36  *\li		struct sockaddr_storage
     37  *\li		in_port_t
     38  *
     39  * It ensures that the AF_ and PF_ macros are defined.
     40  *
     41  * It declares ntoh[sl]() and hton[sl]().
     42  *
     43  * It declares inet_ntop(), and inet_pton().
     44  *
     45  * It ensures that #INADDR_LOOPBACK, #INADDR_ANY, #IN6ADDR_ANY_INIT,
     46  * IN6ADDR_V4MAPPED_INIT, in6addr_any, and in6addr_loopback are available.
     47  *
     48  * It ensures that IN_MULTICAST() is available to check for multicast
     49  * addresses.
     50  *
     51  * MP:
     52  *\li	No impact.
     53  *
     54  * Reliability:
     55  *\li	No anticipated impact.
     56  *
     57  * Resources:
     58  *\li	N/A.
     59  *
     60  * Security:
     61  *\li	No anticipated impact.
     62  *
     63  * Standards:
     64  *\li	BSD Socket API
     65  *\li	RFC2553
     66  */
     67 
     68 /***
     69  *** Imports.
     70  ***/
     71 #include <inttypes.h>
     72 
     73 #include <isc/lang.h>
     74 #include <isc/platform.h>
     75 #include <isc/types.h>
     76 
     77 #include <arpa/inet.h> /* Contractual promise. */
     78 #include <net/if.h>
     79 #include <netinet/in.h> /* Contractual promise. */
     80 #include <sys/socket.h> /* Contractual promise. */
     81 #include <sys/types.h>
     82 
     83 #ifndef IN6ADDR_LOOPBACK_INIT
     84 #ifdef s6_addr
     85 /*% IPv6 address loopback init */
     86 #define IN6ADDR_LOOPBACK_INIT                                                  \
     87 	{                                                                      \
     88 		{                                                              \
     89 			{                                                      \
     90 				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \
     91 			}                                                      \
     92 		}                                                              \
     93 	}
     94 #else /* ifdef s6_addr */
     95 #define IN6ADDR_LOOPBACK_INIT                                          \
     96 	{                                                              \
     97 		{                                                      \
     98 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \
     99 		}                                                      \
    100 	}
    101 #endif /* ifdef s6_addr */
    102 #endif /* ifndef IN6ADDR_LOOPBACK_INIT */
    103 
    104 #ifndef IN6ADDR_V4MAPPED_INIT
    105 #ifdef s6_addr
    106 /*% IPv6 v4mapped prefix init */
    107 #define IN6ADDR_V4MAPPED_INIT                                                \
    108 	{                                                                    \
    109 		{                                                            \
    110 			{                                                    \
    111 				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, \
    112 					0, 0, 0                              \
    113 			}                                                    \
    114 		}                                                            \
    115 	}
    116 #else /* ifdef s6_addr */
    117 #define IN6ADDR_V4MAPPED_INIT                                                \
    118 	{                                                                    \
    119 		{                                                            \
    120 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0 \
    121 		}                                                            \
    122 	}
    123 #endif /* ifdef s6_addr */
    124 #endif /* ifndef IN6ADDR_V4MAPPED_INIT */
    125 
    126 #ifndef IN6_IS_ADDR_V4MAPPED
    127 /*% Is IPv6 address V4 mapped? */
    128 #define IN6_IS_ADDR_V4MAPPED(x)                                \
    129 	(memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \
    130 	 (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff)
    131 #endif /* ifndef IN6_IS_ADDR_V4MAPPED */
    132 
    133 #ifndef IN6_IS_ADDR_V4COMPAT
    134 /*% Is IPv6 address V4 compatible? */
    135 #define IN6_IS_ADDR_V4COMPAT(x)                                \
    136 	(memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \
    137 	 ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 ||    \
    138 	  (x)->s6_addr[14] != 0 ||                             \
    139 	  ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1)))
    140 #endif /* ifndef IN6_IS_ADDR_V4COMPAT */
    141 
    142 #ifndef IN6_IS_ADDR_MULTICAST
    143 /*% Is IPv6 address multicast? */
    144 #define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff)
    145 #endif /* ifndef IN6_IS_ADDR_MULTICAST */
    146 
    147 #ifndef IN6_IS_ADDR_LINKLOCAL
    148 /*% Is IPv6 address linklocal? */
    149 #define IN6_IS_ADDR_LINKLOCAL(a) \
    150 	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
    151 #endif /* ifndef IN6_IS_ADDR_LINKLOCAL */
    152 
    153 #ifndef IN6_IS_ADDR_SITELOCAL
    154 /*% is IPv6 address sitelocal? */
    155 #define IN6_IS_ADDR_SITELOCAL(a) \
    156 	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
    157 #endif /* ifndef IN6_IS_ADDR_SITELOCAL */
    158 
    159 #ifndef IN6_IS_ADDR_LOOPBACK
    160 /*% is IPv6 address loopback? */
    161 #define IN6_IS_ADDR_LOOPBACK(x) \
    162 	(memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0)
    163 #endif /* ifndef IN6_IS_ADDR_LOOPBACK */
    164 
    165 #ifndef AF_INET6
    166 /*% IPv6 */
    167 #define AF_INET6 99
    168 #endif /* ifndef AF_INET6 */
    169 
    170 #ifndef PF_INET6
    171 /*% IPv6 */
    172 #define PF_INET6 AF_INET6
    173 #endif /* ifndef PF_INET6 */
    174 
    175 #ifndef INADDR_ANY
    176 /*% inaddr any */
    177 #define INADDR_ANY 0x00000000UL
    178 #endif /* ifndef INADDR_ANY */
    179 
    180 #ifndef INADDR_LOOPBACK
    181 /*% inaddr loopback */
    182 #define INADDR_LOOPBACK 0x7f000001UL
    183 #endif /* ifndef INADDR_LOOPBACK */
    184 
    185 #ifndef MSG_TRUNC
    186 /*%
    187  * If this system does not have MSG_TRUNC (as returned from recvmsg())
    188  * ISC_PLATFORM_RECVOVERFLOW will be defined.  This will enable the MSG_TRUNC
    189  * faking code in socket.c.
    190  */
    191 #define ISC_PLATFORM_RECVOVERFLOW
    192 #endif /* ifndef MSG_TRUNC */
    193 
    194 /*% IP address. */
    195 #define ISC__IPADDR(x) ((uint32_t)htonl((uint32_t)(x)))
    196 
    197 /*% Is IP address multicast? */
    198 #define ISC_IPADDR_ISMULTICAST(i) \
    199 	(((uint32_t)(i)&ISC__IPADDR(0xf0000000)) == ISC__IPADDR(0xe0000000))
    200 
    201 #define ISC_IPADDR_ISEXPERIMENTAL(i) \
    202 	(((uint32_t)(i)&ISC__IPADDR(0xf0000000)) == ISC__IPADDR(0xf0000000))
    203 
    204 /***
    205  *** Functions.
    206  ***/
    207 
    208 ISC_LANG_BEGINDECLS
    209 
    210 isc_result_t
    211 isc_net_probeipv4(void);
    212 /*%<
    213  * Check if the system's kernel supports IPv4.
    214  *
    215  * Returns:
    216  *
    217  *\li	#ISC_R_SUCCESS		IPv4 is supported.
    218  *\li	#ISC_R_NOTFOUND		IPv4 is not supported.
    219  *\li	#ISC_R_DISABLED		IPv4 is disabled.
    220  *\li	#ISC_R_UNEXPECTED
    221  */
    222 
    223 isc_result_t
    224 isc_net_probeipv6(void);
    225 /*%<
    226  * Check if the system's kernel supports IPv6.
    227  *
    228  * Returns:
    229  *
    230  *\li	#ISC_R_SUCCESS		IPv6 is supported.
    231  *\li	#ISC_R_NOTFOUND		IPv6 is not supported.
    232  *\li	#ISC_R_DISABLED		IPv6 is disabled.
    233  *\li	#ISC_R_UNEXPECTED
    234  */
    235 
    236 isc_result_t
    237 isc_net_probe_ipv6only(void);
    238 /*%<
    239  * Check if the system's kernel supports the IPV6_V6ONLY socket option.
    240  *
    241  * Returns:
    242  *
    243  *\li	#ISC_R_SUCCESS		the option is supported for both TCP and UDP.
    244  *\li	#ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
    245  *\li	#ISC_R_UNEXPECTED
    246  */
    247 
    248 isc_result_t
    249 isc_net_probe_ipv6pktinfo(void);
    250 /*
    251  * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
    252  * for UDP sockets.
    253  *
    254  * Returns:
    255  *
    256  * \li	#ISC_R_SUCCESS		the option is supported.
    257  * \li	#ISC_R_NOTFOUND		IPv6 itself or the option is not supported.
    258  * \li	#ISC_R_UNEXPECTED
    259  */
    260 
    261 void
    262 isc_net_disableipv4(void);
    263 
    264 void
    265 isc_net_disableipv6(void);
    266 
    267 void
    268 isc_net_enableipv4(void);
    269 
    270 void
    271 isc_net_enableipv6(void);
    272 
    273 isc_result_t
    274 isc_net_probeunix(void);
    275 /*
    276  * Returns whether UNIX domain sockets are supported.
    277  */
    278 
    279 #define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */
    280 #define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */
    281 #define ISC_NET_DSCPSETV4  0x04 /* Can set DSCP on socket IPv4 */
    282 #define ISC_NET_DSCPSETV6  0x08 /* Can set DSCP on socket IPv6 */
    283 #define ISC_NET_DSCPPKTV4  0x10 /* Can set DSCP on per packet IPv4 */
    284 #define ISC_NET_DSCPPKTV6  0x20 /* Can set DSCP on per packet IPv6 */
    285 #define ISC_NET_DSCPALL	   0x3f /* All valid flags */
    286 
    287 unsigned int
    288 isc_net_probedscp(void);
    289 /*%<
    290  * Probe the level of DSCP support.
    291  */
    292 
    293 isc_result_t
    294 isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
    295 /*%<
    296  * Returns system's default range of ephemeral UDP ports, if defined.
    297  * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
    298  * ISC_NET_PORTRANGEHIGH will be returned.
    299  *
    300  * Requires:
    301  *
    302  *\li	'low' and 'high' must be non NULL.
    303  *
    304  * Returns:
    305  *
    306  *\li	*low and *high will be the ports specifying the low and high ends of
    307  *	the range.
    308  */
    309 
    310 ISC_LANG_ENDDECLS
    311 
    312 #endif /* ISC_NET_H */
    313