2 * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 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: getipnode.c,v 1.30.2.4.2.6 2005/04/29 00:03:32 marka Exp $ */
27 #include <lwres/lwres.h>
28 #include <lwres/net.h>
29 #include <lwres/netdb.h> /* XXX #include <netdb.h> */
40 #ifdef LWRES_PLATFORM_NEEDIN6ADDRANY
41 LIBLWRES_EXTERNAL_DATA
const struct in6_addr in6addr_any
= IN6ADDR_ANY_INIT
;
44 #ifndef IN6_IS_ADDR_V4COMPAT
45 static const unsigned char in6addr_compat
[12] = {
46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
48 #define IN6_IS_ADDR_V4COMPAT(x) (!memcmp((x)->s6_addr, in6addr_compat, 12) && \
49 ((x)->s6_addr[12] != 0 || \
50 (x)->s6_addr[13] != 0 || \
51 (x)->s6_addr[14] != 0 || \
52 ((x)->s6_addr[15] != 0 && \
53 (x)->s6_addr[15] != 1)))
55 #ifndef IN6_IS_ADDR_V4MAPPED
56 #define IN6_IS_ADDR_V4MAPPED(x) (!memcmp((x)->s6_addr, in6addr_mapped, 12))
59 static const unsigned char in6addr_mapped
[12] = {
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff
64 *** Forward declarations.
68 scan_interfaces(int *, int *);
70 static struct hostent
*
71 copyandmerge(struct hostent
*, struct hostent
*, int, int *);
73 static struct hostent
*
74 hostfromaddr(lwres_gnbaresponse_t
*addr
, int af
, const void *src
);
76 static struct hostent
*
77 hostfromname(lwres_gabnresponse_t
*name
, int af
);
84 * AI_V4MAPPED + AF_INET6
85 * If no IPv6 address then a query for IPv4 and map returned values.
87 * AI_ALL + AI_V4MAPPED + AF_INET6
88 * Return IPv6 and IPv4 mapped.
91 * Only return IPv6 / IPv4 address if there is an interface of that
96 lwres_getipnodebyname(const char *name
, int af
, int flags
, int *error_num
) {
97 int have_v4
= 1, have_v6
= 1;
100 struct hostent he
, *he1
= NULL
, *he2
= NULL
, *he3
= NULL
;
103 lwres_context_t
*lwrctx
= NULL
;
104 lwres_gabnresponse_t
*by
= NULL
;
108 * If we care about active interfaces then check.
110 if ((flags
& AI_ADDRCONFIG
) != 0)
111 if (scan_interfaces(&have_v4
, &have_v6
) == -1) {
112 *error_num
= NO_RECOVERY
;
116 /* Check for literal address. */
117 if ((v4
= lwres_net_pton(AF_INET
, name
, &in4
)) != 1)
118 v6
= lwres_net_pton(AF_INET6
, name
, &in6
);
121 * Impossible combination?
123 if ((af
== AF_INET6
&& (flags
& AI_V4MAPPED
) == 0 && v4
== 1) ||
124 (af
== AF_INET
&& v6
== 1) ||
125 (have_v4
== 0 && v4
== 1) ||
126 (have_v6
== 0 && v6
== 1) ||
127 (have_v4
== 0 && af
== AF_INET
) ||
128 (have_v6
== 0 && af
== AF_INET6
&&
129 (((flags
& AI_V4MAPPED
) != 0 && have_v4
) ||
130 (flags
& AI_V4MAPPED
) == 0))) {
131 *error_num
= HOST_NOT_FOUND
;
138 if (v4
== 1 || v6
== 1) {
141 char mappedname
[sizeof("::ffff:123.123.123.123")];
143 const char *const_name
;
148 if (v4
== 1 && af
== AF_INET6
) {
149 strcpy(mappedname
, "::ffff:");
150 lwres_net_ntop(AF_INET
, (char *)&in4
,
151 mappedname
+ sizeof("::ffff:") - 1,
152 sizeof(mappedname
) - sizeof("::ffff:")
154 he
.h_name
= mappedname
;
156 he
.h_name
= u
.deconst_name
;
157 he
.h_addr_list
= addr_list
;
158 he
.h_addr_list
[0] = (v4
== 1) ? (char *)&in4
: (char *)&in6
;
159 he
.h_addr_list
[1] = NULL
;
160 he
.h_aliases
= aliases
;
161 he
.h_aliases
[0] = NULL
;
162 he
.h_length
= (v4
== 1) ? INADDRSZ
: IN6ADDRSZ
;
163 he
.h_addrtype
= (v4
== 1) ? AF_INET
: AF_INET6
;
164 return (copyandmerge(&he
, NULL
, af
, error_num
));
167 n
= lwres_context_create(&lwrctx
, NULL
, NULL
, NULL
, 0);
169 *error_num
= NO_RECOVERY
;
172 (void) lwres_conf_parse(lwrctx
, lwres_resolv_conf
);
173 tmp_err
= NO_RECOVERY
;
174 if (have_v6
&& af
== AF_INET6
) {
176 n
= lwres_getaddrsbyname(lwrctx
, name
, LWRES_ADDRTYPE_V6
, &by
);
178 he1
= hostfromname(by
, AF_INET6
);
179 lwres_gabnresponse_free(lwrctx
, &by
);
181 *error_num
= NO_RECOVERY
;
185 tmp_err
= HOST_NOT_FOUND
;
191 (af
== AF_INET6
&& (flags
& AI_V4MAPPED
) != 0 &&
192 (he1
== NULL
|| (flags
& AI_ALL
) != 0)))) {
193 n
= lwres_getaddrsbyname(lwrctx
, name
, LWRES_ADDRTYPE_V4
, &by
);
195 he2
= hostfromname(by
, AF_INET
);
196 lwres_gabnresponse_free(lwrctx
, &by
);
198 *error_num
= NO_RECOVERY
;
201 } else if (he1
== NULL
) {
202 if (n
== LWRES_R_NOTFOUND
)
203 *error_num
= HOST_NOT_FOUND
;
205 *error_num
= NO_RECOVERY
;
209 *error_num
= tmp_err
;
211 he3
= copyandmerge(he1
, he2
, af
, error_num
);
215 lwres_freehostent(he1
);
217 lwres_freehostent(he2
);
218 if (lwrctx
!= NULL
) {
219 lwres_conf_clear(lwrctx
);
220 lwres_context_destroy(&lwrctx
);
226 lwres_getipnodebyaddr(const void *src
, size_t len
, int af
, int *error_num
) {
227 struct hostent
*he1
, *he2
;
228 lwres_context_t
*lwrctx
= NULL
;
229 lwres_gnbaresponse_t
*by
= NULL
;
233 struct in6_addr
*in6
;
240 *error_num
= NO_RECOVERY
;
246 if (len
!= (unsigned int)INADDRSZ
) {
247 *error_num
= NO_RECOVERY
;
252 if (len
!= (unsigned int)IN6ADDRSZ
) {
253 *error_num
= NO_RECOVERY
;
258 *error_num
= NO_RECOVERY
;
263 * The de-"const"-ing game is done because at least one
264 * vendor's system (RedHat 6.0) defines the IN6_IS_ADDR_*
265 * macros in such a way that they discard the const with
266 * internal casting, and gcc ends up complaining. Rather
267 * than replacing their own (possibly optimized) definitions
268 * with our own, cleanly discarding the const is the easiest
274 * Look up IPv4 and IPv4 mapped/compatible addresses.
276 if ((af
== AF_INET6
&& IN6_IS_ADDR_V4COMPAT(u
.in6
)) ||
277 (af
== AF_INET6
&& IN6_IS_ADDR_V4MAPPED(u
.in6
)) ||
279 const unsigned char *cp
= src
;
283 n
= lwres_context_create(&lwrctx
, NULL
, NULL
, NULL
, 0);
284 if (n
== LWRES_R_SUCCESS
)
285 (void) lwres_conf_parse(lwrctx
, lwres_resolv_conf
);
286 if (n
== LWRES_R_SUCCESS
)
287 n
= lwres_getnamebyaddr(lwrctx
, LWRES_ADDRTYPE_V4
,
289 if (n
!= LWRES_R_SUCCESS
) {
290 lwres_conf_clear(lwrctx
);
291 lwres_context_destroy(&lwrctx
);
292 if (n
== LWRES_R_NOTFOUND
)
293 *error_num
= HOST_NOT_FOUND
;
295 *error_num
= NO_RECOVERY
;
298 he1
= hostfromaddr(by
, AF_INET
, cp
);
299 lwres_gnbaresponse_free(lwrctx
, &by
);
300 lwres_conf_clear(lwrctx
);
301 lwres_context_destroy(&lwrctx
);
306 * Convert from AF_INET to AF_INET6.
308 he2
= copyandmerge(he1
, NULL
, af
, error_num
);
309 lwres_freehostent(he1
);
313 * Restore original address.
315 memcpy(he2
->h_addr
, src
, len
);
320 * Lookup IPv6 address.
322 if (memcmp(src
, &in6addr_any
, IN6ADDRSZ
) == 0) {
323 *error_num
= HOST_NOT_FOUND
;
327 n
= lwres_context_create(&lwrctx
, NULL
, NULL
, NULL
, 0);
328 if (n
== LWRES_R_SUCCESS
)
329 (void) lwres_conf_parse(lwrctx
, lwres_resolv_conf
);
330 if (n
== LWRES_R_SUCCESS
)
331 n
= lwres_getnamebyaddr(lwrctx
, LWRES_ADDRTYPE_V6
, IN6ADDRSZ
,
334 lwres_conf_clear(lwrctx
);
335 lwres_context_destroy(&lwrctx
);
336 *error_num
= HOST_NOT_FOUND
;
339 he1
= hostfromaddr(by
, AF_INET6
, src
);
340 lwres_gnbaresponse_free(lwrctx
, &by
);
342 *error_num
= NO_RECOVERY
;
343 lwres_conf_clear(lwrctx
);
344 lwres_context_destroy(&lwrctx
);
349 lwres_freehostent(struct hostent
*he
) {
356 cpp
= he
->h_addr_list
;
357 while (*cpp
!= NULL
) {
365 while (*cpp
!= NULL
) {
372 free(he
->h_addr_list
);
381 * Scan the interface table and set have_v4 and have_v6 depending
382 * upon whether there are IPv4 and IPv6 interface addresses.
389 #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
390 !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
393 #define lifc_len iflc_len
394 #define lifc_buf iflc_buf
395 #define lifc_req iflc_req
396 #define LIFCONF if_laddrconf
398 #define ISC_HAVE_LIFC_FAMILY 1
399 #define ISC_HAVE_LIFC_FLAGS 1
400 #define LIFCONF lifconf
404 #define lifr_addr iflr_addr
405 #define lifr_name iflr_name
406 #define lifr_dstaddr iflr_dstaddr
407 #define lifr_flags iflr_flags
408 #define ss_family sa_family
409 #define LIFREQ if_laddrreq
411 #define LIFREQ lifreq
415 scan_interfaces6(int *have_v4
, int *have_v6
) {
417 struct LIFREQ lifreq
;
420 char *buf
= NULL
, *cp
, *cplim
;
421 static unsigned int bufsiz
= 4095;
425 * Set to zero. Used as loop terminators below.
427 *have_v4
= *have_v6
= 0;
430 * Get interface list from system.
432 if ((s
= socket(AF_INET6
, SOCK_DGRAM
, 0)) == -1)
436 * Grow buffer until large enough to contain all interface
440 buf
= malloc(bufsiz
);
443 #ifdef ISC_HAVE_LIFC_FAMILY
444 lifc
.lifc_family
= AF_UNSPEC
; /* request all families */
446 #ifdef ISC_HAVE_LIFC_FLAGS
449 lifc
.lifc_len
= bufsiz
;
451 if ((n
= ioctl(s
, SIOCGLIFCONF
, (char *)&lifc
)) != -1) {
453 * Some OS's just return what will fit rather
454 * than set EINVAL if the buffer is too small
455 * to fit all the interfaces in. If
456 * lifc.lifc_len is too near to the end of the
457 * buffer we will grow it just in case and
460 if (lifc
.lifc_len
+ 2 * sizeof(lifreq
) < bufsiz
)
463 if ((n
== -1) && errno
!= EINVAL
)
466 if (bufsiz
> 1000000)
474 * Parse system's interface list.
476 cplim
= buf
+ lifc
.lifc_len
; /* skip over if's with big ifr_addr's */
478 (*have_v4
== 0 || *have_v6
== 0) && cp
< cplim
;
480 memcpy(&lifreq
, cp
, sizeof(lifreq
));
481 #ifdef LWRES_PLATFORM_HAVESALEN
482 #ifdef FIX_ZERO_SA_LEN
483 if (lifreq
.lifr_addr
.sa_len
== 0)
484 lifreq
.lifr_addr
.sa_len
= 16;
486 #ifdef HAVE_MINIMUM_IFREQ
487 cpsize
= sizeof(lifreq
);
488 if (lifreq
.lifr_addr
.sa_len
> sizeof(struct sockaddr
))
489 cpsize
+= (int)lifreq
.lifr_addr
.sa_len
-
490 (int)(sizeof(struct sockaddr
));
492 cpsize
= sizeof(lifreq
.lifr_name
) + lifreq
.lifr_addr
.sa_len
;
493 #endif /* HAVE_MINIMUM_IFREQ */
494 #elif defined SIOCGIFCONF_ADDR
495 cpsize
= sizeof(lifreq
);
497 cpsize
= sizeof(lifreq
.lifr_name
);
498 /* XXX maybe this should be a hard error? */
499 if (ioctl(s
, SIOCGLIFADDR
, (char *)&lifreq
) < 0)
502 switch (lifreq
.lifr_addr
.ss_family
) {
506 &((struct sockaddr_in
*)
507 &lifreq
.lifr_addr
)->sin_addr
,
509 if (in4
.s_addr
== INADDR_ANY
)
511 n
= ioctl(s
, SIOCGLIFFLAGS
, (char *)&lifreq
);
514 if ((lifreq
.lifr_flags
& IFF_UP
) == 0)
522 &((struct sockaddr_in6
*)
523 &lifreq
.lifr_addr
)->sin6_addr
,
525 if (memcmp(&in6
, &in6addr_any
,
528 n
= ioctl(s
, SIOCGLIFFLAGS
, (char *)&lifreq
);
531 if ((lifreq
.lifr_flags
& IFF_UP
) == 0)
552 scan_interfaces(int *have_v4
, int *have_v6
) {
553 #if !defined(SIOCGIFCONF) || !defined(SIOCGIFADDR)
554 *have_v4
= *have_v6
= 1;
559 char _pad
[256]; /* leave space for IPv6 addresses */
564 char *buf
= NULL
, *cp
, *cplim
;
565 static unsigned int bufsiz
= 4095;
569 #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
570 !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF)
572 * Try to scan the interfaces using IPv6 ioctls().
574 if (!scan_interfaces6(have_v4
, have_v6
))
579 * Set to zero. Used as loop terminators below.
581 *have_v4
= *have_v6
= 0;
584 * Get interface list from system.
586 if ((s
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1)
590 * Grow buffer until large enough to contain all interface
594 buf
= malloc(bufsiz
);
597 ifc
.ifc_len
= bufsiz
;
599 #ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF
601 * This is a fix for IRIX OS in which the call to ioctl with
602 * the flag SIOCGIFCONF may not return an entry for all the
603 * interfaces like most flavors of Unix.
605 if (emul_ioctl(&ifc
) >= 0)
608 if ((n
= ioctl(s
, SIOCGIFCONF
, (char *)&ifc
)) != -1) {
610 * Some OS's just return what will fit rather
611 * than set EINVAL if the buffer is too small
612 * to fit all the interfaces in. If
613 * ifc.ifc_len is too near to the end of the
614 * buffer we will grow it just in case and
617 if (ifc
.ifc_len
+ 2 * sizeof(u
.ifreq
) < bufsiz
)
621 if ((n
== -1) && errno
!= EINVAL
)
624 if (bufsiz
> 1000000)
632 * Parse system's interface list.
634 cplim
= buf
+ ifc
.ifc_len
; /* skip over if's with big ifr_addr's */
636 (*have_v4
== 0 || *have_v6
== 0) && cp
< cplim
;
638 memcpy(&u
.ifreq
, cp
, sizeof(u
.ifreq
));
639 #ifdef LWRES_PLATFORM_HAVESALEN
640 #ifdef FIX_ZERO_SA_LEN
641 if (u
.ifreq
.ifr_addr
.sa_len
== 0)
642 u
.ifreq
.ifr_addr
.sa_len
= 16;
644 #ifdef HAVE_MINIMUM_IFREQ
645 cpsize
= sizeof(u
.ifreq
);
646 if (u
.ifreq
.ifr_addr
.sa_len
> sizeof(struct sockaddr
))
647 cpsize
+= (int)u
.ifreq
.ifr_addr
.sa_len
-
648 (int)(sizeof(struct sockaddr
));
650 cpsize
= sizeof(u
.ifreq
.ifr_name
) + u
.ifreq
.ifr_addr
.sa_len
;
651 #endif /* HAVE_MINIMUM_IFREQ */
652 if (cpsize
> sizeof(u
.ifreq
) && cpsize
<= sizeof(u
))
653 memcpy(&u
.ifreq
, cp
, cpsize
);
654 #elif defined SIOCGIFCONF_ADDR
655 cpsize
= sizeof(u
.ifreq
);
657 cpsize
= sizeof(u
.ifreq
.ifr_name
);
658 /* XXX maybe this should be a hard error? */
659 if (ioctl(s
, SIOCGIFADDR
, (char *)&u
.ifreq
) < 0)
662 switch (u
.ifreq
.ifr_addr
.sa_family
) {
666 &((struct sockaddr_in
*)
667 &u
.ifreq
.ifr_addr
)->sin_addr
,
669 if (in4
.s_addr
== INADDR_ANY
)
671 n
= ioctl(s
, SIOCGIFFLAGS
, (char *)&u
.ifreq
);
674 if ((u
.ifreq
.ifr_flags
& IFF_UP
) == 0)
682 &((struct sockaddr_in6
*)
683 &u
.ifreq
.ifr_addr
)->sin6_addr
,
685 if (memcmp(&in6
, &in6addr_any
,
688 n
= ioctl(s
, SIOCGIFFLAGS
, (char *)&u
.ifreq
);
691 if ((u
.ifreq
.ifr_flags
& IFF_UP
) == 0)
711 static struct hostent
*
712 copyandmerge(struct hostent
*he1
, struct hostent
*he2
, int af
, int *error_num
)
714 struct hostent
*he
= NULL
;
715 int addresses
= 1; /* NULL terminator */
716 int names
= 1; /* NULL terminator */
721 * Work out array sizes.
724 cpp
= he1
->h_addr_list
;
725 while (*cpp
!= NULL
) {
729 cpp
= he1
->h_aliases
;
730 while (*cpp
!= NULL
) {
737 cpp
= he2
->h_addr_list
;
738 while (*cpp
!= NULL
) {
743 cpp
= he2
->h_aliases
;
744 while (*cpp
!= NULL
) {
751 if (addresses
== 1) {
752 *error_num
= NO_ADDRESS
;
756 he
= malloc(sizeof(*he
));
760 he
->h_addr_list
= malloc(sizeof(char *) * (addresses
));
761 if (he
->h_addr_list
== NULL
)
763 memset(he
->h_addr_list
, 0, sizeof(char *) * (addresses
));
768 npp
= he
->h_addr_list
;
770 cpp
= he1
->h_addr_list
;
771 while (*cpp
!= NULL
) {
772 *npp
= malloc((af
== AF_INET
) ? INADDRSZ
: IN6ADDRSZ
);
776 * Convert to mapped if required.
778 if (af
== AF_INET6
&& he1
->h_addrtype
== AF_INET
) {
779 memcpy(*npp
, in6addr_mapped
,
780 sizeof(in6addr_mapped
));
781 memcpy(*npp
+ sizeof(in6addr_mapped
), *cpp
,
785 (af
== AF_INET
) ? INADDRSZ
: IN6ADDRSZ
);
793 cpp
= he2
->h_addr_list
;
794 while (*cpp
!= NULL
) {
795 *npp
= malloc((af
== AF_INET
) ? INADDRSZ
: IN6ADDRSZ
);
799 * Convert to mapped if required.
801 if (af
== AF_INET6
&& he2
->h_addrtype
== AF_INET
) {
802 memcpy(*npp
, in6addr_mapped
,
803 sizeof(in6addr_mapped
));
804 memcpy(*npp
+ sizeof(in6addr_mapped
), *cpp
,
808 (af
== AF_INET
) ? INADDRSZ
: IN6ADDRSZ
);
815 he
->h_aliases
= malloc(sizeof(char *) * (names
));
816 if (he
->h_aliases
== NULL
)
818 memset(he
->h_aliases
, 0, sizeof(char *) * (names
));
824 cpp
= (he1
!= NULL
) ? he1
->h_aliases
: he2
->h_aliases
;
825 while (*cpp
!= NULL
) {
826 len
= strlen (*cpp
) + 1;
838 he
->h_name
= malloc(strlen((he1
!= NULL
) ?
839 he1
->h_name
: he2
->h_name
) + 1);
840 if (he
->h_name
== NULL
)
842 strcpy(he
->h_name
, (he1
!= NULL
) ? he1
->h_name
: he2
->h_name
);
845 * Set address type and length.
848 he
->h_length
= (af
== AF_INET
) ? INADDRSZ
: IN6ADDRSZ
;
853 while (*cpp
!= NULL
) {
860 cpp
= he
->h_addr_list
;
861 while (*cpp
!= NULL
) {
866 free(he
->h_addr_list
);
872 *error_num
= NO_RECOVERY
;
876 static struct hostent
*
877 hostfromaddr(lwres_gnbaresponse_t
*addr
, int af
, const void *src
) {
881 he
= malloc(sizeof(*he
));
884 memset(he
, 0, sizeof(*he
));
887 * Set family and length.
892 he
->h_length
= INADDRSZ
;
895 he
->h_length
= IN6ADDRSZ
;
904 he
->h_name
= strdup(addr
->realname
);
905 if (he
->h_name
== NULL
)
911 he
->h_aliases
= malloc(sizeof(char *) * (addr
->naliases
+ 1));
912 if (he
->h_aliases
== NULL
)
914 for (i
= 0; i
< addr
->naliases
; i
++) {
915 he
->h_aliases
[i
] = strdup(addr
->aliases
[i
]);
916 if (he
->h_aliases
[i
] == NULL
)
919 he
->h_aliases
[i
] = NULL
;
924 he
->h_addr_list
= malloc(sizeof(char *) * 2);
925 if (he
->h_addr_list
== NULL
)
927 he
->h_addr_list
[0] = malloc(he
->h_length
);
928 if (he
->h_addr_list
[0] == NULL
)
930 memcpy(he
->h_addr_list
[0], src
, he
->h_length
);
931 he
->h_addr_list
[1] = NULL
;
935 if (he
!= NULL
&& he
->h_addr_list
!= NULL
) {
936 for (i
= 0; he
->h_addr_list
[i
] != NULL
; i
++)
937 free(he
->h_addr_list
[i
]);
938 free(he
->h_addr_list
);
940 if (he
!= NULL
&& he
->h_aliases
!= NULL
) {
941 for (i
= 0; he
->h_aliases
[i
] != NULL
; i
++)
942 free(he
->h_aliases
[i
]);
945 if (he
!= NULL
&& he
->h_name
!= NULL
)
952 static struct hostent
*
953 hostfromname(lwres_gabnresponse_t
*name
, int af
) {
958 he
= malloc(sizeof(*he
));
961 memset(he
, 0, sizeof(*he
));
964 * Set family and length.
969 he
->h_length
= INADDRSZ
;
972 he
->h_length
= IN6ADDRSZ
;
981 he
->h_name
= strdup(name
->realname
);
982 if (he
->h_name
== NULL
)
988 he
->h_aliases
= malloc(sizeof(char *) * (name
->naliases
+ 1));
989 for (i
= 0; i
< name
->naliases
; i
++) {
990 he
->h_aliases
[i
] = strdup(name
->aliases
[i
]);
991 if (he
->h_aliases
[i
] == NULL
)
994 he
->h_aliases
[i
] = NULL
;
999 he
->h_addr_list
= malloc(sizeof(char *) * (name
->naddrs
+ 1));
1000 addr
= LWRES_LIST_HEAD(name
->addrs
);
1002 while (addr
!= NULL
) {
1003 he
->h_addr_list
[i
] = malloc(he
->h_length
);
1004 if (he
->h_addr_list
[i
] == NULL
)
1006 memcpy(he
->h_addr_list
[i
], addr
->address
, he
->h_length
);
1007 addr
= LWRES_LIST_NEXT(addr
, link
);
1010 he
->h_addr_list
[i
] = NULL
;
1014 if (he
!= NULL
&& he
->h_addr_list
!= NULL
) {
1015 for (i
= 0; he
->h_addr_list
[i
] != NULL
; i
++)
1016 free(he
->h_addr_list
[i
]);
1017 free(he
->h_addr_list
);
1019 if (he
!= NULL
&& he
->h_aliases
!= NULL
) {
1020 for (i
= 0; he
->h_aliases
[i
] != NULL
; i
++)
1021 free(he
->h_aliases
[i
]);
1022 free(he
->h_aliases
);
1024 if (he
!= NULL
&& he
->h_name
!= NULL
)