net.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004, 2005, 2007, 2008, 2012-2014  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1999-2003  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id$ */
00019 
00020 #ifndef ISC_NET_H
00021 #define ISC_NET_H 1
00022 
00023 /*****
00024  ***** Module Info
00025  *****/
00026 
00027 /*! \file
00028  * \brief
00029  * Basic Networking Types
00030  *
00031  * This module is responsible for defining the following basic networking
00032  * types:
00033  *
00034  *\li           struct in_addr
00035  *\li           struct in6_addr
00036  *\li           struct in6_pktinfo
00037  *\li           struct sockaddr
00038  *\li           struct sockaddr_in
00039  *\li           struct sockaddr_in6
00040  *\li           struct sockaddr_storage
00041  *\li           in_port_t
00042  *
00043  * It ensures that the AF_ and PF_ macros are defined.
00044  *
00045  * It declares ntoh[sl]() and hton[sl]().
00046  *
00047  * It declares inet_aton(), inet_ntop(), and inet_pton().
00048  *
00049  * It ensures that #INADDR_LOOPBACK, #INADDR_ANY, #IN6ADDR_ANY_INIT,
00050  * in6addr_any, and in6addr_loopback are available.
00051  *
00052  * It ensures that IN_MULTICAST() is available to check for multicast
00053  * addresses.
00054  *
00055  * MP:
00056  *\li   No impact.
00057  *
00058  * Reliability:
00059  *\li   No anticipated impact.
00060  *
00061  * Resources:
00062  *\li   N/A.
00063  *
00064  * Security:
00065  *\li   No anticipated impact.
00066  *
00067  * Standards:
00068  *\li   BSD Socket API
00069  *\li   RFC2553
00070  */
00071 
00072 /***
00073  *** Imports.
00074  ***/
00075 #include <isc/platform.h>
00076 
00077 #include <sys/types.h>
00078 #include <sys/socket.h>         /* Contractual promise. */
00079 
00080 #include <net/if.h>
00081 
00082 #include <netinet/in.h>         /* Contractual promise. */
00083 #include <arpa/inet.h>          /* Contractual promise. */
00084 #ifdef ISC_PLATFORM_NEEDNETINETIN6H
00085 #include <netinet/in6.h>        /* Required on UnixWare. */
00086 #endif
00087 #ifdef ISC_PLATFORM_NEEDNETINET6IN6H
00088 #include <netinet6/in6.h>       /* Required on BSD/OS for in6_pktinfo. */
00089 #endif
00090 
00091 #ifndef ISC_PLATFORM_HAVEIPV6
00092 #include <isc/ipv6.h>           /* Contractual promise. */
00093 #endif
00094 
00095 #include <isc/lang.h>
00096 #include <isc/types.h>
00097 
00098 #ifdef ISC_PLATFORM_HAVEINADDR6
00099 #define in6_addr in_addr6       /*%< Required for pre RFC2133 implementations. */
00100 #endif
00101 
00102 #ifdef ISC_PLATFORM_HAVEIPV6
00103 #ifndef IN6ADDR_ANY_INIT
00104 #ifdef s6_addr
00105 /*%
00106  * Required for some pre RFC2133 implementations.
00107  * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in
00108  * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt.
00109  * If 's6_addr' is defined then assume that there is a union and three
00110  * levels otherwise assume two levels required.
00111  */
00112 #define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
00113 #else
00114 #define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }
00115 #endif
00116 #endif
00117 
00118 #ifndef IN6ADDR_LOOPBACK_INIT
00119 #ifdef s6_addr
00120 /*% IPv6 address loopback init */
00121 #define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
00122 #else
00123 #define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } }
00124 #endif
00125 #endif
00126 
00127 #ifndef IN6_IS_ADDR_V4MAPPED
00128 /*% Is IPv6 address V4 mapped? */
00129 #define IN6_IS_ADDR_V4MAPPED(x) \
00130          (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \
00131           (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff)
00132 #endif
00133 
00134 #ifndef IN6_IS_ADDR_V4COMPAT
00135 /*% Is IPv6 address V4 compatible? */
00136 #define IN6_IS_ADDR_V4COMPAT(x) \
00137          (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \
00138          ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \
00139           (x)->s6_addr[14] != 0 || \
00140           ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1)))
00141 #endif
00142 
00143 #ifndef IN6_IS_ADDR_MULTICAST
00144 /*% Is IPv6 address multicast? */
00145 #define IN6_IS_ADDR_MULTICAST(a)        ((a)->s6_addr[0] == 0xff)
00146 #endif
00147 
00148 #ifndef IN6_IS_ADDR_LINKLOCAL
00149 /*% Is IPv6 address linklocal? */
00150 #define IN6_IS_ADDR_LINKLOCAL(a) \
00151         (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
00152 #endif
00153 
00154 #ifndef IN6_IS_ADDR_SITELOCAL
00155 /*% is IPv6 address sitelocal? */
00156 #define IN6_IS_ADDR_SITELOCAL(a) \
00157         (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
00158 #endif
00159 
00160 
00161 #ifndef IN6_IS_ADDR_LOOPBACK
00162 /*% is IPv6 address loopback? */
00163 #define IN6_IS_ADDR_LOOPBACK(x) \
00164         (memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0)
00165 #endif
00166 #endif
00167 
00168 #ifndef AF_INET6
00169 /*% IPv6 */
00170 #define AF_INET6 99
00171 #endif
00172 
00173 #ifndef PF_INET6
00174 /*% IPv6 */
00175 #define PF_INET6 AF_INET6
00176 #endif
00177 
00178 #ifndef INADDR_LOOPBACK
00179 /*% inaddr loopback */
00180 #define INADDR_LOOPBACK 0x7f000001UL
00181 #endif
00182 
00183 #ifndef ISC_PLATFORM_HAVEIN6PKTINFO
00184 /*% IPv6 packet info */
00185 struct in6_pktinfo {
00186         struct in6_addr ipi6_addr;    /*%< src/dst IPv6 address */
00187         unsigned int    ipi6_ifindex; /*%< send/recv interface index */
00188 };
00189 #endif
00190 
00191 
00192 #ifndef ISC_PLATFORM_HAVESOCKADDRSTORAGE
00193 #define _SS_MAXSIZE 128
00194 #define _SS_ALIGNSIZE  (sizeof (isc_uint64_t))
00195 #ifdef ISC_PLATFORM_HAVESALEN
00196 #define _SS_PAD1SIZE (_SS_ALIGNSIZE - (2 * sizeof(isc_uint8_t)))
00197 #define _SS_PAD2SIZE (_SS_MAXSIZE - (_SS_ALIGNSIZE + _SS_PAD1SIZE \
00198                        + 2 * sizeof(isc_uint8_t)))
00199 #else
00200 #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(isc_uint16_t))
00201 #define _SS_PAD2SIZE (_SS_MAXSIZE - (_SS_ALIGNSIZE + _SS_PAD1SIZE \
00202                         + sizeof(isc_uint16_t)))
00203 #endif
00204 
00205 struct sockaddr_storage {
00206 #ifdef ISC_PLATFORM_HAVESALEN
00207        isc_uint8_t             ss_len;
00208        isc_uint8_t             ss_family;
00209 #else
00210        isc_uint16_t            ss_family;
00211 #endif
00212        char                    __ss_pad1[_SS_PAD1SIZE];
00213        isc_uint64_t            __ss_align;  /* field to force desired structure */
00214        char                    __ss_pad2[_SS_PAD2SIZE];
00215 };
00216 #endif
00217 
00218 #if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRANY)
00219 extern const struct in6_addr isc_net_in6addrany;
00220 /*%
00221  * Cope with a missing in6addr_any and in6addr_loopback.
00222  */
00223 #define in6addr_any isc_net_in6addrany
00224 #endif
00225 
00226 #if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK)
00227 extern const struct in6_addr isc_net_in6addrloop;
00228 #define in6addr_loopback isc_net_in6addrloop
00229 #endif
00230 
00231 #ifdef ISC_PLATFORM_FIXIN6ISADDR
00232 #undef  IN6_IS_ADDR_GEOGRAPHIC
00233 /*!
00234  * \brief
00235  * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions.
00236  */
00237 #define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80)
00238 #undef  IN6_IS_ADDR_IPX
00239 #define IN6_IS_ADDR_IPX(a)        (((a)->S6_un.S6_l[0] & 0xFE) == 0x04)
00240 #undef  IN6_IS_ADDR_LINKLOCAL
00241 #define IN6_IS_ADDR_LINKLOCAL(a)  (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE)
00242 #undef  IN6_IS_ADDR_MULTICAST
00243 #define IN6_IS_ADDR_MULTICAST(a)  (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF)
00244 #undef  IN6_IS_ADDR_NSAP
00245 #define IN6_IS_ADDR_NSAP(a)       (((a)->S6_un.S6_l[0] & 0xFE) == 0x02)
00246 #undef  IN6_IS_ADDR_PROVIDER
00247 #define IN6_IS_ADDR_PROVIDER(a)   (((a)->S6_un.S6_l[0] & 0xE0) == 0x40)
00248 #undef  IN6_IS_ADDR_SITELOCAL
00249 #define IN6_IS_ADDR_SITELOCAL(a)  (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE)
00250 #endif /* ISC_PLATFORM_FIXIN6ISADDR */
00251 
00252 #ifdef ISC_PLATFORM_NEEDPORTT
00253 /*%
00254  * Ensure type in_port_t is defined.
00255  */
00256 typedef isc_uint16_t in_port_t;
00257 #endif
00258 
00259 #ifndef MSG_TRUNC
00260 /*%
00261  * If this system does not have MSG_TRUNC (as returned from recvmsg())
00262  * ISC_PLATFORM_RECVOVERFLOW will be defined.  This will enable the MSG_TRUNC
00263  * faking code in socket.c.
00264  */
00265 #define ISC_PLATFORM_RECVOVERFLOW
00266 #endif
00267 
00268 /*% IP address. */
00269 #define ISC__IPADDR(x)  ((isc_uint32_t)htonl((isc_uint32_t)(x)))
00270 
00271 /*% Is IP address multicast? */
00272 #define ISC_IPADDR_ISMULTICAST(i) \
00273                 (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
00274                  == ISC__IPADDR(0xe0000000))
00275 
00276 #define ISC_IPADDR_ISEXPERIMENTAL(i) \
00277                 (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
00278                  == ISC__IPADDR(0xf0000000))
00279 
00280 /***
00281  *** Functions.
00282  ***/
00283 
00284 ISC_LANG_BEGINDECLS
00285 
00286 isc_result_t
00287 isc_net_probeipv4(void);
00288 /*%<
00289  * Check if the system's kernel supports IPv4.
00290  *
00291  * Returns:
00292  *
00293  *\li   #ISC_R_SUCCESS          IPv4 is supported.
00294  *\li   #ISC_R_NOTFOUND         IPv4 is not supported.
00295  *\li   #ISC_R_DISABLED         IPv4 is disabled.
00296  *\li   #ISC_R_UNEXPECTED
00297  */
00298 
00299 isc_result_t
00300 isc_net_probeipv6(void);
00301 /*%<
00302  * Check if the system's kernel supports IPv6.
00303  *
00304  * Returns:
00305  *
00306  *\li   #ISC_R_SUCCESS          IPv6 is supported.
00307  *\li   #ISC_R_NOTFOUND         IPv6 is not supported.
00308  *\li   #ISC_R_DISABLED         IPv6 is disabled.
00309  *\li   #ISC_R_UNEXPECTED
00310  */
00311 
00312 isc_result_t
00313 isc_net_probe_ipv6only(void);
00314 /*%<
00315  * Check if the system's kernel supports the IPV6_V6ONLY socket option.
00316  *
00317  * Returns:
00318  *
00319  *\li   #ISC_R_SUCCESS          the option is supported for both TCP and UDP.
00320  *\li   #ISC_R_NOTFOUND         IPv6 itself or the option is not supported.
00321  *\li   #ISC_R_UNEXPECTED
00322  */
00323 
00324 isc_result_t
00325 isc_net_probe_ipv6pktinfo(void);
00326 /*
00327  * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
00328  * for UDP sockets.
00329  *
00330  * Returns:
00331  *
00332  * \li  #ISC_R_SUCCESS          the option is supported.
00333  * \li  #ISC_R_NOTFOUND         IPv6 itself or the option is not supported.
00334  * \li  #ISC_R_UNEXPECTED
00335  */
00336 
00337 void
00338 isc_net_disableipv4(void);
00339 
00340 void
00341 isc_net_disableipv6(void);
00342 
00343 void
00344 isc_net_enableipv4(void);
00345 
00346 void
00347 isc_net_enableipv6(void);
00348 
00349 isc_result_t
00350 isc_net_probeunix(void);
00351 /*
00352  * Returns whether UNIX domain sockets are supported.
00353  */
00354 
00355 #define ISC_NET_DSCPRECVV4      0x01    /* Can receive sent DSCP value IPv4 */
00356 #define ISC_NET_DSCPRECVV6      0x02    /* Can receive sent DSCP value IPv6 */
00357 #define ISC_NET_DSCPSETV4       0x04    /* Can set DSCP on socket IPv4 */
00358 #define ISC_NET_DSCPSETV6       0x08    /* Can set DSCP on socket IPv6 */
00359 #define ISC_NET_DSCPPKTV4       0x10    /* Can set DSCP on per packet IPv4 */
00360 #define ISC_NET_DSCPPKTV6       0x20    /* Can set DSCP on per packet IPv6 */
00361 #define ISC_NET_DSCPALL         0x3f    /* All valid flags */
00362 
00363 unsigned int
00364 isc_net_probedscp(void);
00365 /*%<
00366  * Probe the level of DSCP support.
00367  */
00368 
00369 
00370 isc_result_t
00371 isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
00372 /*%<
00373  * Returns system's default range of ephemeral UDP ports, if defined.
00374  * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
00375  * ISC_NET_PORTRANGEHIGH will be returned.
00376  *
00377  * Requires:
00378  *
00379  *\li   'low' and 'high' must be non NULL.
00380  *
00381  * Returns:
00382  *
00383  *\li   *low and *high will be the ports specifying the low and high ends of
00384  *      the range.
00385  */
00386 
00387 #ifdef ISC_PLATFORM_NEEDNTOP
00388 const char *
00389 isc_net_ntop(int af, const void *src, char *dst, size_t size);
00390 #define inet_ntop isc_net_ntop
00391 #endif
00392 
00393 #ifdef ISC_PLATFORM_NEEDPTON
00394 int
00395 isc_net_pton(int af, const char *src, void *dst);
00396 #undef inet_pton
00397 #define inet_pton isc_net_pton
00398 #endif
00399 
00400 int
00401 isc_net_aton(const char *cp, struct in_addr *addr);
00402 #undef inet_aton
00403 #define inet_aton isc_net_aton
00404 
00405 ISC_LANG_ENDDECLS
00406 
00407 #endif /* ISC_NET_H */

Generated on Tue Apr 28 17:41:05 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha