2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * Copyright (c) 1982, 1986, 1990, 1993
32 * The Regents of the University of California. All rights reserved.
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in the
41 * documentation and/or other materials provided with the distribution.
42 * 3. All advertising materials mentioning features or use of this software
43 * must display the following acknowledgement:
44 * This product includes software developed by the University of
45 * California, Berkeley and its contributors.
46 * 4. Neither the name of the University nor the names of its contributors
47 * may be used to endorse or promote products derived from this software
48 * without specific prior written permission.
50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * Compatability shims with the rfc2553 API to simplify ntp.
72 #include <sys/types.h>
74 #include <sys/socket.h>
75 #include "ntp_rfc2553.h"
76 #ifdef HAVE_NETINET_IN_H
77 #include <netinet/in.h>
82 #include "ntp_malloc.h"
83 #include "ntp_stdlib.h"
84 #include "ntp_string.h"
88 #if defined(SYS_WINNT)
89 /* XXX This is the preferred way, but for some reason the SunOS compiler
92 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
94 const struct in6_addr in6addr_any;
97 static char *ai_errlist[] = {
99 "Address family for hostname not supported", /* EAI_ADDRFAMILY */
100 "Temporary failure in name resolution", /* EAI_AGAIN */
101 "Invalid value for ai_flags", /* EAI_BADFLAGS */
102 "Non-recoverable failure in name resolution", /* EAI_FAIL */
103 "ai_family not supported", /* EAI_FAMILY */
104 "Memory allocation failure", /* EAI_MEMORY */
105 "No address associated with hostname", /* EAI_NODATA */
106 "hostname nor servname provided, or not known", /* EAI_NONAME */
107 "servname not supported for ai_socktype", /* EAI_SERVICE */
108 "ai_socktype not supported", /* EAI_SOCKTYPE */
109 "System error returned in errno", /* EAI_SYSTEM */
110 "Invalid value for hints", /* EAI_BADHINTS */
111 "Resolved protocol is unknown", /* EAI_PROTOCOL */
112 "Unknown error", /* EAI_MAX */
115 static int ipv4_aton P((const char *, struct sockaddr_storage *));
116 static int do_nodename P((const char *nodename, struct addrinfo *ai,
117 const struct addrinfo *hints));
120 getaddrinfo (const char *nodename, const char *servname,
121 const struct addrinfo *hints, struct addrinfo **res)
125 struct sockaddr_in *sockin;
127 ai = calloc(sizeof(struct addrinfo), 1);
131 if (nodename != NULL) {
132 rval = do_nodename(nodename, ai, hints);
138 if (nodename == NULL && hints != NULL) {
139 ai->ai_addr = calloc(sizeof(struct sockaddr_storage), 1);
140 if (ai->ai_addr == NULL) {
144 ai->ai_family = AF_INET;
145 ai->ai_addrlen = sizeof(struct sockaddr_storage);
146 sockin = (struct sockaddr_in *)ai->ai_addr;
147 sockin->sin_family = AF_INET;
148 sockin->sin_addr.s_addr = htonl(INADDR_ANY);
149 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
150 ai->ai_addr->sa_len = SOCKLEN(ai->ai_addr);
153 if (servname != NULL) {
154 ai->ai_family = AF_INET;
155 ai->ai_socktype = SOCK_DGRAM;
156 if (strcmp(servname, "ntp") != 0) {
158 return (EAI_SERVICE);
160 sockin = (struct sockaddr_in *)ai->ai_addr;
161 sockin->sin_port = htons(NTP_PORT);
168 freeaddrinfo(struct addrinfo *ai)
170 if (ai->ai_canonname != NULL)
171 free(ai->ai_canonname);
172 if (ai->ai_addr != NULL)
178 getnameinfo (const struct sockaddr *sa, u_int salen, char *host,
179 size_t hostlen, char *serv, size_t servlen, int flags)
183 if (sa->sa_family != AF_INET)
186 (const char *)&((const struct sockaddr_in *)sa)->sin_addr,
189 if (h_errno == TRY_AGAIN)
195 strncpy(host, hp->h_name, hostlen);
196 host[hostlen] = '\0';
202 gai_strerror(int ecode)
204 if (ecode < 0 || ecode > EAI_MAX)
206 return ai_errlist[ecode];
211 const char *nodename,
213 const struct addrinfo *hints)
216 struct sockaddr_in *sockin;
218 ai->ai_addr = calloc(sizeof(struct sockaddr_storage), 1);
219 if (ai->ai_addr == NULL)
222 if (hints != NULL && hints->ai_flags & AI_NUMERICHOST) {
223 if (ipv4_aton(nodename,
224 (struct sockaddr_storage *)ai->ai_addr) == 1) {
225 ai->ai_family = AF_INET;
226 ai->ai_addrlen = sizeof(struct sockaddr_in);
231 hp = gethostbyname(nodename);
233 if (h_errno == TRY_AGAIN)
236 if (ipv4_aton(nodename,
237 (struct sockaddr_storage *)ai->ai_addr) == 1) {
238 ai->ai_family = AF_INET;
239 ai->ai_addrlen = sizeof(struct sockaddr_in);
245 ai->ai_family = hp->h_addrtype;
246 ai->ai_addrlen = sizeof(struct sockaddr);
247 sockin = (struct sockaddr_in *)ai->ai_addr;
248 memcpy(&sockin->sin_addr, hp->h_addr, hp->h_length);
249 ai->ai_addr->sa_family = hp->h_addrtype;
250 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
251 ai->ai_addr->sa_len = sizeof(struct sockaddr);
253 if (hints != NULL && hints->ai_flags & AI_CANONNAME) {
254 ai->ai_canonname = malloc(strlen(hp->h_name) + 1);
255 if (ai->ai_canonname == NULL)
257 strcpy(ai->ai_canonname, hp->h_name);
263 * ipv4_aton - return a net number (this is crude, but careful)
268 struct sockaddr_storage *saddr
275 char buf[80]; /* will core dump on really stupid stuff */
277 struct sockaddr_in *addr;
281 for (i = 0; i < 4; i++) {
283 while (isdigit((int)*cp))
291 } else if (*cp != '\0')
302 printf("ipv4_aton %s step %d buf %s temp %d netnum %lu\n",
303 num, i, buf, temp, (u_long)netnum);
311 "ipv4_aton: \"%s\" invalid host number, line ignored\n",
318 * make up socket address. Clear it out for neatness.
320 memset((void *)saddr, 0, sizeof(struct sockaddr_storage));
321 addr = (struct sockaddr_in *)saddr;
322 addr->sin_family = AF_INET;
323 addr->sin_port = htons(NTP_PORT);
324 addr->sin_addr.s_addr = htonl(netnum);
327 printf("ipv4_aton given %s, got %s.\n", num, ntoa(saddr));
331 #endif /* !HAVE_IPV6 */