2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2001 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: net.c,v 1.22.2.3 2004/03/09 06:12:11 marka Exp $ */
29 #include <isc/strerror.h>
30 #include <isc/string.h>
33 #if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRANY)
34 const struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT;
37 #if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK)
38 const struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT;
41 static isc_once_t once = ISC_ONCE_INIT;
42 static isc_result_t ipv4_result = ISC_R_NOTFOUND;
43 static isc_result_t ipv6_result = ISC_R_NOTFOUND;
46 try_proto(int domain) {
48 isc_result_t result = ISC_R_SUCCESS;
49 char strbuf[ISC_STRERRORSIZE];
51 s = socket(domain, SOCK_STREAM, 0);
57 #ifdef EPROTONOSUPPORT
63 return (ISC_R_NOTFOUND);
65 isc__strerror(errno, strbuf, sizeof(strbuf));
66 UNEXPECTED_ERROR(__FILE__, __LINE__,
68 isc_msgcat_get(isc_msgcat,
73 return (ISC_R_UNEXPECTED);
77 #ifdef ISC_PLATFORM_HAVEIPV6
79 #ifdef ISC_PLATFORM_HAVEIN6PKTINFO
80 if (domain == PF_INET6) {
81 struct sockaddr_in6 sin6;
85 * Check to see if IPv6 is broken, as is common on Linux.
88 if (getsockname(s, (struct sockaddr *)&sin6, (void *)&len) < 0)
90 isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
91 ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
92 "retrieving the address of an IPv6 "
93 "socket from the kernel failed.");
94 isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
95 ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
96 "IPv6 support is disabled.");
97 result = ISC_R_NOTFOUND;
99 if (len == sizeof(struct sockaddr_in6))
100 result = ISC_R_SUCCESS;
102 isc_log_write(isc_lctx,
103 ISC_LOGCATEGORY_GENERAL,
104 ISC_LOGMODULE_SOCKET,
106 "IPv6 structures in kernel and "
107 "user space do not match.");
108 isc_log_write(isc_lctx,
109 ISC_LOGCATEGORY_GENERAL,
110 ISC_LOGMODULE_SOCKET,
112 "IPv6 support is disabled.");
113 result = ISC_R_NOTFOUND;
127 initialize_action(void) {
128 ipv4_result = try_proto(PF_INET);
129 #ifdef ISC_PLATFORM_HAVEIPV6
131 #ifdef ISC_PLATFORM_HAVEIN6PKTINFO
132 ipv6_result = try_proto(PF_INET6);
140 RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
144 isc_net_probeipv4(void) {
146 return (ipv4_result);
150 isc_net_probeipv6(void) {
152 return (ipv6_result);