diff --git a/lib/isc/unix/net.c b/lib/isc/unix/net.c new file mode 100644 index 0000000000..9ab9b6946f --- /dev/null +++ b/lib/isc/unix/net.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +static isc_once_t once = ISC_ONCE_INIT; +static isc_result_t ipv4_result = ISC_R_NOTFOUND; +static isc_result_t ipv6_result = ISC_R_NOTFOUND; + +static isc_result_t +try_proto(int domain) { + int s; + + s = socket(domain, SOCK_STREAM, 0); + if (s == -1) { + switch (errno) { +#ifdef EAFNOSUPPORT + case EAFNOSUPPORT: +#endif +#ifdef EINVAL + case EINVAL: +#endif + return (ISC_R_NOTFOUND); + default: + UNEXPECTED_ERROR(__FILE__, __LINE__, + "socket() failed: %s", + strerror(errno)); + return (ISC_R_UNEXPECTED); + } + } + close (s); + + return (ISC_R_SUCCESS); +} + +static void +initialize_action(void) { + ipv4_result = try_proto(PF_INET); +#ifdef ISC_NET_HAVEIPV6 + ipv6_result = try_proto(PF_INET6); +#endif +} + +static void +initialize(void) { + RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); +} + +isc_result_t +isc_net_haveipv4(void) { + + /* + * Check if the system's kernel supports IPv4. + */ + + initialize(); + return (ipv4_result); +} + +isc_result_t +isc_net_haveipv6(void) { + + /* + * Check if the system's kernel supports IPv6. + */ + + initialize(); + return (ipv6_result); +}