]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ntp/libisc/net.c
Fix compilation with gcc 4.1. This is imported on the vendor branch as it
[FreeBSD/FreeBSD.git] / contrib / ntp / libisc / net.c
1 /*
2  * Copyright (C) 1999-2001  Internet Software Consortium.
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
9  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
10  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
11  * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
13  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
14  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: net.c,v 1.25 2001/11/30 01:59:45 gson Exp $ */
19
20 #include <config.h>
21
22 #include <errno.h>
23 #include <unistd.h>
24
25 #include <isc/net.h>
26 #include <isc/strerror.h>
27 #include <isc/string.h>
28 #include <isc/util.h>
29
30 #if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRANY)
31 const struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT;
32 #endif
33
34 static isc_boolean_t    once = ISC_FALSE;
35 static isc_result_t     ipv4_result = ISC_R_NOTFOUND;
36 static isc_result_t     ipv6_result = ISC_R_NOTFOUND;
37
38 static isc_result_t
39 try_proto(int domain) {
40         int s;
41         isc_result_t result = ISC_R_SUCCESS;
42         char strbuf[ISC_STRERRORSIZE];
43
44         s = socket(domain, SOCK_STREAM, 0);
45         if (s == -1) {
46                 switch (errno) {
47 #ifdef EAFNOSUPPORT
48                 case EAFNOSUPPORT:
49 #endif
50 #ifdef EPROTONOSUPPORT
51                 case EPROTONOSUPPORT:
52 #endif
53 #ifdef EINVAL
54                 case EINVAL:
55 #endif
56                         return (ISC_R_NOTFOUND);
57                 default:
58                         isc__strerror(errno, strbuf, sizeof(strbuf));
59                         UNEXPECTED_ERROR(__FILE__, __LINE__,
60                                          "socket() %s failed",
61                                          strbuf);
62                         return (ISC_R_UNEXPECTED);
63                 }
64         }
65
66 #ifdef ISC_PLATFORM_HAVEIPV6
67 #ifdef ISC_PLATFORM_HAVEIN6PKTINFO
68         if (domain == PF_INET6) {
69                 struct sockaddr_in6 sin6;
70                 unsigned int len;
71
72                 /*
73                  * Check to see if IPv6 is broken, as is common on Linux.
74                  */
75                 len = sizeof(sin6);
76                 if (getsockname(s, (struct sockaddr *)&sin6, (void *)&len) < 0)
77                 {
78                         result = ISC_R_NOTFOUND;
79                 } else {
80                         if (len == sizeof(struct sockaddr_in6))
81                                 result = ISC_R_SUCCESS;
82                         else {
83                                 result = ISC_R_NOTFOUND;
84                         }
85                 }
86         }
87 #endif
88 #endif
89
90         (void)close(s);
91
92         return (result);
93 }
94
95 static void
96 initialize_action(void) {
97         ipv4_result = try_proto(PF_INET);
98 #ifdef ISC_PLATFORM_HAVEIPV6
99 #ifdef ISC_PLATFORM_HAVEIN6PKTINFO
100         ipv6_result = try_proto(PF_INET6);
101 #endif
102 #endif
103 }
104
105 static void
106 initialize(void) {
107         if(once == ISC_FALSE) {
108                 initialize_action();
109                 once = ISC_TRUE;
110         }
111 }
112
113 isc_result_t
114 isc_net_probeipv4(void) {
115         initialize();
116         return (ipv4_result);
117 }
118
119 isc_result_t
120 isc_net_probeipv6(void) {
121         initialize();
122         return (ipv6_result);
123 }