13bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* $NetBSD: getaddrinfo.c,v 1.91.6.1 2009/01/26 00:27:34 snj Exp $ */ 23bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* $KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $ */ 33bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 43bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* 53bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 63bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * All rights reserved. 73bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * 83bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Redistribution and use in source and binary forms, with or without 93bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * modification, are permitted provided that the following conditions 103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * are met: 113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * 1. Redistributions of source code must retain the above copyright 123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * notice, this list of conditions and the following disclaimer. 133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * 2. Redistributions in binary form must reproduce the above copyright 143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * notice, this list of conditions and the following disclaimer in the 153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * documentation and/or other materials provided with the distribution. 163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * 3. Neither the name of the project nor the names of its contributors 173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * may be used to endorse or promote products derived from this software 183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * without specific prior written permission. 193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * 203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * SUCH DAMAGE. 313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* 343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Issues to be discussed: 353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * - Return values. There are nonstandard return values defined and used 363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * in the source code. This is because RFC2553 is silent about which error 373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * code must be returned for which situation. 383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * - IPv4 classful (shortened) form. RFC2553 is silent about it. XNET 5.2 393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * says to use inet_aton() to convert IPv4 numeric to binary (alows 403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * classful form as a result). 413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * current code - disallow classful form for IPv4 (due to use of inet_pton). 423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * - freeaddrinfo(NULL). RFC2553 is silent about it. XNET 5.2 says it is 433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * invalid. 443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * current code - SEGV on freeaddrinfo(NULL) 453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Note: 463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * - The code filters out AFs that are not supported by the kernel, 473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * when globbing NULL hostname (to loopback, or wildcard). Is it the right 483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG 493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * in ai_flags? 503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague. 513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * (1) what should we do against numeric hostname (2) what should we do 523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * against NULL hostname (3) what is AI_ADDRCONFIG itself. AF not ready? 533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * non-loopback address configured? global address configured? 543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <sys/cdefs.h> 573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#if defined(LIBC_SCCS) && !defined(lint) 583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy__RCSID("$NetBSD: getaddrinfo.c,v 1.91.6.1 2009/01/26 00:27:34 snj Exp $"); 593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif /* LIBC_SCCS and not lint */ 603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define INET6 1 623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include "namespace.h" 643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <sys/types.h> 653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <sys/param.h> 663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <sys/socket.h> 673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <net/if.h> 683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <netinet/in.h> 693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <arpa/inet.h> 703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <arpa/nameser.h> 713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <assert.h> 723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <ctype.h> 733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <errno.h> 743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <netdb.h> 753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <resolv.h> 763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <stddef.h> 773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <stdio.h> 783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <stdlib.h> 793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <string.h> 803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <unistd.h> 813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <stdarg.h> 833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <nsswitch.h> 843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <resolv.h> 853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy//#ifdef YP 873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy//#include <rpc/rpc.h> 883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy//#include <rpcsvc/yp_prot.h> 893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy//#include <rpcsvc/ypclnt.h> 903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy//#endif 913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#include <net/servent.h> 933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define endservent_r(svd) endservent() 953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define nsdispatch(pResult,dtab,database,routine,files,hostname,pai) NS_NOTFOUND 963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define res_nmkquery(state,op,dname,class,type,data,datalen,newrr_in,buf,buflen) res_mkquery( op, dname, class, type, data, datalen, newrr_in, buf, buflen ) 973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define res_nsend(state,buf,buflen,ans,anssiz) res_send ( buf, buflen, ans, anssiz ) 983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* Things involving an internal (static) resolver context. */ 1003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy__BEGIN_DECLS 1013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define __res_get_state() (( 0 != _res.nscount ) ? &_res : NULL ) 1023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define __res_put_state(state) 1033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define __res_state() _res 1043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy__END_DECLS 1053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 1063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef __weak_alias 1073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy__weak_alias(getaddrinfo,_getaddrinfo) 1083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy__weak_alias(freeaddrinfo,_freeaddrinfo) 1093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy__weak_alias(gai_strerror,_gai_strerror) 1103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 1113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 1123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define SUCCESS 0 1133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define ANY 0 1143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define YES 1 1153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define NO 0 1163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 1173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic const char in_addrany[] = { 0, 0, 0, 0 }; 1183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic const char in_loopback[] = { 127, 0, 0, 1 }; 1193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef INET6 1203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic const char in6_addrany[] = { 1213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy}; 1233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic const char in6_loopback[] = { 1243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 1253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy}; 1263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 1273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 1283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic const struct afd { 1293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int a_af; 1303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int a_addrlen; 1313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int a_socklen; 1323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int a_off; 1333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *a_addrany; 1343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *a_loopback; 1353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int a_scoped; 1363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} afdl [] = { 1373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef INET6 1383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy {PF_INET6, sizeof(struct in6_addr), 1393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy sizeof(struct sockaddr_in6), 1403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy offsetof(struct sockaddr_in6, sin6_addr), 1413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy in6_addrany, in6_loopback, 1}, 1423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 1433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy {PF_INET, sizeof(struct in_addr), 1443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy sizeof(struct sockaddr_in), 1453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy offsetof(struct sockaddr_in, sin_addr), 1463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy in_addrany, in_loopback, 0}, 1473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy {0, 0, 0, 0, NULL, NULL, 0}, 1483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy}; 1493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 1503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystruct explore { 1513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int e_af; 1523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int e_socktype; 1533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int e_protocol; 1543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *e_protostr; 1553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int e_wild; 1563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define WILD_AF(ex) ((ex)->e_wild & 0x01) 1573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02) 1583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04) 1593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy}; 1603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 1613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic const struct explore explore[] = { 1623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#if 0 1633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 }, 1643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 1653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef INET6 1663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 1673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 1683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 }, 1693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 1703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 1713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 1723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { PF_INET, SOCK_RAW, ANY, NULL, 0x05 }, 1733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 1743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 1753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 }, 1763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { -1, 0, 0, NULL, 0 }, 1773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy}; 1783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 1793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef INET6 1803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define PTON_MAX 16 1813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#else 1823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define PTON_MAX 4 1833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 1843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 1853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic const ns_src default_dns_files[] = { 1863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { NSSRC_FILES, NS_SUCCESS }, 1873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { NSSRC_DNS, NS_SUCCESS }, 1883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy { 0, 0 } 1893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy}; 1903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 1913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define MAXPACKET (64*1024) 1923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 1933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahytypedef union { 1943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy HEADER hdr; 1953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy u_char buf[MAXPACKET]; 1963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} querybuf; 1973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 1983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystruct res_target { 1993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct res_target *next; 2003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *name; /* domain name */ 2013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int qclass, qtype; /* class and type of query */ 2023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy u_char *answer; /* buffer to put answer */ 2033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int anslen; /* size of answer buffer */ 2043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int n; /* result length */ 2053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy}; 2063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 2073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int str2number(const char *); 2083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int explore_fqdn(const struct addrinfo *, const char *, 2093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *, struct addrinfo **, struct servent_data *); 2103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int explore_null(const struct addrinfo *, 2113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *, struct addrinfo **, struct servent_data *); 2123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int explore_numeric(const struct addrinfo *, const char *, 2133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *, struct addrinfo **, const char *, struct servent_data *); 2143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int explore_numeric_scope(const struct addrinfo *, const char *, 2153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *, struct addrinfo **, struct servent_data *); 2163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int get_canonname(const struct addrinfo *, 2173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *, const char *); 2183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic struct addrinfo *get_ai(const struct addrinfo *, 2193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct afd *, const char *); 2203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int get_portmatch(const struct addrinfo *, const char *, 2213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct servent_data *); 2223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int get_port(const struct addrinfo *, const char *, int, 2233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct servent_data *); 2243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic const struct afd *find_afd(int); 2253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef INET6 2263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *); 2273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 2283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 2293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic struct addrinfo *getanswer(const querybuf *, int, const char *, int, 2303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct addrinfo *); 2313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic void aisort(struct addrinfo *s, res_state res); 2323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int _dns_getaddrinfo(void *, void *, va_list); 2333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic void _sethtent(FILE **); 2343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic void _endhtent(FILE **); 2353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic struct addrinfo *_gethtent(FILE **, const char *, 2363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct addrinfo *); 2373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int _files_getaddrinfo(void *, void *, va_list); 2383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef YP 2393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic struct addrinfo *_yphostent(char *, const struct addrinfo *); 2403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int _yp_getaddrinfo(void *, void *, va_list); 2413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 2423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 2433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int res_queryN(const char *, struct res_target *, res_state); 2443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int res_searchN(const char *, struct res_target *, res_state); 2453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int res_querydomainN(const char *, const char *, 2463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct res_target *, res_state); 2473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 2483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic const char * const ai_errlist[] = { 2493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "Success", 2503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "Address family for hostname not supported", /* EAI_ADDRFAMILY */ 2513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "Temporary failure in name resolution", /* EAI_AGAIN */ 2523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "Invalid value for ai_flags", /* EAI_BADFLAGS */ 2533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "Non-recoverable failure in name resolution", /* EAI_FAIL */ 2543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "ai_family not supported", /* EAI_FAMILY */ 2553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "Memory allocation failure", /* EAI_MEMORY */ 2563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "No address associated with hostname", /* EAI_NODATA */ 2573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "hostname nor servname provided, or not known", /* EAI_NONAME */ 2583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "servname not supported for ai_socktype", /* EAI_SERVICE */ 2593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "ai_socktype not supported", /* EAI_SOCKTYPE */ 2603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "System error returned in errno", /* EAI_SYSTEM */ 2613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "Invalid value for hints", /* EAI_BADHINTS */ 2623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "Resolved protocol is unknown", /* EAI_PROTOCOL */ 2633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "Argument buffer overflow", /* EAI_OVERFLOW */ 2643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "Unknown error", /* EAI_MAX */ 2653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy}; 2663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 2673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* XXX macros that make external reference is BAD. */ 2683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 2693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define GET_AI(ai, afd, addr) \ 2703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahydo { \ 2713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* external reference: pai, error, and label free */ \ 2723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy (ai) = get_ai(pai, (afd), (addr)); \ 2733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((ai) == NULL) { \ 2743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = EAI_MEMORY; \ 2753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto free; \ 2763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } \ 2773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} while (/*CONSTCOND*/0) 2783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 2793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define GET_PORT(ai, serv, svd) \ 2803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahydo { \ 2813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* external reference: error and label free */ \ 2823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = get_port((ai), (serv), 0, (svd)); \ 2833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (error != 0) \ 2843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto free; \ 2853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} while (/*CONSTCOND*/0) 2863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 2873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define GET_CANONNAME(ai, str) \ 2883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahydo { \ 2893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* external reference: pai, error and label free */ \ 2903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = get_canonname(pai, (ai), (str)); \ 2913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (error != 0) \ 2923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto free; \ 2933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} while (/*CONSTCOND*/0) 2943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 2953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define ERR(err) \ 2963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahydo { \ 2973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* external reference: error, and label bad */ \ 2983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = (err); \ 2993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto bad; \ 3003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /*NOTREACHED*/ \ 3013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} while (/*CONSTCOND*/0) 3023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define MATCH_FAMILY(x, y, w) \ 3043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || \ 3053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy (y) == PF_UNSPEC))) 3063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define MATCH(x, y, w) \ 3073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY))) 3083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyconst char * 3103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahygai_strerror(int ecode) 3113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 3123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ecode < 0 || ecode > EAI_MAX) 3133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ecode = EAI_MAX; 3143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return ai_errlist[ecode]; 3153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 3163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyvoid 3183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyfreeaddrinfo(struct addrinfo *ai) 3193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 3203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *next; 3213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(ai != NULL); 3233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy do { 3253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy next = ai->ai_next; 3263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ai->ai_canonname) 3273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(ai->ai_canonname); 3283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* no need to free(ai->ai_addr) */ 3293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(ai); 3303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai = next; 3313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } while (ai); 3323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 3333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 3353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystr2number(const char *p) 3363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 3373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *ep; 3383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy unsigned long v; 3393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(p != NULL); 3413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (*p == '\0') 3433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return -1; 3443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ep = NULL; 3453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy errno = 0; 3463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy v = strtoul(p, &ep, 10); 3473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (errno == 0 && ep && *ep == '\0' && v <= UINT_MAX) 3483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return v; 3493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy else 3503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return -1; 3513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 3523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyint 3543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahygetaddrinfo(const char *hostname, const char *servname, 3553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct addrinfo *hints, struct addrinfo **res) 3563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 3573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo sentinel; 3583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *cur; 3593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int error = 0; 3603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo ai; 3613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo ai0; 3623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *pai; 3633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct explore *ex; 3643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct servent_data svd; 3653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* hostname is allowed to be NULL */ 3673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* servname is allowed to be NULL */ 3683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* hints is allowed to be NULL */ 3693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(res != NULL); 3703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy (void)memset(&svd, 0, sizeof(svd)); 3723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memset(&sentinel, 0, sizeof(sentinel)); 3733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = &sentinel; 3743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memset(&ai, 0, sizeof(ai)); 3753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai = &ai; 3763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_flags = 0; 3773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_family = PF_UNSPEC; 3783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_socktype = ANY; 3793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_protocol = ANY; 3803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_addrlen = 0; 3813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_canonname = NULL; 3823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_addr = NULL; 3833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_next = NULL; 3843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 3853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (hostname == NULL && servname == NULL) 3863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return EAI_NONAME; 3873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (hints) { 3883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* error check for hints */ 3893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (hints->ai_addrlen || hints->ai_canonname || 3903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy hints->ai_addr || hints->ai_next) 3913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ERR(EAI_BADHINTS); /* xxx */ 3923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (hints->ai_flags & ~AI_MASK) 3933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ERR(EAI_BADFLAGS); 3943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (hints->ai_family) { 3953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case PF_UNSPEC: 3963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case PF_INET: 3973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef INET6 3983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case PF_INET6: 3993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 4003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 4013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default: 4023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ERR(EAI_FAMILY); 4033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 4043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memcpy(pai, hints, sizeof(*pai)); 4053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 4073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * if both socktype/protocol are specified, check if they 4083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * are meaningful combination. 4093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 4103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) { 4113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (ex = explore; ex->e_af >= 0; ex++) { 4123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_family != ex->e_af) 4133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 4143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ex->e_socktype == ANY) 4153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 4163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ex->e_protocol == ANY) 4173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 4183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_socktype == ex->e_socktype 4193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy && pai->ai_protocol != ex->e_protocol) { 4203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ERR(EAI_BADHINTS); 4213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 4223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 4233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 4243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 4253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 4273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * check for special cases. (1) numeric servname is disallowed if 4283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * socktype/protocol are left unspecified. (2) servname is disallowed 4293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * for raw and other inet{,6} sockets. 4303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 4313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (MATCH_FAMILY(pai->ai_family, PF_INET, 1) 4323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef PF_INET6 4333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy || MATCH_FAMILY(pai->ai_family, PF_INET6, 1) 4343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 4353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ) { 4363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai0 = *pai; /* backup *pai */ 4373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_family == PF_UNSPEC) { 4393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef PF_INET6 4403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_family = PF_INET6; 4413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#else 4423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_family = PF_INET; 4433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 4443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 4453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = get_portmatch(pai, servname, &svd); 4463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (error) 4473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ERR(error); 4483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *pai = ai0; 4503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 4513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai0 = *pai; 4533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* NULL hostname, or numeric hostname */ 4553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (ex = explore; ex->e_af >= 0; ex++) { 4563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *pai = ai0; 4573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* PF_UNSPEC entries are prepared for DNS queries only */ 4593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ex->e_af == PF_UNSPEC) 4603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 4613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) 4633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 4643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) 4653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 4663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) 4673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 4683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_family == PF_UNSPEC) 4703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_family = ex->e_af; 4713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 4723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_socktype = ex->e_socktype; 4733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 4743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_protocol = ex->e_protocol; 4753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (hostname == NULL) 4773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = explore_null(pai, servname, &cur->ai_next, 4783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy &svd); 4793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy else 4803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = explore_numeric_scope(pai, hostname, servname, 4813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy &cur->ai_next, &svd); 4823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (error) 4843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto free; 4853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (cur->ai_next) 4873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = cur->ai_next; 4883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 4893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 4913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * XXX 4923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * If numeric representation of AF1 can be interpreted as FQDN 4933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * representation of AF2, we need to think again about the code below. 4943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 4953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (sentinel.ai_next) 4963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto good; 4973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 4983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (hostname == NULL) 4993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ERR(EAI_NODATA); 5003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_flags & AI_NUMERICHOST) 5013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ERR(EAI_NONAME); 5023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 5043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * hostname as alphabetical name. 5053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * we would like to prefer AF_INET6 than AF_INET, so we'll make a 5063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * outer loop by AFs. 5073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 5083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (ex = explore; ex->e_af >= 0; ex++) { 5093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *pai = ai0; 5103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* require exact match for family field */ 5123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_family != ex->e_af) 5133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 5143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!MATCH(pai->ai_socktype, ex->e_socktype, 5163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy WILD_SOCKTYPE(ex))) { 5173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 5183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 5193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!MATCH(pai->ai_protocol, ex->e_protocol, 5203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy WILD_PROTOCOL(ex))) { 5213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 5223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 5233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 5253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_socktype = ex->e_socktype; 5263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 5273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_protocol = ex->e_protocol; 5283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = explore_fqdn(pai, hostname, servname, &cur->ai_next, 5303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy &svd); 5313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (cur && cur->ai_next) 5333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = cur->ai_next; 5343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 5353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* XXX */ 5373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (sentinel.ai_next) 5383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = 0; 5393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (error) 5413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto free; 5423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (sentinel.ai_next) { 5443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy good: 5453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy endservent_r(&svd); 5463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *res = sentinel.ai_next; 5473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return SUCCESS; 5483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else 5493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = EAI_FAIL; 5503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free: 5513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy bad: 5523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy endservent_r(&svd); 5533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (sentinel.ai_next) 5543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy freeaddrinfo(sentinel.ai_next); 5553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *res = NULL; 5563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return error; 5573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 5583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 559826f9005c21d61845f64f779bc86c4ca15caa1e6lpleahystatic const ns_dtab dtab[] = { 5607700f0f5c0ab90bf052e33fa0ddd2f2aa7e7893elpleahy NS_FILES_CB(((nss_method)_files_getaddrinfo), NULL) 5617700f0f5c0ab90bf052e33fa0ddd2f2aa7e7893elpleahy { NSSRC_DNS, ((nss_method)_dns_getaddrinfo), NULL }, /* force -DHESIOD */ 562826f9005c21d61845f64f779bc86c4ca15caa1e6lpleahy NS_NIS_CB(_yp_getaddrinfo, NULL) 563826f9005c21d61845f64f779bc86c4ca15caa1e6lpleahy NS_NULL_CB 564826f9005c21d61845f64f779bc86c4ca15caa1e6lpleahy}; 565826f9005c21d61845f64f779bc86c4ca15caa1e6lpleahy 5663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* 5673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * FQDN hostname, DNS lookup 5683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 5693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 5703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyexplore_fqdn(const struct addrinfo *pai, const char *hostname, 5713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *servname, struct addrinfo **res, struct servent_data *svd) 5723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 5733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *result; 5743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *cur; 5753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int error = 0; 5763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(pai != NULL); 5783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* hostname may be NULL */ 5793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* servname may be NULL */ 5803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(res != NULL); 5813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy result = NULL; 5833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 5853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * if the servname does not match socktype/protocol, ignore it. 5863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 5873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (get_portmatch(pai, servname, svd) != 0) 5883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 5893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 5903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo", 5913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default_dns_files, hostname, pai)) { 5923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case NS_TRYAGAIN: 5933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = EAI_AGAIN; 5943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto free; 5953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case NS_UNAVAIL: 5963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = EAI_FAIL; 5973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto free; 5983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case NS_NOTFOUND: 5993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = EAI_NODATA; 6003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto free; 6013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case NS_SUCCESS: 6023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = 0; 6033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (cur = result; cur; cur = cur->ai_next) { 6043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy GET_PORT(cur, servname, svd); 6053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* canonname should be filled already */ 6063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 6073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 6083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 6093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *res = result; 6113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 6133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyfree: 6153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (result) 6163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy freeaddrinfo(result); 6173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return error; 6183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 6193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* 6213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * hostname == NULL. 6223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * passive socket -> anyaddr (0.0.0.0 or ::) 6233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * non-passive socket -> localhost (127.0.0.1 or ::1) 6243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 6253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 6263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyexplore_null(const struct addrinfo *pai, const char *servname, 6273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo **res, struct servent_data *svd) 6283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 6293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int s; 6303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct afd *afd; 6313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *cur; 6323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo sentinel; 6333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int error; 6343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(pai != NULL); 6363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* servname may be NULL */ 6373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(res != NULL); 6383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *res = NULL; 6403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy sentinel.ai_next = NULL; 6413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = &sentinel; 6423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 6443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * filter out AFs that are not supported by the kernel 6453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * XXX errno? 6463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 6473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy s = socket(pai->ai_family, SOCK_DGRAM, 0); 6483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (s < 0) { 6493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (errno != EMFILE) 6503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 6513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else 6523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy close(s); 6533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 6553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * if the servname does not match socktype/protocol, ignore it. 6563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 6573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (get_portmatch(pai, servname, svd) != 0) 6583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 6593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy afd = find_afd(pai->ai_family); 6613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (afd == NULL) 6623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 6633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_flags & AI_PASSIVE) { 6653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy GET_AI(cur->ai_next, afd, afd->a_addrany); 6663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* xxx meaningless? 6673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * GET_CANONNAME(cur->ai_next, "anyaddr"); 6683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 6693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy GET_PORT(cur->ai_next, servname, svd); 6703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else { 6713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy GET_AI(cur->ai_next, afd, afd->a_loopback); 6723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* xxx meaningless? 6733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * GET_CANONNAME(cur->ai_next, "localhost"); 6743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 6753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy GET_PORT(cur->ai_next, servname, svd); 6763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 6773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = cur->ai_next; 6783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *res = sentinel.ai_next; 6803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 6813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyfree: 6833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (sentinel.ai_next) 6843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy freeaddrinfo(sentinel.ai_next); 6853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return error; 6863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 6873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 6883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* 6893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * numeric hostname 6903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 6913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 6923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyexplore_numeric(const struct addrinfo *pai, const char *hostname, 6933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *servname, struct addrinfo **res, const char *canonname, 6943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct servent_data *svd) 6953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 6963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct afd *afd; 6973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *cur; 6983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo sentinel; 6993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int error; 7003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char pton[PTON_MAX]; 7013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 7023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(pai != NULL); 7033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* hostname may be NULL */ 7043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* servname may be NULL */ 7053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(res != NULL); 7063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 7073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *res = NULL; 7083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy sentinel.ai_next = NULL; 7093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = &sentinel; 7103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 7113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 7123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * if the servname does not match socktype/protocol, ignore it. 7133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 7143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (get_portmatch(pai, servname, svd) != 0) 7153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 7163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 7173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy afd = find_afd(pai->ai_family); 7183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (afd == NULL) 7193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 7203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 7213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (afd->a_af) { 7223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#if 0 /*X/Open spec*/ 7233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case AF_INET: 7243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (inet_aton(hostname, (struct in_addr *)pton) == 1) { 7253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_family == afd->a_af || 7263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_family == PF_UNSPEC /*?*/) { 7273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy GET_AI(cur->ai_next, afd, pton); 7283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy GET_PORT(cur->ai_next, servname, svd); 7293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((pai->ai_flags & AI_CANONNAME)) { 7303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 7313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Set the numeric address itself as 7323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * the canonical name, based on a 7333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * clarification in rfc2553bis-03. 7343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 7353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy GET_CANONNAME(cur->ai_next, canonname); 7363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 7373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (cur && cur->ai_next) 7383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = cur->ai_next; 7393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else 7403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ERR(EAI_FAMILY); /*xxx*/ 7413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 7423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 7433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 7443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default: 7453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (inet_pton(afd->a_af, hostname, pton) == 1) { 7463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_family == afd->a_af || 7473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai->ai_family == PF_UNSPEC /*?*/) { 7483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy GET_AI(cur->ai_next, afd, pton); 7493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy GET_PORT(cur->ai_next, servname, svd); 7503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((pai->ai_flags & AI_CANONNAME)) { 7513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 7523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Set the numeric address itself as 7533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * the canonical name, based on a 7543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * clarification in rfc2553bis-03. 7553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 7563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy GET_CANONNAME(cur->ai_next, canonname); 7573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 7583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (cur->ai_next) 7593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = cur->ai_next; 7603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else 7613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ERR(EAI_FAMILY); /*xxx*/ 7623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 7633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 7643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 7653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 7663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *res = sentinel.ai_next; 7673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 7683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 7693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyfree: 7703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahybad: 7713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (sentinel.ai_next) 7723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy freeaddrinfo(sentinel.ai_next); 7733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return error; 7743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 7753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 7763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* 7773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * numeric hostname with scope 7783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 7793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 7803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyexplore_numeric_scope(const struct addrinfo *pai, const char *hostname, 7813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *servname, struct addrinfo **res, struct servent_data *svd) 7823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 7833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#if !defined(SCOPE_DELIMITER) || !defined(INET6) 7843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return explore_numeric(pai, hostname, servname, res, hostname, svd); 7853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#else 7863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct afd *afd; 7873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *cur; 7883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int error; 7893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *cp, *hostname2 = NULL, *scope, *addr; 7903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct sockaddr_in6 *sin6; 7913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 7923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(pai != NULL); 7933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* hostname may be NULL */ 7943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* servname may be NULL */ 7953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(res != NULL); 7963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 7973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 7983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * if the servname does not match socktype/protocol, ignore it. 7993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 8003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (get_portmatch(pai, servname, svd) != 0) 8013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 8023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy afd = find_afd(pai->ai_family); 8043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (afd == NULL) 8053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 8063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!afd->a_scoped) 8083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return explore_numeric(pai, hostname, servname, res, hostname, 8093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy svd); 8103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp = strchr(hostname, SCOPE_DELIMITER); 8123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (cp == NULL) 8133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return explore_numeric(pai, hostname, servname, res, hostname, 8143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy svd); 8153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 8173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Handle special case of <scoped_address><delimiter><scope id> 8183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 8193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy hostname2 = strdup(hostname); 8203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (hostname2 == NULL) 8213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return EAI_MEMORY; 8223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* terminate at the delimiter */ 8233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy hostname2[cp - hostname] = '\0'; 8243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy addr = hostname2; 8253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy scope = cp + 1; 8263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = explore_numeric(pai, addr, servname, res, hostname, svd); 8283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (error == 0) { 8293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy u_int32_t scopeid; 8303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (cur = *res; cur; cur = cur->ai_next) { 8323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (cur->ai_family != AF_INET6) 8333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 8343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr; 8353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) { 8363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(hostname2); 8373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return(EAI_NODATA); /* XXX: is return OK? */ 8383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 8393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy sin6->sin6_scope_id = scopeid; 8403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 8413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 8423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(hostname2); 8443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return error; 8463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 8473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 8483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 8503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyget_canonname(const struct addrinfo *pai, struct addrinfo *ai, const char *str) 8513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 8523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(pai != NULL); 8543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(ai != NULL); 8553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(str != NULL); 8563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((pai->ai_flags & AI_CANONNAME) != 0) { 8583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai->ai_canonname = strdup(str); 8593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ai->ai_canonname == NULL) 8603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return EAI_MEMORY; 8613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 8623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 8633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 8643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic struct addrinfo * 8663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyget_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr) 8673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 8683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *p; 8693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *ai; 8703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(pai != NULL); 8723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(afd != NULL); 8733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(addr != NULL); 8743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) 8763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy + (afd->a_socklen)); 8773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ai == NULL) 8783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NULL; 8793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memcpy(ai, pai, sizeof(struct addrinfo)); 8813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai->ai_addr = (struct sockaddr *)(void *)(ai + 1); 8823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memset(ai->ai_addr, 0, (size_t)afd->a_socklen); 8833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai->ai_addr->sa_len = (uint8_t)afd->a_socklen; 8843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai->ai_addrlen = afd->a_socklen; 8853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai->ai_family = afd->a_af; 8863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai->ai_addr->sa_family = (sa_family_t)ai->ai_family; 8873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy p = (char *)(void *)(ai->ai_addr); 8883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen); 8893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return ai; 8903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 8913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 8933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyget_portmatch(const struct addrinfo *ai, const char *servname, 8943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct servent_data *svd) 8953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 8963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 8973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(ai != NULL); 8983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* servname may be NULL */ 8993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 9003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return get_port(ai, servname, 1, svd); 9013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 9023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 9033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 9043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyget_port(const struct addrinfo *ai, const char *servname, int matchonly, 9053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct servent_data *svd) 9063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 9073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *proto; 9083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct servent *sp; 9093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int port; 9103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int allownumeric; 9113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 9123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(ai != NULL); 9133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* servname may be NULL */ 9143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 9153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (servname == NULL) 9163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 9173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (ai->ai_family) { 9183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case AF_INET: 9193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef AF_INET6 9203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case AF_INET6: 9213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 9223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 9233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default: 9243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 9253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 9263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 9273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (ai->ai_socktype) { 9283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case SOCK_RAW: 9293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return EAI_SERVICE; 9303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case SOCK_DGRAM: 9313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case SOCK_STREAM: 9323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy allownumeric = 1; 9333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 9343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case ANY: 9353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 9363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * This was 0. It is now 1 so that queries specifying 9373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * a NULL hint, or hint without socktype (but, hopefully, 9383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * with protocol) and numeric address actually work. 9393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 9403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy allownumeric = 1; 9413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 9423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default: 9433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return EAI_SOCKTYPE; 9443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 9453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 9463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy port = str2number(servname); 9473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (port >= 0) { 9483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!allownumeric) 9493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return EAI_SERVICE; 9503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (port < 0 || port > 65535) 9513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return EAI_SERVICE; 9523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy port = htons(port); 9533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else { 9543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy// struct servent sv; 9553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ai->ai_flags & AI_NUMERICSERV) 9563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return EAI_NONAME; 9573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 9583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (ai->ai_socktype) { 9593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case SOCK_DGRAM: 9603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy proto = "udp"; 9613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 9623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case SOCK_STREAM: 9633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy proto = "tcp"; 9643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 9653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default: 9663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy proto = NULL; 9673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 9683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 9693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 9703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy// sp = getservbyname_r(servname, proto, &sv, svd); 9713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy sp = getservbyname ( servname, proto ); 9723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (sp == NULL) 9733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return EAI_SERVICE; 9743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy port = sp->s_port; 9753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 9763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 9773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!matchonly) { 9783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (ai->ai_family) { 9793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case AF_INET: 9803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ((struct sockaddr_in *)(void *) 9813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai->ai_addr)->sin_port = (in_port_t)port; 9823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 9833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef INET6 9843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case AF_INET6: 9853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ((struct sockaddr_in6 *)(void *) 9863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai->ai_addr)->sin6_port = (in_port_t)port; 9873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 9883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 9893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 9903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 9913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 9923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 9933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 9943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 9953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic const struct afd * 9963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyfind_afd(int af) 9973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 9983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct afd *afd; 9993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (af == PF_UNSPEC) 10013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NULL; 10023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (afd = afdl; afd->a_af; afd++) { 10033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (afd->a_af == af) 10043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return afd; 10053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 10063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NULL; 10073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 10083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef INET6 10103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* convert a string to a scope identifier. XXX: IPv6 specific */ 10113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 10123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid) 10133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 10143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy u_long lscopeid; 10153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct in6_addr *a6; 10163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *ep; 10173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(scope != NULL); 10193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(sin6 != NULL); 10203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(scopeid != NULL); 10213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy a6 = &sin6->sin6_addr; 10233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* empty scopeid portion is invalid */ 10253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (*scope == '\0') 10263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return -1; 10273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) { 10293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 10303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * We currently assume a one-to-one mapping between links 10313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * and interfaces, so we simply use interface indices for 10323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * like-local scopes. 10333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 10343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* 10353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *scopeid = if_nametoindex(scope); 10363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (*scopeid == 0) 10373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto trynumeric; 10383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 10393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy*/ 10403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return -1; 10413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 10423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* still unclear about literal, allow numeric only - placeholder */ 10443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6)) 10453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto trynumeric; 10463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (IN6_IS_ADDR_MC_ORGLOCAL(a6)) 10473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto trynumeric; 10483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy else 10493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto trynumeric; /* global */ 10503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* try to convert to a numeric id as a last resort */ 10523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy trynumeric: 10533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy errno = 0; 10543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy lscopeid = strtoul(scope, &ep, 10); 10553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *scopeid = (u_int32_t)(lscopeid & 0xffffffffUL); 10563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid) 10573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return 0; 10583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy else 10593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return -1; 10603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 10613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 10623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* code duplicate with gethnamaddr.c */ 10643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic const char AskedForGot[] = 10663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "gethostby*.getanswer: asked for \"%s\", got \"%s\""; 10673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic struct addrinfo * 10693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahygetanswer(const querybuf *answer, int anslen, const char *qname, int qtype, 10703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct addrinfo *pai) 10713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 10723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo sentinel, *cur; 10733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo ai; 10743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct afd *afd; 10753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *canonname; 10763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const HEADER *hp; 10773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const u_char *cp; 10783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int n; 10793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const u_char *eom; 10803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *bp, *ep; 10813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int type, class, ancount, qdcount; 10823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int haveanswer, had_error; 10833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char tbuf[MAXDNAME]; 10843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int (*name_ok) (const char *); 10853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy static char hostbuf[8*1024]; 10863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(answer != NULL); 10883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(qname != NULL); 10893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(pai != NULL); 10903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memset(&sentinel, 0, sizeof(sentinel)); 10923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = &sentinel; 10933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 10943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy canonname = NULL; 10953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy eom = answer->buf + anslen; 10963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (qtype) { 10973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case T_A: 10983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case T_AAAA: 10993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case T_ANY: /*use T_ANY only for T_A/T_AAAA lookup*/ 11003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy name_ok = res_hnok; 11013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 11023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default: 11033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NULL; /* XXX should be abort(); */ 11043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 11063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * find first satisfactory answer 11073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 11083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy hp = &answer->hdr; 11093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ancount = ntohs(hp->ancount); 11103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy qdcount = ntohs(hp->qdcount); 11113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy bp = hostbuf; 11123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ep = hostbuf + sizeof hostbuf; 11133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp = answer->buf + HFIXEDSZ; 11143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (qdcount != 1) { 11153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NO_RECOVERY; 11163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return (NULL); 11173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy n = dn_expand(answer->buf, eom, cp, bp, (int)(ep - bp)); 11193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((n < 0) || !(*name_ok)(bp)) { 11203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NO_RECOVERY; 11213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return (NULL); 11223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n + QFIXEDSZ; 11243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) { 11253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* res_send() has already verified that the query name is the 11263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * same as the one we sent; this just gets the expanded name 11273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * (i.e., with the succeeding search-domain tacked on). 11283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 11293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy n = (int)strlen(bp) + 1; /* for the \0 */ 11303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (n >= MAXHOSTNAMELEN) { 11313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NO_RECOVERY; 11323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return (NULL); 11333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy canonname = bp; 11353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy bp += n; 11363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* The qname can be abbreviated, but h_name is now absolute. */ 11373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy qname = canonname; 11383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy haveanswer = 0; 11403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy had_error = 0; 11413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (ancount-- > 0 && cp < eom && !had_error) { 11423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy n = dn_expand(answer->buf, eom, cp, bp, (int)(ep - bp)); 11433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((n < 0) || !(*name_ok)(bp)) { 11443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy had_error++; 11453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 11463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n; /* name */ 11483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy type = _getshort(cp); 11493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += INT16SZ; /* type */ 11503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy class = _getshort(cp); 11513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += INT16SZ + INT32SZ; /* class, TTL */ 11523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy n = _getshort(cp); 11533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += INT16SZ; /* len */ 11543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (class != C_IN) { 11553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* XXX - debug? syslog? */ 11563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n; 11573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; /* XXX - had_error++ ? */ 11583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) && 11603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy type == T_CNAME) { 11613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); 11623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((n < 0) || !(*name_ok)(tbuf)) { 11633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy had_error++; 11643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 11653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n; 11673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* Get canonical name. */ 11683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy n = (int)strlen(tbuf) + 1; /* for the \0 */ 11693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (n > ep - bp || n >= MAXHOSTNAMELEN) { 11703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy had_error++; 11713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 11723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy strlcpy(bp, tbuf, (size_t)(ep - bp)); 11743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy canonname = bp; 11753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy bp += n; 11763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 11773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (qtype == T_ANY) { 11793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!(type == T_A || type == T_AAAA)) { 11803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n; 11813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 11823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else if (type != qtype) { 11843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (type != T_KEY && type != T_SIG) { 11853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef _ORG_FREEBSD_ 11863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct syslog_data sd = SYSLOG_DATA_INIT; 11873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy syslog_r(LOG_NOTICE|LOG_AUTH, &sd, 11883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", 11893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy qname, p_class(C_IN), p_type(qtype), 11903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy p_type(type)); 11913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 11923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n; 11943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; /* XXX - had_error++ ? */ 11953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 11963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (type) { 11973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case T_A: 11983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case T_AAAA: 11993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (strcasecmp(canonname, bp) != 0) { 12003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef _ORG_FREEBSD_ 12013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct syslog_data sd = SYSLOG_DATA_INIT; 12023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy syslog_r(LOG_NOTICE|LOG_AUTH, &sd, 12033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy AskedForGot, canonname, bp); 12043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 12053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n; 12063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; /* XXX - had_error++ ? */ 12073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (type == T_A && n != INADDRSZ) { 12093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n; 12103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 12113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (type == T_AAAA && n != IN6ADDRSZ) { 12133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n; 12143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 12153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (type == T_AAAA) { 12173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct in6_addr in6; 12183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memcpy(&in6, cp, IN6ADDRSZ); 12193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (IN6_IS_ADDR_V4MAPPED(&in6)) { 12203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n; 12213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 12223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!haveanswer) { 12253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int nn; 12263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 12273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy canonname = bp; 12283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy nn = (int)strlen(bp) + 1; /* for the \0 */ 12293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy bp += nn; 12303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 12323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* don't overwrite pai */ 12333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai = *pai; 12343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai.ai_family = (type == T_A) ? AF_INET : AF_INET6; 12353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy afd = find_afd(ai.ai_family); 12363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (afd == NULL) { 12373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n; 12383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 12393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur->ai_next = get_ai(&ai, afd, (const char *)cp); 12413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (cur->ai_next == NULL) 12423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy had_error++; 12433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (cur && cur->ai_next) 12443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = cur->ai_next; 12453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp += n; 12463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 12473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default: 12483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy abort(); 12493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!had_error) 12513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy haveanswer++; 12523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (haveanswer) { 12543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!canonname) 12553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy (void)get_canonname(pai, sentinel.ai_next, qname); 12563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy else 12573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy (void)get_canonname(pai, sentinel.ai_next, canonname); 12583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NETDB_SUCCESS; 12593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return sentinel.ai_next; 12603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 12623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NO_RECOVERY; 12633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NULL; 12643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 12653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 12663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define SORTEDADDR(p) (((struct sockaddr_in *)(void *)(p->ai_next->ai_addr))->sin_addr.s_addr) 12673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#define SORTMATCH(p, s) ((SORTEDADDR(p) & (s).mask) == (s).addr.s_addr) 12683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 12693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic void 12703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyaisort(struct addrinfo *s, res_state res) 12713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 12723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo head, *t, *p; 12733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int i; 12743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 12753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy head.ai_next = NULL; 12763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy t = &head; 12773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 12783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (i = 0; i < (int)res->nsort; i++) { 12793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy p = s; 12803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (p->ai_next) { 12813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((p->ai_next->ai_family != AF_INET) 12823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy || SORTMATCH(p, res->sort_list[i])) { 12833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy t->ai_next = p->ai_next; 12843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy t = t->ai_next; 12853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy p->ai_next = p->ai_next->ai_next; 12863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else { 12873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy p = p->ai_next; 12883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 12913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 12923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* add rest of list and reset s to the new list*/ 12933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy t->ai_next = s->ai_next; 12943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy s->ai_next = head.ai_next; 12953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 12963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 12973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/*ARGSUSED*/ 12983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 12993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy_dns_getaddrinfo(void *rv, void *cb_data, va_list ap) 13003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 13013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *ai; 13023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy querybuf *buf, *buf2; 13033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *name; 13043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct addrinfo *pai; 13053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo sentinel, *cur; 13063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct res_target q, q2; 13073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy res_state res; 13083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 13093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy name = va_arg(ap, char *); 13103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai = va_arg(ap, const struct addrinfo *); 13113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 13123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memset(&q, 0, sizeof(q)); 13133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memset(&q2, 0, sizeof(q2)); 13143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memset(&sentinel, 0, sizeof(sentinel)); 13153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = &sentinel; 13163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 13173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy buf = malloc(sizeof(*buf)); 13183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (buf == NULL) { 13193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NETDB_INTERNAL; 13203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_NOTFOUND; 13213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 13223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy buf2 = malloc(sizeof(*buf2)); 13233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (buf2 == NULL) { 13243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(buf); 13253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NETDB_INTERNAL; 13263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_NOTFOUND; 13273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 13283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 13293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (pai->ai_family) { 13303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case AF_UNSPEC: 13313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* prefer IPv6 */ 13323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.name = name; 13333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.qclass = C_IN; 13343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.qtype = T_AAAA; 13353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.answer = buf->buf; 13363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.anslen = sizeof(buf->buf); 13373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.next = &q2; 13383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q2.name = name; 13393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q2.qclass = C_IN; 13403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q2.qtype = T_A; 13413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q2.answer = buf2->buf; 13423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q2.anslen = sizeof(buf2->buf); 13433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 13443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case AF_INET: 13453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.name = name; 13463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.qclass = C_IN; 13473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.qtype = T_A; 13483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.answer = buf->buf; 13493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.anslen = sizeof(buf->buf); 13503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 13513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case AF_INET6: 13523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.name = name; 13533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.qclass = C_IN; 13543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.qtype = T_AAAA; 13553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.answer = buf->buf; 13563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy q.anslen = sizeof(buf->buf); 13573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 13583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default: 13593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(buf); 13603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(buf2); 13613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_UNAVAIL; 13623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 13633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 13643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy res = __res_get_state(); 13653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (res == NULL) { 13663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(buf); 13673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(buf2); 13683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_NOTFOUND; 13693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 13703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 13713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (res_searchN(name, &q, res) < 0) { 13723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy __res_put_state(res); 13733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(buf); 13743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(buf2); 13753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_NOTFOUND; 13763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 13773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai = getanswer(buf, q.n, q.name, q.qtype, pai); 13783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ai) { 13793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur->ai_next = ai; 13803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (cur && cur->ai_next) 13813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = cur->ai_next; 13823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 13833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (q.next) { 13843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai); 13853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ai) 13863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur->ai_next = ai; 13873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 13883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(buf); 13893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(buf2); 13903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (sentinel.ai_next == NULL) { 13913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy __res_put_state(res); 13923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (h_errno) { 13933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case HOST_NOT_FOUND: 13943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_NOTFOUND; 13953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case TRY_AGAIN: 13963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_TRYAGAIN; 13973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default: 13983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_UNAVAIL; 13993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 14003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 14013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (res->nsort) 14033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy aisort(&sentinel, res); 14043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy __res_put_state(res); 14063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *((struct addrinfo **)rv) = sentinel.ai_next; 14083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_SUCCESS; 14093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 14103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic void 14123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy_sethtent(FILE **hostf) 14133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 14143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!*hostf) 14163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *hostf = fopen(_PATH_HOSTS, "r" ); 14173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy else 14183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy rewind(*hostf); 14193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 14203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic void 14223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy_endhtent(FILE **hostf) 14233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 14243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (*hostf) { 14263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy (void) fclose(*hostf); 14273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *hostf = NULL; 14283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 14293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 14303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic struct addrinfo * 14323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy_gethtent(FILE **hostf, const char *name, const struct addrinfo *pai) 14333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 14343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *p; 14353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *cp, *tname, *cname; 14363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo hints, *res0, *res; 14373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int error; 14383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *addr; 14393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy static char hostbuf[8*1024]; 14403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(name != NULL); 14423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(pai != NULL); 14433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!*hostf && ( NULL == (*hostf = fopen(_PATH_HOSTS, "r" )))) 14453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return (NULL); 14463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy again: 14473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ( NULL == (p = fgets(hostbuf, sizeof hostbuf, *hostf))) 14483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return (NULL); 14493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (*p == '#') 14503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto again; 14513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ( NULL == (cp = strpbrk(p, "#\n"))) 14523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto again; 14533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *cp = '\0'; 14543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ( NULL == (cp = strpbrk(p, " \t"))) 14553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto again; 14563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *cp++ = '\0'; 14573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy addr = p; 14583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* if this is not something we're looking for, skip it. */ 14593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cname = NULL; 14603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (cp && *cp) { 14613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (*cp == ' ' || *cp == '\t') { 14623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp++; 14633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 14643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 14653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!cname) 14663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cname = cp; 14673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy tname = cp; 14683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((cp = strpbrk(cp, " \t")) != NULL) 14693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *cp++ = '\0'; 14703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (strcasecmp(name, tname) == 0) 14713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto found; 14723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 14733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto again; 14743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyfound: 14763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy hints = *pai; 14773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy hints.ai_flags = AI_NUMERICHOST; 14783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = getaddrinfo(addr, NULL, &hints, &res0); 14793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (error) 14803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto again; 14813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (res = res0; res; res = res->ai_next) { 14823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* cover it up */ 14833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy res->ai_flags = pai->ai_flags; 14843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_flags & AI_CANONNAME) { 14863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (get_canonname(pai, res, cname) != 0) { 14873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy freeaddrinfo(res0); 14883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto again; 14893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 14903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 14913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 14923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return res0; 14933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 14943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 14953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/*ARGSUSED*/ 14963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 14973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy_files_getaddrinfo(void *rv, void *cb_data, va_list ap) 14983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 14993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *name; 15003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct addrinfo *pai; 15013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo sentinel, *cur; 15023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *p; 15033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifndef _REENTRANT 15043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy static 15053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 15063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy FILE *hostf = NULL; 15073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy name = va_arg(ap, char *); 15093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai = va_arg(ap, const struct addrinfo *); 15103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memset(&sentinel, 0, sizeof(sentinel)); 15123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = &sentinel; 15133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _sethtent(&hostf); 15153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while ((p = _gethtent(&hostf, name, pai)) != NULL) { 15163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur->ai_next = p; 15173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (cur && cur->ai_next) 15183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = cur->ai_next; 15193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 15203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _endhtent(&hostf); 15213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *((struct addrinfo **)rv) = sentinel.ai_next; 15233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (sentinel.ai_next == NULL) 15243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_NOTFOUND; 15253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_SUCCESS; 15263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 15273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef YP 15293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/*ARGSUSED*/ 15303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic struct addrinfo * 15313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy_yphostent(char *line, const struct addrinfo *pai) 15323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 15333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo sentinel, *cur; 15343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo hints, *res, *res0; 15353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int error; 15363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *p; 15373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *addr, *canonname; 15383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *nextline; 15393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *cp; 15403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(line != NULL); 15423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(pai != NULL); 15433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy p = line; 15453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy addr = canonname = NULL; 15463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memset(&sentinel, 0, sizeof(sentinel)); 15483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = &sentinel; 15493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahynextline: 15513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* terminate line */ 15523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp = strchr(p, '\n'); 15533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (cp) { 15543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *cp++ = '\0'; 15553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy nextline = cp; 15563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else 15573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy nextline = NULL; 15583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp = strpbrk(p, " \t"); 15603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (cp == NULL) { 15613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (canonname == NULL) 15623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return (NULL); 15633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy else 15643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto done; 15653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 15663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *cp++ = '\0'; 15673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy addr = p; 15693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (cp && *cp) { 15713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (*cp == ' ' || *cp == '\t') { 15723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cp++; 15733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 15743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 15753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!canonname) 15763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy canonname = cp; 15773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((cp = strpbrk(cp, " \t")) != NULL) 15783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *cp++ = '\0'; 15793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 15803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy hints = *pai; 15823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy hints.ai_flags = AI_NUMERICHOST; 15833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy error = getaddrinfo(addr, NULL, &hints, &res0); 15843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (error == 0) { 15853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (res = res0; res; res = res->ai_next) { 15863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* cover it up */ 15873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy res->ai_flags = pai->ai_flags; 15883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 15893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_flags & AI_CANONNAME) 15903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy (void)get_canonname(pai, res, canonname); 15913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 15923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else 15933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy res0 = NULL; 15943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (res0) { 15953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur->ai_next = res0; 15963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (cur->ai_next) 15973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = cur->ai_next; 15983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 15993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (nextline) { 16013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy p = nextline; 16023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy goto nextline; 16033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 16043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahydone: 16063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return sentinel.ai_next; 16073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 16083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/*ARGSUSED*/ 16103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 16113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy_yp_getaddrinfo(void *rv, void *cb_data, va_list ap) 16123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 16133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo sentinel, *cur; 16143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo *ai = NULL; 16153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *ypbuf; 16163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int ypbuflen, r; 16173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *name; 16183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const struct addrinfo *pai; 16193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char *ypdomain; 16203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (_yp_check(&ypdomain) == 0) 16223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_UNAVAIL; 16233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy name = va_arg(ap, char *); 16253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy pai = va_arg(ap, const struct addrinfo *); 16263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy memset(&sentinel, 0, sizeof(sentinel)); 16283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = &sentinel; 16293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* hosts.byname is only for IPv4 (Solaris8) */ 16313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (pai->ai_family == PF_UNSPEC || pai->ai_family == PF_INET) { 16323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy r = yp_match(ypdomain, "hosts.byname", name, 16333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy (int)strlen(name), &ypbuf, &ypbuflen); 16343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (r == 0) { 16353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct addrinfo ai4; 16363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai4 = *pai; 16383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai4.ai_family = AF_INET; 16393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai = _yphostent(ypbuf, &ai4); 16403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ai) { 16413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur->ai_next = ai; 16423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy while (cur && cur->ai_next) 16433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur = cur->ai_next; 16443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 16453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 16463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(ypbuf); 16473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 16483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* ipnodes.byname can hold both IPv4/v6 */ 16503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy r = yp_match(ypdomain, "ipnodes.byname", name, 16513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy (int)strlen(name), &ypbuf, &ypbuflen); 16523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (r == 0) { 16533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ai = _yphostent(ypbuf, pai); 16543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ai) 16553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy cur->ai_next = ai; 16563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy free(ypbuf); 16573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 16583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (sentinel.ai_next == NULL) { 16603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = HOST_NOT_FOUND; 16613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_NOTFOUND; 16623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 16633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *((struct addrinfo **)rv) = sentinel.ai_next; 16643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return NS_SUCCESS; 16653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 16663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 16673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* resolver logic */ 16693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* 16713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Formulate a normal query, send, and await answer. 16723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Returned answer is placed in supplied buffer "answer". 16733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Perform preliminary check of answer, returning success only 16743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * if no error is indicated and the answer count is nonzero. 16753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Return the size of the response on success, -1 on error. 16763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Error number is left in h_errno. 16773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * 16783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Caller must parse answer and determine whether it answers the question. 16793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 16803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 16813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyres_queryN(const char *name, /* domain name */ struct res_target *target, 16823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy res_state res) 16833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 16843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy static u_char buf[MAXPACKET]; 16853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy HEADER *hp; 16863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int n; 16873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct res_target *t; 16883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int rcode; 16893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int ancount; 16903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(name != NULL); 16923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* XXX: target may be NULL??? */ 16933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy rcode = NOERROR; 16953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ancount = 0; 16963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 16973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (t = target; t; t = t->next) { 16983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int class, type; 16993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy u_char *answer; 17003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int anslen; 17013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 17023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy hp = (HEADER *)(void *)t->answer; 17033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy hp->rcode = NOERROR; /* default */ 17043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 17053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* make it easier... */ 17063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy class = t->qclass; 17073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy type = t->qtype; 17083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy answer = t->answer; 17093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy anslen = t->anslen; 17103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef DEBUG 17113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (res->options & RES_DEBUG) 17123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy printf(";; res_nquery(%s, %d, %d)\n", name, class, type); 17133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 17143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 17153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy n = res_nmkquery(res, QUERY, name, class, type, NULL, 0, NULL, 17163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy buf, sizeof(buf)); 17173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef RES_USE_EDNS0 17183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (n > 0 && (res->options & RES_USE_EDNS0) != 0) 17193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy n = res_nopt(res, n, buf, sizeof(buf), anslen); 17203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 17213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (n <= 0) { 17223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef DEBUG 17233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (res->options & RES_DEBUG) 17243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy printf(";; res_nquery: mkquery failed\n"); 17253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 17263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NO_RECOVERY; 17273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return n; 17283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 17293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy n = res_nsend(res, buf, n, answer, anslen); 17303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#if 0 17313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (n < 0) { 17323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef DEBUG 17333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (res->options & RES_DEBUG) 17343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy printf(";; res_query: send error\n"); 17353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 17363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = TRY_AGAIN; 17373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return n; 17383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 17393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 17403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 17413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { 17423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy rcode = hp->rcode; /* record most recent error */ 17433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef DEBUG 17443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (res->options & RES_DEBUG) 17453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy printf(";; rcode = %u, ancount=%u\n", hp->rcode, 17463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ntohs(hp->ancount)); 17473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 17483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy continue; 17493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 17503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 17513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ancount += ntohs(hp->ancount); 17523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 17533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy t->n = n; 17543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 17553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 17563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ancount == 0) { 17573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (rcode) { 17583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case NXDOMAIN: 17593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = HOST_NOT_FOUND; 17603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 17613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case SERVFAIL: 17623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = TRY_AGAIN; 17633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 17643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case NOERROR: 17653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NO_DATA; 17663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 17673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case FORMERR: 17683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case NOTIMP: 17693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case REFUSED: 17703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default: 17713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NO_RECOVERY; 17723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 17733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 17743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return -1; 17753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 17763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return ancount; 17773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 17783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 17793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* 17803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Formulate a normal query, send, and retrieve answer in supplied buffer. 17813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Return the size of the response on success, -1 on error. 17823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * If enabled, implement search rules until answer or unrecoverable failure 17833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * is detected. Error code, if any, is left in h_errno. 17843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 17853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 17863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyres_searchN(const char *name, struct res_target *target, res_state res) 17873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 17883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *cp, * const *domain; 17893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy HEADER *hp; 17903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy u_int dots; 17913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int trailing_dot, ret, saved_herrno; 17923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int got_nodata = 0, got_servfail = 0, tried_as_is = 0; 17933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 17943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(name != NULL); 17953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(target != NULL); 17963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 17973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy hp = (HEADER *)(void *)target->answer; /*XXX*/ 17983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 17993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy errno = 0; 18003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = HOST_NOT_FOUND; /* default, if we never query */ 18013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy dots = 0; 18023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (cp = name; *cp; cp++) 18033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy dots += (*cp == '.'); 18043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy trailing_dot = 0; 18053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (cp > name && *--cp == '.') 18063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy trailing_dot++; 18073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 18083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 18093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * if there aren't any dots, it could be a user-level alias 18103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 18113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!dots && (cp = __hostalias(name)) != NULL) { 18123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ret = res_queryN(cp, target, res); 18133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return ret; 18143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 18153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 18163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 18173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * If there are dots in the name already, let's just give it a try 18183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * 'as is'. The threshold can be set with the "ndots" option. 18193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 18203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy saved_herrno = -1; 18213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (dots >= res->ndots) { 18223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ret = res_querydomainN(name, NULL, target, res); 18233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ret > 0) 18243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return (ret); 18253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy saved_herrno = h_errno; 18263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy tried_as_is++; 18273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 18283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 18293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 18303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * We do at least one level of search if 18313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * - there is no dot and RES_DEFNAME is set, or 18323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * - there is at least one dot, there is no trailing dot, 18333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * and RES_DNSRCH is set. 18343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 18353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if ((!dots && (res->options & RES_DEFNAMES)) || 18363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy (dots && !trailing_dot && (res->options & RES_DNSRCH))) { 18373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy int done = 0; 18383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 18393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy for (domain = (const char * const *)res->dnsrch; 18403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy *domain && !done; 18413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy domain++) { 18423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 18433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ret = res_querydomainN(name, *domain, target, res); 18443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ret > 0) 18453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return ret; 18463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 18473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 18483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * If no server present, give up. 18493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * If name isn't found in this domain, 18503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * keep trying higher domains in the search list 18513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * (if that's enabled). 18523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * On a NO_DATA error, keep trying, otherwise 18533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * a wildcard entry of another type could keep us 18543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * from finding this entry higher in the domain. 18553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * If we get some other error (negative answer or 18563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * server failure), then stop searching up, 18573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * but try the input name below in case it's 18583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * fully-qualified. 18593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 18603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (errno == ECONNREFUSED) { 18613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = TRY_AGAIN; 18623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return -1; 18633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 18643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 18653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy switch (h_errno) { 18663bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case NO_DATA: 18673bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy got_nodata++; 18683bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* FALLTHROUGH */ 18693bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case HOST_NOT_FOUND: 18703bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* keep trying */ 18713bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 18723bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy case TRY_AGAIN: 18733bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (hp->rcode == SERVFAIL) { 18743bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* try next search element, if any */ 18753bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy got_servfail++; 18763bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy break; 18773bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 18783bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* FALLTHROUGH */ 18793bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy default: 18803bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* anything else implies that we're done */ 18813bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy done++; 18823bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 18833bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 18843bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * if we got here for some reason other than DNSRCH, 18853bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * we only wanted one iteration of the loop, so stop. 18863bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 18873bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!(res->options & RES_DNSRCH)) 18883bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy done++; 18893bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 18903bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 18913bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 18923bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 18933bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * if we have not already tried the name "as is", do that now. 18943bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * note that we do this regardless of how many dots were in the 18953bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * name or whether it ends with a dot. 18963bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 18973bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (!tried_as_is) { 18983bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy ret = res_querydomainN(name, NULL, target, res); 18993bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (ret > 0) 19003bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return ret; 19013bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 19023bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 19033bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 19043bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * if we got here, we didn't satisfy the search. 19053bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * if we did an initial full query, return that query's h_errno 19063bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * (note that we wouldn't be here if that query had succeeded). 19073bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * else if we ever got a nodata, send that back as the reason. 19083bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * else send back meaningless h_errno, that being the one from 19093bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * the last DNSRCH we did. 19103bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 19113bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (saved_herrno != -1) 19123bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = saved_herrno; 19133bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy else if (got_nodata) 19143bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NO_DATA; 19153bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy else if (got_servfail) 19163bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = TRY_AGAIN; 19173bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return -1; 19183bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 19193bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 19203bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy/* 19213bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Perform a call on res_query on the concatenation of name and domain, 19223bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * removing a trailing dot from name if domain is NULL. 19233bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 19243bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahystatic int 19253bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahyres_querydomainN(const char *name, const char *domain, 19263bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy struct res_target *target, res_state res) 19273bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy{ 19283bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy char nbuf[MAXDNAME]; 19293bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy const char *longname = nbuf; 19303bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy size_t n, d; 19313bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 19323bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy _DIAGASSERT(name != NULL); 19333bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* XXX: target may be NULL??? */ 19343bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy 19353bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#ifdef DEBUG 19363bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (res->options & RES_DEBUG) 19373bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy printf(";; res_querydomain(%s, %s)\n", 19383bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy name, domain?domain:"<Nil>"); 19393bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy#endif 19403bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (domain == NULL) { 19413bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy /* 19423bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * Check for trailing '.'; 19433bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy * copy without '.' if present. 19443bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy */ 19453bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy n = strlen(name); 19463bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (n + 1 > sizeof(nbuf)) { 19473bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NO_RECOVERY; 19483bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return -1; 19493bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 19503bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (n > 0 && name[--n] == '.') { 19513bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy strncpy(nbuf, name, n); 19523bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy nbuf[n] = '\0'; 19533bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else 19543bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy longname = name; 19553bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } else { 19563bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy n = strlen(name); 19573bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy d = strlen(domain); 19583bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy if (n + 1 + d + 1 > sizeof(nbuf)) { 19593bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy h_errno = NO_RECOVERY; 19603bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return -1; 19613bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 19623bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain); 19633bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy } 19643bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy return res_queryN(longname, target, res); 19653bdf9aae5f7f4c5f47fc8f807ae4409dfe3bdd58lpleahy} 1966