ยปCore Development>Code coverage>Modules/getaddrinfo.c

Python code coverage for Modules/getaddrinfo.c

#countcontent
1n/a/*
2n/a * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3n/a * All rights reserved.
4n/a *
5n/a * Redistribution and use in source and binary forms, with or without
6n/a * modification, are permitted provided that the following conditions
7n/a * are met:
8n/a * 1. Redistributions of source code must retain the above copyright
9n/a * notice, this list of conditions and the following disclaimer.
10n/a * 2. Redistributions in binary form must reproduce the above copyright
11n/a * notice, this list of conditions and the following disclaimer in the
12n/a * documentation and/or other materials provided with the distribution.
13n/a * 3. Neither the name of the project nor the names of its contributors
14n/a * may be used to endorse or promote products derived from this software
15n/a * without specific prior written permission.
16n/a *
17n/a * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18n/a * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19n/a * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20n/a * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21n/a * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22n/a * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23n/a * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24n/a * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25n/a * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26n/a * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27n/a * SUCH DAMAGE.
28n/a */
29n/a
30n/a/*
31n/a * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
32n/a *
33n/a * Issues to be discussed:
34n/a * - Thread safe-ness must be checked.
35n/a * - Return values. There are nonstandard return values defined and used
36n/a * in the source code. This is because RFC2133 is silent about which error
37n/a * code must be returned for which situation.
38n/a * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag.
39n/a */
40n/a
41n/a#if 0
42n/a#include <sys/types.h>
43n/a#include <sys/param.h>
44n/a#include <sys/sysctl.h>
45n/a#include <sys/socket.h>
46n/a#include <netinet/in.h>
47n/a#include <arpa/inet.h>
48n/a#include <arpa/nameser.h>
49n/a#include <netdb.h>
50n/a#include <resolv.h>
51n/a#include <string.h>
52n/a#include <stdlib.h>
53n/a#include <stddef.h>
54n/a#include <ctype.h>
55n/a#include <unistd.h>
56n/a
57n/a#include "addrinfo.h"
58n/a#endif
59n/a
60n/a#if defined(__KAME__) && defined(ENABLE_IPV6)
61n/a# define FAITH
62n/a#endif
63n/a
64n/a#define SUCCESS 0
65n/a#define GAI_ANY 0
66n/a#define YES 1
67n/a#define NO 0
68n/a
69n/a#ifdef FAITH
70n/astatic int translate = NO;
71n/astatic struct in6_addr faith_prefix = IN6ADDR_GAI_ANY_INIT;
72n/a#endif
73n/a
74n/astatic const char in_addrany[] = { 0, 0, 0, 0 };
75n/astatic const char in6_addrany[] = {
76n/a 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
77n/a};
78n/astatic const char in_loopback[] = { 127, 0, 0, 1 };
79n/astatic const char in6_loopback[] = {
80n/a 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
81n/a};
82n/a
83n/astruct sockinet {
84n/a u_char si_len;
85n/a u_char si_family;
86n/a u_short si_port;
87n/a};
88n/a
89n/astatic struct gai_afd {
90n/a int a_af;
91n/a int a_addrlen;
92n/a int a_socklen;
93n/a int a_off;
94n/a const char *a_addrany;
95n/a const char *a_loopback;
96n/a} gai_afdl [] = {
97n/a#ifdef ENABLE_IPV6
98n/a#define N_INET6 0
99n/a {PF_INET6, sizeof(struct in6_addr),
100n/a sizeof(struct sockaddr_in6),
101n/a offsetof(struct sockaddr_in6, sin6_addr),
102n/a in6_addrany, in6_loopback},
103n/a#define N_INET 1
104n/a#else
105n/a#define N_INET 0
106n/a#endif
107n/a {PF_INET, sizeof(struct in_addr),
108n/a sizeof(struct sockaddr_in),
109n/a offsetof(struct sockaddr_in, sin_addr),
110n/a in_addrany, in_loopback},
111n/a {0, 0, 0, 0, NULL, NULL},
112n/a};
113n/a
114n/a#ifdef ENABLE_IPV6
115n/a#define PTON_MAX 16
116n/a#else
117n/a#define PTON_MAX 4
118n/a#endif
119n/a
120n/a#ifndef IN_MULTICAST
121n/a#define IN_MULTICAST(i) (((i) & 0xf0000000U) == 0xe0000000U)
122n/a#endif
123n/a
124n/a#ifndef IN_EXPERIMENTAL
125n/a#define IN_EXPERIMENTAL(i) (((i) & 0xe0000000U) == 0xe0000000U)
126n/a#endif
127n/a
128n/a#ifndef IN_LOOPBACKNET
129n/a#define IN_LOOPBACKNET 127
130n/a#endif
131n/a
132n/astatic int get_name(const char *, struct gai_afd *,
133n/a struct addrinfo **, char *, struct addrinfo *,
134n/a int);
135n/astatic int get_addr(const char *, int, struct addrinfo **,
136n/a struct addrinfo *, int);
137n/astatic int str_isnumber(const char *);
138n/a
139n/astatic const char * const ai_errlist[] = {
140n/a "success.",
141n/a "address family for hostname not supported.", /* EAI_ADDRFAMILY */
142n/a "temporary failure in name resolution.", /* EAI_AGAIN */
143n/a "invalid value for ai_flags.", /* EAI_BADFLAGS */
144n/a "non-recoverable failure in name resolution.", /* EAI_FAIL */
145n/a "ai_family not supported.", /* EAI_FAMILY */
146n/a "memory allocation failure.", /* EAI_MEMORY */
147n/a "no address associated with hostname.", /* EAI_NODATA */
148n/a "hostname nor servname provided, or not known.",/* EAI_NONAME */
149n/a "servname not supported for ai_socktype.", /* EAI_SERVICE */
150n/a "ai_socktype not supported.", /* EAI_SOCKTYPE */
151n/a "system error returned in errno.", /* EAI_SYSTEM */
152n/a "invalid value for hints.", /* EAI_BADHINTS */
153n/a "resolved protocol is unknown.", /* EAI_PROTOCOL */
154n/a "unknown error.", /* EAI_MAX */
155n/a};
156n/a
157n/a#define GET_CANONNAME(ai, str) \
158n/aif (pai->ai_flags & AI_CANONNAME) {\
159n/a if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\
160n/a strcpy((ai)->ai_canonname, (str));\
161n/a } else {\
162n/a error = EAI_MEMORY;\
163n/a goto free;\
164n/a }\
165n/a}
166n/a
167n/a#ifdef HAVE_SOCKADDR_SA_LEN
168n/a#define GET_AI(ai, gai_afd, addr, port) {\
169n/a char *p;\
170n/a if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
171n/a ((gai_afd)->a_socklen)))\
172n/a == NULL) goto free;\
173n/a memcpy(ai, pai, sizeof(struct addrinfo));\
174n/a (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
175n/a memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\
176n/a (ai)->ai_addr->sa_len = (ai)->ai_addrlen = (gai_afd)->a_socklen;\
177n/a (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\
178n/a ((struct sockinet *)(ai)->ai_addr)->si_port = port;\
179n/a p = (char *)((ai)->ai_addr);\
180n/a memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\
181n/a}
182n/a#else
183n/a#define GET_AI(ai, gai_afd, addr, port) {\
184n/a char *p;\
185n/a if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
186n/a ((gai_afd)->a_socklen)))\
187n/a == NULL) goto free;\
188n/a memcpy(ai, pai, sizeof(struct addrinfo));\
189n/a (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
190n/a memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\
191n/a (ai)->ai_addrlen = (gai_afd)->a_socklen;\
192n/a (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\
193n/a ((struct sockinet *)(ai)->ai_addr)->si_port = port;\
194n/a p = (char *)((ai)->ai_addr);\
195n/a memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\
196n/a}
197n/a#endif
198n/a
199n/a#define ERR(err) { error = (err); goto bad; }
200n/a
201n/aconst char *
202n/agai_strerror(int ecode)
203n/a{
204n/a if (ecode < 0 || ecode > EAI_MAX)
205n/a ecode = EAI_MAX;
206n/a return ai_errlist[ecode];
207n/a}
208n/a
209n/avoid
210n/afreeaddrinfo(struct addrinfo *ai)
211n/a{
212n/a struct addrinfo *next;
213n/a
214n/a do {
215n/a next = ai->ai_next;
216n/a if (ai->ai_canonname)
217n/a free(ai->ai_canonname);
218n/a /* no need to free(ai->ai_addr) */
219n/a free(ai);
220n/a } while ((ai = next) != NULL);
221n/a}
222n/a
223n/astatic int
224n/astr_isnumber(const char *p)
225n/a{
226n/a unsigned char *q = (unsigned char *)p;
227n/a while (*q) {
228n/a if (! isdigit(*q))
229n/a return NO;
230n/a q++;
231n/a }
232n/a return YES;
233n/a}
234n/a
235n/aint
236n/agetaddrinfo(const char*hostname, const char*servname,
237n/a const struct addrinfo *hints, struct addrinfo **res)
238n/a{
239n/a struct addrinfo sentinel;
240n/a struct addrinfo *top = NULL;
241n/a struct addrinfo *cur;
242n/a int i, error = 0;
243n/a char pton[PTON_MAX];
244n/a struct addrinfo ai;
245n/a struct addrinfo *pai;
246n/a u_short port;
247n/a
248n/a#ifdef FAITH
249n/a static int firsttime = 1;
250n/a
251n/a if (firsttime) {
252n/a /* translator hack */
253n/a {
254n/a char *q = getenv("GAI");
255n/a if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
256n/a translate = YES;
257n/a }
258n/a firsttime = 0;
259n/a }
260n/a#endif
261n/a
262n/a /* initialize file static vars */
263n/a sentinel.ai_next = NULL;
264n/a cur = &sentinel;
265n/a pai = &ai;
266n/a pai->ai_flags = 0;
267n/a pai->ai_family = PF_UNSPEC;
268n/a pai->ai_socktype = GAI_ANY;
269n/a pai->ai_protocol = GAI_ANY;
270n/a pai->ai_addrlen = 0;
271n/a pai->ai_canonname = NULL;
272n/a pai->ai_addr = NULL;
273n/a pai->ai_next = NULL;
274n/a port = GAI_ANY;
275n/a
276n/a if (hostname == NULL && servname == NULL)
277n/a return EAI_NONAME;
278n/a if (hints) {
279n/a /* error check for hints */
280n/a if (hints->ai_addrlen || hints->ai_canonname ||
281n/a hints->ai_addr || hints->ai_next)
282n/a ERR(EAI_BADHINTS); /* xxx */
283n/a if (hints->ai_flags & ~AI_MASK)
284n/a ERR(EAI_BADFLAGS);
285n/a switch (hints->ai_family) {
286n/a case PF_UNSPEC:
287n/a case PF_INET:
288n/a#ifdef ENABLE_IPV6
289n/a case PF_INET6:
290n/a#endif
291n/a break;
292n/a default:
293n/a ERR(EAI_FAMILY);
294n/a }
295n/a memcpy(pai, hints, sizeof(*pai));
296n/a switch (pai->ai_socktype) {
297n/a case GAI_ANY:
298n/a switch (pai->ai_protocol) {
299n/a case GAI_ANY:
300n/a break;
301n/a case IPPROTO_UDP:
302n/a pai->ai_socktype = SOCK_DGRAM;
303n/a break;
304n/a case IPPROTO_TCP:
305n/a pai->ai_socktype = SOCK_STREAM;
306n/a break;
307n/a default:
308n/a pai->ai_socktype = SOCK_RAW;
309n/a break;
310n/a }
311n/a break;
312n/a case SOCK_RAW:
313n/a break;
314n/a case SOCK_DGRAM:
315n/a if (pai->ai_protocol != IPPROTO_UDP &&
316n/a pai->ai_protocol != GAI_ANY)
317n/a ERR(EAI_BADHINTS); /*xxx*/
318n/a pai->ai_protocol = IPPROTO_UDP;
319n/a break;
320n/a case SOCK_STREAM:
321n/a if (pai->ai_protocol != IPPROTO_TCP &&
322n/a pai->ai_protocol != GAI_ANY)
323n/a ERR(EAI_BADHINTS); /*xxx*/
324n/a pai->ai_protocol = IPPROTO_TCP;
325n/a break;
326n/a default:
327n/a ERR(EAI_SOCKTYPE);
328n/a /* unreachable */
329n/a }
330n/a }
331n/a
332n/a /*
333n/a * service port
334n/a */
335n/a if (servname) {
336n/a if (str_isnumber(servname)) {
337n/a if (pai->ai_socktype == GAI_ANY) {
338n/a /* caller accept *GAI_ANY* socktype */
339n/a pai->ai_socktype = SOCK_DGRAM;
340n/a pai->ai_protocol = IPPROTO_UDP;
341n/a }
342n/a port = htons((u_short)atoi(servname));
343n/a } else {
344n/a struct servent *sp;
345n/a char *proto;
346n/a
347n/a proto = NULL;
348n/a switch (pai->ai_socktype) {
349n/a case GAI_ANY:
350n/a proto = NULL;
351n/a break;
352n/a case SOCK_DGRAM:
353n/a proto = "udp";
354n/a break;
355n/a case SOCK_STREAM:
356n/a proto = "tcp";
357n/a break;
358n/a default:
359n/a fprintf(stderr, "panic!\n");
360n/a break;
361n/a }
362n/a if ((sp = getservbyname(servname, proto)) == NULL)
363n/a ERR(EAI_SERVICE);
364n/a port = sp->s_port;
365n/a if (pai->ai_socktype == GAI_ANY) {
366n/a if (strcmp(sp->s_proto, "udp") == 0) {
367n/a pai->ai_socktype = SOCK_DGRAM;
368n/a pai->ai_protocol = IPPROTO_UDP;
369n/a } else if (strcmp(sp->s_proto, "tcp") == 0) {
370n/a pai->ai_socktype = SOCK_STREAM;
371n/a pai->ai_protocol = IPPROTO_TCP;
372n/a } else
373n/a ERR(EAI_PROTOCOL); /*xxx*/
374n/a }
375n/a }
376n/a }
377n/a
378n/a /*
379n/a * hostname == NULL.
380n/a * passive socket -> anyaddr (0.0.0.0 or ::)
381n/a * non-passive socket -> localhost (127.0.0.1 or ::1)
382n/a */
383n/a if (hostname == NULL) {
384n/a struct gai_afd *gai_afd;
385n/a
386n/a for (gai_afd = &gai_afdl[0]; gai_afd->a_af; gai_afd++) {
387n/a if (!(pai->ai_family == PF_UNSPEC
388n/a || pai->ai_family == gai_afd->a_af)) {
389n/a continue;
390n/a }
391n/a
392n/a if (pai->ai_flags & AI_PASSIVE) {
393n/a GET_AI(cur->ai_next, gai_afd, gai_afd->a_addrany, port);
394n/a /* xxx meaningless?
395n/a * GET_CANONNAME(cur->ai_next, "anyaddr");
396n/a */
397n/a } else {
398n/a GET_AI(cur->ai_next, gai_afd, gai_afd->a_loopback,
399n/a port);
400n/a /* xxx meaningless?
401n/a * GET_CANONNAME(cur->ai_next, "localhost");
402n/a */
403n/a }
404n/a cur = cur->ai_next;
405n/a }
406n/a top = sentinel.ai_next;
407n/a if (top)
408n/a goto good;
409n/a else
410n/a ERR(EAI_FAMILY);
411n/a }
412n/a
413n/a /* hostname as numeric name */
414n/a for (i = 0; gai_afdl[i].a_af; i++) {
415n/a if (inet_pton(gai_afdl[i].a_af, hostname, pton)) {
416n/a u_long v4a;
417n/a#ifdef ENABLE_IPV6
418n/a u_char pfx;
419n/a#endif
420n/a
421n/a switch (gai_afdl[i].a_af) {
422n/a case AF_INET:
423n/a v4a = ((struct in_addr *)pton)->s_addr;
424n/a v4a = ntohl(v4a);
425n/a if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
426n/a pai->ai_flags &= ~AI_CANONNAME;
427n/a v4a >>= IN_CLASSA_NSHIFT;
428n/a if (v4a == 0 || v4a == IN_LOOPBACKNET)
429n/a pai->ai_flags &= ~AI_CANONNAME;
430n/a break;
431n/a#ifdef ENABLE_IPV6
432n/a case AF_INET6:
433n/a pfx = ((struct in6_addr *)pton)->s6_addr[0];
434n/a if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
435n/a pai->ai_flags &= ~AI_CANONNAME;
436n/a break;
437n/a#endif
438n/a }
439n/a
440n/a if (pai->ai_family == gai_afdl[i].a_af ||
441n/a pai->ai_family == PF_UNSPEC) {
442n/a if (! (pai->ai_flags & AI_CANONNAME)) {
443n/a GET_AI(top, &gai_afdl[i], pton, port);
444n/a goto good;
445n/a }
446n/a /*
447n/a * if AI_CANONNAME and if reverse lookup
448n/a * fail, return ai anyway to pacify
449n/a * calling application.
450n/a *
451n/a * XXX getaddrinfo() is a name->address
452n/a * translation function, and it looks strange
453n/a * that we do addr->name translation here.
454n/a */
455n/a get_name(pton, &gai_afdl[i], &top, pton, pai, port);
456n/a goto good;
457n/a } else
458n/a ERR(EAI_FAMILY); /*xxx*/
459n/a }
460n/a }
461n/a
462n/a if (pai->ai_flags & AI_NUMERICHOST)
463n/a ERR(EAI_NONAME);
464n/a
465n/a /* hostname as alphabetical name */
466n/a error = get_addr(hostname, pai->ai_family, &top, pai, port);
467n/a if (error == 0) {
468n/a if (top) {
469n/a good:
470n/a *res = top;
471n/a return SUCCESS;
472n/a } else
473n/a error = EAI_FAIL;
474n/a }
475n/a free:
476n/a if (top)
477n/a freeaddrinfo(top);
478n/a bad:
479n/a *res = NULL;
480n/a return error;
481n/a}
482n/a
483n/astatic int
484n/aget_name(addr, gai_afd, res, numaddr, pai, port0)
485n/a const char *addr;
486n/a struct gai_afd *gai_afd;
487n/a struct addrinfo **res;
488n/a char *numaddr;
489n/a struct addrinfo *pai;
490n/a int port0;
491n/a{
492n/a u_short port = port0 & 0xffff;
493n/a struct hostent *hp;
494n/a struct addrinfo *cur;
495n/a int error = 0;
496n/a#ifdef ENABLE_IPV6
497n/a int h_error;
498n/a#endif
499n/a
500n/a#ifdef ENABLE_IPV6
501n/a hp = getipnodebyaddr(addr, gai_afd->a_addrlen, gai_afd->a_af, &h_error);
502n/a#else
503n/a hp = gethostbyaddr(addr, gai_afd->a_addrlen, AF_INET);
504n/a#endif
505n/a if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
506n/a GET_AI(cur, gai_afd, hp->h_addr_list[0], port);
507n/a GET_CANONNAME(cur, hp->h_name);
508n/a } else
509n/a GET_AI(cur, gai_afd, numaddr, port);
510n/a
511n/a#ifdef ENABLE_IPV6
512n/a if (hp)
513n/a freehostent(hp);
514n/a#endif
515n/a *res = cur;
516n/a return SUCCESS;
517n/a free:
518n/a if (cur)
519n/a freeaddrinfo(cur);
520n/a#ifdef ENABLE_IPV6
521n/a if (hp)
522n/a freehostent(hp);
523n/a#endif
524n/a /* bad: */
525n/a *res = NULL;
526n/a return error;
527n/a}
528n/a
529n/astatic int
530n/aget_addr(hostname, af, res, pai, port0)
531n/a const char *hostname;
532n/a int af;
533n/a struct addrinfo **res;
534n/a struct addrinfo *pai;
535n/a int port0;
536n/a{
537n/a u_short port = port0 & 0xffff;
538n/a struct addrinfo sentinel;
539n/a struct hostent *hp;
540n/a struct addrinfo *top, *cur;
541n/a struct gai_afd *gai_afd;
542n/a int i, error = 0, h_error;
543n/a char *ap;
544n/a
545n/a top = NULL;
546n/a sentinel.ai_next = NULL;
547n/a cur = &sentinel;
548n/a#ifdef ENABLE_IPV6
549n/a if (af == AF_UNSPEC) {
550n/a hp = getipnodebyname(hostname, AF_INET6,
551n/a AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);
552n/a } else
553n/a hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);
554n/a#else
555n/a hp = gethostbyname(hostname);
556n/a h_error = h_errno;
557n/a#endif
558n/a if (hp == NULL) {
559n/a switch (h_error) {
560n/a case HOST_NOT_FOUND:
561n/a case NO_DATA:
562n/a error = EAI_NODATA;
563n/a break;
564n/a case TRY_AGAIN:
565n/a error = EAI_AGAIN;
566n/a break;
567n/a case NO_RECOVERY:
568n/a default:
569n/a error = EAI_FAIL;
570n/a break;
571n/a }
572n/a goto free;
573n/a }
574n/a
575n/a if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
576n/a (hp->h_addr_list[0] == NULL)) {
577n/a error = EAI_FAIL;
578n/a goto free;
579n/a }
580n/a
581n/a for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {
582n/a switch (af) {
583n/a#ifdef ENABLE_IPV6
584n/a case AF_INET6:
585n/a gai_afd = &gai_afdl[N_INET6];
586n/a break;
587n/a#endif
588n/a#ifndef ENABLE_IPV6
589n/a default: /* AF_UNSPEC */
590n/a#endif
591n/a case AF_INET:
592n/a gai_afd = &gai_afdl[N_INET];
593n/a break;
594n/a#ifdef ENABLE_IPV6
595n/a default: /* AF_UNSPEC */
596n/a if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
597n/a ap += sizeof(struct in6_addr) -
598n/a sizeof(struct in_addr);
599n/a gai_afd = &gai_afdl[N_INET];
600n/a } else
601n/a gai_afd = &gai_afdl[N_INET6];
602n/a break;
603n/a#endif
604n/a }
605n/a#ifdef FAITH
606n/a if (translate && gai_afd->a_af == AF_INET) {
607n/a struct in6_addr *in6;
608n/a
609n/a GET_AI(cur->ai_next, &gai_afdl[N_INET6], ap, port);
610n/a in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;
611n/a memcpy(&in6->s6_addr32[0], &faith_prefix,
612n/a sizeof(struct in6_addr) - sizeof(struct in_addr));
613n/a memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr));
614n/a } else
615n/a#endif /* FAITH */
616n/a GET_AI(cur->ai_next, gai_afd, ap, port);
617n/a if (cur == &sentinel) {
618n/a top = cur->ai_next;
619n/a GET_CANONNAME(top, hp->h_name);
620n/a }
621n/a cur = cur->ai_next;
622n/a }
623n/a#ifdef ENABLE_IPV6
624n/a freehostent(hp);
625n/a#endif
626n/a *res = top;
627n/a return SUCCESS;
628n/a free:
629n/a if (top)
630n/a freeaddrinfo(top);
631n/a#ifdef ENABLE_IPV6
632n/a if (hp)
633n/a freehostent(hp);
634n/a#endif
635n/a/* bad: */
636n/a *res = NULL;
637n/a return error;
638n/a}