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
);