2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
26 #include <mach/mach.h>
29 #include <rpc/types.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
35 #include <arpa/inet.h>
39 #include "_lu_types.h"
44 static pthread_mutex_t _host_lock
= PTHREAD_MUTEX_INITIALIZER
;
46 extern struct hostent
*_res_gethostbyaddr();
47 extern struct hostent
*_res_gethostbyname();
48 extern struct hostent
*_old_gethostbyaddr();
49 extern struct hostent
*_old_gethostbyname();
50 extern struct hostent
*_old_gethostent();
51 extern void _old_sethostent();
52 extern void _old_endhostent();
53 extern void _old_sethostfile();
55 extern mach_port_t _lu_port
;
56 extern int _lu_running(void);
60 #define IPV6_ADDR_LEN 16
61 #define IPV4_ADDR_LEN 4
63 __private_extern__
void
64 free_host_data(struct hostent
*h
)
69 if (h
== NULL
) return;
71 if (h
->h_name
!= NULL
) free(h
->h_name
);
73 aliases
= h
->h_aliases
;
76 while (*aliases
!= NULL
) free(*aliases
++);
80 if (h
->h_addr_list
!= NULL
)
82 for (i
= 0; h
->h_addr_list
[i
] != NULL
; i
++) free(h
->h_addr_list
[i
]);
88 freehostent(struct hostent
*h
)
90 if (h
== NULL
) return;
96 free_lu_thread_info_host(void *x
)
98 struct lu_thread_info
*tdata
;
100 if (x
== NULL
) return;
102 tdata
= (struct lu_thread_info
*)x
;
104 if (tdata
->lu_entry
!= NULL
)
106 freehostent((struct hostent
*)tdata
->lu_entry
);
107 tdata
->lu_entry
= NULL
;
110 _lu_data_free_vm_xdr(tdata
);
115 __private_extern__
struct hostent
*
116 extract_host(XDR
*xdr
, int want
, int *err
)
119 int i
, j
, nvals
, nkeys
, status
, addr_len
;
120 int family
, addr_count
, map_count
;
122 struct in6_addr addr6
;
123 char *key
, **vals
, **mapvals
;
128 addr_len
= sizeof(u_long
*);
136 if (!xdr_int(xdr
, &nkeys
))
142 h
= (struct hostent
*)calloc(1, sizeof(struct hostent
));
145 h
->h_length
= IPV4_ADDR_LEN
;
147 if (want
> WANT_A4_ONLY
)
150 h
->h_length
= IPV6_ADDR_LEN
;
153 h
->h_addrtype
= family
;
155 for (i
= 0; i
< nkeys
; i
++)
161 status
= _lu_xdr_attribute(xdr
, &key
, &vals
, &nvals
);
177 if ((h
->h_name
== NULL
) && (!strcmp("name", key
)))
182 h
->h_aliases
= (char **)calloc(nvals
, sizeof(char *));
183 for (j
= 1; j
< nvals
; j
++) h
->h_aliases
[j
-1] = vals
[j
];
187 else if ((family
== AF_INET
) && (h
->h_addr_list
== NULL
) && (!strcmp("ip_address", key
)))
190 h
->h_addr_list
= (char **)calloc(nvals
+ 1, addr_len
);
192 for (j
= 0; j
< nvals
; j
++)
195 inet_aton(vals
[j
], &addr
);
196 h
->h_addr_list
[j
] = (char *)calloc(1, IPV4_ADDR_LEN
);
197 memmove(h
->h_addr_list
[j
], &(addr
.s_addr
), IPV4_ADDR_LEN
);
200 h
->h_addr_list
[nvals
] = NULL
;
203 else if ((family
== AF_INET6
) && (h
->h_addr_list
== NULL
) && (!strcmp("ipv6_address", key
)))
206 h
->h_addr_list
= (char **)calloc(nvals
+ 1, addr_len
);
208 for (j
= 0; j
< nvals
; j
++)
210 memset(&addr6
, 0, sizeof(struct in6_addr
));
211 inet_pton(family
, vals
[j
], &addr6
);
212 h
->h_addr_list
[j
] = (char *)calloc(1, IPV6_ADDR_LEN
);
213 memmove(h
->h_addr_list
[j
], &(addr6
.__u6_addr
.__u6_addr32
[0]), IPV6_ADDR_LEN
);
216 h
->h_addr_list
[nvals
] = NULL
;
219 else if ((family
== AF_INET6
) && (mapvals
== NULL
) && (!strcmp("ip_address", key
)))
229 for (; j
< nvals
; j
++) free(vals
[j
]);
234 if ((mapvals
!= NULL
) && (want
> WANT_A6_ONLY
))
236 addr6
.__u6_addr
.__u6_addr32
[0] = 0x00000000;
237 addr6
.__u6_addr
.__u6_addr32
[1] = 0x00000000;
238 addr6
.__u6_addr
.__u6_addr32
[2] = htonl(0x0000ffff);
242 h
->h_addr_list
= (char **)calloc(map_count
+ 1, addr_len
);
246 h
->h_addr_list
= (char **)realloc(h
->h_addr_list
, (addr_count
+ map_count
+ 1) * addr_len
);
249 for (i
= 0; i
< map_count
; i
++)
252 inet_aton(mapvals
[i
], &addr
);
253 h
->h_addr_list
[addr_count
] = (char *)calloc(1, IPV6_ADDR_LEN
);
254 memmove(&(addr6
.__u6_addr
.__u6_addr32
[3]), &(addr
.s_addr
), IPV4_ADDR_LEN
);
255 memcpy(h
->h_addr_list
[addr_count
++], &(addr6
.__u6_addr
.__u6_addr32
[0]), IPV6_ADDR_LEN
);
258 h
->h_addr_list
[addr_count
] = NULL
;
263 for (i
= 0; i
< map_count
; i
++) free(mapvals
[i
]);
267 if (h
->h_name
== NULL
) h
->h_name
= strdup("");
268 if (h
->h_aliases
== NULL
) h
->h_aliases
= (char **)calloc(1, sizeof(char *));
269 if (h
->h_addr_list
== NULL
) h
->h_addr_list
= (char **)calloc(1, sizeof(char *));
274 static struct hostent
*
275 copy_host(struct hostent
*in
)
277 int i
, len
, addr_len
;
280 if (in
== NULL
) return NULL
;
282 h
= (struct hostent
*)calloc(1, sizeof(struct hostent
));
284 h
->h_name
= LU_COPY_STRING(in
->h_name
);
287 if (in
->h_aliases
!= NULL
)
289 for (len
= 0; in
->h_aliases
[len
] != NULL
; len
++);
292 h
->h_aliases
= (char **)calloc(len
+ 1, sizeof(char *));
293 for (i
= 0; i
< len
; i
++)
295 h
->h_aliases
[i
] = strdup(in
->h_aliases
[i
]);
298 h
->h_addrtype
= in
->h_addrtype
;
299 h
->h_length
= in
->h_length
;
302 if (in
->h_addr_list
!= NULL
)
304 for (len
= 0; in
->h_addr_list
[len
] != NULL
; len
++);
307 addr_len
= sizeof(u_long
*);
308 h
->h_addr_list
= (char **)calloc(len
+ 1, addr_len
);
309 for (i
= 0; i
< len
; i
++)
311 h
->h_addr_list
[i
] = (char *)malloc(h
->h_length
);
312 memmove(h
->h_addr_list
[i
], in
->h_addr_list
[i
], h
->h_length
);
319 recycle_host(struct lu_thread_info
*tdata
, struct hostent
*in
)
323 if (tdata
== NULL
) return;
324 h
= (struct hostent
*)tdata
->lu_entry
;
329 tdata
->lu_entry
= NULL
;
332 if (tdata
->lu_entry
== NULL
)
334 tdata
->lu_entry
= in
;
340 h
->h_name
= in
->h_name
;
341 h
->h_aliases
= in
->h_aliases
;
342 h
->h_addrtype
= in
->h_addrtype
;
343 h
->h_length
= in
->h_length
;
344 h
->h_addr_list
= in
->h_addr_list
;
349 __private_extern__
struct hostent
*
350 fake_hostent(const char *name
, struct in_addr addr
)
355 if (name
== NULL
) return NULL
;
357 h
= (struct hostent
*)calloc(1, sizeof(struct hostent
));
359 h
->h_name
= strdup(name
);
361 h
->h_aliases
= (char **)calloc(1, sizeof(char *));
363 h
->h_addrtype
= AF_INET
;
364 h
->h_length
= sizeof(long);
366 addr_len
= sizeof(u_long
*);
367 h
->h_addr_list
= (char **)calloc(2, addr_len
);
369 h
->h_addr_list
[0] = (char *)malloc(h
->h_length
);
370 memmove(h
->h_addr_list
[0], &(addr
.s_addr
), h
->h_length
);
375 __private_extern__
struct hostent
*
376 fake_hostent6(const char *name
, struct in6_addr addr
)
381 if (name
== NULL
) return NULL
;
383 h
= (struct hostent
*)calloc(1, sizeof(struct hostent
));
385 h
->h_name
= strdup(name
);
387 h
->h_aliases
= (char **)calloc(1, sizeof(char *));
389 h
->h_addrtype
= AF_INET6
;
392 addr_len
= sizeof(u_long
*);
393 h
->h_addr_list
= (char **)calloc(2, addr_len
);
395 h
->h_addr_list
[0] = (char *)malloc(h
->h_length
);
396 memmove(h
->h_addr_list
[0], &(addr
.__u6_addr
.__u6_addr32
[0]), h
->h_length
);
401 static struct hostent
*
402 lu_gethostbyaddr(const char *addr
, int want
, int *err
)
405 unsigned int datalen
;
407 static int proc4
= -1;
408 static int proc6
= -1;
409 char *lookup_buf
, *address
;
410 int proc
, count
, len
, family
;
411 struct in_addr addr4
;
412 struct in6_addr addr6
;
416 if (want
> WANT_A4_ONLY
)
422 if ((family
== AF_INET
) && (proc4
< 0))
424 if (_lookup_link(_lu_port
, "gethostbyaddr", &proc4
) != KERN_SUCCESS
)
430 else if ((family
== AF_INET6
) && (proc6
< 0))
432 if (_lookup_link(_lu_port
, "getipv6nodebyaddr", &proc6
) != KERN_SUCCESS
)
441 if (family
== AF_INET
)
443 memmove(&(addr4
.s_addr
), addr
, IPV4_ADDR_LEN
);
444 addr4
.s_addr
= htonl(addr4
.s_addr
);
445 address
= (char *)&(addr4
.s_addr
);
450 memmove(&(addr6
.__u6_addr
.__u6_addr32
[0]), addr
, IPV6_ADDR_LEN
);
451 addr6
.__u6_addr
.__u6_addr32
[0] = htonl(addr6
.__u6_addr
.__u6_addr32
[0]);
452 addr6
.__u6_addr
.__u6_addr32
[1] = htonl(addr6
.__u6_addr
.__u6_addr32
[1]);
453 addr6
.__u6_addr
.__u6_addr32
[2] = htonl(addr6
.__u6_addr
.__u6_addr32
[2]);
454 addr6
.__u6_addr
.__u6_addr32
[3] = htonl(addr6
.__u6_addr
.__u6_addr32
[3]);
455 address
= (char *)&(addr6
.__u6_addr
.__u6_addr32
[0]);
462 if (_lookup_all(_lu_port
, proc
, (unit
*)address
, len
/ BYTES_PER_XDR_UNIT
, &lookup_buf
, &datalen
) != KERN_SUCCESS
)
468 datalen
*= BYTES_PER_XDR_UNIT
;
469 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
471 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
474 if (!xdr_int(&inxdr
, &count
))
477 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
485 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
486 *err
= HOST_NOT_FOUND
;
492 h
= extract_host(&inxdr
, want
, err
);
494 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
499 static struct hostent
*
500 lu_gethostbyname(const char *name
, int want
, int *err
)
503 unsigned int datalen
;
504 char namebuf
[_LU_MAXLUSTRLEN
+ BYTES_PER_XDR_UNIT
];
507 static int proc4
= -1;
508 static int proc6
= -1;
510 int proc
, count
, family
;
513 if (want
> WANT_A4_ONLY
) family
= AF_INET6
;
515 if (((want
== WANT_MAPPED_A4_ONLY
) || (family
== AF_INET
)) && (proc4
< 0))
517 if (_lookup_link(_lu_port
, "gethostbyname", &proc4
) != KERN_SUCCESS
)
523 else if ((family
== AF_INET6
) && (proc6
< 0))
525 if (_lookup_link(_lu_port
, "getipv6nodebyname", &proc6
) != KERN_SUCCESS
)
533 if ((family
== AF_INET6
) && (want
!= WANT_MAPPED_A4_ONLY
)) proc
= proc6
;
535 xdrmem_create(&outxdr
, namebuf
, sizeof(namebuf
), XDR_ENCODE
);
536 if (!xdr__lu_string(&outxdr
, (_lu_string
*)&name
))
538 xdr_destroy(&outxdr
);
546 if (_lookup_all(_lu_port
, proc
, (unit
*)namebuf
, xdr_getpos(&outxdr
) / BYTES_PER_XDR_UNIT
, &lookup_buf
, &datalen
) != KERN_SUCCESS
)
548 xdr_destroy(&outxdr
);
553 xdr_destroy(&outxdr
);
555 datalen
*= BYTES_PER_XDR_UNIT
;
556 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
558 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
561 if (!xdr_int(&inxdr
, &count
))
564 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
572 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
573 *err
= HOST_NOT_FOUND
;
579 h
= extract_host(&inxdr
, want
, err
);
581 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
589 struct lu_thread_info
*tdata
;
591 tdata
= _lu_data_create_key(_lu_data_key_host
, free_lu_thread_info_host
);
592 _lu_data_free_vm_xdr(tdata
);
601 static struct hostent
*
602 lu_gethostent(int want
, int *err
)
604 static int proc
= -1;
605 struct lu_thread_info
*tdata
;
608 tdata
= _lu_data_create_key(_lu_data_key_host
, free_lu_thread_info_host
);
611 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
612 _lu_data_set_key(_lu_data_key_host
, tdata
);
615 if (tdata
->lu_vm
== NULL
)
619 if (_lookup_link(_lu_port
, "gethostent", &proc
) != KERN_SUCCESS
)
627 if (_lookup_all(_lu_port
, proc
, NULL
, 0, &(tdata
->lu_vm
), &(tdata
->lu_vm_length
)) != KERN_SUCCESS
)
634 /* mig stubs measure size in words (4 bytes) */
635 tdata
->lu_vm_length
*= 4;
637 if (tdata
->lu_xdr
!= NULL
)
639 xdr_destroy(tdata
->lu_xdr
);
642 tdata
->lu_xdr
= (XDR
*)calloc(1, sizeof(XDR
));
644 xdrmem_create(tdata
->lu_xdr
, tdata
->lu_vm
, tdata
->lu_vm_length
, XDR_DECODE
);
645 if (!xdr_int(tdata
->lu_xdr
, &tdata
->lu_vm_cursor
))
653 if (tdata
->lu_vm_cursor
== 0)
656 *err
= HOST_NOT_FOUND
;
660 h
= extract_host(tdata
->lu_xdr
, want
, err
);
664 *err
= HOST_NOT_FOUND
;
669 tdata
->lu_vm_cursor
--;
674 static struct hostent
*
675 gethostbyaddrerrno(const char *addr
, int len
, int type
, int *err
)
677 struct hostent
*res
= NULL
;
683 if (type
== AF_INET6
) want
= WANT_A6_ONLY
;
687 res
= lu_gethostbyaddr(addr
, want
, err
);
691 pthread_mutex_lock(&_host_lock
);
692 res
= copy_host(_res_gethostbyaddr(addr
, len
, type
));
693 if (res
== NULL
) res
= copy_host(_old_gethostbyaddr(addr
, len
, type
));
695 pthread_mutex_unlock(&_host_lock
);
702 gethostbyaddr(const char *addr
, int len
, int type
)
705 struct lu_thread_info
*tdata
;
707 res
= gethostbyaddrerrno(addr
, len
, type
, &h_errno
);
713 tdata
= _lu_data_create_key(_lu_data_key_host
, free_lu_thread_info_host
);
716 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
717 _lu_data_set_key(_lu_data_key_host
, tdata
);
720 recycle_host(tdata
, res
);
721 return (struct hostent
*)tdata
->lu_entry
;
725 gethostbynameerrno(const char *name
, int *err
)
727 struct hostent
*res
= NULL
;
734 * If name is all dots and digits without a trailing dot,
735 * call inet_aton. If it's OK, return a fake entry.
736 * Otherwise, return an error.
738 * If name has alpha or ends with a dot, proceed as usual...
742 *err
= HOST_NOT_FOUND
;
748 *err
= HOST_NOT_FOUND
;
753 for (i
= 0; name
[i
] != '\0'; i
++)
755 if (name
[i
] == '.') continue;
756 if ((name
[i
] >= '0') && (name
[i
] <= '9')) continue;
761 if ((is_addr
== 1) && (name
[i
-1] == '.')) is_addr
= 0;
765 if (inet_aton(name
, &addr
) == 0)
767 *err
= HOST_NOT_FOUND
;
770 res
= fake_hostent(name
, addr
);
772 else if (_lu_running())
774 res
= lu_gethostbyname(name
, WANT_A4_ONLY
, err
);
778 pthread_mutex_lock(&_host_lock
);
779 res
= copy_host(_res_gethostbyname(name
));
780 if (res
== NULL
) res
= copy_host(_old_gethostbyname(name
));
782 pthread_mutex_unlock(&_host_lock
);
787 if (inet_aton(name
, &addr
) == 0)
789 *err
= HOST_NOT_FOUND
;
793 res
= gethostbyaddrerrno((char *)&addr
, sizeof(addr
), AF_INET
, err
);
795 res
= fake_hostent(name
, addr
);
803 gethostbyname(const char *name
)
806 struct lu_thread_info
*tdata
;
808 res
= gethostbynameerrno(name
, &h_errno
);
814 tdata
= _lu_data_create_key(_lu_data_key_host
, free_lu_thread_info_host
);
817 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
818 _lu_data_set_key(_lu_data_key_host
, tdata
);
821 recycle_host(tdata
, res
);
822 return (struct hostent
*)tdata
->lu_entry
;
828 struct hostent
*res
= NULL
;
829 struct lu_thread_info
*tdata
;
831 tdata
= _lu_data_create_key(_lu_data_key_host
, free_lu_thread_info_host
);
834 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
835 _lu_data_set_key(_lu_data_key_host
, tdata
);
840 res
= lu_gethostent(WANT_A4_ONLY
, &h_errno
);
844 pthread_mutex_lock(&_host_lock
);
845 res
= copy_host(_old_gethostent());
846 pthread_mutex_unlock(&_host_lock
);
849 recycle_host(tdata
, res
);
850 return (struct hostent
*)tdata
->lu_entry
;
854 sethostent(int stayopen
)
856 if (_lu_running()) lu_sethostent();
857 else _old_sethostent(stayopen
);
863 if (_lu_running()) lu_endhostent();
864 else _old_endhostent();
867 __private_extern__
int
868 is_a4_mapped(const char *s
)
873 if (s
== NULL
) return 0;
875 for (i
= 0; i
< 10; i
++)
878 if (c
!= 0x0) return 0;
881 for (i
= 10; i
< 12; i
++)
884 if (c
!= 0xff) return 0;
890 __private_extern__
int
891 is_a4_compat(const char *s
)
896 if (s
== NULL
) return 0;
898 for (i
= 0; i
< 12; i
++)
901 if (c
!= 0x0) return 0;
904 /* Check for :: and ::1 */
905 for (i
= 13; i
< 15; i
++)
907 /* anything non-zero in these 3 bytes means it's a V4 address */
909 if (c
!= 0x0) return 1;
912 /* Leading 15 bytes are all zero */
914 if (c
== 0x0) return 0;
915 if (c
== 0x1) return 0;
921 getipnodebyaddr(const void *src
, size_t len
, int af
, int *err
)
927 if ((af
== AF_INET6
) && (len
== 16) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
934 res
= gethostbyaddrerrno((const char *)src
, len
, af
, err
);
939 if (res
->h_name
== NULL
) {
948 getipnodebyname(const char *name
, int af
, int flags
, int *err
)
950 int status
, want
, really_want
, if4
, if6
;
952 struct ifaddrs
*ifa
, *ifap
;
953 struct in_addr addr4
;
954 struct in6_addr addr6
;
956 memset(&addr4
, 0, sizeof(struct in_addr
));
957 memset(&addr6
, 0, sizeof(struct in6_addr
));
963 status
= inet_aton(name
, &addr4
);
966 /* return a fake hostent */
967 res
= fake_hostent(name
, addr4
);
971 else if (af
== AF_INET6
)
973 status
= inet_pton(af
, name
, &addr6
);
976 /* return a fake hostent */
977 res
= fake_hostent6(name
, addr6
);
980 status
= inet_aton(name
, &addr4
);
983 if (!(flags
& (AI_V4MAPPED
|AI_V4MAPPED_CFG
)))
985 *err
= HOST_NOT_FOUND
;
989 addr6
.__u6_addr
.__u6_addr32
[0] = 0x00000000;
990 addr6
.__u6_addr
.__u6_addr32
[1] = 0x00000000;
991 addr6
.__u6_addr
.__u6_addr32
[2] = htonl(0x0000ffff);
992 memmove(&(addr6
.__u6_addr
.__u6_addr32
[3]), &(addr4
.s_addr
), IPV4_ADDR_LEN
);
994 /* return a fake hostent */
995 res
= fake_hostent6(name
, addr6
);
1006 * IF AI_ADDRCONFIG is set, we need to know what interface flavors we really have.
1012 if (flags
& AI_ADDRCONFIG
)
1014 if (getifaddrs(&ifa
) < 0)
1020 for (ifap
= ifa
; ifap
!= NULL
; ifap
= ifap
->ifa_next
)
1022 if (ifap
->ifa_addr
== NULL
) continue;
1023 if ((ifap
->ifa_flags
& IFF_UP
) == 0) continue;
1024 if (ifap
->ifa_addr
->sa_family
== AF_INET
) if4
++;
1025 else if (ifap
->ifa_addr
->sa_family
== AF_INET6
) if6
++;
1030 /* Bail out if there are no interfaces */
1031 if ((if4
== 0) && (if6
== 0))
1039 * Figure out what we want.
1040 * If user asked for AF_INET, we only want V4 addresses.
1042 want
= WANT_A4_ONLY
;
1047 want
= WANT_A4_ONLY
;
1048 if ((flags
& AI_ADDRCONFIG
) && (if4
== 0))
1056 /* af == AF_INET6 */
1057 want
= WANT_A6_ONLY
;
1059 if (flags
& (AI_V4MAPPED
|AI_V4MAPPED_CFG
))
1063 want
= WANT_A6_PLUS_MAPPED_A4
;
1068 want
= WANT_A6_ONLY
;
1069 really_want
= WANT_A6_OR_MAPPED_A4_IF_NO_A6
;
1074 if ((flags
& AI_ADDRCONFIG
) && (if6
== 0))
1086 res
= lu_gethostbyname(name
, want
, err
);
1087 if ((res
== NULL
) &&
1088 ((really_want
== WANT_A6_OR_MAPPED_A4_IF_NO_A6
) ||
1089 (really_want
== WANT_A6_PLUS_MAPPED_A4
)))
1091 res
= lu_gethostbyname(name
, WANT_MAPPED_A4_ONLY
, err
);
1096 pthread_mutex_lock(&_host_lock
);
1097 res
= copy_host(_res_gethostbyname(name
));
1098 if (res
== NULL
) res
= copy_host(_old_gethostbyname(name
));
1100 pthread_mutex_unlock(&_host_lock
);
1105 *err
= HOST_NOT_FOUND
;