summaryrefslogtreecommitdiff
path: root/lib/libc/net
diff options
context:
space:
mode:
authorEric Faurot <eric@cvs.openbsd.org>2013-11-12 20:37:17 +0000
committerEric Faurot <eric@cvs.openbsd.org>2013-11-12 20:37:17 +0000
commit5102035ebd8903a092c74d91c132d9f73115ccd8 (patch)
treeddd985c2a701c7937e8c56e413c27a881883fa82 /lib/libc/net
parent4be467036ac3b35dec768dbf428ec7e3fc487dac (diff)
remove dead files
ok deraadt@
Diffstat (limited to 'lib/libc/net')
-rw-r--r--lib/libc/net/getaddrinfo.c1755
-rw-r--r--lib/libc/net/gethostnamadr.c1131
-rw-r--r--lib/libc/net/getnameinfo.c351
-rw-r--r--lib/libc/net/getnetnamadr.c384
-rw-r--r--lib/libc/net/getrrsetbyname.c517
-rw-r--r--lib/libc/net/res_debug.c1395
-rw-r--r--lib/libc/net/res_init.c707
-rw-r--r--lib/libc/net/res_mkquery.c232
-rw-r--r--lib/libc/net/res_query.c403
-rw-r--r--lib/libc/net/res_send.c853
-rw-r--r--lib/libc/net/sethostent.c57
11 files changed, 0 insertions, 7785 deletions
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c
deleted file mode 100644
index 29cc1f463e0..00000000000
--- a/lib/libc/net/getaddrinfo.c
+++ /dev/null
@@ -1,1755 +0,0 @@
-/* $OpenBSD: getaddrinfo.c,v 1.72 2011/04/05 00:46:06 matthew Exp $ */
-/* $KAME: getaddrinfo.c,v 1.31 2000/08/31 17:36:43 itojun Exp $ */
-
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Issues to be discussed:
- * - Thread safe-ness must be checked.
- * - Return values. There are nonstandard return values defined and used
- * in the source code. This is because RFC2553 is silent about which error
- * code must be returned for which situation.
- * - IPv4 classful (shortened) form. RFC2553 is silent about it. XNET 5.2
- * says to use inet_aton() to convert IPv4 numeric to binary (allows
- * classful form as a result).
- * current code - disallow classful form for IPv4 (due to use of inet_pton).
- * - freeaddrinfo(NULL). RFC2553 is silent about it. XNET 5.2 says it is
- * invalid.
- * current code - SEGV on freeaddrinfo(NULL)
- * Note:
- * - We use getipnodebyname() just for thread-safeness. There's no intent
- * to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to
- * getipnodebyname().
- * - The code filters out AFs that are not supported by the kernel,
- * when globbing NULL hostname (to loopback, or wildcard). Is it the right
- * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG
- * in ai_flags?
- * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
- * (1) what should we do against numeric hostname (2) what should we do
- * against NULL hostname (3) what is AI_ADDRCONFIG itself. AF not ready?
- * non-loopback address configured? global address configured?
- * - To avoid search order issue, we have a big amount of code duplicate
- * from gethnamaddr.c and some other places. The issues that there's no
- * lower layer function to lookup "IPv4 or IPv6" record. Calling
- * gethostbyname2 from getaddrinfo will end up in wrong search order, as
- * follows:
- * - The code makes use of following calls when asked to resolver with
- * ai_family = PF_UNSPEC:
- * getipnodebyname(host, AF_INET6);
- * getipnodebyname(host, AF_INET);
- * This will result in the following queries if the node is configure to
- * prefer /etc/hosts than DNS:
- * lookup /etc/hosts for IPv6 address
- * lookup DNS for IPv6 address
- * lookup /etc/hosts for IPv4 address
- * lookup DNS for IPv4 address
- * which may not meet people's requirement.
- * The right thing to happen is to have underlying layer which does
- * PF_UNSPEC lookup (lookup both) and return chain of addrinfos.
- * This would result in a bit of code duplicate with _dns_ghbyname() and
- * friends.
- */
-
-#ifndef INET6
-#define INET6
-#endif
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include <syslog.h>
-#include <stdarg.h>
-
-#ifdef YP
-#include <rpc/rpc.h>
-#include <rpcsvc/yp.h>
-#include <rpcsvc/ypclnt.h>
-#include "ypinternal.h"
-#endif
-
-#include "thread_private.h"
-
-#define SUCCESS 0
-#define ANY 0
-#define YES 1
-#define NO 0
-
-static const char in_addrany[] = { 0, 0, 0, 0 };
-static const char in6_addrany[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-static const char in_loopback[] = { 127, 0, 0, 1 };
-static const char in6_loopback[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
-};
-
-static const struct afd {
- int a_af;
- int a_addrlen;
- int a_socklen;
- int a_off;
- const char *a_addrany;
- const char *a_loopback;
- int a_scoped;
-} afdl [] = {
-#ifdef INET6
- {PF_INET6, sizeof(struct in6_addr),
- sizeof(struct sockaddr_in6),
- offsetof(struct sockaddr_in6, sin6_addr),
- in6_addrany, in6_loopback, 1},
-#endif
- {PF_INET, sizeof(struct in_addr),
- sizeof(struct sockaddr_in),
- offsetof(struct sockaddr_in, sin_addr),
- in_addrany, in_loopback, 0},
- {0, 0, 0, 0, NULL, NULL, 0},
-};
-
-struct explore {
- int e_af;
- int e_socktype;
- int e_protocol;
- const char *e_protostr;
- int e_wild;
-#define WILD_AF(ex) ((ex)->e_wild & 0x01)
-#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02)
-#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04)
-};
-
-static const struct explore explore[] = {
-#if 0
- { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
-#endif
-#ifdef INET6
- { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
- { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
- { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
-#endif
- { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
- { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
- { PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
- { PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
- { PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
- { PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 },
- { -1, 0, 0, NULL, 0 },
-};
-
-#ifdef INET6
-#define PTON_MAX 16
-#else
-#define PTON_MAX 4
-#endif
-
-#define MAXPACKET (64*1024)
-
-typedef union {
- HEADER hdr;
- u_char buf[MAXPACKET];
-} querybuf;
-
-struct res_target {
- struct res_target *next;
- const char *name; /* domain name */
- int qclass, qtype; /* class and type of query */
- u_char *answer; /* buffer to put answer */
- int anslen; /* size of answer buffer */
- int n; /* result length */
-};
-
-static int explore_fqdn(const struct addrinfo *, const char *,
- const char *, struct addrinfo **);
-static int explore_null(const struct addrinfo *,
- const char *, struct addrinfo **);
-static int explore_numeric(const struct addrinfo *, const char *,
- const char *, struct addrinfo **, const char *);
-static int explore_numeric_scope(const struct addrinfo *, const char *,
- const char *, struct addrinfo **);
-static int get_canonname(const struct addrinfo *,
- struct addrinfo *, const char *);
-static struct addrinfo *get_ai(const struct addrinfo *,
- const struct afd *, const char *);
-static int get_portmatch(const struct addrinfo *, const char *);
-static int get_port(struct addrinfo *, const char *, int);
-static const struct afd *find_afd(int);
-#ifdef INET6
-static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *);
-#endif
-
-static struct addrinfo * _gethtent(const char *, const struct addrinfo *,
- FILE *);
-static struct addrinfo *_files_getaddrinfo(const char *,
- const struct addrinfo *);
-
-#ifdef YP
-static struct addrinfo *_yphostent(char *, const struct addrinfo *);
-static struct addrinfo *_yp_getaddrinfo(const char *,
- const struct addrinfo *);
-#endif
-
-static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
- const struct addrinfo *);
-static int res_queryN(const char *, struct res_target *);
-static int res_searchN(const char *, struct res_target *);
-static int res_querydomainN(const char *, const char *, struct res_target *);
-static struct addrinfo *_dns_getaddrinfo(const char *, const struct addrinfo *,
- const struct __res_state *);
-
-
-/* XXX macros that make external reference is BAD. */
-
-#define GET_AI(ai, afd, addr) \
-do { \
- /* external reference: pai, error, and label free */ \
- (ai) = get_ai(pai, (afd), (addr)); \
- if ((ai) == NULL) { \
- error = EAI_MEMORY; \
- goto free; \
- } \
-} while (/*CONSTCOND*/0)
-
-#define GET_PORT(ai, serv) \
-do { \
- /* external reference: error and label free */ \
- error = get_port((ai), (serv), 0); \
- if (error != 0) \
- goto free; \
-} while (/*CONSTCOND*/0)
-
-#define GET_CANONNAME(ai, str) \
-do { \
- /* external reference: pai, error and label free */ \
- error = get_canonname(pai, (ai), (str)); \
- if (error != 0) \
- goto free; \
-} while (/*CONSTCOND*/0)
-
-#define ERR(err) \
-do { \
- /* external reference: error, and label bad */ \
- error = (err); \
- goto bad; \
- /*NOTREACHED*/ \
-} while (/*CONSTCOND*/0)
-
-#define MATCH_FAMILY(x, y, w) \
- ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
-#define MATCH(x, y, w) \
- ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
-
-int
-getaddrinfo(const char *hostname, const char *servname,
- const struct addrinfo *hints, struct addrinfo **res)
-{
- struct addrinfo sentinel;
- struct addrinfo *cur;
- int error = 0;
- struct addrinfo ai;
- struct addrinfo ai0;
- struct addrinfo *pai;
- const struct explore *ex;
-
- memset(&sentinel, 0, sizeof(sentinel));
- cur = &sentinel;
- pai = &ai;
- pai->ai_flags = 0;
- pai->ai_family = PF_UNSPEC;
- pai->ai_socktype = ANY;
- pai->ai_protocol = ANY;
- pai->ai_addrlen = 0;
- pai->ai_canonname = NULL;
- pai->ai_addr = NULL;
- pai->ai_next = NULL;
-
- if (hostname == NULL && servname == NULL)
- return EAI_NONAME;
- if (hints) {
- /* error check for hints */
- if (hints->ai_addrlen || hints->ai_canonname ||
- hints->ai_addr || hints->ai_next)
- ERR(EAI_BADHINTS); /* xxx */
- if ((hints->ai_flags & ~AI_MASK) != 0 ||
- (hints->ai_flags & (AI_CANONNAME | AI_FQDN)) ==
- (AI_CANONNAME | AI_FQDN))
- ERR(EAI_BADFLAGS);
- switch (hints->ai_family) {
- case PF_UNSPEC:
- case PF_INET:
-#ifdef INET6
- case PF_INET6:
-#endif
- break;
- default:
- ERR(EAI_FAMILY);
- }
- memcpy(pai, hints, sizeof(*pai));
-
- /*
- * if both socktype/protocol are specified, check if they
- * are meaningful combination.
- */
- if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
- for (ex = explore; ex->e_af >= 0; ex++) {
- if (pai->ai_family != ex->e_af)
- continue;
- if (ex->e_socktype == ANY)
- continue;
- if (ex->e_protocol == ANY)
- continue;
- if (pai->ai_socktype == ex->e_socktype
- && pai->ai_protocol != ex->e_protocol) {
- ERR(EAI_BADHINTS);
- }
- }
- }
- }
-
- /*
- * check for special cases. (1) numeric servname is disallowed if
- * socktype/protocol are left unspecified. (2) servname is disallowed
- * for raw and other inet{,6} sockets.
- */
- if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
-#ifdef PF_INET6
- || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
-#endif
- ) {
- ai0 = *pai; /* backup *pai */
-
- if (pai->ai_family == PF_UNSPEC) {
-#ifdef PF_INET6
- pai->ai_family = PF_INET6;
-#else
- pai->ai_family = PF_INET;
-#endif
- }
- error = get_portmatch(pai, servname);
- if (error)
- ERR(error);
-
- *pai = ai0;
- }
-
- ai0 = *pai;
-
- /* NULL hostname, or numeric hostname */
- for (ex = explore; ex->e_af >= 0; ex++) {
- *pai = ai0;
-
- /* PF_UNSPEC entries are prepared for DNS queries only */
- if (ex->e_af == PF_UNSPEC)
- continue;
-
- if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
- continue;
- if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
- continue;
- if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
- continue;
-
- if (pai->ai_family == PF_UNSPEC)
- pai->ai_family = ex->e_af;
- if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
- pai->ai_socktype = ex->e_socktype;
- if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
- pai->ai_protocol = ex->e_protocol;
-
- if (hostname == NULL)
- error = explore_null(pai, servname, &cur->ai_next);
- else
- error = explore_numeric_scope(pai, hostname, servname,
- &cur->ai_next);
-
- if (error)
- goto free;
-
- while (cur && cur->ai_next)
- cur = cur->ai_next;
- }
-
- /*
- * XXX
- * If numeric representation of AF1 can be interpreted as FQDN
- * representation of AF2, we need to think again about the code below.
- */
- if (sentinel.ai_next)
- goto good;
-
- if (hostname == NULL)
- ERR(EAI_NODATA);
- if (pai->ai_flags & AI_NUMERICHOST)
- ERR(EAI_NONAME);
-
- /*
- * hostname as alphabetical name.
- * we would like to prefer AF_INET6 than AF_INET, so we'll make an
- * outer loop by AFs.
- */
- for (ex = explore; ex->e_af >= 0; ex++) {
- *pai = ai0;
-
- /* require exact match for family field */
- if (pai->ai_family != ex->e_af)
- continue;
-
- if (!MATCH(pai->ai_socktype, ex->e_socktype,
- WILD_SOCKTYPE(ex))) {
- continue;
- }
- if (!MATCH(pai->ai_protocol, ex->e_protocol,
- WILD_PROTOCOL(ex))) {
- continue;
- }
-
- if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
- pai->ai_socktype = ex->e_socktype;
- if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
- pai->ai_protocol = ex->e_protocol;
-
- error = explore_fqdn(pai, hostname, servname,
- &cur->ai_next);
-
- while (cur && cur->ai_next)
- cur = cur->ai_next;
- }
-
- /* XXX */
- if (sentinel.ai_next)
- error = 0;
-
- if (error == 0) {
- if (sentinel.ai_next) {
- good:
- *res = sentinel.ai_next;
- return SUCCESS;
- } else
- error = EAI_FAIL;
- }
- free:
- bad:
- if (sentinel.ai_next)
- freeaddrinfo(sentinel.ai_next);
- *res = NULL;
- return error;
-}
-
-/*
- * FQDN hostname, DNS lookup
- */
-
-static int
-explore_fqdn(const struct addrinfo *pai, const char *hostname,
- const char *servname, struct addrinfo **res)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- struct addrinfo *result;
- struct addrinfo *cur;
- int error = 0;
- char lookups[MAXDNSLUS];
- int i;
- _THREAD_PRIVATE_MUTEX(_explore_mutex);
-
- result = NULL;
-
- /*
- * if the servname does not match socktype/protocol, ignore it.
- */
- if (get_portmatch(pai, servname) != 0) {
- return 0;
- }
-
- if (_res_init(0) == -1)
- strlcpy(lookups, "f", sizeof lookups);
- else {
- bcopy(_resp->lookups, lookups, sizeof lookups);
- if (lookups[0] == '\0')
- strlcpy(lookups, "bf", sizeof lookups);
- }
-
- /*
- * The yp/dns/files getaddrinfo functions are not thread safe.
- * Protect them with a mutex.
- */
- _THREAD_PRIVATE_MUTEX_LOCK(_explore_mutex);
- for (i = 0; i < MAXDNSLUS && result == NULL && lookups[i]; i++) {
- switch (lookups[i]) {
-#ifdef YP
- case 'y':
- result = _yp_getaddrinfo(hostname, pai);
- break;
-#endif
- case 'b':
- result = _dns_getaddrinfo(hostname, pai, _resp);
- break;
- case 'f':
- result = _files_getaddrinfo(hostname, pai);
- break;
- }
- }
- _THREAD_PRIVATE_MUTEX_UNLOCK(_explore_mutex);
- if (result) {
- for (cur = result; cur; cur = cur->ai_next) {
- GET_PORT(cur, servname);
- /* canonname should be filled already */
- }
- *res = result;
- return 0;
- } else {
- /* translate error code */
- switch (h_errno) {
- case NETDB_SUCCESS:
- error = EAI_FAIL; /*XXX strange */
- break;
- case HOST_NOT_FOUND:
- error = EAI_NODATA;
- break;
- case TRY_AGAIN:
- error = EAI_AGAIN;
- break;
- case NO_RECOVERY:
- error = EAI_FAIL;
- break;
- case NO_DATA:
-#if NO_ADDRESS != NO_DATA
- case NO_ADDRESS:
-#endif
- error = EAI_NODATA;
- break;
- default: /* unknown ones */
- error = EAI_FAIL;
- break;
- }
- }
-
-free:
- if (result)
- freeaddrinfo(result);
- return error;
-}
-
-/*
- * hostname == NULL.
- * passive socket -> anyaddr (0.0.0.0 or ::)
- * non-passive socket -> localhost (127.0.0.1 or ::1)
- */
-static int
-explore_null(const struct addrinfo *pai, const char *servname,
- struct addrinfo **res)
-{
- int s;
- const struct afd *afd;
- struct addrinfo *cur;
- struct addrinfo sentinel;
- int error;
-
- *res = NULL;
- sentinel.ai_next = NULL;
- cur = &sentinel;
-
- /*
- * filter out AFs that are not supported by the kernel
- * XXX errno?
- */
- s = socket(pai->ai_family, SOCK_DGRAM, 0);
- if (s < 0) {
- if (errno != EMFILE)
- return 0;
- } else
- close(s);
-
- /*
- * if the servname does not match socktype/protocol, ignore it.
- */
- if (get_portmatch(pai, servname) != 0)
- return 0;
-
- afd = find_afd(pai->ai_family);
- if (afd == NULL)
- return 0;
-
- if (pai->ai_flags & AI_PASSIVE) {
- GET_AI(cur->ai_next, afd, afd->a_addrany);
- /* xxx meaningless?
- * GET_CANONNAME(cur->ai_next, "anyaddr");
- */
- } else {
- GET_AI(cur->ai_next, afd, afd->a_loopback);
- /* xxx meaningless?
- * GET_CANONNAME(cur->ai_next, "localhost");
- */
- }
- GET_PORT(cur->ai_next, servname);
- cur = cur->ai_next;
-
- *res = sentinel.ai_next;
- return 0;
-
-free:
- if (sentinel.ai_next)
- freeaddrinfo(sentinel.ai_next);
- return error;
-}
-
-/*
- * numeric hostname
- */
-static int
-explore_numeric(const struct addrinfo *pai, const char *hostname,
- const char *servname, struct addrinfo **res, const char *canonname)
-{
- const struct afd *afd;
- struct addrinfo *cur;
- struct addrinfo sentinel;
- int error;
- char pton[PTON_MAX];
-
- *res = NULL;
- sentinel.ai_next = NULL;
- cur = &sentinel;
-
- /*
- * if the servname does not match socktype/protocol, ignore it.
- */
- if (get_portmatch(pai, servname) != 0)
- return 0;
-
- afd = find_afd(pai->ai_family);
- if (afd == NULL)
- return 0;
-
- switch (afd->a_af) {
-#if 0 /*X/Open spec*/
- case AF_INET:
- error = inet_aton(hostname, (struct in_addr *)pton);
- break;
-#endif
- default:
- error = inet_pton(afd->a_af, hostname, pton);
- break;
- }
- if (error == 1) {
- if (pai->ai_family == afd->a_af ||
- pai->ai_family == PF_UNSPEC /*?*/) {
- GET_AI(cur->ai_next, afd, pton);
- GET_PORT(cur->ai_next, servname);
- /*
- * Set the numeric address itself as
- * the canonical name, based on a
- * clarification in rfc2553bis-03.
- */
- GET_CANONNAME(cur->ai_next, canonname);
-
- while (cur && cur->ai_next)
- cur = cur->ai_next;
- } else
- ERR(EAI_FAMILY); /*xxx*/
- }
-
- *res = sentinel.ai_next;
- return 0;
-
-free:
-bad:
- if (sentinel.ai_next)
- freeaddrinfo(sentinel.ai_next);
- return error;
-}
-
-/*
- * numeric hostname with scope
- */
-static int
-explore_numeric_scope(const struct addrinfo *pai, const char *hostname,
- const char *servname, struct addrinfo **res)
-{
-#if !defined(SCOPE_DELIMITER) || !defined(INET6)
- return explore_numeric(pai, hostname, servname, res, hostname);
-#else
- const struct afd *afd;
- struct addrinfo *cur;
- int error;
- char *cp, *hostname2 = NULL, *scope, *addr;
- struct sockaddr_in6 *sin6;
-
- /*
- * if the servname does not match socktype/protocol, ignore it.
- */
- if (get_portmatch(pai, servname) != 0)
- return 0;
-
- afd = find_afd(pai->ai_family);
- if (afd == NULL)
- return 0;
-
- if (!afd->a_scoped)
- return explore_numeric(pai, hostname, servname, res, hostname);
-
- cp = strchr(hostname, SCOPE_DELIMITER);
- if (cp == NULL)
- return explore_numeric(pai, hostname, servname, res, hostname);
-
- /*
- * Handle special case of <scoped_address><delimiter><scope id>
- */
- hostname2 = strdup(hostname);
- if (hostname2 == NULL)
- return EAI_MEMORY;
- /* terminate at the delimiter */
- hostname2[cp - hostname] = '\0';
- addr = hostname2;
- scope = cp + 1;
-
- error = explore_numeric(pai, addr, servname, res, hostname);
- if (error == 0) {
- u_int32_t scopeid;
-
- for (cur = *res; cur; cur = cur->ai_next) {
- if (cur->ai_family != AF_INET6)
- continue;
- sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
- if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {
- free(hostname2);
- return(EAI_NODATA); /* XXX: is return OK? */
- }
- sin6->sin6_scope_id = scopeid;
- }
- }
-
- free(hostname2);
-
- return error;
-#endif
-}
-
-static int
-get_canonname(const struct addrinfo *pai, struct addrinfo *ai, const char *str)
-{
- if ((pai->ai_flags & (AI_CANONNAME | AI_FQDN)) != 0) {
- ai->ai_canonname = strdup(str);
- if (ai->ai_canonname == NULL)
- return EAI_MEMORY;
- }
- return 0;
-}
-
-static struct addrinfo *
-get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
-{
- char *p;
- struct addrinfo *ai;
-
- ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
- + (afd->a_socklen));
- if (ai == NULL)
- return NULL;
-
- memcpy(ai, pai, sizeof(struct addrinfo));
- ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
- memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
- ai->ai_addr->sa_len = afd->a_socklen;
- ai->ai_addrlen = afd->a_socklen;
- ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
- p = (char *)(void *)(ai->ai_addr);
- memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
- return ai;
-}
-
-static int
-get_portmatch(const struct addrinfo *ai, const char *servname)
-{
-
- /* get_port does not touch first argument. when matchonly == 1. */
- /* LINTED const cast */
- return get_port((struct addrinfo *)ai, servname, 1);
-}
-
-static int
-get_port(struct addrinfo *ai, const char *servname, int matchonly)
-{
- const char *errstr, *proto;
- int port;
- int allownumeric;
-
- if (servname == NULL)
- return 0;
- switch (ai->ai_family) {
- case AF_INET:
-#ifdef AF_INET6
- case AF_INET6:
-#endif
- break;
- default:
- return 0;
- }
-
- switch (ai->ai_socktype) {
- case SOCK_RAW:
- return EAI_SERVICE;
- case SOCK_DGRAM:
- case SOCK_STREAM:
- case ANY:
- allownumeric = 1;
- break;
- default:
- return EAI_SOCKTYPE;
- }
-
- port = (int)strtonum(servname, 0, USHRT_MAX, &errstr);
- if (!errstr) {
- if (!allownumeric)
- return EAI_SERVICE;
- port = htons(port);
- } else {
- struct servent sp;
- struct servent_data sd;
-
- if (errno == ERANGE)
- return EAI_SERVICE;
- if (ai->ai_flags & AI_NUMERICSERV)
- return EAI_NONAME;
-
- switch (ai->ai_socktype) {
- case SOCK_DGRAM:
- proto = "udp";
- break;
- case SOCK_STREAM:
- proto = "tcp";
- break;
- default:
- proto = NULL;
- break;
- }
-
- (void)memset(&sd, 0, sizeof(sd));
- if (getservbyname_r(servname, proto, &sp, &sd) == -1)
- return EAI_SERVICE;
- port = sp.s_port;
- endservent_r(&sd);
- }
-
- if (!matchonly) {
- switch (ai->ai_family) {
- case AF_INET:
- ((struct sockaddr_in *)(void *)
- ai->ai_addr)->sin_port = port;
- break;
-#ifdef INET6
- case AF_INET6:
- ((struct sockaddr_in6 *)(void *)
- ai->ai_addr)->sin6_port = port;
- break;
-#endif
- }
- }
-
- return 0;
-}
-
-static const struct afd *
-find_afd(int af)
-{
- const struct afd *afd;
-
- if (af == PF_UNSPEC)
- return NULL;
- for (afd = afdl; afd->a_af; afd++) {
- if (afd->a_af == af)
- return afd;
- }
- return NULL;
-}
-
-#ifdef INET6
-/* convert a string to a scope identifier. XXX: IPv6 specific */
-static int
-ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid)
-{
- struct in6_addr *a6 = &sin6->sin6_addr;
- const char *errstr;
-
- /* empty scopeid portion is invalid */
- if (*scope == '\0')
- return -1;
-
- if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6) ||
- IN6_IS_ADDR_MC_INTFACELOCAL(a6)) {
- /*
- * We currently assume a one-to-one mapping between links
- * and interfaces, so we simply use interface indices for
- * like-local scopes.
- */
- *scopeid = if_nametoindex(scope);
- if (*scopeid == 0)
- goto trynumeric;
- return 0;
- }
-
- /* still unclear about literal, allow numeric only - placeholder */
- if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
- goto trynumeric;
- if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
- goto trynumeric;
- else
- goto trynumeric; /* global */
-
- /* try to convert to a numeric id as a last resort */
- trynumeric:
- *scopeid = (u_int32_t)strtonum(scope, 0, UINT32_MAX, &errstr);
- if (errstr)
- return (-1);
- return (0);
-}
-#endif
-
-/* code duplicate with gethnamaddr.c */
-
-static const char AskedForGot[] =
- "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
-
-static struct addrinfo *
-getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
- const struct addrinfo *pai)
-{
- struct addrinfo sentinel, *cur;
- struct addrinfo ai;
- const struct afd *afd;
- char *canonname;
- const HEADER *hp;
- const u_char *cp;
- int n;
- const u_char *eom;
- char *bp, *ep;
- int type, class, ancount, qdcount;
- int haveanswer, had_error;
- char tbuf[MAXDNAME];
- int (*name_ok)(const char *);
- char hostbuf[8*1024];
-
- memset(&sentinel, 0, sizeof(sentinel));
- cur = &sentinel;
-
- canonname = NULL;
- eom = answer->buf + anslen;
- switch (qtype) {
- case T_A:
- case T_AAAA:
- case T_ANY: /*use T_ANY only for T_A/T_AAAA lookup*/
- name_ok = res_hnok;
- break;
- default:
- return (NULL); /* XXX should be abort() -- but that is illegal */
- }
- /*
- * find first satisfactory answer
- */
- hp = &answer->hdr;
- ancount = ntohs(hp->ancount);
- qdcount = ntohs(hp->qdcount);
- bp = hostbuf;
- ep = hostbuf + sizeof hostbuf;
- cp = answer->buf + HFIXEDSZ;
- if (qdcount != 1) {
- h_errno = NO_RECOVERY;
- return (NULL);
- }
- n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
- if ((n < 0) || !(*name_ok)(bp)) {
- h_errno = NO_RECOVERY;
- return (NULL);
- }
- cp += n + QFIXEDSZ;
- if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
- size_t len;
-
- /* res_send() has already verified that the query name is the
- * same as the one we sent; this just gets the expanded name
- * (i.e., with the succeeding search-domain tacked on).
- */
- len = strlen(bp) + 1; /* for the \0 */
- if (len >= MAXHOSTNAMELEN) {
- h_errno = NO_RECOVERY;
- return (NULL);
- }
- canonname = bp;
- bp += len;
- /* The qname can be abbreviated, but h_name is now absolute. */
- qname = canonname;
- }
- haveanswer = 0;
- had_error = 0;
- while (ancount-- > 0 && cp < eom && !had_error) {
- n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
- if ((n < 0) || !(*name_ok)(bp)) {
- had_error++;
- continue;
- }
- cp += n; /* name */
- type = _getshort(cp);
- cp += INT16SZ; /* type */
- class = _getshort(cp);
- cp += INT16SZ + INT32SZ; /* class, TTL */
- n = _getshort(cp);
- cp += INT16SZ; /* len */
- if (class != C_IN) {
- /* XXX - debug? syslog? */
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
- if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
- type == T_CNAME) {
- size_t len;
-
- n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
- if ((n < 0) || !(*name_ok)(tbuf)) {
- had_error++;
- continue;
- }
- cp += n;
- /* Get canonical name. */
- len = strlen(tbuf) + 1; /* for the \0 */
- if (len > ep - bp || len >= MAXHOSTNAMELEN) {
- had_error++;
- continue;
- }
- strlcpy(bp, tbuf, ep - bp);
- canonname = bp;
- bp += len;
- continue;
- }
- if (qtype == T_ANY) {
- if (!(type == T_A || type == T_AAAA)) {
- cp += n;
- continue;
- }
- } else if (type != qtype) {
-#ifndef NO_LOG_BAD_DNS_RESPONSES
- if (type != T_KEY && type != T_SIG) {
- struct syslog_data sdata = SYSLOG_DATA_INIT;
-
- syslog_r(LOG_NOTICE|LOG_AUTH, &sdata,
- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
- qname, p_class(C_IN), p_type(qtype),
- p_type(type));
- }
-#endif /* NO_LOG_BAD_DNS_RESPONSES */
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
- switch (type) {
- case T_A:
- case T_AAAA:
- if (strcasecmp(canonname, bp) != 0) {
- struct syslog_data sdata = SYSLOG_DATA_INIT;
-
- syslog_r(LOG_NOTICE|LOG_AUTH, &sdata,
- AskedForGot, canonname, bp);
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
- if (type == T_A && n != INADDRSZ) {
- cp += n;
- continue;
- }
- if (type == T_AAAA && n != IN6ADDRSZ) {
- cp += n;
- continue;
- }
- if (type == T_AAAA) {
- struct in6_addr in6;
- memcpy(&in6, cp, IN6ADDRSZ);
- if (IN6_IS_ADDR_V4MAPPED(&in6)) {
- cp += n;
- continue;
- }
- }
- if (!haveanswer) {
- canonname = bp;
- bp += strlen(bp) + 1; /* for the \0 */
- }
-
- /* don't overwrite pai */
- ai = *pai;
- ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
- afd = find_afd(ai.ai_family);
- if (afd == NULL) {
- cp += n;
- continue;
- }
- cur->ai_next = get_ai(&ai, afd, (const char *)cp);
- if (cur->ai_next == NULL)
- had_error++;
- while (cur && cur->ai_next)
- cur = cur->ai_next;
- cp += n;
- break;
- default:
- abort(); /* XXX abort illegal in library */
- }
- if (!had_error)
- haveanswer++;
- }
- if (haveanswer) {
- if (!canonname || (pai->ai_flags & AI_FQDN) != 0)
- (void)get_canonname(pai, sentinel.ai_next, qname);
- else
- (void)get_canonname(pai, sentinel.ai_next, canonname);
- h_errno = NETDB_SUCCESS;
- return sentinel.ai_next;
- }
-
- h_errno = NO_RECOVERY;
- return NULL;
-}
-
-/*ARGSUSED*/
-static struct addrinfo *
-_dns_getaddrinfo(const char *name, const struct addrinfo *pai,
- const struct __res_state *_resp)
-{
- struct addrinfo *ai;
- querybuf *buf, *buf2;
- struct addrinfo sentinel, *cur;
- struct res_target q, q2;
-
- memset(&q, 0, sizeof(q));
- memset(&q2, 0, sizeof(q2));
- memset(&sentinel, 0, sizeof(sentinel));
- cur = &sentinel;
-
- buf = malloc(sizeof(*buf));
- if (buf == NULL) {
- h_errno = NETDB_INTERNAL;
- return NULL;
- }
- buf2 = malloc(sizeof(*buf2));
- if (buf2 == NULL) {
- free(buf);
- h_errno = NETDB_INTERNAL;
- return NULL;
- }
-
- switch (pai->ai_family) {
- case AF_UNSPEC:
- /* respect user supplied order */
- q.qclass = C_IN;
- q.qtype = (_resp->family[0] == AF_INET6) ? T_AAAA : T_A;
- q.answer = buf->buf;
- q.anslen = sizeof(buf->buf);
- q.next = &q2;
-
- if (_resp->family[1] == -1) {
- /* stop here if only one family was given */
- q.next = NULL;
- break;
- }
-
- q2.qclass = C_IN;
- q2.qtype = (_resp->family[1] == AF_INET6) ? T_AAAA : T_A;
- q2.answer = buf2->buf;
- q2.anslen = sizeof(buf2->buf);
- break;
- case AF_INET:
- q.qclass = C_IN;
- q.qtype = T_A;
- q.answer = buf->buf;
- q.anslen = sizeof(buf->buf);
- break;
- case AF_INET6:
- q.qclass = C_IN;
- q.qtype = T_AAAA;
- q.answer = buf->buf;
- q.anslen = sizeof(buf->buf);
- break;
- default:
- free(buf);
- free(buf2);
- return NULL;
- }
- if (res_searchN(name, &q) < 0) {
- free(buf);
- free(buf2);
- return NULL;
- }
- ai = getanswer(buf, q.n, q.name, q.qtype, pai);
- if (ai) {
- cur->ai_next = ai;
- while (cur && cur->ai_next)
- cur = cur->ai_next;
- }
- if (q.next) {
- ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
- if (ai)
- cur->ai_next = ai;
- }
- free(buf);
- free(buf2);
- return sentinel.ai_next;
-}
-
-static struct addrinfo *
-_gethtent(const char *name, const struct addrinfo *pai, FILE *hostf)
-{
- char *p;
- char *cp, *tname, *cname;
- struct addrinfo hints, *res0, *res;
- int error;
- const char *addr;
- char hostbuf[8*1024];
-
- again:
- if (!(p = fgets(hostbuf, sizeof hostbuf, hostf)))
- return (NULL);
- if (*p == '#')
- goto again;
- if (!(cp = strpbrk(p, "#\n")))
- goto again;
- *cp = '\0';
- if (!(cp = strpbrk(p, " \t")))
- goto again;
- *cp++ = '\0';
- addr = p;
- /* if this is not something we're looking for, skip it. */
- cname = NULL;
- while (cp && *cp) {
- if (*cp == ' ' || *cp == '\t') {
- cp++;
- continue;
- }
- if (!cname)
- cname = cp;
- tname = cp;
- if ((cp = strpbrk(cp, " \t")) != NULL)
- *cp++ = '\0';
- if (strcasecmp(name, tname) == 0)
- goto found;
- }
- goto again;
-
-found:
- hints = *pai;
- hints.ai_flags = AI_NUMERICHOST;
- error = getaddrinfo(addr, NULL, &hints, &res0);
- if (error)
- goto again;
- for (res = res0; res; res = res->ai_next) {
- /* cover it up */
- res->ai_flags = pai->ai_flags;
-
- if (get_canonname(pai, res, cname) != 0) {
- freeaddrinfo(res0);
- goto again;
- }
- }
- return res0;
-}
-
-/*ARGSUSED*/
-static struct addrinfo *
-_files_getaddrinfo(const char *name, const struct addrinfo *pai)
-{
- struct addrinfo sentinel, *cur;
- struct addrinfo *p;
- FILE *hostf;
-
- hostf = fopen(_PATH_HOSTS, "r");
- if (hostf == NULL)
- return NULL;
-
- memset(&sentinel, 0, sizeof(sentinel));
- cur = &sentinel;
-
- while ((p = _gethtent(name, pai, hostf)) != NULL) {
- cur->ai_next = p;
- while (cur && cur->ai_next)
- cur = cur->ai_next;
- }
- fclose(hostf);
-
- return sentinel.ai_next;
-}
-
-#ifdef YP
-static char *__ypdomain;
-
-/*ARGSUSED*/
-static struct addrinfo *
-_yphostent(char *line, const struct addrinfo *pai)
-{
- struct addrinfo sentinel, *cur;
- struct addrinfo hints, *res, *res0;
- int error;
- char *p = line;
- const char *addr, *canonname;
- char *nextline;
- char *cp;
-
- addr = canonname = NULL;
-
- memset(&sentinel, 0, sizeof(sentinel));
- cur = &sentinel;
-
-nextline:
- /* terminate line */
- cp = strchr(p, '\n');
- if (cp) {
- *cp++ = '\0';
- nextline = cp;
- } else
- nextline = NULL;
-
- cp = strpbrk(p, " \t");
- if (cp == NULL) {
- if (canonname == NULL)
- return (NULL);
- else
- goto done;
- }
- *cp++ = '\0';
-
- addr = p;
-
- while (cp && *cp) {
- if (*cp == ' ' || *cp == '\t') {
- cp++;
- continue;
- }
- if (!canonname)
- canonname = cp;
- if ((cp = strpbrk(cp, " \t")) != NULL)
- *cp++ = '\0';
- }
-
- hints = *pai;
- hints.ai_flags = AI_NUMERICHOST;
- error = getaddrinfo(addr, NULL, &hints, &res0);
- if (error == 0) {
- for (res = res0; res; res = res->ai_next) {
- /* cover it up */
- res->ai_flags = pai->ai_flags;
-
- (void)get_canonname(pai, res, canonname);
- }
- } else
- res0 = NULL;
- if (res0) {
- cur->ai_next = res0;
- while (cur && cur->ai_next)
- cur = cur->ai_next;
- }
-
- if (nextline) {
- p = nextline;
- goto nextline;
- }
-
-done:
- return sentinel.ai_next;
-}
-
-/*ARGSUSED*/
-static struct addrinfo *
-_yp_getaddrinfo(const char *name, const struct addrinfo *pai)
-{
- struct addrinfo sentinel, *cur;
- struct addrinfo *ai = NULL;
- static char *__ypcurrent;
- int __ypcurrentlen, r;
-
- memset(&sentinel, 0, sizeof(sentinel));
- cur = &sentinel;
-
- if (!__ypdomain) {
- if (_yp_check(&__ypdomain) == 0)
- return NULL;
- }
- if (__ypcurrent)
- free(__ypcurrent);
- __ypcurrent = NULL;
-
- /* hosts.byname is only for IPv4 (Solaris8) */
- if (pai->ai_family == PF_UNSPEC || pai->ai_family == PF_INET) {
- r = yp_match(__ypdomain, "hosts.byname", name,
- (int)strlen(name), &__ypcurrent, &__ypcurrentlen);
- if (r == 0) {
- struct addrinfo ai4;
-
- ai4 = *pai;
- ai4.ai_family = AF_INET;
- ai = _yphostent(__ypcurrent, &ai4);
- if (ai) {
- cur->ai_next = ai;
- while (cur && cur->ai_next)
- cur = cur->ai_next;
- }
- }
- }
-
- /* ipnodes.byname can hold both IPv4/v6 */
- r = yp_match(__ypdomain, "ipnodes.byname", name,
- (int)strlen(name), &__ypcurrent, &__ypcurrentlen);
- if (r == 0) {
- ai = _yphostent(__ypcurrent, pai);
- if (ai) {
- cur->ai_next = ai;
- while (cur && cur->ai_next)
- cur = cur->ai_next;
- }
- }
-
- return sentinel.ai_next;
-}
-#endif
-
-
-/* resolver logic */
-
-extern const char *__hostalias(const char *);
-extern int h_errno;
-extern int res_opt(int, u_char *, int, int);
-
-/*
- * Formulate a normal query, send, and await answer.
- * Returned answer is placed in supplied buffer "answer".
- * Perform preliminary check of answer, returning success only
- * if no error is indicated and the answer count is nonzero.
- * Return the size of the response on success, -1 on error.
- * Error number is left in h_errno.
- *
- * Caller must parse answer and determine whether it answers the question.
- */
-static int
-res_queryN(const char *name, struct res_target *target)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- u_char *buf;
- HEADER *hp;
- int n;
- struct res_target *t;
- int rcode;
- int ancount;
-
- buf = malloc(MAXPACKET);
- if (buf == NULL) {
- h_errno = NETDB_INTERNAL;
- return (-1);
- }
-
- rcode = NOERROR;
- ancount = 0;
-
- if (_res_init(0) == -1) {
- h_errno = NETDB_INTERNAL;
- free(buf);
- return (-1);
- }
-
- for (t = target; t; t = t->next) {
- int class, type;
- u_char *answer;
- int anslen;
-
- hp = (HEADER *)(void *)t->answer;
- hp->rcode = NOERROR; /* default */
-
- /* make it easier... */
- class = t->qclass;
- type = t->qtype;
- answer = t->answer;
- anslen = t->anslen;
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; res_query(%s, %d, %d)\n", name, class, type);
-#endif
-
- n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
- buf, MAXPACKET);
- if (n > 0 && (_resp->options & RES_USE_EDNS0) != 0)
- n = res_opt(n, buf, MAXPACKET, anslen);
- if (n <= 0) {
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; res_query: mkquery failed\n");
-#endif
- h_errno = NO_RECOVERY;
- free(buf);
- return (n);
- }
- n = res_send(buf, n, answer, anslen);
-#if 0
- if (n < 0) {
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; res_query: send error\n");
-#endif
- h_errno = TRY_AGAIN;
- free(buf);
- return (n);
- }
-#endif
-
- if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
- rcode = hp->rcode; /* record most recent error */
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; rcode = %u, ancount=%u\n", hp->rcode,
- ntohs(hp->ancount));
-#endif
- continue;
- }
-
- ancount += ntohs(hp->ancount);
-
- t->n = n;
- }
-
- if (ancount == 0) {
- switch (rcode) {
- case NXDOMAIN:
- h_errno = HOST_NOT_FOUND;
- break;
- case SERVFAIL:
- h_errno = TRY_AGAIN;
- break;
- case NOERROR:
- h_errno = NO_DATA;
- break;
- case FORMERR:
- case NOTIMP:
- case REFUSED:
- default:
- h_errno = NO_RECOVERY;
- break;
- }
- free(buf);
- return (-1);
- }
- free(buf);
- return (ancount);
-}
-
-/*
- * Formulate a normal query, send, and retrieve answer in supplied buffer.
- * Return the size of the response on success, -1 on error.
- * If enabled, implement search rules until answer or unrecoverable failure
- * is detected. Error code, if any, is left in h_errno.
- */
-static int
-res_searchN(const char *name, struct res_target *target)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- const char *cp, * const *domain;
- HEADER *hp = (HEADER *)(void *)target->answer; /*XXX*/
- u_int dots;
- int trailing_dot, ret, saved_herrno;
- int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
-
- if (_res_init(0) == -1) {
- h_errno = NETDB_INTERNAL;
- return (-1);
- }
-
- errno = 0;
- h_errno = HOST_NOT_FOUND; /* default, if we never query */
- dots = 0;
- for (cp = name; *cp; cp++)
- dots += (*cp == '.');
- trailing_dot = 0;
- if (cp > name && *--cp == '.')
- trailing_dot++;
-
- /*
- * if there aren't any dots, it could be a user-level alias
- */
- if (!dots && (cp = __hostalias(name)) != NULL)
- return (res_queryN(cp, target));
-
- /*
- * If there are dots in the name already, let's just give it a try
- * 'as is'. The threshold can be set with the "ndots" option.
- */
- saved_herrno = -1;
- if (dots >= _resp->ndots) {
- ret = res_querydomainN(name, NULL, target);
- if (ret > 0)
- return (ret);
- saved_herrno = h_errno;
- tried_as_is++;
- }
-
- /*
- * We do at least one level of search if
- * - there is no dot and RES_DEFNAME is set, or
- * - there is at least one dot, there is no trailing dot,
- * and RES_DNSRCH is set.
- */
- if ((!dots && (_resp->options & RES_DEFNAMES)) ||
- (dots && !trailing_dot && (_resp->options & RES_DNSRCH))) {
- int done = 0;
-
- for (domain = (const char * const *)_resp->dnsrch;
- *domain && !done;
- domain++) {
-
- ret = res_querydomainN(name, *domain, target);
- if (ret > 0)
- return (ret);
-
- /*
- * If no server present, give up.
- * If name isn't found in this domain,
- * keep trying higher domains in the search list
- * (if that's enabled).
- * On a NO_DATA error, keep trying, otherwise
- * a wildcard entry of another type could keep us
- * from finding this entry higher in the domain.
- * If we get some other error (negative answer or
- * server failure), then stop searching up,
- * but try the input name below in case it's
- * fully-qualified.
- */
- if (errno == ECONNREFUSED) {
- h_errno = TRY_AGAIN;
- return (-1);
- }
-
- switch (h_errno) {
- case NO_DATA:
- got_nodata++;
- /* FALLTHROUGH */
- case HOST_NOT_FOUND:
- /* keep trying */
- break;
- case TRY_AGAIN:
- if (hp->rcode == SERVFAIL) {
- /* try next search element, if any */
- got_servfail++;
- break;
- }
- /* FALLTHROUGH */
- default:
- /* anything else implies that we're done */
- done++;
- }
- /*
- * if we got here for some reason other than DNSRCH,
- * we only wanted one iteration of the loop, so stop.
- */
- if (!(_resp->options & RES_DNSRCH))
- done++;
- }
- }
-
- /*
- * if we have not already tried the name "as is", do that now.
- * note that we do this regardless of how many dots were in the
- * name or whether it ends with a dot.
- */
- if (!tried_as_is) {
- ret = res_querydomainN(name, NULL, target);
- if (ret > 0)
- return (ret);
- }
-
- /*
- * if we got here, we didn't satisfy the search.
- * if we did an initial full query, return that query's h_errno
- * (note that we wouldn't be here if that query had succeeded).
- * else if we ever got a nodata, send that back as the reason.
- * else send back meaningless h_errno, that being the one from
- * the last DNSRCH we did.
- */
- if (saved_herrno != -1)
- h_errno = saved_herrno;
- else if (got_nodata)
- h_errno = NO_DATA;
- else if (got_servfail)
- h_errno = TRY_AGAIN;
- return (-1);
-}
-
-/*
- * Perform a call on res_query on the concatenation of name and domain,
- * removing a trailing dot from name if domain is NULL.
- */
-static int
-res_querydomainN(const char *name, const char *domain,
- struct res_target *target)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- char nbuf[MAXDNAME];
- const char *longname = nbuf;
- size_t len;
-
- if (_res_init(0) == -1) {
- h_errno = NETDB_INTERNAL;
- return (-1);
- }
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; res_querydomain(%s, %s)\n",
- name, domain?domain:"<Nil>");
-#endif
- if (domain == NULL) {
- /*
- * Check for trailing '.';
- * copy without '.' if present.
- */
- len = strlcpy(nbuf, name, sizeof(nbuf));
- if (len >= sizeof(nbuf)) {
- h_errno = NO_RECOVERY;
- return (-1);
- }
- if (len > 0 && nbuf[len - 1] == '.')
- nbuf[len - 1] = '\0';
- } else {
- int i;
-
- i = snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
- if (i < 0 || i >= sizeof(nbuf)) {
- h_errno = NO_RECOVERY;
- return (-1);
- }
- }
- return (res_queryN(longname, target));
-}
diff --git a/lib/libc/net/gethostnamadr.c b/lib/libc/net/gethostnamadr.c
deleted file mode 100644
index f4e655eeaf4..00000000000
--- a/lib/libc/net/gethostnamadr.c
+++ /dev/null
@@ -1,1131 +0,0 @@
-/* $OpenBSD: gethostnamadr.c,v 1.73 2009/11/18 07:43:22 guenther Exp $ */
-/*-
- * Copyright (c) 1985, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <syslog.h>
-#include <stdlib.h>
-#ifdef YP
-#include <rpc/rpc.h>
-#include <rpcsvc/yp.h>
-#include <rpcsvc/ypclnt.h>
-#include "ypinternal.h"
-#endif
-#include "thread_private.h"
-
-#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
-
-#define MAXALIASES 35
-#define MAXADDRS 35
-
-static char *h_addr_ptrs[MAXADDRS + 1];
-
-#ifdef YP
-static char *__ypdomain;
-#endif
-
-static struct hostent host;
-static char *host_aliases[MAXALIASES];
-static char hostbuf[BUFSIZ+1];
-static union {
- struct in_addr _host_in_addr;
- u_char _host_addr[16]; /* IPv4 or IPv6 */
-} _host_addr_u;
-#define host_addr _host_addr_u._host_addr
-static FILE *hostf = NULL;
-static int stayopen = 0;
-
-static void map_v4v6_address(const char *src, char *dst);
-static void map_v4v6_hostent(struct hostent *hp, char **bp, char *);
-
-#ifdef RESOLVSORT
-static void addrsort(char **, int);
-#endif
-
-int _hokchar(const char *);
-
-static const char AskedForGot[] =
- "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
-
-#define MAXPACKET (64*1024)
-
-typedef union {
- HEADER hdr;
- u_char buf[MAXPACKET];
-} querybuf;
-
-typedef union {
- int32_t al;
- char ac;
-} align;
-
-static struct hostent *getanswer(const querybuf *, int, const char *, int);
-
-extern int h_errno;
-
-int
-_hokchar(const char *p)
-{
- char c;
-
- /*
- * Many people do not obey RFC 822 and 1035. The valid
- * characters are a-z, A-Z, 0-9, '-' and . But the others
- * tested for below can happen, and we must be more permissive
- * than the resolver until those idiots clean up their act.
- * We let '/' through, but not '..'
- */
- while ((c = *p++)) {
- if (('a' <= c && c <= 'z') ||
- ('A' <= c && c <= 'Z') ||
- ('0' <= c && c <= '9'))
- continue;
- if (strchr("-_/", c))
- continue;
- if (c == '.' && *p != '.')
- continue;
- return 0;
- }
- return 1;
-}
-
-static struct hostent *
-getanswer(const querybuf *answer, int anslen, const char *qname, int qtype)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- const HEADER *hp;
- const u_char *cp, *eom;
- char tbuf[MAXDNAME];
- char *bp, **ap, **hap, *ep;
- int type, class, ancount, qdcount, n;
- int haveanswer, had_error, toobig = 0;
- const char *tname;
- int (*name_ok)(const char *);
-
- tname = qname;
- host.h_name = NULL;
- eom = answer->buf + anslen;
- switch (qtype) {
- case T_A:
- case T_AAAA:
-#ifdef USE_RESOLV_NAME_OK
- name_ok = res_hnok;
- break;
-#endif
- case T_PTR:
-#ifdef USE_RESOLV_NAME_OK
- name_ok = res_dnok;
-#else
- name_ok = _hokchar;
-#endif
- break;
- default:
- return (NULL);
- }
- /*
- * find first satisfactory answer
- */
- hp = &answer->hdr;
- ancount = ntohs(hp->ancount);
- qdcount = ntohs(hp->qdcount);
- bp = hostbuf;
- ep = hostbuf + sizeof hostbuf;
- cp = answer->buf + HFIXEDSZ;
- if (qdcount != 1) {
- h_errno = NO_RECOVERY;
- return (NULL);
- }
- n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
- if ((n < 0) || !(*name_ok)(bp)) {
- h_errno = NO_RECOVERY;
- return (NULL);
- }
- cp += n + QFIXEDSZ;
- if (qtype == T_A || qtype == T_AAAA) {
- /* res_send() has already verified that the query name is the
- * same as the one we sent; this just gets the expanded name
- * (i.e., with the succeeding search-domain tacked on).
- */
- host.h_name = bp;
- bp += strlen(bp) + 1; /* for the \0 */
- /* The qname can be abbreviated, but h_name is now absolute. */
- qname = host.h_name;
- }
- ap = host_aliases;
- *ap = NULL;
- host.h_aliases = host_aliases;
- hap = h_addr_ptrs;
- *hap = NULL;
- host.h_addr_list = h_addr_ptrs;
- haveanswer = 0;
- had_error = 0;
- while (ancount-- > 0 && cp < eom && !had_error) {
- size_t len;
-
- n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
- if ((n < 0) || !(*name_ok)(bp)) {
- had_error++;
- continue;
- }
- cp += n; /* name */
- if (cp >= eom)
- break;
- type = _getshort(cp);
- cp += INT16SZ; /* type */
- if (cp >= eom)
- break;
- class = _getshort(cp);
- cp += INT16SZ + INT32SZ; /* class, TTL */
- if (cp >= eom)
- break;
- n = _getshort(cp);
- cp += INT16SZ; /* len */
- if (cp >= eom)
- break;
- if (type == T_SIG || type == T_RRSIG) {
- /* XXX - ignore signatures as we don't use them yet */
- cp += n;
- continue;
- }
- if (class != C_IN) {
- /* XXX - debug? syslog? */
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
- if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
- if (ap >= &host_aliases[MAXALIASES-1])
- continue;
- n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
- if ((n < 0) || !(*name_ok)(tbuf)) {
- had_error++;
- continue;
- }
- cp += n;
- /* Store alias. */
- *ap++ = bp;
- bp += strlen(bp) + 1; /* for the \0 */
- /* Get canonical name. */
- len = strlen(tbuf) + 1; /* for the \0 */
- if (len > ep - bp) {
- had_error++;
- continue;
- }
- strlcpy(bp, tbuf, ep - bp);
- host.h_name = bp;
- bp += len;
- continue;
- }
- if (qtype == T_PTR && type == T_CNAME) {
- n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
-#ifdef USE_RESOLV_NAME_OK
- if ((n < 0) || !res_hnok(tbuf)) {
-#else
- if ((n < 0) || !_hokchar(tbuf)) {
-#endif
- had_error++;
- continue;
- }
- cp += n;
- /* Get canonical name. */
- len = strlen(tbuf) + 1; /* for the \0 */
- if (len > ep - bp) {
- had_error++;
- continue;
- }
- strlcpy(bp, tbuf, ep - bp);
- tname = bp;
- bp += len;
- continue;
- }
- if (type != qtype) {
-#ifndef NO_LOG_BAD_DNS_RESPONSES
- syslog(LOG_NOTICE|LOG_AUTH,
- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
- qname, p_class(C_IN), p_type(qtype),
- p_type(type));
-#endif /* NO_LOG_BAD_DNS_RESPONSES */
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
- switch (type) {
- case T_PTR:
- if (strcasecmp(tname, bp) != 0) {
- syslog(LOG_NOTICE|LOG_AUTH,
- AskedForGot, qname, bp);
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
- n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
-#ifdef USE_RESOLV_NAME_OK
- if ((n < 0) || !res_hnok(bp)) {
-#else
- if ((n < 0) || !_hokchar(bp)) {
-#endif
- had_error++;
- break;
- }
-#if MULTI_PTRS_ARE_ALIASES
- cp += n;
- if (!haveanswer)
- host.h_name = bp;
- else if (ap < &host_aliases[MAXALIASES-1])
- *ap++ = bp;
- else
- n = -1;
- if (n != -1) {
- n = strlen(bp) + 1; /* for the \0 */
- bp += n;
- }
- break;
-#else
- host.h_name = bp;
- if (_resp->options & RES_USE_INET6) {
- n = strlen(bp) + 1; /* for the \0 */
- bp += n;
- map_v4v6_hostent(&host, &bp, ep);
- }
- h_errno = NETDB_SUCCESS;
- return (&host);
-#endif
- case T_A:
- case T_AAAA:
- if (strcasecmp(host.h_name, bp) != 0) {
- syslog(LOG_NOTICE|LOG_AUTH,
- AskedForGot, host.h_name, bp);
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
- if (n != host.h_length) {
- cp += n;
- continue;
- }
- if (type == T_AAAA) {
- struct in6_addr in6;
- memcpy(&in6, cp, IN6ADDRSZ);
- if (IN6_IS_ADDR_V4MAPPED(&in6)) {
- cp += n;
- continue;
- }
- }
- if (!haveanswer) {
- host.h_name = bp;
- bp += strlen(bp) + 1; /* for the \0 */
- }
-
- bp += sizeof(align) - ((u_long)bp % sizeof(align));
-
- if (bp + n >= &hostbuf[sizeof hostbuf]) {
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf("size (%d) too big\n", n);
-#endif
- had_error++;
- continue;
- }
- if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
- if (!toobig++)
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf("Too many addresses (%d)\n", MAXADDRS);
-#endif
- cp += n;
- continue;
- }
- bcopy(cp, *hap++ = bp, n);
- bp += n;
- cp += n;
- break;
- }
- if (!had_error)
- haveanswer++;
- }
- if (haveanswer) {
- *ap = NULL;
- *hap = NULL;
-# if defined(RESOLVSORT)
- /*
- * Note: we sort even if host can take only one address
- * in its return structures - should give it the "best"
- * address in that case, not some random one
- */
- if (_resp->nsort && haveanswer > 1 && qtype == T_A)
- addrsort(h_addr_ptrs, haveanswer);
-# endif /*RESOLVSORT*/
- if (!host.h_name) {
- size_t len;
-
- len = strlen(qname) + 1;
- if (len > ep - bp) /* for the \0 */
- goto try_again;
- strlcpy(bp, qname, ep - bp);
- host.h_name = bp;
- bp += len;
- }
- if (_resp->options & RES_USE_INET6)
- map_v4v6_hostent(&host, &bp, ep);
- h_errno = NETDB_SUCCESS;
- return (&host);
- }
- try_again:
- h_errno = TRY_AGAIN;
- return (NULL);
-}
-
-#ifdef notyet
-/*
- * XXX This is an extremely bogus implementation.
- *
- * FreeBSD has this interface:
- * int gethostbyaddr_r(const char *addr, int len, int type,
- * struct hostent *result, struct hostent_data *buffer)
- */
-
-struct hostent *
-gethostbyname_r(const char *name, struct hostent *hp, char *buf, int buflen,
- int *errorp)
-{
- struct hostent *res;
-
- res = gethostbyname(name);
- *errorp = h_errno;
- if (res == NULL)
- return NULL;
- memcpy(hp, res, sizeof *hp); /* XXX not sufficient */
- return hp;
-}
-
-/*
- * XXX This is an extremely bogus implementation.
- */
-struct hostent *
-gethostbyaddr_r(const char *addr, int len, int af, struct hostent *he,
- char *buf, int buflen, int *errorp)
-{
- struct hostent * res;
-
- res = gethostbyaddr(addr, len, af);
- *errorp = h_errno;
- if (res == NULL)
- return NULL;
- memcpy(he, res, sizeof *he); /* XXX not sufficient */
- return he;
-}
-
-/* XXX RFC2133 expects a gethostbyname2_r() -- unimplemented */
-#endif
-
-struct hostent *
-gethostbyname(const char *name)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- struct hostent *hp;
- extern struct hostent *_gethtbyname2(const char *, int);
-
- if (_res_init(0) == -1)
- hp = _gethtbyname2(name, AF_INET);
-
- else if (_resp->options & RES_USE_INET6) {
- hp = gethostbyname2(name, AF_INET6);
- if (hp == NULL)
- hp = gethostbyname2(name, AF_INET);
- }
- else
- hp = gethostbyname2(name, AF_INET);
- return hp;
-}
-
-struct hostent *
-gethostbyname2(const char *name, int af)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- querybuf *buf;
- const char *cp;
- char *bp, *ep;
- int n, size, type, i;
- struct hostent *hp;
- char lookups[MAXDNSLUS];
- extern struct hostent *_gethtbyname2(const char *, int);
-#ifdef YP
- extern struct hostent *_yp_gethtbyname(const char *);
-#endif
-
- if (_res_init(0) == -1)
- return (_gethtbyname2(name, af));
-
- switch (af) {
- case AF_INET:
- size = INADDRSZ;
- type = T_A;
- break;
- case AF_INET6:
- size = IN6ADDRSZ;
- type = T_AAAA;
- break;
- default:
- h_errno = NETDB_INTERNAL;
- errno = EAFNOSUPPORT;
- return (NULL);
- }
-
- host.h_addrtype = af;
- host.h_length = size;
-
- /*
- * if there aren't any dots, it could be a user-level alias.
- * this is also done in res_query() since we are not the only
- * function that looks up host names.
- */
- if (!strchr(name, '.') && (cp = __hostalias(name)))
- name = cp;
-
- /*
- * disallow names consisting only of digits/dots, unless
- * they end in a dot.
- */
- if (isdigit(name[0]))
- for (cp = name;; ++cp) {
- if (!*cp) {
- if (*--cp == '.')
- break;
- /*
- * All-numeric, no dot at the end.
- * Fake up a hostent as if we'd actually
- * done a lookup.
- */
- if (inet_pton(af, name, host_addr) <= 0) {
- h_errno = HOST_NOT_FOUND;
- return (NULL);
- }
- strlcpy(hostbuf, name, MAXHOSTNAMELEN);
- bp = hostbuf + MAXHOSTNAMELEN;
- ep = hostbuf + sizeof(hostbuf);
- host.h_name = hostbuf;
- host.h_aliases = host_aliases;
- host_aliases[0] = NULL;
- h_addr_ptrs[0] = (char *)host_addr;
- h_addr_ptrs[1] = NULL;
- host.h_addr_list = h_addr_ptrs;
- if (_resp->options & RES_USE_INET6)
- map_v4v6_hostent(&host, &bp, ep);
- h_errno = NETDB_SUCCESS;
- return (&host);
- }
- if (!isdigit(*cp) && *cp != '.')
- break;
- }
- if ((isxdigit(name[0]) && strchr(name, ':') != NULL) ||
- name[0] == ':')
- for (cp = name;; ++cp) {
- if (!*cp) {
- if (*--cp == '.')
- break;
- /*
- * All-IPv6-legal, no dot at the end.
- * Fake up a hostent as if we'd actually
- * done a lookup.
- */
- if (inet_pton(af, name, host_addr) <= 0) {
- h_errno = HOST_NOT_FOUND;
- return (NULL);
- }
- strlcpy(hostbuf, name, MAXHOSTNAMELEN);
- bp = hostbuf + MAXHOSTNAMELEN;
- ep = hostbuf + sizeof(hostbuf);
- host.h_name = hostbuf;
- host.h_aliases = host_aliases;
- host_aliases[0] = NULL;
- h_addr_ptrs[0] = (char *)host_addr;
- h_addr_ptrs[1] = NULL;
- host.h_addr_list = h_addr_ptrs;
- h_errno = NETDB_SUCCESS;
- return (&host);
- }
- if (!isxdigit(*cp) && *cp != ':' && *cp != '.')
- break;
- }
-
- bcopy(_resp->lookups, lookups, sizeof lookups);
- if (lookups[0] == '\0')
- strlcpy(lookups, "bf", sizeof lookups);
-
- hp = (struct hostent *)NULL;
- for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
- switch (lookups[i]) {
-#ifdef YP
- case 'y':
- /* YP only supports AF_INET. */
- if (af == AF_INET)
- hp = _yp_gethtbyname(name);
- break;
-#endif
- case 'b':
- buf = malloc(sizeof(*buf));
- if (buf == NULL)
- break;
- if ((n = res_search(name, C_IN, type, buf->buf,
- sizeof(buf->buf))) < 0) {
- free(buf);
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf("res_search failed\n");
-#endif
- break;
- }
- hp = getanswer(buf, n, name, type);
- free(buf);
- break;
- case 'f':
- hp = _gethtbyname2(name, af);
- break;
- }
- }
- /* XXX h_errno not correct in all cases... */
- return (hp);
-}
-
-struct hostent *
-gethostbyaddr(const void *addr, socklen_t len, int af)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- const u_char *uaddr = (const u_char *)addr;
- int n, size, i;
- querybuf *buf;
- struct hostent *hp;
- char qbuf[MAXDNAME+1], *qp, *ep;
- char lookups[MAXDNSLUS];
- struct hostent *res;
- extern struct hostent *_gethtbyaddr(const void *, socklen_t, int);
-#ifdef YP
- extern struct hostent *_yp_gethtbyaddr(const void *);
-#endif
-
- if (_res_init(0) == -1) {
- res = _gethtbyaddr(addr, len, af);
- return (res);
- }
-
- if (af == AF_INET6 && len == IN6ADDRSZ &&
- (IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)uaddr) ||
- IN6_IS_ADDR_SITELOCAL((struct in6_addr *)uaddr))) {
- h_errno = HOST_NOT_FOUND;
- return (NULL);
- }
- if (af == AF_INET6 && len == IN6ADDRSZ &&
- (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)uaddr) ||
- IN6_IS_ADDR_V4COMPAT((struct in6_addr *)uaddr))) {
- /* Unmap. */
- uaddr += IN6ADDRSZ - INADDRSZ;
- af = AF_INET;
- len = INADDRSZ;
- }
- switch (af) {
- case AF_INET:
- size = INADDRSZ;
- break;
- case AF_INET6:
- size = IN6ADDRSZ;
- break;
- default:
- errno = EAFNOSUPPORT;
- h_errno = NETDB_INTERNAL;
- return (NULL);
- }
- if (size != len) {
- errno = EINVAL;
- h_errno = NETDB_INTERNAL;
- return (NULL);
- }
- ep = qbuf + sizeof(qbuf);
- switch (af) {
- case AF_INET:
- (void) snprintf(qbuf, sizeof qbuf, "%u.%u.%u.%u.in-addr.arpa",
- (uaddr[3] & 0xff), (uaddr[2] & 0xff),
- (uaddr[1] & 0xff), (uaddr[0] & 0xff));
- break;
- case AF_INET6:
- qp = qbuf;
- for (n = IN6ADDRSZ - 1; n >= 0; n--) {
- i = snprintf(qp, ep - qp, "%x.%x.",
- uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf);
- if (i <= 0 || i >= ep - qp) {
- errno = EINVAL;
- h_errno = NETDB_INTERNAL;
- return (NULL);
- }
- qp += i;
- }
- strlcpy(qp, "ip6.arpa", ep - qp);
- break;
- }
-
- bcopy(_resp->lookups, lookups, sizeof lookups);
- if (lookups[0] == '\0')
- strlcpy(lookups, "bf", sizeof lookups);
-
- hp = (struct hostent *)NULL;
- for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
- switch (lookups[i]) {
-#ifdef YP
- case 'y':
- /* YP only supports AF_INET. */
- if (af == AF_INET)
- hp = _yp_gethtbyaddr(uaddr);
- break;
-#endif
- case 'b':
- buf = malloc(sizeof(*buf));
- if (!buf)
- break;
- n = res_query(qbuf, C_IN, T_PTR, buf->buf,
- sizeof(buf->buf));
- if (n < 0) {
- free(buf);
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf("res_query failed\n");
-#endif
- break;
- }
- if (!(hp = getanswer(buf, n, qbuf, T_PTR))) {
- free(buf);
- break;
- }
- free(buf);
- hp->h_addrtype = af;
- hp->h_length = len;
- bcopy(uaddr, host_addr, len);
- h_addr_ptrs[0] = (char *)host_addr;
- h_addr_ptrs[1] = NULL;
- if (af == AF_INET && (_resp->options & RES_USE_INET6)) {
- map_v4v6_address((char*)host_addr,
- (char*)host_addr);
- hp->h_addrtype = AF_INET6;
- hp->h_length = IN6ADDRSZ;
- }
- h_errno = NETDB_SUCCESS;
- break;
- case 'f':
- hp = _gethtbyaddr(uaddr, len, af);
- break;
- }
- }
- /* XXX h_errno not correct in all cases... */
- return (hp);
-}
-
-void
-_sethtent(int f)
-{
- if (hostf == NULL)
- hostf = fopen(_PATH_HOSTS, "r" );
- else
- rewind(hostf);
- stayopen = f;
-}
-
-void
-_endhtent(void)
-{
- if (hostf && !stayopen) {
- (void) fclose(hostf);
- hostf = NULL;
- }
-}
-
-static struct hostent *
-_gethtent(void)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- char *p, *cp, **q;
- int af;
- size_t len;
-
- if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
- h_errno = NETDB_INTERNAL;
- return (NULL);
- }
- again:
- if ((p = fgetln(hostf, &len)) == NULL) {
- h_errno = HOST_NOT_FOUND;
- return (NULL);
- }
- if (p[len-1] == '\n')
- len--;
- if (len >= sizeof(hostbuf) || len == 0)
- goto again;
- p = memcpy(hostbuf, p, len);
- hostbuf[len] = '\0';
- if (*p == '#')
- goto again;
- if ((cp = strchr(p, '#')))
- *cp = '\0';
- if (!(cp = strpbrk(p, " \t")))
- goto again;
- *cp++ = '\0';
- if (inet_pton(AF_INET6, p, host_addr) > 0) {
- af = AF_INET6;
- len = IN6ADDRSZ;
- } else if (inet_pton(AF_INET, p, host_addr) > 0) {
- if (_resp->options & RES_USE_INET6) {
- map_v4v6_address((char*)host_addr, (char*)host_addr);
- af = AF_INET6;
- len = IN6ADDRSZ;
- } else {
- af = AF_INET;
- len = INADDRSZ;
- }
- } else {
- goto again;
- }
- /* if this is not something we're looking for, skip it. */
- if (host.h_addrtype != AF_UNSPEC && host.h_addrtype != af)
- goto again;
- if (host.h_length != 0 && host.h_length != len)
- goto again;
- h_addr_ptrs[0] = (char *)host_addr;
- h_addr_ptrs[1] = NULL;
- host.h_addr_list = h_addr_ptrs;
- host.h_length = len;
- host.h_addrtype = af;
- while (*cp == ' ' || *cp == '\t')
- cp++;
- host.h_name = cp;
- q = host.h_aliases = host_aliases;
- if ((cp = strpbrk(cp, " \t")))
- *cp++ = '\0';
- while (cp && *cp) {
- if (*cp == ' ' || *cp == '\t') {
- cp++;
- continue;
- }
- if (q < &host_aliases[MAXALIASES - 1])
- *q++ = cp;
- if ((cp = strpbrk(cp, " \t")))
- *cp++ = '\0';
- }
- *q = NULL;
- if (_resp->options & RES_USE_INET6) {
- char *bp = hostbuf;
- char *ep = hostbuf + sizeof hostbuf;
-
- map_v4v6_hostent(&host, &bp, ep);
- }
- h_errno = NETDB_SUCCESS;
- return (&host);
-}
-
-struct hostent *
-_gethtbyname2(const char *name, int af)
-{
- struct hostent *p;
- char **cp;
-
- _sethtent(0);
- while ((p = _gethtent())) {
- if (p->h_addrtype != af)
- continue;
- if (strcasecmp(p->h_name, name) == 0)
- break;
- for (cp = p->h_aliases; *cp != 0; cp++)
- if (strcasecmp(*cp, name) == 0)
- goto found;
- }
- found:
- _endhtent();
- return (p);
-}
-
-struct hostent *
-_gethtbyaddr(const void *addr, socklen_t len, int af)
-{
- struct hostent *p;
-
- host.h_length = len;
- host.h_addrtype = af;
-
- _sethtent(0);
- while ((p = _gethtent()))
- if (p->h_addrtype == af && p->h_length == len &&
- !bcmp(p->h_addr, addr, len))
- break;
- _endhtent();
- return (p);
-}
-
-#ifdef YP
-struct hostent *
-_yphostent(char *line)
-{
- static struct in_addr host_addrs[MAXADDRS];
- char *p = line;
- char *cp, **q;
- char **hap;
- struct in_addr *buf;
- int more;
-
- host.h_name = NULL;
- host.h_addr_list = h_addr_ptrs;
- host.h_length = INADDRSZ;
- host.h_addrtype = AF_INET;
- hap = h_addr_ptrs;
- buf = host_addrs;
- q = host.h_aliases = host_aliases;
-
-nextline:
- /* check for host_addrs overflow */
- if (buf >= &host_addrs[sizeof(host_addrs) / sizeof(host_addrs[0])])
- goto done;
-
- more = 0;
- cp = strpbrk(p, " \t");
- if (cp == NULL)
- goto done;
- *cp++ = '\0';
-
- *hap++ = (char *)buf;
- (void) inet_aton(p, buf++);
-
- while (*cp == ' ' || *cp == '\t')
- cp++;
- p = cp;
- cp = strpbrk(p, " \t\n");
- if (cp != NULL) {
- if (*cp == '\n')
- more = 1;
- *cp++ = '\0';
- }
- if (!host.h_name)
- host.h_name = p;
- else if (strcmp(host.h_name, p)==0)
- ;
- else if (q < &host_aliases[MAXALIASES - 1])
- *q++ = p;
- p = cp;
- if (more)
- goto nextline;
-
- while (cp && *cp) {
- if (*cp == ' ' || *cp == '\t') {
- cp++;
- continue;
- }
- if (*cp == '\n') {
- cp++;
- goto nextline;
- }
- if (q < &host_aliases[MAXALIASES - 1])
- *q++ = cp;
- cp = strpbrk(cp, " \t");
- if (cp != NULL)
- *cp++ = '\0';
- }
-done:
- if (host.h_name == NULL)
- return (NULL);
- *q = NULL;
- *hap = NULL;
- return (&host);
-}
-
-struct hostent *
-_yp_gethtbyaddr(const void *addr)
-{
- struct hostent *hp = NULL;
- const u_char *uaddr = (const u_char *)addr;
- static char *__ypcurrent;
- int __ypcurrentlen, r;
- char name[sizeof("xxx.xxx.xxx.xxx")];
-
- if (!__ypdomain) {
- if (_yp_check(&__ypdomain) == 0)
- return (hp);
- }
- snprintf(name, sizeof name, "%u.%u.%u.%u", (uaddr[0] & 0xff),
- (uaddr[1] & 0xff), (uaddr[2] & 0xff), (uaddr[3] & 0xff));
- if (__ypcurrent)
- free(__ypcurrent);
- __ypcurrent = NULL;
- r = yp_match(__ypdomain, "hosts.byaddr", name,
- strlen(name), &__ypcurrent, &__ypcurrentlen);
- if (r==0)
- hp = _yphostent(__ypcurrent);
- if (hp==NULL)
- h_errno = HOST_NOT_FOUND;
- return (hp);
-}
-
-struct hostent *
-_yp_gethtbyname(const char *name)
-{
- struct hostent *hp = (struct hostent *)NULL;
- static char *__ypcurrent;
- int __ypcurrentlen, r;
-
- if (strlen(name) >= MAXHOSTNAMELEN)
- return (NULL);
- if (!__ypdomain) {
- if (_yp_check(&__ypdomain) == 0)
- return (hp);
- }
- if (__ypcurrent)
- free(__ypcurrent);
- __ypcurrent = NULL;
- r = yp_match(__ypdomain, "hosts.byname", name,
- strlen(name), &__ypcurrent, &__ypcurrentlen);
- if (r == 0)
- hp = _yphostent(__ypcurrent);
- if (hp == NULL)
- h_errno = HOST_NOT_FOUND;
- return (hp);
-}
-#endif
-
-static void
-map_v4v6_address(const char *src, char *dst)
-{
- u_char *p = (u_char *)dst;
- char tmp[INADDRSZ];
- int i;
-
- /* Stash a temporary copy so our caller can update in place. */
- bcopy(src, tmp, INADDRSZ);
- /* Mark this ipv6 addr as a mapped ipv4. */
- for (i = 0; i < 10; i++)
- *p++ = 0x00;
- *p++ = 0xff;
- *p++ = 0xff;
- /* Retrieve the saved copy and we're done. */
- bcopy(tmp, (void*)p, INADDRSZ);
-}
-
-static void
-map_v4v6_hostent(struct hostent *hp, char **bpp, char *ep)
-{
- char **ap;
-
- if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
- return;
- hp->h_addrtype = AF_INET6;
- hp->h_length = IN6ADDRSZ;
- for (ap = hp->h_addr_list; *ap; ap++) {
- int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
-
- if (ep - *bpp < (i + IN6ADDRSZ)) {
- /* Out of memory. Truncate address list here. XXX */
- *ap = NULL;
- return;
- }
- *bpp += i;
- map_v4v6_address(*ap, *bpp);
- *ap = *bpp;
- *bpp += IN6ADDRSZ;
- }
-}
-
-struct hostent *
-gethostent(void)
-{
- host.h_addrtype = AF_UNSPEC;
- host.h_length = 0;
- return (_gethtent());
-}
-
-#ifdef RESOLVSORT
-static void
-addrsort(char **ap, int num)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- int i, j;
- char **p;
- short aval[MAXADDRS];
- int needsort = 0;
-
- p = ap;
- for (i = 0; i < num; i++, p++) {
- for (j = 0 ; (unsigned)j < _resp->nsort; j++)
- if (_resp->sort_list[j].addr.s_addr ==
- (((struct in_addr *)(*p))->s_addr &
- _resp->sort_list[j].mask))
- break;
- aval[i] = j;
- if (needsort == 0 && i > 0 && j < aval[i-1])
- needsort = i;
- }
- if (!needsort)
- return;
-
- while (needsort < num) {
- for (j = needsort - 1; j >= 0; j--) {
- if (aval[j] > aval[j+1]) {
- char *hp;
-
- i = aval[j];
- aval[j] = aval[j+1];
- aval[j+1] = i;
-
- hp = ap[j];
- ap[j] = ap[j+1];
- ap[j+1] = hp;
- } else
- break;
- }
- needsort++;
- }
-}
-#endif
diff --git a/lib/libc/net/getnameinfo.c b/lib/libc/net/getnameinfo.c
deleted file mode 100644
index 7041a4ee48a..00000000000
--- a/lib/libc/net/getnameinfo.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/* $OpenBSD: getnameinfo.c,v 1.33 2007/02/15 04:25:35 ray Exp $ */
-/* $KAME: getnameinfo.c,v 1.45 2000/09/25 22:43:56 itojun Exp $ */
-
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Issues to be discussed:
- * - Thread safe-ness must be checked
- * - RFC2553 says that we should raise error on short buffer. X/Open says
- * we need to truncate the result. We obey RFC2553 (and X/Open should be
- * modified). ipngwg rough consensus seems to follow RFC2553.
- * - What is "local" in NI_FQDN?
- * - NI_NAMEREQD and NI_NUMERICHOST conflict with each other.
- * - (KAME extension) always attach textual scopeid (fe80::1%lo0), if
- * sin6_scope_id is filled - standardization status?
- * XXX breaks backward compat for code that expects no scopeid.
- * beware on merge.
- */
-
-#ifndef INET6
-#define INET6
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <string.h>
-#include <stddef.h>
-
-#include "thread_private.h"
-
-static const struct afd {
- int a_af;
- int a_addrlen;
- int a_socklen;
- int a_off;
-} afdl [] = {
-#ifdef INET6
- {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
- offsetof(struct sockaddr_in6, sin6_addr)},
-#endif
- {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
- offsetof(struct sockaddr_in, sin_addr)},
- {0, 0, 0},
-};
-
-struct sockinet {
- u_char si_len;
- u_char si_family;
- u_short si_port;
-};
-
-#ifdef INET6
-static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
- size_t, int);
-static int ip6_sa2str(const struct sockaddr_in6 *, char *, size_t, int);
-#endif
-
-void *__THREAD_NAME(serv_mutex);
-
-int
-getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
- size_t hostlen, char *serv, size_t servlen, int flags)
-{
- const struct afd *afd;
- struct hostent *hp;
- u_short port;
- int family, i;
- const char *addr;
- u_int32_t v4a;
- char numserv[512];
- char numaddr[512];
-
- if (sa == NULL)
- return EAI_FAIL;
-
- family = sa->sa_family;
- for (i = 0; afdl[i].a_af; i++)
- if (afdl[i].a_af == family) {
- afd = &afdl[i];
- goto found;
- }
- return EAI_FAMILY;
-
- found:
- if (salen != afd->a_socklen)
- return EAI_FAIL;
-
- /* network byte order */
- port = ((const struct sockinet *)sa)->si_port;
- addr = (const char *)sa + afd->a_off;
-
- if (serv == NULL || servlen == 0) {
- /*
- * do nothing in this case.
- * in case you are wondering if "&&" is more correct than
- * "||" here: rfc2553bis-03 says that serv == NULL OR
- * servlen == 0 means that the caller does not want the result.
- */
- } else if (!(flags & NI_NUMERICSERV)) {
- struct servent sp;
- struct servent_data sd;
-
- (void)memset(&sd, 0, sizeof(sd));
- if (getservbyport_r(port,
- (flags & NI_DGRAM) ? "udp" : "tcp", &sp, &sd) == -1)
- goto numeric;
-
- if (strlen(sp.s_name) + 1 > servlen) {
- endservent_r(&sd);
- return EAI_MEMORY;
- }
- strlcpy(serv, sp.s_name, servlen);
- endservent_r(&sd);
- } else {
- numeric:
- i = snprintf(numserv, sizeof(numserv), "%u", ntohs(port));
- if (i < 0 || i >= servlen || i >= sizeof(numserv))
- return EAI_MEMORY;
- strlcpy(serv, numserv, servlen);
- }
-
- switch (sa->sa_family) {
- case AF_INET:
- v4a = (u_int32_t)
- ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr);
- if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
- flags |= NI_NUMERICHOST;
- v4a >>= IN_CLASSA_NSHIFT;
- if (v4a == 0)
- flags |= NI_NUMERICHOST;
- break;
-#ifdef INET6
- case AF_INET6:
- {
- const struct sockaddr_in6 *sin6;
- sin6 = (const struct sockaddr_in6 *)sa;
- switch (sin6->sin6_addr.s6_addr[0]) {
- case 0x00:
- if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
- ;
- else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
- ;
- else
- flags |= NI_NUMERICHOST;
- break;
- default:
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- flags |= NI_NUMERICHOST;
- }
- else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
- flags |= NI_NUMERICHOST;
- break;
- }
- }
- break;
-#endif
- }
- if (host == NULL || hostlen == 0) {
- /*
- * do nothing in this case.
- * in case you are wondering if "&&" is more correct than
- * "||" here: rfc2553bis-03 says that host == NULL or
- * hostlen == 0 means that the caller does not want the result.
- */
- } else if (flags & NI_NUMERICHOST) {
- int numaddrlen;
-
- /* NUMERICHOST and NAMEREQD conflicts with each other */
- if (flags & NI_NAMEREQD)
- return EAI_NONAME;
-
- switch(afd->a_af) {
-#ifdef INET6
- case AF_INET6:
- {
- int error;
-
- if ((error = ip6_parsenumeric(sa, addr, host,
- hostlen, flags)) != 0)
- return(error);
- break;
- }
-#endif
- default:
- if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
- == NULL)
- return EAI_SYSTEM;
- numaddrlen = strlen(numaddr);
- if (numaddrlen + 1 > hostlen) /* don't forget terminator */
- return EAI_MEMORY;
- strlcpy(host, numaddr, hostlen);
- break;
- }
- } else {
- _THREAD_PRIVATE_MUTEX_LOCK(serv_mutex);
- hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
- _THREAD_PRIVATE_MUTEX_UNLOCK(serv_mutex);
-
- if (hp) {
-#if 0
- /*
- * commented out, since "for local host" is not
- * implemented here - see RFC2553 p30
- */
- if (flags & NI_NOFQDN) {
- char *p;
- p = strchr(hp->h_name, '.');
- if (p)
- *p = '\0';
- }
-#endif
- if (strlen(hp->h_name) + 1 > hostlen) {
- return EAI_MEMORY;
- }
- strlcpy(host, hp->h_name, hostlen);
- } else {
- if (flags & NI_NAMEREQD)
- return EAI_NONAME;
- switch(afd->a_af) {
-#ifdef INET6
- case AF_INET6:
- {
- int error;
-
- if ((error = ip6_parsenumeric(sa, addr, host,
- hostlen,
- flags)) != 0)
- return(error);
- break;
- }
-#endif
- default:
- if (inet_ntop(afd->a_af, addr, host,
- hostlen) == NULL)
- return EAI_SYSTEM;
- break;
- }
- }
- }
- return(0);
-}
-
-#ifdef INET6
-static int
-ip6_parsenumeric(const struct sockaddr *sa, const char *addr, char *host,
- size_t hostlen, int flags)
-{
- int numaddrlen;
- char numaddr[512];
-
- if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) == NULL)
- return EAI_SYSTEM;
-
- numaddrlen = strlen(numaddr);
- if (numaddrlen + 1 > hostlen) /* don't forget terminator */
- return EAI_MEMORY;
- strlcpy(host, numaddr, hostlen);
-
- if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
- char zonebuf[MAXHOSTNAMELEN];
- int zonelen;
-
- zonelen = ip6_sa2str(
- (const struct sockaddr_in6 *)(const void *)sa,
- zonebuf, sizeof(zonebuf), flags);
- if (zonelen < 0)
- return EAI_MEMORY;
- if (zonelen + 1 + numaddrlen + 1 > hostlen)
- return EAI_MEMORY;
-
- /* construct <numeric-addr><delim><zoneid> */
- memcpy(host + numaddrlen + 1, zonebuf,
- (size_t)zonelen);
- host[numaddrlen] = SCOPE_DELIMITER;
- host[numaddrlen + 1 + zonelen] = '\0';
- }
-
- return 0;
-}
-
-/* ARGSUSED */
-static int
-ip6_sa2str(const struct sockaddr_in6 *sa6, char *buf, size_t bufsiz, int flags)
-{
- unsigned int ifindex;
- const struct in6_addr *a6;
- int n;
-
- ifindex = (unsigned int)sa6->sin6_scope_id;
- a6 = &sa6->sin6_addr;
-
-#ifdef notdef
- if ((flags & NI_NUMERICSCOPE) != 0) {
- n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
- if (n < 0 || n >= bufsiz)
- return -1;
- else
- return n;
- }
-#endif
-
- /* if_indextoname() does not take buffer size. not a good api... */
- if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6) ||
- IN6_IS_ADDR_MC_INTFACELOCAL(a6)) && bufsiz >= IF_NAMESIZE) {
- char *p = if_indextoname(ifindex, buf);
- if (p) {
- return(strlen(p));
- }
- }
-
- /* last resort */
- n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
- if (n < 0 || n >= bufsiz)
- return -1;
- else
- return n;
-}
-#endif /* INET6 */
diff --git a/lib/libc/net/getnetnamadr.c b/lib/libc/net/getnetnamadr.c
deleted file mode 100644
index 7b770f1ce70..00000000000
--- a/lib/libc/net/getnetnamadr.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/* $OpenBSD: getnetnamadr.c,v 1.26 2005/08/06 20:30:03 espie Exp $ */
-
-/*
- * Copyright (c) 1997, Jason Downs. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
- * Dep. Matematica Universidade de Coimbra, Portugal, Europe
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-/*
- * Copyright (c) 1983, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-
-#include <stdio.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "thread_private.h"
-
-extern int h_errno;
-
-struct netent *_getnetbyaddr(in_addr_t net, int type);
-struct netent *_getnetbyname(const char *name);
-
-int _hokchar(const char *);
-
-#define BYADDR 0
-#define BYNAME 1
-#define MAXALIASES 35
-
-#define MAXPACKET (64*1024)
-
-typedef union {
- HEADER hdr;
- u_char buf[MAXPACKET];
-} querybuf;
-
-typedef union {
- long al;
- char ac;
-} align;
-
-static struct netent *
-getnetanswer(querybuf *answer, int anslen, int net_i)
-{
-
- HEADER *hp;
- u_char *cp;
- int n;
- u_char *eom;
- int type, class, ancount, qdcount, haveanswer, i, nchar;
- char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];
- char *in, *st, *pauxt, *bp, **ap, *ep;
- char *paux1 = &aux1[0], *paux2 = &aux2[0];
- static struct netent net_entry;
- static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
-
- /*
- * find first satisfactory answer
- *
- * answer --> +------------+ ( MESSAGE )
- * | Header |
- * +------------+
- * | Question | the question for the name server
- * +------------+
- * | Answer | RRs answering the question
- * +------------+
- * | Authority | RRs pointing toward an authority
- * | Additional | RRs holding additional information
- * +------------+
- */
- eom = answer->buf + anslen;
- hp = &answer->hdr;
- ancount = ntohs(hp->ancount); /* #/records in the answer section */
- qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
- bp = netbuf;
- ep = netbuf + sizeof(netbuf);
- cp = answer->buf + HFIXEDSZ;
- if (!qdcount) {
- if (hp->aa)
- h_errno = HOST_NOT_FOUND;
- else
- h_errno = TRY_AGAIN;
- return (NULL);
- }
- while (qdcount-- > 0) {
- n = __dn_skipname(cp, eom);
- if (n < 0 || (cp + n + QFIXEDSZ) > eom) {
- h_errno = NO_RECOVERY;
- return(NULL);
- }
- cp += n + QFIXEDSZ;
- }
- ap = net_aliases;
- *ap = NULL;
- net_entry.n_aliases = net_aliases;
- haveanswer = 0;
- while (--ancount >= 0 && cp < eom) {
- n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
-#ifdef USE_RESOLV_NAME_OK
- if ((n < 0) || !res_dnok(bp))
-#else
- if ((n < 0) || !_hokchar(bp))
-#endif
- break;
- cp += n;
- ans[0] = '\0';
- strlcpy(&ans[0], bp, sizeof ans);
- GETSHORT(type, cp);
- GETSHORT(class, cp);
- cp += INT32SZ; /* TTL */
- GETSHORT(n, cp);
- if (class == C_IN && type == T_PTR) {
- n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
-#ifdef USE_RESOLV_NAME_OK
- if ((n < 0) || !res_hnok(bp))
-#else
- if ((n < 0) || !_hokchar(bp))
-#endif
- {
- cp += n;
- return (NULL);
- }
- cp += n;
- if ((ap + 2) < &net_aliases[MAXALIASES]) {
- *ap++ = bp;
- bp += strlen(bp) + 1;
- net_entry.n_addrtype =
- (class == C_IN) ? AF_INET : AF_UNSPEC;
- haveanswer++;
- }
- }
- }
- if (haveanswer) {
- *ap = NULL;
- switch (net_i) {
- case BYADDR:
- net_entry.n_name = *net_entry.n_aliases;
- net_entry.n_net = 0L;
- break;
- case BYNAME:
- ap = net_entry.n_aliases;
- next_alias:
- in = *ap++;
- if (in == NULL) {
- h_errno = HOST_NOT_FOUND;
- return (NULL);
- }
- net_entry.n_name = ans;
- aux2[0] = '\0';
- for (i = 0; i < 4; i++) {
- for (st = in, nchar = 0;
- isdigit((unsigned char)*st);
- st++, nchar++)
- ;
- if (*st != '.' || nchar == 0 || nchar > 3)
- goto next_alias;
- if (i != 0)
- nchar++;
- strlcpy(paux1, in, nchar+1);
- strlcat(paux1, paux2, MAXHOSTNAMELEN);
- pauxt = paux2;
- paux2 = paux1;
- paux1 = pauxt;
- in = ++st;
- }
- if (strcasecmp(in, "IN-ADDR.ARPA") != 0)
- goto next_alias;
- net_entry.n_net = inet_network(paux2);
- break;
- }
- net_entry.n_aliases++;
- return (&net_entry);
- }
- h_errno = TRY_AGAIN;
- return (NULL);
-}
-
-struct netent *
-getnetbyaddr(in_addr_t net, int net_type)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- unsigned int netbr[4];
- int nn, anslen;
- querybuf *buf;
- char qbuf[MAXDNAME];
- in_addr_t net2;
- struct netent *net_entry = NULL;
- char lookups[MAXDNSLUS];
- int i;
-
- if (_res_init(0) == -1)
- return(_getnetbyaddr(net, net_type));
-
- bcopy(_resp->lookups, lookups, sizeof lookups);
- if (lookups[0] == '\0')
- strlcpy(lookups, "bf", sizeof lookups);
-
- for (i = 0; i < MAXDNSLUS && lookups[i]; i++) {
- switch (lookups[i]) {
-#ifdef YP
- case 'y':
- /* There is no YP support. */
- break;
-#endif /* YP */
- case 'b':
- if (net_type != AF_INET)
- break; /* DNS only supports AF_INET? */
-
- for (nn = 4, net2 = net; net2; net2 >>= 8)
- netbr[--nn] = net2 & 0xff;
- switch (nn) {
- case 3: /* Class A */
- snprintf(qbuf, sizeof(qbuf),
- "0.0.0.%u.in-addr.arpa", netbr[3]);
- break;
- case 2: /* Class B */
- snprintf(qbuf, sizeof(qbuf),
- "0.0.%u.%u.in-addr.arpa",
- netbr[3], netbr[2]);
- break;
- case 1: /* Class C */
- snprintf(qbuf, sizeof(qbuf),
- "0.%u.%u.%u.in-addr.arpa",
- netbr[3], netbr[2], netbr[1]);
- break;
- case 0: /* Class D - E */
- snprintf(qbuf, sizeof(qbuf),
- "%u.%u.%u.%u.in-addr.arpa",
- netbr[3], netbr[2], netbr[1], netbr[0]);
- break;
- }
- buf = malloc(sizeof(*buf));
- if (buf == NULL)
- break;
- anslen = res_query(qbuf, C_IN, T_PTR, buf->buf,
- sizeof(buf->buf));
- if (anslen < 0) {
- free(buf);
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf("res_query failed\n");
-#endif
- break;
- }
- net_entry = getnetanswer(buf, anslen, BYADDR);
- free(buf);
- if (net_entry != NULL) {
- unsigned u_net = net; /* maybe net should be unsigned ? */
-
- /* Strip trailing zeros */
- while ((u_net & 0xff) == 0 && u_net != 0)
- u_net >>= 8;
- net_entry->n_net = u_net;
- return (net_entry);
- }
- break;
- case 'f':
- net_entry = _getnetbyaddr(net, net_type);
- if (net_entry != NULL)
- return (net_entry);
- }
- }
-
- /* Nothing matched. */
- return (NULL);
-}
-
-struct netent *
-getnetbyname(const char *net)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- int anslen;
- querybuf *buf;
- char qbuf[MAXDNAME];
- struct netent *net_entry = NULL;
- char lookups[MAXDNSLUS];
- int i;
-
- if (_res_init(0) == -1)
- return (_getnetbyname(net));
-
- bcopy(_resp->lookups, lookups, sizeof lookups);
- if (lookups[0] == '\0')
- strlcpy(lookups, "bf", sizeof lookups);
-
- for (i = 0; i < MAXDNSLUS && lookups[i]; i++) {
- switch (lookups[i]) {
-#ifdef YP
- case 'y':
- /* There is no YP support. */
- break;
-#endif /* YP */
- case 'b':
- strlcpy(qbuf, net, sizeof qbuf);
- buf = malloc(sizeof(*buf));
- if (buf == NULL)
- break;
- anslen = res_search(qbuf, C_IN, T_PTR, buf->buf,
- sizeof(buf->buf));
- if (anslen < 0) {
- free(buf);
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf("res_query failed\n");
-#endif
- break;
- }
- net_entry = getnetanswer(buf, anslen, BYNAME);
- free(buf);
- if (net_entry != NULL)
- return (net_entry);
- break;
- case 'f':
- net_entry = _getnetbyname(net);
- if (net_entry != NULL)
- return (net_entry);
- break;
- }
- }
-
- /* Nothing matched. */
- return (NULL);
-}
diff --git a/lib/libc/net/getrrsetbyname.c b/lib/libc/net/getrrsetbyname.c
deleted file mode 100644
index 2bbb6ccf83e..00000000000
--- a/lib/libc/net/getrrsetbyname.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/* $OpenBSD: getrrsetbyname.c,v 1.12 2010/06/29 09:22:06 deraadt Exp $ */
-
-/*
- * Copyright (c) 2001 Jakob Schlyter. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Portions Copyright (c) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "thread_private.h"
-
-#define MAXPACKET 1024*64
-
-struct dns_query {
- char *name;
- u_int16_t type;
- u_int16_t class;
- struct dns_query *next;
-};
-
-struct dns_rr {
- char *name;
- u_int16_t type;
- u_int16_t class;
- u_int16_t ttl;
- u_int16_t size;
- void *rdata;
- struct dns_rr *next;
-};
-
-struct dns_response {
- HEADER header;
- struct dns_query *query;
- struct dns_rr *answer;
- struct dns_rr *authority;
- struct dns_rr *additional;
-};
-
-static struct dns_response *parse_dns_response(const u_char *, int);
-static struct dns_query *parse_dns_qsection(const u_char *, int,
- const u_char **, int);
-static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **,
- int);
-
-static void free_dns_query(struct dns_query *);
-static void free_dns_rr(struct dns_rr *);
-static void free_dns_response(struct dns_response *);
-
-static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t);
-
-int
-getrrsetbyname(const char *hostname, unsigned int rdclass,
- unsigned int rdtype, unsigned int flags,
- struct rrsetinfo **res)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- int result;
- struct rrsetinfo *rrset = NULL;
- struct dns_response *response = NULL;
- struct dns_rr *rr;
- struct rdatainfo *rdata;
- int length;
- unsigned int index_ans, index_sig;
- union {
- HEADER hdr;
- u_char buf[MAXPACKET];
- } answer;
-
- /* check for invalid class and type */
- if (rdclass > 0xffff || rdtype > 0xffff) {
- result = ERRSET_INVAL;
- goto fail;
- }
-
- /* don't allow queries of class or type ANY */
- if (rdclass == 0xff || rdtype == 0xff) {
- result = ERRSET_INVAL;
- goto fail;
- }
-
- /* don't allow flags yet, unimplemented */
- if (flags) {
- result = ERRSET_INVAL;
- goto fail;
- }
-
- /* initialize resolver */
- if (_res_init(0) == -1) {
- result = ERRSET_FAIL;
- goto fail;
- }
-
-#ifdef DEBUG
- _resp->options |= RES_DEBUG;
-#endif /* DEBUG */
-
-#ifdef RES_USE_DNSSEC
- /* turn on DNSSEC if EDNS0 is configured */
- if (_resp->options & RES_USE_EDNS0)
- _resp->options |= RES_USE_DNSSEC;
-#endif /* RES_USE_DNSEC */
-
- /* make query */
- length = res_query(hostname, (signed int) rdclass, (signed int) rdtype,
- answer.buf, sizeof(answer.buf));
- if (length < 0) {
- switch(h_errno) {
- case HOST_NOT_FOUND:
- result = ERRSET_NONAME;
- goto fail;
- case NO_DATA:
- result = ERRSET_NODATA;
- goto fail;
- default:
- result = ERRSET_FAIL;
- goto fail;
- }
- }
-
- /* parse result */
- response = parse_dns_response(answer.buf, length);
- if (response == NULL) {
- result = ERRSET_FAIL;
- goto fail;
- }
-
- if (response->header.qdcount != 1) {
- result = ERRSET_FAIL;
- goto fail;
- }
-
- /* initialize rrset */
- rrset = calloc(1, sizeof(struct rrsetinfo));
- if (rrset == NULL) {
- result = ERRSET_NOMEMORY;
- goto fail;
- }
- rrset->rri_rdclass = response->query->class;
- rrset->rri_rdtype = response->query->type;
- rrset->rri_ttl = response->answer->ttl;
- rrset->rri_nrdatas = response->header.ancount;
-
- /* check for authenticated data */
- if (response->header.ad == 1)
- rrset->rri_flags |= RRSET_VALIDATED;
-
- /* copy name from answer section */
- rrset->rri_name = strdup(response->answer->name);
- if (rrset->rri_name == NULL) {
- result = ERRSET_NOMEMORY;
- goto fail;
- }
-
- /* count answers */
- rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass,
- rrset->rri_rdtype);
- rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass,
- T_RRSIG);
-
- /* allocate memory for answers */
- rrset->rri_rdatas = calloc(rrset->rri_nrdatas,
- sizeof(struct rdatainfo));
- if (rrset->rri_rdatas == NULL) {
- result = ERRSET_NOMEMORY;
- goto fail;
- }
-
- /* allocate memory for signatures */
- rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo));
- if (rrset->rri_sigs == NULL) {
- result = ERRSET_NOMEMORY;
- goto fail;
- }
-
- /* copy answers & signatures */
- for (rr = response->answer, index_ans = 0, index_sig = 0;
- rr; rr = rr->next) {
-
- rdata = NULL;
-
- if (rr->class == rrset->rri_rdclass &&
- rr->type == rrset->rri_rdtype)
- rdata = &rrset->rri_rdatas[index_ans++];
-
- if (rr->class == rrset->rri_rdclass &&
- rr->type == T_RRSIG)
- rdata = &rrset->rri_sigs[index_sig++];
-
- if (rdata) {
- rdata->rdi_length = rr->size;
- rdata->rdi_data = malloc(rr->size);
-
- if (rdata->rdi_data == NULL) {
- result = ERRSET_NOMEMORY;
- goto fail;
- }
- memcpy(rdata->rdi_data, rr->rdata, rr->size);
- }
- }
- free_dns_response(response);
-
- *res = rrset;
- return (ERRSET_SUCCESS);
-
-fail:
- if (rrset != NULL)
- freerrset(rrset);
- if (response != NULL)
- free_dns_response(response);
- return (result);
-}
-
-void
-freerrset(struct rrsetinfo *rrset)
-{
- u_int16_t i;
-
- if (rrset == NULL)
- return;
-
- if (rrset->rri_rdatas) {
- for (i = 0; i < rrset->rri_nrdatas; i++) {
- if (rrset->rri_rdatas[i].rdi_data == NULL)
- break;
- free(rrset->rri_rdatas[i].rdi_data);
- }
- free(rrset->rri_rdatas);
- }
-
- if (rrset->rri_sigs) {
- for (i = 0; i < rrset->rri_nsigs; i++) {
- if (rrset->rri_sigs[i].rdi_data == NULL)
- break;
- free(rrset->rri_sigs[i].rdi_data);
- }
- free(rrset->rri_sigs);
- }
-
- if (rrset->rri_name)
- free(rrset->rri_name);
- free(rrset);
-}
-
-/*
- * DNS response parsing routines
- */
-static struct dns_response *
-parse_dns_response(const u_char *answer, int size)
-{
- struct dns_response *resp;
- const u_char *cp;
-
- /* allocate memory for the response */
- resp = calloc(1, sizeof(*resp));
- if (resp == NULL)
- return (NULL);
-
- /* initialize current pointer */
- cp = answer;
-
- /* copy header */
- memcpy(&resp->header, cp, HFIXEDSZ);
- cp += HFIXEDSZ;
-
- /* fix header byte order */
- resp->header.qdcount = ntohs(resp->header.qdcount);
- resp->header.ancount = ntohs(resp->header.ancount);
- resp->header.nscount = ntohs(resp->header.nscount);
- resp->header.arcount = ntohs(resp->header.arcount);
-
- /* there must be at least one query */
- if (resp->header.qdcount < 1) {
- free_dns_response(resp);
- return (NULL);
- }
-
- /* parse query section */
- resp->query = parse_dns_qsection(answer, size, &cp,
- resp->header.qdcount);
- if (resp->header.qdcount && resp->query == NULL) {
- free_dns_response(resp);
- return (NULL);
- }
-
- /* parse answer section */
- resp->answer = parse_dns_rrsection(answer, size, &cp,
- resp->header.ancount);
- if (resp->header.ancount && resp->answer == NULL) {
- free_dns_response(resp);
- return (NULL);
- }
-
- /* parse authority section */
- resp->authority = parse_dns_rrsection(answer, size, &cp,
- resp->header.nscount);
- if (resp->header.nscount && resp->authority == NULL) {
- free_dns_response(resp);
- return (NULL);
- }
-
- /* parse additional section */
- resp->additional = parse_dns_rrsection(answer, size, &cp,
- resp->header.arcount);
- if (resp->header.arcount && resp->additional == NULL) {
- free_dns_response(resp);
- return (NULL);
- }
-
- return (resp);
-}
-
-static struct dns_query *
-parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count)
-{
- struct dns_query *head, *curr, *prev;
- int i, length;
- char name[MAXDNAME];
-
- for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
-
- /* allocate and initialize struct */
- curr = calloc(1, sizeof(struct dns_query));
- if (curr == NULL) {
- free_dns_query(head);
- return (NULL);
- }
- if (head == NULL)
- head = curr;
- if (prev != NULL)
- prev->next = curr;
-
- /* name */
- length = dn_expand(answer, answer + size, *cp, name,
- sizeof(name));
- if (length < 0) {
- free_dns_query(head);
- return (NULL);
- }
- curr->name = strdup(name);
- if (curr->name == NULL) {
- free_dns_query(head);
- return (NULL);
- }
- *cp += length;
-
- /* type */
- curr->type = _getshort(*cp);
- *cp += INT16SZ;
-
- /* class */
- curr->class = _getshort(*cp);
- *cp += INT16SZ;
- }
-
- return (head);
-}
-
-static struct dns_rr *
-parse_dns_rrsection(const u_char *answer, int size, const u_char **cp,
- int count)
-{
- struct dns_rr *head, *curr, *prev;
- int i, length;
- char name[MAXDNAME];
-
- for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
-
- /* allocate and initialize struct */
- curr = calloc(1, sizeof(struct dns_rr));
- if (curr == NULL) {
- free_dns_rr(head);
- return (NULL);
- }
- if (head == NULL)
- head = curr;
- if (prev != NULL)
- prev->next = curr;
-
- /* name */
- length = dn_expand(answer, answer + size, *cp, name,
- sizeof(name));
- if (length < 0) {
- free_dns_rr(head);
- return (NULL);
- }
- curr->name = strdup(name);
- if (curr->name == NULL) {
- free_dns_rr(head);
- return (NULL);
- }
- *cp += length;
-
- /* type */
- curr->type = _getshort(*cp);
- *cp += INT16SZ;
-
- /* class */
- curr->class = _getshort(*cp);
- *cp += INT16SZ;
-
- /* ttl */
- curr->ttl = _getlong(*cp);
- *cp += INT32SZ;
-
- /* rdata size */
- curr->size = _getshort(*cp);
- *cp += INT16SZ;
-
- /* rdata itself */
- curr->rdata = malloc(curr->size);
- if (curr->rdata == NULL) {
- free_dns_rr(head);
- return (NULL);
- }
- memcpy(curr->rdata, *cp, curr->size);
- *cp += curr->size;
- }
-
- return (head);
-}
-
-static void
-free_dns_query(struct dns_query *p)
-{
- if (p == NULL)
- return;
-
- if (p->name)
- free(p->name);
- free_dns_query(p->next);
- free(p);
-}
-
-static void
-free_dns_rr(struct dns_rr *p)
-{
- if (p == NULL)
- return;
-
- if (p->name)
- free(p->name);
- if (p->rdata)
- free(p->rdata);
- free_dns_rr(p->next);
- free(p);
-}
-
-static void
-free_dns_response(struct dns_response *p)
-{
- if (p == NULL)
- return;
-
- free_dns_query(p->query);
- free_dns_rr(p->answer);
- free_dns_rr(p->authority);
- free_dns_rr(p->additional);
- free(p);
-}
-
-static int
-count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type)
-{
- int n = 0;
-
- while(p) {
- if (p->class == class && p->type == type)
- n++;
- p = p->next;
- }
-
- return (n);
-}
diff --git a/lib/libc/net/res_debug.c b/lib/libc/net/res_debug.c
deleted file mode 100644
index 246fefef3c4..00000000000
--- a/lib/libc/net/res_debug.c
+++ /dev/null
@@ -1,1395 +0,0 @@
-/* $OpenBSD: res_debug.c,v 1.22 2007/10/11 18:36:41 jakob Exp $ */
-
-/*
- * ++Copyright++ 1985, 1990, 1993
- * -
- * Copyright (c) 1985, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * Portions Copyright (c) 1995 by International Business Machines, Inc.
- *
- * International Business Machines, Inc. (hereinafter called IBM) grants
- * permission under its copyrights to use, copy, modify, and distribute this
- * Software with or without fee, provided that the above copyright notice and
- * all paragraphs of this notice appear in all copies, and that the name of IBM
- * not be used in connection with the marketing of any product incorporating
- * the Software or modifications thereof, without specific, written prior
- * permission.
- *
- * To the extent it has a right to do so, IBM grants an immunity from suit
- * under its patents, if any, for the use, sale or manufacture of products to
- * the extent that such products are used for performing Domain Name System
- * dynamic updates in TCP/IP networks by means of the Software. No immunity is
- * granted for any product per se or for any other function of any product.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
- * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
- * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
- * --Copyright--
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-
-#include <ctype.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <stdio.h>
-#include <time.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "thread_private.h"
-
-extern const char *_res_opcodes[];
-extern const char *_res_resultcodes[];
-
-static const char *loc_ntoal(const u_char *binary, char *ascii, int ascii_len);
-
-/* XXX: we should use getservbyport() instead. */
-static const char *
-dewks(int wks)
-{
- static char nbuf[20];
-
- switch (wks) {
- case 5: return "rje";
- case 7: return "echo";
- case 9: return "discard";
- case 11: return "systat";
- case 13: return "daytime";
- case 15: return "netstat";
- case 17: return "qotd";
- case 19: return "chargen";
- case 20: return "ftp-data";
- case 21: return "ftp";
- case 23: return "telnet";
- case 25: return "smtp";
- case 37: return "time";
- case 39: return "rlp";
- case 42: return "name";
- case 43: return "whois";
- case 53: return "domain";
- case 57: return "apts";
- case 59: return "apfs";
- case 67: return "bootps";
- case 68: return "bootpc";
- case 69: return "tftp";
- case 77: return "rje";
- case 79: return "finger";
- case 87: return "link";
- case 95: return "supdup";
- case 100: return "newacct";
- case 101: return "hostnames";
- case 102: return "iso-tsap";
- case 103: return "x400";
- case 104: return "x400-snd";
- case 105: return "csnet-ns";
- case 109: return "pop-2";
- case 111: return "sunrpc";
- case 113: return "auth";
- case 115: return "sftp";
- case 117: return "uucp-path";
- case 119: return "nntp";
- case 121: return "erpc";
- case 123: return "ntp";
- case 133: return "statsrv";
- case 136: return "profile";
- case 144: return "NeWS";
- case 161: return "snmp";
- case 162: return "snmp-trap";
- case 170: return "print-srv";
- default:
- (void) snprintf(nbuf, sizeof nbuf, "%d", wks);
- return (nbuf);
- }
-}
-
-/* XXX: we should use getprotobynumber() instead. */
-static const char *
-deproto(int protonum)
-{
- static char nbuf[20];
-
- switch (protonum) {
- case 1: return "icmp";
- case 2: return "igmp";
- case 3: return "ggp";
- case 5: return "st";
- case 6: return "tcp";
- case 7: return "ucl";
- case 8: return "egp";
- case 9: return "igp";
- case 11: return "nvp-II";
- case 12: return "pup";
- case 16: return "chaos";
- case 17: return "udp";
- default:
- (void) snprintf(nbuf, sizeof nbuf, "%d", protonum);
- return (nbuf);
- }
-}
-
-static const u_char *
-do_rrset(const u_char *msg, int len, const u_char *cp, int cnt, int pflag,
- FILE *file, const char *hs)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- int n;
- int sflag;
-
- /*
- * Print answer records.
- */
- sflag = (_resp->pfcode & pflag);
- if ((n = ntohs(cnt))) {
- if ((!_resp->pfcode) ||
- ((sflag) && (_resp->pfcode & RES_PRF_HEAD1)))
- fprintf(file, "%s", hs);
- while (--n >= 0) {
- if ((!_resp->pfcode) || sflag) {
- cp = p_rr(cp, msg, file);
- } else {
- unsigned int dlen;
- cp += __dn_skipname(cp, cp + MAXCDNAME);
- cp += INT16SZ;
- cp += INT16SZ;
- cp += INT32SZ;
- dlen = _getshort((u_char*)cp);
- cp += INT16SZ;
- cp += dlen;
- }
- if ((cp - msg) > len)
- return (NULL);
- }
- if ((!_resp->pfcode) ||
- ((sflag) && (_resp->pfcode & RES_PRF_HEAD1)))
- putc('\n', file);
- }
- return (cp);
-}
-
-void
-__p_query(const u_char *msg)
-{
- __fp_query(msg, stdout);
-}
-
-/*
- * Print the current options.
- * This is intended to be primarily a debugging routine.
- */
-void
-__fp_resstat(struct __res_state *statp, FILE *file)
-{
- u_long mask;
-
- fprintf(file, ";; res options:");
- if (!statp)
- statp = &_res;
- for (mask = 1; mask != 0; mask <<= 1)
- if (statp->options & mask)
- fprintf(file, " %s", p_option(mask));
- putc('\n', file);
-}
-
-/*
- * Print the contents of a query.
- * This is intended to be primarily a debugging routine.
- */
-void
-__fp_nquery(const u_char *msg, int len, FILE *file)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- const u_char *cp, *endMark;
- const HEADER *hp;
- int n;
-
- if (_res_init(0) == -1)
- return;
-
-#define TruncTest(x) if (x > endMark) goto trunc
-#define ErrorTest(x) if (x == NULL) goto error
-
- /*
- * Print header fields.
- */
- hp = (HEADER *)msg;
- cp = msg + HFIXEDSZ;
- endMark = msg + len;
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEADX) || hp->rcode) {
- fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %u",
- _res_opcodes[hp->opcode],
- _res_resultcodes[hp->rcode],
- ntohs(hp->id));
- putc('\n', file);
- }
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEADX))
- putc(';', file);
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEAD2)) {
- fprintf(file, "; flags:");
- if (hp->qr)
- fprintf(file, " qr");
- if (hp->aa)
- fprintf(file, " aa");
- if (hp->tc)
- fprintf(file, " tc");
- if (hp->rd)
- fprintf(file, " rd");
- if (hp->ra)
- fprintf(file, " ra");
- if (hp->unused)
- fprintf(file, " UNUSED-BIT-ON");
- if (hp->ad)
- fprintf(file, " ad");
- if (hp->cd)
- fprintf(file, " cd");
- }
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEAD1)) {
- fprintf(file, "; Ques: %u", ntohs(hp->qdcount));
- fprintf(file, ", Ans: %u", ntohs(hp->ancount));
- fprintf(file, ", Auth: %u", ntohs(hp->nscount));
- fprintf(file, ", Addit: %u", ntohs(hp->arcount));
- }
- if ((!_resp->pfcode) || (_resp->pfcode &
- (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
- putc('\n',file);
- }
- /*
- * Print question records.
- */
- if ((n = ntohs(hp->qdcount))) {
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
- fprintf(file, ";; QUESTIONS:\n");
- while (--n >= 0) {
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
- fprintf(file, ";;\t");
- TruncTest(cp);
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
- cp = p_cdnname(cp, msg, len, file);
- else {
- int n;
- char name[MAXDNAME];
-
- if ((n = dn_expand(msg, msg+len, cp, name,
- sizeof name)) < 0)
- cp = NULL;
- else
- cp += n;
- }
- ErrorTest(cp);
- TruncTest(cp);
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
- fprintf(file, ", type = %s",
- __p_type(_getshort((u_char*)cp)));
- cp += INT16SZ;
- TruncTest(cp);
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
- fprintf(file, ", class = %s\n",
- __p_class(_getshort((u_char*)cp)));
- cp += INT16SZ;
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
- putc('\n', file);
- }
- }
- /*
- * Print authoritative answer records
- */
- TruncTest(cp);
- cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
- ";; ANSWERS:\n");
- ErrorTest(cp);
-
- /*
- * print name server records
- */
- TruncTest(cp);
- cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
- ";; AUTHORITY RECORDS:\n");
- ErrorTest(cp);
-
- TruncTest(cp);
- /*
- * print additional records
- */
- cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
- ";; ADDITIONAL RECORDS:\n");
- ErrorTest(cp);
- return;
- trunc:
- fprintf(file, "\n;; ...truncated\n");
- return;
- error:
- fprintf(file, "\n;; ...malformed\n");
-}
-
-void
-__fp_query(const u_char *msg, FILE *file)
-{
- fp_nquery(msg, PACKETSZ, file);
-}
-
-const u_char *
-__p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file)
-{
- char name[MAXDNAME];
- int n;
-
- if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
- return (NULL);
- if (name[0] == '\0')
- putc('.', file);
- else
- fputs(name, file);
- return (cp + n);
-}
-
-const u_char *
-__p_cdname(const u_char *cp, const u_char *msg, FILE *file)
-{
- return (p_cdnname(cp, msg, PACKETSZ, file));
-}
-
-
-/* Return a fully-qualified domain name from a compressed name (with
- length supplied). */
-
-const u_char *
-__p_fqnname(const u_char *cp, const u_char *msg, int msglen, char *name, int namelen)
-{
- int n, newlen;
-
- if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
- return (NULL);
- newlen = strlen(name);
- if (newlen == 0 || name[newlen - 1] != '.') {
- if (newlen + 1 >= namelen) /* Lack space for final dot */
- return (NULL);
- else
- strlcpy(name + newlen, ".", namelen - newlen);
- }
- return (cp + n);
-}
-
-/* XXX: the rest of these functions need to become length-limited, too. (vix)
- */
-
-const u_char *
-__p_fqname(const u_char *cp, const u_char *msg, FILE *file)
-{
- char name[MAXDNAME];
- const u_char *n;
-
- n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
- if (n == NULL)
- return (NULL);
- fputs(name, file);
- return (n);
-}
-
-/*
- * Print resource record fields in human readable form.
- */
-const u_char *
-__p_rr(const u_char *cp, const u_char *msg, FILE *file)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- int type, class, dlen, n, c;
- struct in_addr inaddr;
- const u_char *cp1, *cp2;
- u_int32_t tmpttl, t;
- int lcnt;
- u_int16_t keyflags;
- char rrname[MAXDNAME]; /* The fqdn of this RR */
- char base64_key[MAX_KEY_BASE64];
-
- if (_res_init(0) == -1) {
- h_errno = NETDB_INTERNAL;
- return (NULL);
- }
- cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
- if (!cp)
- return (NULL); /* compression error */
- fputs(rrname, file);
-
- type = _getshort((u_char*)cp);
- cp += INT16SZ;
- class = _getshort((u_char*)cp);
- cp += INT16SZ;
- tmpttl = _getlong((u_char*)cp);
- cp += INT32SZ;
- dlen = _getshort((u_char*)cp);
- cp += INT16SZ;
- cp1 = cp;
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_TTLID))
- fprintf(file, "\t%lu", (u_long)tmpttl);
- if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_CLASS))
- fprintf(file, "\t%s", __p_class(class));
- fprintf(file, "\t%s", __p_type(type));
- /*
- * Print type specific data, if appropriate
- */
- switch (type) {
- case T_A:
- switch (class) {
- case C_IN:
- case C_HS:
- bcopy(cp, (char *)&inaddr, INADDRSZ);
- if (dlen == 4) {
- fprintf(file, "\t%s", inet_ntoa(inaddr));
- cp += dlen;
- } else if (dlen == 7) {
- char *address;
- u_char protocol;
- in_port_t port;
-
- address = inet_ntoa(inaddr);
- cp += INADDRSZ;
- protocol = *(u_char*)cp;
- cp += sizeof (u_char);
- port = _getshort((u_char*)cp);
- cp += INT16SZ;
- fprintf(file, "\t%s\t; proto %u, port %u",
- address, protocol, port);
- }
- break;
- default:
- cp += dlen;
- }
- break;
- case T_CNAME:
- case T_MB:
- case T_MG:
- case T_MR:
- case T_NS:
- case T_PTR:
- putc('\t', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
-
- case T_HINFO:
- case T_ISDN:
- cp2 = cp + dlen;
- (void) fputs("\t\"", file);
- if ((n = (unsigned char) *cp++) != 0) {
- for (c = n; c > 0 && cp < cp2; c--) {
- if (strchr("\n\"\\", *cp))
- (void) putc('\\', file);
- (void) putc(*cp++, file);
- }
- }
- putc('"', file);
- if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
- (void) fputs ("\t\"", file);
- for (c = n; c > 0 && cp < cp2; c--) {
- if (strchr("\n\"\\", *cp))
- (void) putc('\\', file);
- (void) putc(*cp++, file);
- }
- putc('"', file);
- } else if (type == T_HINFO) {
- (void) fputs("\"?\"", file);
- fprintf(file, "\n;; *** Warning *** OS-type missing");
- }
- break;
-
- case T_SOA:
- putc('\t', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- putc(' ', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- fputs(" (\n", file);
- t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
- t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
- (u_long)t, __p_time(t));
- t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
- (u_long)t, __p_time(t));
- t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
- (u_long)t, __p_time(t));
- t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
- (u_long)t, __p_time(t));
- break;
-
- case T_MX:
- case T_AFSDB:
- case T_RT:
- fprintf(file, "\t%u ", _getshort((u_char*)cp));
- cp += INT16SZ;
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
-
- case T_PX:
- fprintf(file, "\t%u ", _getshort((u_char*)cp));
- cp += INT16SZ;
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- putc(' ', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
-
- case T_X25:
- cp2 = cp + dlen;
- (void) fputs("\t\"", file);
- if ((n = (unsigned char) *cp++) != 0) {
- for (c = n; c > 0 && cp < cp2; c--) {
- if (strchr("\n\"\\", *cp))
- (void) putc('\\', file);
- (void) putc(*cp++, file);
- }
- }
- putc('"', file);
- break;
-
- case T_TXT:
- (void) putc('\t', file);
- cp2 = cp1 + dlen;
- while (cp < cp2) {
- putc('"', file);
- if ((n = (unsigned char) *cp++)) {
- for (c = n; c > 0 && cp < cp2; c--) {
- if (strchr("\n\"\\", *cp))
- (void) putc('\\', file);
- (void) putc(*cp++, file);
- }
- }
- putc('"', file);
- if (cp < cp2)
- putc(' ', file);
- }
- break;
-
- case T_NSAP:
- (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
- cp += dlen;
- break;
-
- case T_AAAA: {
- char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
-
- fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));
- cp += dlen;
- break;
- }
-
- case T_LOC: {
- char t[255];
-
- fprintf(file, "\t%s", loc_ntoal(cp, t, sizeof t));
- cp += dlen;
- break;
- }
-
- case T_NAPTR: {
- u_int order, preference;
-
- order = _getshort(cp); cp += INT16SZ;
- preference = _getshort(cp); cp += INT16SZ;
- fprintf(file, "\t%u %u ",order, preference);
- /* Flags */
- n = *cp++;
- fprintf(file,"\"%.*s\" ", (int)n, cp);
- cp += n;
- /* Service */
- n = *cp++;
- fprintf(file,"\"%.*s\" ", (int)n, cp);
- cp += n;
- /* Regexp */
- n = *cp++;
- fprintf(file,"\"%.*s\" ", (int)n, cp);
- cp += n;
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
- }
-
- case T_SRV: {
- u_int priority, weight, port;
-
- priority = _getshort(cp); cp += INT16SZ;
- weight = _getshort(cp); cp += INT16SZ;
- port = _getshort(cp); cp += INT16SZ;
- fprintf(file, "\t%u %u %u ", priority, weight, port);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
- }
-
- case T_MINFO:
- case T_RP:
- putc('\t', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- putc(' ', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
-
- case T_UINFO:
- putc('\t', file);
- fputs((char *)cp, file);
- cp += dlen;
- break;
-
- case T_UID:
- case T_GID:
- if (dlen == 4) {
- fprintf(file, "\t%u", _getlong((u_char*)cp));
- cp += INT32SZ;
- }
- break;
-
- case T_WKS:
- if (dlen < INT32SZ + 1)
- break;
- bcopy(cp, (char *)&inaddr, INADDRSZ);
- cp += INT32SZ;
- fprintf(file, "\t%s %s ( ",
- inet_ntoa(inaddr),
- deproto((int) *cp));
- cp += sizeof (u_char);
- n = 0;
- lcnt = 0;
- while (cp < cp1 + dlen) {
- c = *cp++;
- do {
- if (c & 0200) {
- if (lcnt == 0) {
- fputs("\n\t\t\t", file);
- lcnt = 5;
- }
- fputs(dewks(n), file);
- putc(' ', file);
- lcnt--;
- }
- c <<= 1;
- } while (++n & 07);
- }
- putc(')', file);
- break;
-
- case T_KEY:
- putc('\t', file);
- keyflags = _getshort(cp);
- cp += 2;
- fprintf(file,"0x%04x", keyflags ); /* flags */
- fprintf(file," %u", *cp++); /* protocol */
- fprintf(file," %u (", *cp++); /* algorithm */
-
- n = b64_ntop(cp, (cp1 + dlen) - cp,
- base64_key, sizeof base64_key);
- for (c = 0; c < n; ++c) {
- if (0 == (c & 0x3F))
- fprintf(file, "\n\t");
- putc(base64_key[c], file); /* public key data */
- }
-
- fprintf(file, " )");
- if (n < 0)
- fprintf(file, "\t; BAD BASE64");
- fflush(file);
- cp = cp1 + dlen;
- break;
-
- case T_SIG:
- case T_RRSIG:
- type = _getshort((u_char*)cp);
- cp += INT16SZ;
- fprintf(file, " %s", p_type(type));
- fprintf(file, "\t%u", *cp++); /* algorithm */
- /* Check label value and print error if wrong. */
- n = *cp++;
- c = dn_count_labels (rrname);
- if (n != c)
- fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
- n, c);
- /* orig ttl */
- n = _getlong((u_char*)cp);
- if (n != tmpttl)
- fprintf(file, " %u", n);
- cp += INT32SZ;
- /* sig expire */
- fprintf(file, " (\n\t%s",
- __p_secstodate(_getlong((u_char*)cp)));
- cp += INT32SZ;
- /* time signed */
- fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
- cp += INT32SZ;
- /* sig footprint */
- fprintf(file," %u ", _getshort((u_char*)cp));
- cp += INT16SZ;
- /* signer's name */
- cp = p_fqname(cp, msg, file);
- n = b64_ntop(cp, (cp1 + dlen) - cp,
- base64_key, sizeof base64_key);
- for (c = 0; c < n; c++) {
- if (0 == (c & 0x3F))
- fprintf (file, "\n\t");
- putc(base64_key[c], file); /* signature */
- }
- /* Clean up... */
- fprintf(file, " )");
- if (n < 0)
- fprintf(file, "\t; BAD BASE64");
- fflush(file);
- cp = cp1+dlen;
- break;
-
-#ifdef ALLOW_T_UNSPEC
- case T_UNSPEC:
- {
- int NumBytes = 8;
- u_char *DataPtr;
- int i;
-
- if (dlen < NumBytes) NumBytes = dlen;
- fprintf(file, "\tFirst %d bytes of hex data:",
- NumBytes);
- for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
- fprintf(file, " %x", *DataPtr);
- cp += dlen;
- }
- break;
-#endif /* ALLOW_T_UNSPEC */
-
- default:
- fprintf(file, "\t?%d?", type);
- cp += dlen;
- }
-#if 0
- fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
-#else
- putc('\n', file);
-#endif
- if (cp - cp1 != dlen) {
- fprintf(file, ";; packet size error (found %ld, dlen was %d)\n",
- (long)(cp - cp1), dlen);
- cp = NULL;
- }
- return (cp);
-}
-
-int
-__sym_ston(const struct res_sym *syms, char *name, int *success)
-{
- for (; syms->name != 0; syms++) {
- if (strcasecmp (name, syms->name) == 0) {
- if (success)
- *success = 1;
- return (syms->number);
- }
- }
- if (success)
- *success = 0;
- return (syms->number); /* The default value. */
-}
-
-
-const char *
-__sym_ntop(const struct res_sym *syms, int number, int *success)
-{
- static char unname[20];
-
- for (; syms->name != 0; syms++) {
- if (number == syms->number) {
- if (success)
- *success = 1;
- return (syms->humanname);
- }
- }
- snprintf(unname, sizeof unname, "%d", number);
- if (success)
- *success = 0;
- return (unname);
-}
-
-/*
- * Return a mnemonic for an option
- */
-const char *
-__p_option(u_long option)
-{
- static char nbuf[40];
-
- switch (option) {
- case RES_INIT: return "init";
- case RES_DEBUG: return "debug";
- case RES_AAONLY: return "aaonly(unimpl)";
- case RES_USEVC: return "usevc";
- case RES_PRIMARY: return "primry(unimpl)";
- case RES_IGNTC: return "igntc";
- case RES_RECURSE: return "recurs";
- case RES_DEFNAMES: return "defnam";
- case RES_STAYOPEN: return "styopn";
- case RES_DNSRCH: return "dnsrch";
- case RES_INSECURE1: return "insecure1";
- case RES_INSECURE2: return "insecure2";
- case RES_USE_INET6: return "inet6";
- case RES_USE_EDNS0: return "edns0";
- default:
- snprintf(nbuf, sizeof nbuf, "?0x%lx?", (u_long)option);
- return (nbuf);
- }
-}
-
-/*
- * Return a mnemonic for a time to live
- */
-const char *
-p_time(u_int32_t value)
-{
- static char nbuf[40];
- char *ebuf;
- int secs, mins, hours, days;
- char *p;
- int tmp;
-
- if (value == 0) {
- strlcpy(nbuf, "0 secs", sizeof nbuf);
- return (nbuf);
- }
-
- secs = value % 60;
- value /= 60;
- mins = value % 60;
- value /= 60;
- hours = value % 24;
- value /= 24;
- days = value;
- value = 0;
-
-#define PLURALIZE(x) x, (x == 1) ? "" : "s"
- p = nbuf;
- ebuf = nbuf + sizeof(nbuf);
- if (days) {
- if ((tmp = snprintf(p, ebuf - p, "%d day%s",
- PLURALIZE(days))) >= ebuf - p || tmp < 0)
- goto full;
- p += tmp;
- }
- if (hours) {
- if (days)
- *p++ = ' ';
- if (p >= ebuf)
- goto full;
- if ((tmp = snprintf(p, ebuf - p, "%d hour%s",
- PLURALIZE(hours))) >= ebuf - p || tmp < 0)
- goto full;
- p += tmp;
- }
- if (mins) {
- if (days || hours)
- *p++ = ' ';
- if (p >= ebuf)
- goto full;
- if ((tmp = snprintf(p, ebuf - p, "%d min%s",
- PLURALIZE(mins))) >= ebuf - p || tmp < 0)
- goto full;
- p += tmp;
- }
- if (secs || ! (days || hours || mins)) {
- if (days || hours || mins)
- *p++ = ' ';
- if (p >= ebuf)
- goto full;
- if ((tmp = snprintf(p, ebuf - p, "%d sec%s",
- PLURALIZE(secs))) >= ebuf - p || tmp < 0)
- goto full;
- }
- return (nbuf);
-full:
- p = nbuf + sizeof(nbuf) - 4;
- *p++ = '.';
- *p++ = '.';
- *p++ = '.';
- *p++ = '\0';
- return (nbuf);
-}
-
-/*
- * routines to convert between on-the-wire RR format and zone file format.
- * Does not contain conversion to/from decimal degrees; divide or multiply
- * by 60*60*1000 for that.
- */
-
-static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
- 1000000,10000000,100000000,1000000000};
-
-/* takes an XeY precision/size value, returns a string representation. */
-static const char *
-precsize_ntoa(u_int8_t prec)
-{
- static char retbuf[sizeof "90000000.00"];
- unsigned long val;
- int mantissa, exponent;
-
- mantissa = (int)((prec >> 4) & 0x0f) % 10;
- exponent = (int)((prec >> 0) & 0x0f) % 10;
-
- val = mantissa * poweroften[exponent];
-
- (void) snprintf(retbuf, sizeof retbuf, "%ld.%.2ld", val/100, val%100);
- return (retbuf);
-}
-
-/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
-static u_int8_t
-precsize_aton(char **strptr)
-{
- unsigned int mval = 0, cmval = 0;
- u_int8_t retval = 0;
- char *cp;
- int exponent;
- int mantissa;
-
- cp = *strptr;
-
- while (isdigit(*cp))
- mval = mval * 10 + (*cp++ - '0');
-
- if (*cp == '.') { /* centimeters */
- cp++;
- if (isdigit(*cp)) {
- cmval = (*cp++ - '0') * 10;
- if (isdigit(*cp)) {
- cmval += (*cp++ - '0');
- }
- }
- }
- cmval = (mval * 100) + cmval;
-
- for (exponent = 0; exponent < 9; exponent++)
- if (cmval < poweroften[exponent+1])
- break;
-
- mantissa = cmval / poweroften[exponent];
- if (mantissa > 9)
- mantissa = 9;
-
- retval = (mantissa << 4) | exponent;
-
- *strptr = cp;
-
- return (retval);
-}
-
-/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
-static u_int32_t
-latlon2ul(char **latlonstrptr, int *which)
-{
- char *cp;
- u_int32_t retval;
- int deg = 0, min = 0, secs = 0, secsfrac = 0;
-
- cp = *latlonstrptr;
-
- while (isdigit(*cp))
- deg = deg * 10 + (*cp++ - '0');
-
- while (isspace(*cp))
- cp++;
-
- if (!(isdigit(*cp)))
- goto fndhemi;
-
- while (isdigit(*cp))
- min = min * 10 + (*cp++ - '0');
-
- while (isspace(*cp))
- cp++;
-
- if (!(isdigit(*cp)))
- goto fndhemi;
-
- while (isdigit(*cp))
- secs = secs * 10 + (*cp++ - '0');
-
- if (*cp == '.') { /* decimal seconds */
- cp++;
- if (isdigit(*cp)) {
- secsfrac = (*cp++ - '0') * 100;
- if (isdigit(*cp)) {
- secsfrac += (*cp++ - '0') * 10;
- if (isdigit(*cp)) {
- secsfrac += (*cp++ - '0');
- }
- }
- }
- }
-
- while (!isspace(*cp)) /* if any trailing garbage */
- cp++;
-
- while (isspace(*cp))
- cp++;
-
- fndhemi:
- switch (*cp) {
- case 'N': case 'n':
- case 'E': case 'e':
- retval = ((unsigned)1<<31)
- + (((((deg * 60) + min) * 60) + secs) * 1000)
- + secsfrac;
- break;
- case 'S': case 's':
- case 'W': case 'w':
- retval = ((unsigned)1<<31)
- - (((((deg * 60) + min) * 60) + secs) * 1000)
- - secsfrac;
- break;
- default:
- retval = 0; /* invalid value -- indicates error */
- break;
- }
-
- switch (*cp) {
- case 'N': case 'n':
- case 'S': case 's':
- *which = 1; /* latitude */
- break;
- case 'E': case 'e':
- case 'W': case 'w':
- *which = 2; /* longitude */
- break;
- default:
- *which = 0; /* error */
- break;
- }
-
- cp++; /* skip the hemisphere */
-
- while (!isspace(*cp)) /* if any trailing garbage */
- cp++;
-
- while (isspace(*cp)) /* move to next field */
- cp++;
-
- *latlonstrptr = cp;
-
- return (retval);
-}
-
-/* converts a zone file representation in a string to an RDATA on-the-wire
- * representation. */
-int
-loc_aton(const char *ascii, u_char *binary)
-{
- const char *maxcp;
- u_char *bcp;
- char *cp;
-
- u_int32_t latit = 0, longit = 0, alt = 0;
- u_int32_t lltemp1 = 0, lltemp2 = 0;
- int altmeters = 0, altfrac = 0, altsign = 1;
- u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
- u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
- u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
- int which1 = 0, which2 = 0;
-
- cp = (char *)ascii;
- maxcp = cp + strlen(ascii);
-
- lltemp1 = latlon2ul(&cp, &which1);
-
- lltemp2 = latlon2ul(&cp, &which2);
-
- switch (which1 + which2) {
- case 3: /* 1 + 2, the only valid combination */
- if ((which1 == 1) && (which2 == 2)) { /* normal case */
- latit = lltemp1;
- longit = lltemp2;
- } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
- longit = lltemp1;
- latit = lltemp2;
- } else { /* some kind of brokenness */
- return (0);
- }
- break;
- default: /* we didn't get one of each */
- return (0);
- }
-
- /* altitude */
- if (*cp == '-') {
- altsign = -1;
- cp++;
- }
-
- if (*cp == '+')
- cp++;
-
- while (isdigit(*cp))
- altmeters = altmeters * 10 + (*cp++ - '0');
-
- if (*cp == '.') { /* decimal meters */
- cp++;
- if (isdigit(*cp)) {
- altfrac = (*cp++ - '0') * 10;
- if (isdigit(*cp)) {
- altfrac += (*cp++ - '0');
- }
- }
- }
-
- alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
-
- while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
- cp++;
-
- while (isspace(*cp) && (cp < maxcp))
- cp++;
-
- if (cp >= maxcp)
- goto defaults;
-
- siz = precsize_aton(&cp);
-
- while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
- cp++;
-
- while (isspace(*cp) && (cp < maxcp))
- cp++;
-
- if (cp >= maxcp)
- goto defaults;
-
- hp = precsize_aton(&cp);
-
- while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
- cp++;
-
- while (isspace(*cp) && (cp < maxcp))
- cp++;
-
- if (cp >= maxcp)
- goto defaults;
-
- vp = precsize_aton(&cp);
-
- defaults:
-
- bcp = binary;
- *bcp++ = (u_int8_t) 0; /* version byte */
- *bcp++ = siz;
- *bcp++ = hp;
- *bcp++ = vp;
- PUTLONG(latit,bcp);
- PUTLONG(longit,bcp);
- PUTLONG(alt,bcp);
-
- return (16); /* size of RR in octets */
-}
-
-const char *
-loc_ntoa(const u_char *binary, char *ascii)
-{
- return loc_ntoal(binary, ascii, 255);
-}
-
-/* takes an on-the-wire LOC RR and formats it in a human readable format. */
-static const char *
-loc_ntoal(const u_char *binary, char *ascii, int ascii_len)
-{
- static char *error = "?";
- const u_char *cp = binary;
-
- int latdeg, latmin, latsec, latsecfrac;
- int longdeg, longmin, longsec, longsecfrac;
- char northsouth, eastwest;
- int altmeters, altfrac, altsign;
-
- const int referencealt = 100000 * 100;
-
- int32_t latval, longval, altval;
- u_int32_t templ;
- u_int8_t sizeval, hpval, vpval, versionval;
-
- char *sizestr, *hpstr, *vpstr;
-
- versionval = *cp++;
-
- if (versionval) {
- snprintf(ascii, ascii_len, "; error: unknown LOC RR version");
- return (ascii);
- }
-
- sizeval = *cp++;
-
- hpval = *cp++;
- vpval = *cp++;
-
- GETLONG(templ, cp);
- latval = (templ - ((unsigned)1<<31));
-
- GETLONG(templ, cp);
- longval = (templ - ((unsigned)1<<31));
-
- GETLONG(templ, cp);
- if (templ < referencealt) { /* below WGS 84 spheroid */
- altval = referencealt - templ;
- altsign = -1;
- } else {
- altval = templ - referencealt;
- altsign = 1;
- }
-
- if (latval < 0) {
- northsouth = 'S';
- latval = -latval;
- } else
- northsouth = 'N';
-
- latsecfrac = latval % 1000;
- latval = latval / 1000;
- latsec = latval % 60;
- latval = latval / 60;
- latmin = latval % 60;
- latval = latval / 60;
- latdeg = latval;
-
- if (longval < 0) {
- eastwest = 'W';
- longval = -longval;
- } else
- eastwest = 'E';
-
- longsecfrac = longval % 1000;
- longval = longval / 1000;
- longsec = longval % 60;
- longval = longval / 60;
- longmin = longval % 60;
- longval = longval / 60;
- longdeg = longval;
-
- altfrac = altval % 100;
- altmeters = (altval / 100) * altsign;
-
- if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
- sizestr = error;
- if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
- hpstr = error;
- if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
- vpstr = error;
-
- snprintf(ascii, ascii_len,
- "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
- latdeg, latmin, latsec, latsecfrac, northsouth,
- longdeg, longmin, longsec, longsecfrac, eastwest,
- altmeters, altfrac, sizestr, hpstr, vpstr);
-
- if (sizestr != error)
- free(sizestr);
- if (hpstr != error)
- free(hpstr);
- if (vpstr != error)
- free(vpstr);
-
- return (ascii);
-}
-
-
-/* Return the number of DNS hierarchy levels in the name. */
-int
-__dn_count_labels(char *name)
-{
- int i, len, count;
-
- len = strlen(name);
-
- for(i = 0, count = 0; i < len; i++) {
- if (name[i] == '.')
- count++;
- }
-
- /* don't count initial wildcard */
- if (name[0] == '*')
- if (count)
- count--;
-
- /* don't count the null label for root. */
- /* if terminating '.' not found, must adjust */
- /* count to include last label */
- if (len > 0 && name[len-1] != '.')
- count++;
- return (count);
-}
-
-
-/*
- * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
- * SIG records are required to be printed like this, by the Secure DNS RFC.
- */
-char *
-__p_secstodate (long unsigned int secs)
-{
- static char output[15]; /* YYYYMMDDHHMMSS and null */
- time_t clock = secs;
- struct tm *time;
-
- time = gmtime(&clock);
- time->tm_year += 1900;
- time->tm_mon += 1;
- snprintf(output, sizeof output, "%04d%02d%02d%02d%02d%02d",
- time->tm_year, time->tm_mon, time->tm_mday,
- time->tm_hour, time->tm_min, time->tm_sec);
- return (output);
-}
diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c
deleted file mode 100644
index 18de3550e65..00000000000
--- a/lib/libc/net/res_init.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/* $OpenBSD: res_init.c,v 1.40 2009/06/05 09:52:26 pyr Exp $ */
-
-/*
- * ++Copyright++ 1985, 1989, 1993
- * -
- * Copyright (c) 1985, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#ifndef INET6
-#define INET6
-#endif
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-
-#include <stdio.h>
-#include <ctype.h>
-#include <resolv.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef INET6
-#include <netdb.h>
-#endif /* INET6 */
-
-#include "thread_private.h"
-
-/*-------------------------------------- info about "sortlist" --------------
- * Marc Majka 1994/04/16
- * Allan Nathanson 1994/10/29 (BIND 4.9.3.x)
- *
- * NetInfo resolver configuration directory support.
- *
- * Allow a NetInfo directory to be created in the hierarchy which
- * contains the same information as the resolver configuration file.
- *
- * - The local domain name is stored as the value of the "domain" property.
- * - The Internet address(es) of the name server(s) are stored as values
- * of the "nameserver" property.
- * - The name server addresses are stored as values of the "nameserver"
- * property.
- * - The search list for host-name lookup is stored as values of the
- * "search" property.
- * - The sortlist comprised of IP address netmask pairs are stored as
- * values of the "sortlist" property. The IP address and optional netmask
- * should be separated by a slash (/) or ampersand (&) character.
- * - Internal resolver variables can be set from the value of the "options"
- * property.
- */
-
-static void res_setoptions(char *, char *);
-
-#ifdef RESOLVSORT
-static const char sort_mask[] = "/&";
-#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
-static u_int32_t net_mask(struct in_addr);
-#endif
-
-/*
- * Resolver state default settings.
- */
-void *__THREAD_NAME(_res);
-
-struct __res_state _res
-# if defined(__BIND_RES_TEXT)
- = { RES_TIMEOUT, } /* Motorola, et al. */
-# endif
- ;
-#ifdef INET6
-void *__THREAD_NAME(_res_ext);
-
-struct __res_state_ext _res_ext;
-#endif /* INET6 */
-
-int __res_chktime = 30;
-
-/*
- * Set up default settings. If the configuration file exist, the values
- * there will have precedence. Otherwise, the server address is set to
- * INADDR_ANY and the default domain name comes from the gethostname().
- *
- * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
- * rather than INADDR_ANY ("0.0.0.0") as the default name server address
- * since it was noted that INADDR_ANY actually meant ``the first interface
- * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
- * it had to be "up" in order for you to reach your own name server. It
- * was later decided that since the recommended practice is to always
- * install local static routes through 127.0.0.1 for all your network
- * interfaces, that we could solve this problem without a code change.
- *
- * The configuration file should always be used, since it is the only way
- * to specify a default domain. If you are running a server on your local
- * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
- * in the configuration file.
- *
- * Return 0 if completes successfully, -1 on error
- */
-int
-res_init(void)
-{
-
- return (_res_init(1));
-}
-
-int
-_res_init(int usercall)
-{
- struct stat sb;
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
-#ifdef INET6
- struct __res_state_ext *_res_extp = _THREAD_PRIVATE(_res_ext, _res_ext,
- &_res_ext);
-#endif
- FILE *fp;
- char *cp, **pp;
- int n;
- int findex;
- char buf[BUFSIZ];
- int nserv = 0; /* number of nameserver records read from file */
- int haveenv = 0;
- int havesearch = 0;
- size_t len;
-#ifdef RESOLVSORT
- int nsort = 0;
- char *net;
-#endif
-#ifndef RFC1535
- int dots;
-#endif
-
- if (!usercall && _resp->options & RES_INIT &&
- _resp->reschktime >= time(NULL))
- return (0);
- _resp->reschktime = time(NULL) + __res_chktime;
- if (stat(_PATH_RESCONF, &sb) != -1) {
- if (!usercall && timespeccmp(&sb.st_mtimespec,
- &_resp->restimespec, ==))
- return (0);
- else
- _resp->restimespec = sb.st_mtimespec;
- } else {
- /*
- * Lost the file, in chroot?
- * Don't trash settings
- */
- if (!usercall && timespecisset(&_resp->restimespec))
- return (0);
- }
-
-
- /*
- * These three fields used to be statically initialized. This made
- * it hard to use this code in a shared library. It is necessary,
- * now that we're doing dynamic initialization here, that we preserve
- * the old semantics: if an application modifies one of these three
- * fields of _res before res_init() is called, res_init() will not
- * alter them. Of course, if an application is setting them to
- * _zero_ before calling res_init(), hoping to override what used
- * to be the static default, we can't detect it and unexpected results
- * will follow. Zero for any of these fields would make no sense,
- * so one can safely assume that the applications were already getting
- * unexpected results.
- *
- * _res.options is tricky since some apps were known to diddle the bits
- * before res_init() was first called. We can't replicate that semantic
- * with dynamic initialization (they may have turned bits off that are
- * set in RES_DEFAULT). Our solution is to declare such applications
- * "broken". They could fool us by setting RES_INIT but none do (yet).
- */
- if (!_resp->retrans)
- _resp->retrans = RES_TIMEOUT;
- if (!_resp->retry)
- _resp->retry = 4;
- if (!(_resp->options & RES_INIT))
- _resp->options = RES_DEFAULT;
-
-#ifdef USELOOPBACK
- _resp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
-#else
- _resp->nsaddr.sin_addr.s_addr = INADDR_ANY;
-#endif
- _resp->nsaddr.sin_family = AF_INET;
- _resp->nsaddr.sin_port = htons(NAMESERVER_PORT);
- _resp->nsaddr.sin_len = sizeof(struct sockaddr_in);
-#ifdef INET6
- if (sizeof(_res_extp->nsaddr) >= _resp->nsaddr.sin_len)
- memcpy(&_res_extp->nsaddr, &_resp->nsaddr, _resp->nsaddr.sin_len);
-#endif
- _resp->nscount = 1;
- _resp->ndots = 1;
- _resp->pfcode = 0;
- strlcpy(_resp->lookups, "f", sizeof _resp->lookups);
-
- /* Allow user to override the local domain definition */
- if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) {
- strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
- haveenv++;
-
- /*
- * Set search list to be blank-separated strings
- * from rest of env value. Permits users of LOCALDOMAIN
- * to still have a search list, and anyone to set the
- * one that they want to use as an individual (even more
- * important now that the rfc1535 stuff restricts searches)
- */
- cp = _resp->defdname;
- pp = _resp->dnsrch;
- *pp++ = cp;
- for (n = 0; *cp && pp < _resp->dnsrch + MAXDNSRCH; cp++) {
- if (*cp == '\n') /* silly backwards compat */
- break;
- else if (*cp == ' ' || *cp == '\t') {
- *cp = 0;
- n = 1;
- } else if (n) {
- *pp++ = cp;
- n = 0;
- havesearch = 1;
- }
- }
- /* null terminate last domain if there are excess */
- while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
- cp++;
- *cp = '\0';
- *pp++ = 0;
- }
-
-#define MATCH(line, name) \
- (!strncmp(line, name, sizeof(name) - 1) && \
- (line[sizeof(name) - 1] == ' ' || \
- line[sizeof(name) - 1] == '\t'))
-
- /* initialize family lookup preference: inet4 first */
- _resp->family[0] = AF_INET;
- _resp->family[1] = AF_INET6;
- if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
- strlcpy(_resp->lookups, "bf", sizeof _resp->lookups);
-
- /* read the config file */
- buf[0] = '\0';
- while ((cp = fgetln(fp, &len)) != NULL) {
- /* skip lines that are too long */
- if (len >= sizeof(buf))
- continue;
- (void)memcpy(buf, cp, len);
- buf[len] = '\0';
- /* skip comments */
- if ((cp = strpbrk(buf, ";#")) != NULL)
- *cp = '\0';
- if (buf[0] == '\0')
- continue;
- /* set family lookup order */
- if (MATCH(buf, "family")) {
- cp = buf + sizeof("family") - 1;
- cp += strspn(cp, " \t");
- cp[strcspn(cp, "\n")] = '\0';
- findex = 0;
- _resp->family[0] = _resp->family[1] = -1;
-#define INETLEN (sizeof("inetX") - 1)
- while (*cp != '\0' && findex < 2) {
- if (!strncmp(cp, "inet6", INETLEN)) {
- _resp->family[findex] = AF_INET6;
- cp += INETLEN;
- } else if (!strncmp(cp, "inet4", INETLEN)) {
- _resp->family[findex] = AF_INET;
- cp += INETLEN;
- } else {
- _resp->family[0] = -1;
- break;
- }
- if (*cp != ' ' && *cp != '\t' && *cp != '\0') {
- _resp->family[findex] = -1;
- break;
- }
- findex++;
- cp += strspn(cp, " \t");
- }
-
- if (_resp->family[0] == -1) {
- /* line contains errors, reset to defaults */
- _resp->family[0] = AF_INET;
- _resp->family[1] = AF_INET6;
- }
- if (_resp->family[0] == _resp->family[1])
- _resp->family[1] = -1;
- }
- /* read default domain name */
- if (MATCH(buf, "domain")) {
- if (haveenv) /* skip if have from environ */
- continue;
- cp = buf + sizeof("domain") - 1;
- while (*cp == ' ' || *cp == '\t')
- cp++;
- if ((*cp == '\0') || (*cp == '\n'))
- continue;
- strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
- if ((cp = strpbrk(_resp->defdname, " \t\n")) != NULL)
- *cp = '\0';
- havesearch = 0;
- continue;
- }
- /* lookup types */
- if (MATCH(buf, "lookup")) {
- char *sp = NULL;
-
- bzero(_resp->lookups, sizeof _resp->lookups);
- cp = buf + sizeof("lookup") - 1;
- for (n = 0;; cp++) {
- if (n == MAXDNSLUS)
- break;
- if ((*cp == '\0') || (*cp == '\n')) {
- if (sp) {
- if (*sp=='y' || *sp=='b' || *sp=='f')
- _resp->lookups[n++] = *sp;
- sp = NULL;
- }
- break;
- } else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) {
- if (sp) {
- if (*sp=='y' || *sp=='b' || *sp=='f')
- _resp->lookups[n++] = *sp;
- sp = NULL;
- }
- } else if (sp == NULL)
- sp = cp;
- }
- continue;
- }
- /* set search list */
- if (MATCH(buf, "search")) {
- if (haveenv) /* skip if have from environ */
- continue;
- cp = buf + sizeof("search") - 1;
- while (*cp == ' ' || *cp == '\t')
- cp++;
- if ((*cp == '\0') || (*cp == '\n'))
- continue;
- strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
- if ((cp = strchr(_resp->defdname, '\n')) != NULL)
- *cp = '\0';
- /*
- * Set search list to be blank-separated strings
- * on rest of line.
- */
- cp = _resp->defdname;
- pp = _resp->dnsrch;
- *pp++ = cp;
- for (n = 0; *cp && pp < _resp->dnsrch + MAXDNSRCH; cp++) {
- if (*cp == ' ' || *cp == '\t') {
- *cp = 0;
- n = 1;
- } else if (n) {
- *pp++ = cp;
- n = 0;
- }
- }
- /* null terminate last domain if there are excess */
- while (*cp != '\0' && *cp != ' ' && *cp != '\t')
- cp++;
- *cp = '\0';
- *pp++ = 0;
- havesearch = 1;
- continue;
- }
- /* read nameservers to query */
- if (MATCH(buf, "nameserver") && nserv < MAXNS) {
- char *q;
- struct addrinfo hints, *res;
- char pbuf[NI_MAXSERV];
-
- cp = buf + sizeof("nameserver") - 1;
- while (*cp == ' ' || *cp == '\t')
- cp++;
- if ((*cp == '\0') || (*cp == '\n'))
- continue;
- for (q = cp; *q; q++) {
- if (isspace(*q)) {
- *q = '\0';
- break;
- }
- }
-
- /* Handle addresses enclosed in [] */
- *pbuf = '\0';
- if (*cp == '[') {
- cp++;
- if ((q = strchr(cp, ']')) == NULL)
- continue;
- *q++ = '\0';
- /* Extract port, if specified */
- if (*q++ == ':') {
- if (strlcpy(pbuf, q, sizeof(pbuf)) >= sizeof(pbuf))
- continue;
- }
- }
- if (*pbuf == '\0')
- snprintf(pbuf, sizeof(pbuf), "%u", NAMESERVER_PORT);
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_NUMERICHOST;
- hints.ai_socktype = SOCK_DGRAM;
- res = NULL;
- if (getaddrinfo(cp, pbuf, &hints, &res) == 0 &&
- res->ai_next == NULL) {
- if (res->ai_addrlen <= sizeof(_res_extp->nsaddr_list[nserv])) {
- memcpy(&_res_extp->nsaddr_list[nserv], res->ai_addr,
- res->ai_addrlen);
- } else {
- memset(&_res_extp->nsaddr_list[nserv], 0,
- sizeof(_res_extp->nsaddr_list[nserv]));
- }
- if (res->ai_addrlen <= sizeof(_resp->nsaddr_list[nserv])) {
- memcpy(&_resp->nsaddr_list[nserv], res->ai_addr,
- res->ai_addrlen);
- } else {
- memset(&_resp->nsaddr_list[nserv], 0,
- sizeof(_resp->nsaddr_list[nserv]));
- }
- nserv++;
- }
- if (res)
- freeaddrinfo(res);
- continue;
- }
-#ifdef RESOLVSORT
- if (MATCH(buf, "sortlist")) {
- struct in_addr a;
-#ifdef INET6
- struct in6_addr a6;
- int m, i;
- u_char *u;
-#endif /* INET6 */
-
- cp = buf + sizeof("sortlist") - 1;
- while (nsort < MAXRESOLVSORT) {
- while (*cp == ' ' || *cp == '\t')
- cp++;
- if (*cp == '\0' || *cp == '\n' || *cp == ';')
- break;
- net = cp;
- while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
- isascii(*cp) && !isspace(*cp))
- cp++;
- n = *cp;
- *cp = 0;
- if (inet_aton(net, &a)) {
- _resp->sort_list[nsort].addr = a;
- if (ISSORTMASK(n)) {
- *cp++ = n;
- net = cp;
- while (*cp && *cp != ';' &&
- isascii(*cp) && !isspace(*cp))
- cp++;
- n = *cp;
- *cp = 0;
- if (inet_aton(net, &a)) {
- _resp->sort_list[nsort].mask = a.s_addr;
- } else {
- _resp->sort_list[nsort].mask =
- net_mask(_resp->sort_list[nsort].addr);
- }
- } else {
- _resp->sort_list[nsort].mask =
- net_mask(_resp->sort_list[nsort].addr);
- }
-#ifdef INET6
- _res_extp->sort_list[nsort].af = AF_INET;
- _res_extp->sort_list[nsort].addr.ina =
- _resp->sort_list[nsort].addr;
- _res_extp->sort_list[nsort].mask.ina.s_addr =
- _resp->sort_list[nsort].mask;
-#endif /* INET6 */
- nsort++;
- }
-#ifdef INET6
- else if (inet_pton(AF_INET6, net, &a6) == 1) {
- _res_extp->sort_list[nsort].af = AF_INET6;
- _res_extp->sort_list[nsort].addr.in6a = a6;
- u = (u_char *)&_res_extp->sort_list[nsort].mask.in6a;
- *cp++ = n;
- net = cp;
- while (*cp && *cp != ';' &&
- isascii(*cp) && !isspace(*cp))
- cp++;
- m = n;
- n = *cp;
- *cp = 0;
- switch (m) {
- case '/':
- m = atoi(net);
- break;
- case '&':
- if (inet_pton(AF_INET6, net, u) == 1) {
- m = -1;
- break;
- }
- /* FALLTHROUGH */
- default:
- m = sizeof(struct in6_addr) * NBBY;
- break;
- }
- if (m >= 0) {
- for (i = 0; i < sizeof(struct in6_addr); i++) {
- if (m <= 0) {
- *u = 0;
- } else {
- m -= NBBY;
- *u = (u_char)~0;
- if (m < 0)
- *u <<= -m;
- }
- u++;
- }
- }
- nsort++;
- }
-#endif /* INET6 */
- *cp = n;
- }
- continue;
- }
-#endif
- if (MATCH(buf, "options")) {
- res_setoptions(buf + sizeof("options") - 1, "conf");
- continue;
- }
- }
- if (nserv > 1)
- _resp->nscount = nserv;
-#ifdef RESOLVSORT
- _resp->nsort = nsort;
-#endif
- (void) fclose(fp);
- }
- if (_resp->defdname[0] == 0 &&
- gethostname(buf, sizeof(_resp->defdname) - 1) == 0 &&
- (cp = strchr(buf, '.')) != NULL)
- {
- strlcpy(_resp->defdname, cp + 1,
- sizeof(_resp->defdname));
- }
-
- /* find components of local domain that might be searched */
- if (havesearch == 0) {
- pp = _resp->dnsrch;
- *pp++ = _resp->defdname;
- *pp = NULL;
-
-#ifndef RFC1535
- dots = 0;
- for (cp = _resp->defdname; *cp; cp++)
- dots += (*cp == '.');
-
- cp = _resp->defdname;
- while (pp < _resp->dnsrch + MAXDFLSRCH) {
- if (dots < LOCALDOMAINPARTS)
- break;
- cp = strchr(cp, '.') + 1; /* we know there is one */
- *pp++ = cp;
- dots--;
- }
- *pp = NULL;
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG) {
- printf(";; res_init()... default dnsrch list:\n");
- for (pp = _resp->dnsrch; *pp; pp++)
- printf(";;\t%s\n", *pp);
- printf(";;\t..END..\n");
- }
-#endif /* DEBUG */
-#endif /* !RFC1535 */
- }
-
- if (issetugid())
- _resp->options |= RES_NOALIASES;
- else if ((cp = getenv("RES_OPTIONS")) != NULL)
- res_setoptions(cp, "env");
- _resp->options |= RES_INIT;
- return (0);
-}
-
-/* ARGSUSED */
-static void
-res_setoptions(char *options, char *source)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- char *cp = options;
- char *endp;
- long l;
-
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; res_setoptions(\"%s\", \"%s\")...\n",
- options, source);
-#endif
- while (*cp) {
- /* skip leading and inner runs of spaces */
- while (*cp == ' ' || *cp == '\t')
- cp++;
- /* search for and process individual options */
- if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
- char *p = cp + sizeof("ndots:") - 1;
- l = strtol(p, &endp, 10);
- if (l >= 0 && endp != p &&
- (*endp = '\0' || isspace(*endp))) {
- if (l <= RES_MAXNDOTS)
- _resp->ndots = l;
- else
- _resp->ndots = RES_MAXNDOTS;
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";;\tndots=%u\n", _resp->ndots);
-#endif
- }
- } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
-#ifdef DEBUG
- if (!(_resp->options & RES_DEBUG)) {
- printf(";; res_setoptions(\"%s\", \"%s\")..\n",
- options, source);
- _resp->options |= RES_DEBUG;
- }
- printf(";;\tdebug\n");
-#endif
- } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
- _resp->options |= RES_USE_INET6;
- } else if (!strncmp(cp, "insecure1", sizeof("insecure1") - 1)) {
- _resp->options |= RES_INSECURE1;
- } else if (!strncmp(cp, "insecure2", sizeof("insecure2") - 1)) {
- _resp->options |= RES_INSECURE2;
- } else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
- _resp->options |= RES_USE_EDNS0;
- } else if (!strncmp(cp, "tcp", sizeof("tcp") - 1)) {
- _resp->options |= RES_USEVC;
- } else {
- /* XXX - print a warning here? */
- }
- /* skip to next run of spaces */
- while (*cp && *cp != ' ' && *cp != '\t')
- cp++;
- }
-}
-
-#ifdef RESOLVSORT
-/* XXX - should really support CIDR which means explicit masks always. */
-static u_int32_t
-net_mask(struct in_addr in) /* XXX - should really use system's version of this */
-{
- u_int32_t i = ntohl(in.s_addr);
-
- if (IN_CLASSA(i))
- return (htonl(IN_CLASSA_NET));
- else if (IN_CLASSB(i))
- return (htonl(IN_CLASSB_NET));
- return (htonl(IN_CLASSC_NET));
-}
-#endif
diff --git a/lib/libc/net/res_mkquery.c b/lib/libc/net/res_mkquery.c
deleted file mode 100644
index 5c6b273abec..00000000000
--- a/lib/libc/net/res_mkquery.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/* $OpenBSD: res_mkquery.c,v 1.17 2005/08/06 20:30:04 espie Exp $ */
-
-/*
- * ++Copyright++ 1985, 1993
- * -
- * Copyright (c) 1985, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-
-#include <stdio.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <string.h>
-
-#include "thread_private.h"
-
-/*
- * Form all types of queries.
- * Returns the size of the result or -1.
- */
-/* ARGSUSED */
-int
-res_mkquery(int op,
- const char *dname, /* opcode of query */
- int class, /* domain name */
- int type, /* class and type of query */
- const u_char *data, /* resource record data */
- int datalen, /* length of data */
- const u_char *newrr_in, /* new rr for modify or append */
- u_char *buf, /* buffer to put query */
- int buflen) /* size of buffer */
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- HEADER *hp;
- u_char *cp, *ep;
- int n;
- u_char *dnptrs[20], **dpp, **lastdnptr;
-
- if (_res_init(0) == -1) {
- h_errno = NETDB_INTERNAL;
- return (-1);
- }
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; res_mkquery(%d, %s, %d, %d)\n",
- op, dname, class, type);
-#endif
- /*
- * Initialize header fields.
- *
- * A special random number generator is used to create non predictable
- * and non repeating ids over a long period. It also avoids reuse
- * by switching between two distinct number cycles.
- */
-
- if ((buf == NULL) || (buflen < HFIXEDSZ))
- return (-1);
- bzero(buf, HFIXEDSZ);
- hp = (HEADER *) buf;
- _resp->id = res_randomid();
- hp->id = htons(_resp->id);
- hp->opcode = op;
- hp->rd = (_resp->options & RES_RECURSE) != 0;
- hp->rcode = NOERROR;
- cp = buf + HFIXEDSZ;
- ep = buf + buflen;
- dpp = dnptrs;
- *dpp++ = buf;
- *dpp++ = NULL;
- lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
- /*
- * perform opcode specific processing
- */
- switch (op) {
- case QUERY: /*FALLTHROUGH*/
- case NS_NOTIFY_OP:
- if (ep - cp < QFIXEDSZ)
- return (-1);
- if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs,
- lastdnptr)) < 0)
- return (-1);
- cp += n;
- __putshort(type, cp);
- cp += INT16SZ;
- __putshort(class, cp);
- cp += INT16SZ;
- hp->qdcount = htons(1);
- if (op == QUERY || data == NULL)
- break;
- /*
- * Make an additional record for completion domain.
- */
- if (ep - cp < RRFIXEDSZ)
- return (-1);
- n = dn_comp((char *)data, cp, ep - cp - RRFIXEDSZ, dnptrs,
- lastdnptr);
- if (n < 0)
- return (-1);
- cp += n;
- __putshort(T_NULL, cp);
- cp += INT16SZ;
- __putshort(class, cp);
- cp += INT16SZ;
- __putlong(0, cp);
- cp += INT32SZ;
- __putshort(0, cp);
- cp += INT16SZ;
- hp->arcount = htons(1);
- break;
-
- case IQUERY:
- /*
- * Initialize answer section
- */
- if (ep - cp < 1 + RRFIXEDSZ + datalen)
- return (-1);
- *cp++ = '\0'; /* no domain name */
- __putshort(type, cp);
- cp += INT16SZ;
- __putshort(class, cp);
- cp += INT16SZ;
- __putlong(0, cp);
- cp += INT32SZ;
- __putshort(datalen, cp);
- cp += INT16SZ;
- if (datalen) {
- bcopy(data, cp, datalen);
- cp += datalen;
- }
- hp->ancount = htons(1);
- break;
-
- default:
- return (-1);
- }
- return (cp - buf);
-}
-
-/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
-int
-res_opt(int n0,
- u_char *buf, /* buffer to put query */
- int buflen, /* size of buffer */
- int anslen) /* answer buffer length */
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- HEADER *hp;
- u_char *cp, *ep;
-
- hp = (HEADER *) buf;
- cp = buf + n0;
- ep = buf + buflen;
-
- if (ep - cp < 1 + RRFIXEDSZ)
- return -1;
-
- *cp++ = 0; /* "." */
-
- __putshort(T_OPT, cp); /* TYPE */
- cp += INT16SZ;
- if (anslen > 0xffff)
- anslen = 0xffff; /* limit to 16bit value */
- __putshort(anslen & 0xffff, cp); /* CLASS = UDP payload size */
- cp += INT16SZ;
- *cp++ = NOERROR; /* extended RCODE */
- *cp++ = 0; /* EDNS version */
- if (_resp->options & RES_USE_DNSSEC) {
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; res_opt()... ENDS0 DNSSEC OK\n");
-#endif /* DEBUG */
- __putshort(DNS_MESSAGEEXTFLAG_DO, cp); /* EDNS Z field */
- cp += INT16SZ;
- } else {
- __putshort(0, cp); /* EDNS Z field */
- cp += INT16SZ;
- }
- __putshort(0, cp); /* RDLEN */
- cp += INT16SZ;
- hp->arcount = htons(ntohs(hp->arcount) + 1);
-
- return cp - buf;
-}
diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c
deleted file mode 100644
index 1485abb2d7d..00000000000
--- a/lib/libc/net/res_query.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/* $OpenBSD: res_query.c,v 1.26 2010/06/29 21:08:54 deraadt Exp $ */
-
-/*
- * ++Copyright++ 1988, 1993
- * -
- * Copyright (c) 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-
-#include <stdio.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "thread_private.h"
-
-#if PACKETSZ > 1024
-#define MAXPACKET PACKETSZ
-#else
-#define MAXPACKET 1024
-#endif
-
-const char *hostalias(const char *);
-int h_errno;
-extern int res_opt(int, u_char *, int, int);
-
-/*
- * Formulate a normal query, send, and await answer.
- * Returned answer is placed in supplied buffer "answer".
- * Perform preliminary check of answer, returning success only
- * if no error is indicated and the answer count is nonzero.
- * Return the size of the response on success, -1 on error.
- * Error number is left in h_errno.
- *
- * Caller must parse answer and determine whether it answers the question.
- */
-int
-res_query(const char *name,
- int class, /* domain name */
- int type, /* class and type of query */
- u_char *answer, /* buffer to put answer */
- int anslen) /* size of answer buffer */
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- union {
- HEADER hdr;
- u_char buf[MAXPACKET];
- } buf;
- HEADER *hp = (HEADER *) answer;
- int n;
-
- hp->rcode = NOERROR; /* default */
-
- if (_res_init(0) == -1) {
- h_errno = NETDB_INTERNAL;
- return (-1);
- }
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; res_query(%s, %d, %d)\n", name, class, type);
-#endif
-
- n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
- buf.buf, sizeof(buf.buf));
- if (n > 0 && ((_resp->options & RES_USE_EDNS0) ||
- (_resp->options & RES_USE_DNSSEC))) {
- n = res_opt(n, buf.buf, sizeof(buf.buf), anslen);
- }
-
- if (n <= 0) {
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; res_query: mkquery failed\n");
-#endif
- h_errno = NO_RECOVERY;
- return (n);
- }
- n = res_send(buf.buf, n, answer, anslen);
- if (n < 0) {
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; res_query: send error\n");
-#endif
- h_errno = TRY_AGAIN;
- return (n);
- }
-
- if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; rcode = %u, ancount=%u\n", hp->rcode,
- ntohs(hp->ancount));
-#endif
- switch (hp->rcode) {
- case NXDOMAIN:
- h_errno = HOST_NOT_FOUND;
- break;
- case SERVFAIL:
- h_errno = TRY_AGAIN;
- break;
- case NOERROR:
- h_errno = NO_DATA;
- break;
- case FORMERR:
- case NOTIMP:
- case REFUSED:
- default:
- h_errno = NO_RECOVERY;
- break;
- }
- return (-1);
- }
- return (n);
-}
-
-/*
- * Formulate a normal query, send, and retrieve answer in supplied buffer.
- * Return the size of the response on success, -1 on error.
- * If enabled, implement search rules until answer or unrecoverable failure
- * is detected. Error code, if any, is left in h_errno.
- */
-int
-res_search(const char *name,
- int class, /* domain name */
- int type, /* class and type of query */
- u_char *answer, /* buffer to put answer */
- int anslen) /* size of answer */
-{
- const char *cp, * const *domain;
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- HEADER *hp = (HEADER *) answer;
- u_int dots;
- int trailing_dot, ret, saved_herrno;
- int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
-
- if (_res_init(0) == -1) {
- h_errno = NETDB_INTERNAL;
- return (-1);
- }
- errno = 0;
- h_errno = HOST_NOT_FOUND; /* default, if we never query */
- dots = 0;
- for (cp = name; *cp; cp++)
- dots += (*cp == '.');
- trailing_dot = 0;
- if (cp > name && *--cp == '.')
- trailing_dot++;
-
- /*
- * if there aren't any dots, it could be a user-level alias
- */
- if (!dots && (cp = __hostalias(name)) != NULL)
- return (res_query(cp, class, type, answer, anslen));
-
- /*
- * If there are dots in the name already, let's just give it a try
- * 'as is'. The threshold can be set with the "ndots" option.
- */
- saved_herrno = -1;
- if (dots >= _resp->ndots) {
- ret = res_querydomain(name, NULL, class, type, answer, anslen);
- if (ret > 0)
- return (ret);
- saved_herrno = h_errno;
- tried_as_is++;
- }
-
- /*
- * We do at least one level of search if
- * - there is no dot and RES_DEFNAME is set, or
- * - there is at least one dot, there is no trailing dot,
- * and RES_DNSRCH is set.
- */
- if ((!dots && (_resp->options & RES_DEFNAMES)) ||
- (dots && !trailing_dot && (_resp->options & RES_DNSRCH))) {
- int done = 0;
-
- for (domain = (const char * const *)_resp->dnsrch;
- *domain && !done;
- domain++) {
-
- ret = res_querydomain(name, *domain, class, type,
- answer, anslen);
- if (ret > 0)
- return (ret);
-
- /*
- * If no server present, give up.
- * If name isn't found in this domain,
- * keep trying higher domains in the search list
- * (if that's enabled).
- * On a NO_DATA error, keep trying, otherwise
- * a wildcard entry of another type could keep us
- * from finding this entry higher in the domain.
- * If we get some other error (negative answer or
- * server failure), then stop searching up,
- * but try the input name below in case it's
- * fully-qualified.
- */
- if (errno == ECONNREFUSED) {
- h_errno = TRY_AGAIN;
- return (-1);
- }
-
- switch (h_errno) {
- case NO_DATA:
- got_nodata++;
- /* FALLTHROUGH */
- case HOST_NOT_FOUND:
- /* keep trying */
- break;
- case TRY_AGAIN:
- if (hp->rcode == SERVFAIL) {
- /* try next search element, if any */
- got_servfail++;
- break;
- }
- /* FALLTHROUGH */
- default:
- /* anything else implies that we're done */
- done++;
- }
-
- /* if we got here for some reason other than DNSRCH,
- * we only wanted one iteration of the loop, so stop.
- */
- if (!(_resp->options & RES_DNSRCH))
- done++;
- }
- }
-
- /* if we have not already tried the name "as is", do that now.
- * note that we do this regardless of how many dots were in the
- * name or whether it ends with a dot.
- */
- if (!tried_as_is) {
- ret = res_querydomain(name, NULL, class, type, answer, anslen);
- if (ret > 0)
- return (ret);
- }
-
- /* if we got here, we didn't satisfy the search.
- * if we did an initial full query, return that query's h_errno
- * (note that we wouldn't be here if that query had succeeded).
- * else if we ever got a nodata, send that back as the reason.
- * else send back meaningless h_errno, that being the one from
- * the last DNSRCH we did.
- */
- if (saved_herrno != -1)
- h_errno = saved_herrno;
- else if (got_nodata)
- h_errno = NO_DATA;
- else if (got_servfail)
- h_errno = TRY_AGAIN;
- return (-1);
-}
-
-/*
- * Perform a call on res_query on the concatenation of name and domain,
- * removing a trailing dot from name if domain is NULL.
- */
-int
-res_querydomain(const char *name,
- const char *domain,
- int class, /* class and type of query */
- int type,
- u_char *answer, /* buffer to put answer */
- int anslen) /* size of answer */
-{
-#ifdef DEBUG
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
-#endif
- char nbuf[MAXDNAME*2+1+1];
- const char *longname = nbuf;
- int n;
-
- if (_res_init(0) == -1) {
- h_errno = NETDB_INTERNAL;
- return (-1);
- }
-#ifdef DEBUG
- if (_resp->options & RES_DEBUG)
- printf(";; res_querydomain(%s, %s, %d, %d)\n",
- name, domain?domain:"<Nil>", class, type);
-#endif
- if (domain == NULL) {
- /*
- * Check for trailing '.';
- * copy without '.' if present.
- */
- n = strlen(name) - 1;
- if (n != (0 - 1) && name[n] == '.' && n < sizeof(nbuf) - 1) {
- bcopy(name, nbuf, n);
- nbuf[n] = '\0';
- } else
- longname = name;
- } else
- snprintf(nbuf, sizeof nbuf, "%.*s.%.*s",
- MAXDNAME, name, MAXDNAME, domain);
-
- return (res_query(longname, class, type, answer, anslen));
-}
-
-const char *
-hostalias(const char *name)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- char *cp1, *cp2;
- FILE *fp;
- char *file;
- char buf[BUFSIZ];
- static char abuf[MAXDNAME];
- size_t len;
-
- if (_resp->options & RES_NOALIASES)
- return (NULL);
- file = getenv("HOSTALIASES");
- if (issetugid() != 0 || file == NULL || (fp = fopen(file, "r")) == NULL)
- return (NULL);
- setbuf(fp, NULL);
- while ((cp1 = fgetln(fp, &len)) != NULL) {
- if (cp1[len-1] == '\n')
- len--;
- if (len >= sizeof(buf) || len == 0)
- continue;
- (void)memcpy(buf, cp1, len);
- buf[len] = '\0';
-
- for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
- ;
- if (!*cp1)
- break;
- *cp1 = '\0';
- if (!strcasecmp(buf, name)) {
- while (isspace(*++cp1))
- ;
- if (!*cp1)
- break;
- for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
- ;
- *cp2 = '\0';
- strlcpy(abuf, cp1, sizeof(abuf));
- fclose(fp);
- return (abuf);
- }
- }
- fclose(fp);
- return (NULL);
-}
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c
deleted file mode 100644
index 09b13858925..00000000000
--- a/lib/libc/net/res_send.c
+++ /dev/null
@@ -1,853 +0,0 @@
-/* $OpenBSD: res_send.c,v 1.21 2008/05/11 05:03:03 brad Exp $ */
-
-/*
- * ++Copyright++ 1985, 1989, 1993
- * -
- * Copyright (c) 1985, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#ifndef INET6
-#define INET6
-#endif
-
- /* change this to "0"
- * if you talk to a lot
- * of multi-homed SunOS
- * ("broken") name servers.
- */
-#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */
-
-/*
- * Send query to name server and wait for reply.
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <netdb.h>
-#include <poll.h>
-#include <resolv.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "thread_private.h"
-
-static int s = -1; /* socket used for communications */
-static int connected = 0; /* is the socket connected */
-static int vc = 0; /* is the socket a virtual ciruit? */
-static int af = 0; /* address family of socket */
-
-#define CAN_RECONNECT 1
-
-#ifndef DEBUG
-# define Dprint(cond, args) /*empty*/
-# define DprintQ(cond, args, query, size) /*empty*/
-# define Aerror(file, string, error, address) /*empty*/
-# define Perror(file, string, error) /*empty*/
-#else
-# define Dprint(cond, args) if (cond) {fprintf args;} else {}
-# define DprintQ(cond, args, query, size) if (cond) {\
- fprintf args;\
- __fp_nquery(query, size, stdout);\
- } else {}
-static char abuf[NI_MAXHOST];
-static char pbuf[NI_MAXSERV];
-static void Aerror(FILE *, char *, int, struct sockaddr *);
-static void Perror(FILE *, char *, int);
-
- static void
- Aerror(FILE *file, char *string, int error, struct sockaddr *address)
- {
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- int save = errno;
-
- if (_resp->options & RES_DEBUG) {
- if (getnameinfo(address, address->sa_len, abuf, sizeof(abuf),
- pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
- strlcpy(abuf, "?", sizeof(abuf));
- strlcpy(pbuf, "?", sizeof(pbuf));
- }
- fprintf(file, "res_send: %s ([%s].%s): %s\n",
- string, abuf, pbuf, strerror(error));
- }
- errno = save;
- }
- static void
- Perror(FILE *file, char *string, int error)
- {
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- int save = errno;
-
- if (_resp->options & RES_DEBUG) {
- fprintf(file, "res_send: %s: %s\n",
- string, strerror(error));
- }
- errno = save;
- }
-#endif
-
-static res_send_qhook Qhook = NULL;
-static res_send_rhook Rhook = NULL;
-
-void
-res_send_setqhook(res_send_qhook hook)
-{
-
- Qhook = hook;
-}
-
-void
-res_send_setrhook(res_send_rhook hook)
-{
-
- Rhook = hook;
-}
-
-#ifdef INET6
-static struct sockaddr * get_nsaddr(size_t);
-
-/*
- * pick appropriate nsaddr_list for use. see res_init() for initialization.
- */
-static struct sockaddr *
-get_nsaddr(size_t n)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- struct __res_state_ext *_res_extp = _THREAD_PRIVATE(_res_ext, _res_ext,
- &_res_ext);
-
- if (!_resp->nsaddr_list[n].sin_family) {
- /*
- * - _res_extp->nsaddr_list[n] holds an address that is larger
- * than struct sockaddr, and
- * - user code did not update _resp->nsaddr_list[n].
- */
- return (struct sockaddr *)&_res_extp->nsaddr_list[n];
- } else {
- /*
- * - user code updated _res.nsaddr_list[n], or
- * - _resp->nsaddr_list[n] has the same content as
- * _res_extp->nsaddr_list[n].
- */
- return (struct sockaddr *)&_resp->nsaddr_list[n];
- }
-}
-#else
-#define get_nsaddr(n) ((struct sockaddr *)&_resp->nsaddr_list[(n)])
-#endif
-
-/* int
- * res_isourserver(ina)
- * looks up "ina" in _resp->ns_addr_list[]
- * returns:
- * 0 : not found
- * >0 : found
- * author:
- * paul vixie, 29may94
- */
-int
-res_isourserver(const struct sockaddr_in *inp)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
-#ifdef INET6
- const struct sockaddr_in6 *in6p = (const struct sockaddr_in6 *)inp;
- const struct sockaddr_in6 *srv6;
-#endif
- const struct sockaddr_in *srv;
- int ns, ret;
-
- ret = 0;
- switch (inp->sin_family) {
-#ifdef INET6
- case AF_INET6:
- for (ns = 0; ns < _resp->nscount; ns++) {
- srv6 = (struct sockaddr_in6 *)get_nsaddr(ns);
- if (srv6->sin6_family == in6p->sin6_family &&
- srv6->sin6_port == in6p->sin6_port &&
- srv6->sin6_scope_id == in6p->sin6_scope_id &&
- (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
- IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr,
- &in6p->sin6_addr))) {
- ret++;
- break;
- }
- }
- break;
-#endif
- case AF_INET:
- for (ns = 0; ns < _resp->nscount; ns++) {
- srv = (struct sockaddr_in *)get_nsaddr(ns);
- if (srv->sin_family == inp->sin_family &&
- srv->sin_port == inp->sin_port &&
- (srv->sin_addr.s_addr == INADDR_ANY ||
- srv->sin_addr.s_addr == inp->sin_addr.s_addr)) {
- ret++;
- break;
- }
- }
- break;
- }
- return (ret);
-}
-
-/* int
- * res_nameinquery(name, type, class, buf, eom)
- * look for (name,type,class) in the query section of packet (buf,eom)
- * returns:
- * -1 : format error
- * 0 : not found
- * >0 : found
- * author:
- * paul vixie, 29may94
- */
-int
-res_nameinquery(const char *name, int type, int class, const u_char *buf,
- const u_char *eom)
-{
- const u_char *cp = buf + HFIXEDSZ;
- int qdcount = ntohs(((HEADER*)buf)->qdcount);
-
- while (qdcount-- > 0) {
- char tname[MAXDNAME+1];
- int n, ttype, tclass;
-
- n = dn_expand(buf, eom, cp, tname, sizeof tname);
- if (n < 0)
- return (-1);
- cp += n;
- ttype = _getshort(cp); cp += INT16SZ;
- tclass = _getshort(cp); cp += INT16SZ;
- if (ttype == type &&
- tclass == class &&
- strcasecmp(tname, name) == 0)
- return (1);
- }
- return (0);
-}
-
-/* int
- * res_queriesmatch(buf1, eom1, buf2, eom2)
- * is there a 1:1 mapping of (name,type,class)
- * in (buf1,eom1) and (buf2,eom2)?
- * returns:
- * -1 : format error
- * 0 : not a 1:1 mapping
- * >0 : is a 1:1 mapping
- * author:
- * paul vixie, 29may94
- */
-int
-res_queriesmatch(const u_char *buf1, const u_char *eom1, const u_char *buf2,
- const u_char *eom2)
-{
- const u_char *cp = buf1 + HFIXEDSZ;
- int qdcount = ntohs(((HEADER*)buf1)->qdcount);
-
- if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
- return (0);
- while (qdcount-- > 0) {
- char tname[MAXDNAME+1];
- int n, ttype, tclass;
-
- n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
- if (n < 0)
- return (-1);
- cp += n;
- ttype = _getshort(cp); cp += INT16SZ;
- tclass = _getshort(cp); cp += INT16SZ;
- if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
- return (0);
- }
- return (1);
-}
-
-int
-res_send(const u_char *buf, int buflen, u_char *ans, int anssiz)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- HEADER *hp = (HEADER *) buf;
- HEADER *anhp = (HEADER *) ans;
- int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
- int n;
- u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
-
- if (_res_init(0) == -1) {
- /* errno should have been set by res_init() in this case. */
- return (-1);
- }
- DprintQ((_resp->options & RES_DEBUG) || (_resp->pfcode & RES_PRF_QUERY),
- (stdout, ";; res_send()\n"), buf, buflen);
- v_circuit = (_resp->options & RES_USEVC) || buflen > PACKETSZ;
- gotsomewhere = 0;
- connreset = 0;
- terrno = ETIMEDOUT;
- badns = 0;
-
- /*
- * Send request, RETRY times, or until successful
- */
- for (try = 0; try < _resp->retry; try++) {
- for (ns = 0; ns < _resp->nscount; ns++) {
- struct sockaddr *nsap = get_nsaddr(ns);
- socklen_t salen;
-
- if (nsap->sa_len)
- salen = nsap->sa_len;
-#ifdef INET6
- else if (nsap->sa_family == AF_INET6)
- salen = sizeof(struct sockaddr_in6);
-#endif
- else if (nsap->sa_family == AF_INET)
- salen = sizeof(struct sockaddr_in);
- else
- salen = 0; /*unknown, die on connect*/
-
- same_ns:
- if (badns & (1 << ns)) {
- res_close();
- goto next_ns;
- }
-
- if (Qhook) {
- int done = 0, loops = 0;
-
- do {
- res_sendhookact act;
-
- act = (*Qhook)((struct sockaddr_in **)&nsap,
- &buf, &buflen,
- ans, anssiz, &resplen);
- switch (act) {
- case res_goahead:
- done = 1;
- break;
- case res_nextns:
- res_close();
- goto next_ns;
- case res_done:
- return (resplen);
- case res_modified:
- /* give the hook another try */
- if (++loops < 42) /*doug adams*/
- break;
- /*FALLTHROUGH*/
- case res_error:
- /*FALLTHROUGH*/
- default:
- return (-1);
- }
- } while (!done);
- }
-
- Dprint((_resp->options & RES_DEBUG) &&
- getnameinfo(nsap, salen, abuf, sizeof(abuf),
- NULL, 0, NI_NUMERICHOST) == 0,
- (stdout, ";; Querying server (# %d) address = %s\n",
- ns + 1, abuf));
-
- if (v_circuit) {
- int truncated;
- struct iovec iov[2];
- u_short len;
- u_char *cp;
-
- /*
- * Use virtual circuit;
- * at most one attempt per server.
- */
- try = _resp->retry;
- truncated = 0;
- if ((s < 0) || (!vc) || (af != nsap->sa_family)) {
- if (s >= 0)
- res_close();
-
- af = nsap->sa_family;
- s = socket(af, SOCK_STREAM, 0);
- if (s < 0) {
- terrno = errno;
- Perror(stderr, "socket(vc)", errno);
-#if 0
- return (-1);
-#else
- badns |= (1 << ns);
- res_close();
- goto next_ns;
-#endif
- }
- errno = 0;
- if (connect(s, nsap, salen) < 0) {
- terrno = errno;
- Aerror(stderr, "connect/vc",
- errno, nsap);
- badns |= (1 << ns);
- res_close();
- goto next_ns;
- }
- vc = 1;
- }
- /*
- * Send length & message
- */
- putshort((u_short)buflen, (u_char*)&len);
- iov[0].iov_base = (caddr_t)&len;
- iov[0].iov_len = INT16SZ;
- iov[1].iov_base = (caddr_t)buf;
- iov[1].iov_len = buflen;
- if (writev(s, iov, 2) != (INT16SZ + buflen)) {
- terrno = errno;
- Perror(stderr, "write failed", errno);
- badns |= (1 << ns);
- res_close();
- goto next_ns;
- }
- /*
- * Receive length & response
- */
- read_len:
- cp = ans;
- len = INT16SZ;
- while ((n = read(s, (char *)cp, (int)len)) > 0) {
- cp += n;
- if ((len -= n) <= 0)
- break;
- }
- if (n <= 0) {
- terrno = errno;
- Perror(stderr, "read failed", errno);
- res_close();
- /*
- * A long running process might get its TCP
- * connection reset if the remote server was
- * restarted. Requery the server instead of
- * trying a new one. When there is only one
- * server, this means that a query might work
- * instead of failing. We only allow one reset
- * per query to prevent looping.
- */
- if (terrno == ECONNRESET && !connreset) {
- connreset = 1;
- res_close();
- goto same_ns;
- }
- res_close();
- goto next_ns;
- }
- resplen = _getshort(ans);
- if (resplen > anssiz) {
- Dprint(_resp->options & RES_DEBUG,
- (stdout, ";; response truncated\n")
- );
- truncated = 1;
- len = anssiz;
- } else
- len = resplen;
- cp = ans;
- while (len != 0 &&
- (n = read(s, (char *)cp, (int)len)) > 0) {
- cp += n;
- len -= n;
- }
- if (n <= 0) {
- terrno = errno;
- Perror(stderr, "read(vc)", errno);
- res_close();
- goto next_ns;
- }
- if (truncated) {
- /*
- * Flush rest of answer
- * so connection stays in synch.
- */
- anhp->tc = 1;
- len = resplen - anssiz;
- while (len != 0) {
- char junk[PACKETSZ];
-
- n = (len > sizeof(junk)
- ? sizeof(junk)
- : len);
- if ((n = read(s, junk, n)) > 0)
- len -= n;
- else
- break;
- }
- }
- /*
- * The calling applicating has bailed out of
- * a previous call and failed to arrange to have
- * the circuit closed or the server has got
- * itself confused. Anyway drop the packet and
- * wait for the correct one.
- */
- if (hp->id != anhp->id) {
- DprintQ((_resp->options & RES_DEBUG) ||
- (_resp->pfcode & RES_PRF_REPLY),
- (stdout, ";; old answer (unexpected):\n"),
- ans, (resplen>anssiz)?anssiz:resplen);
- goto read_len;
- }
- } else {
- /*
- * Use datagrams.
- */
- struct pollfd pfd;
- int timeout;
- struct sockaddr_storage from;
- socklen_t fromlen;
-
- if ((s < 0) || vc || (af != nsap->sa_family)) {
- if (vc)
- res_close();
- af = nsap->sa_family;
- s = socket(af, SOCK_DGRAM, 0);
- if (s < 0) {
-#if !CAN_RECONNECT
- bad_dg_sock:
-#endif
- terrno = errno;
- Perror(stderr, "socket(dg)", errno);
-#if 0
- return (-1);
-#else
- badns |= (1 << ns);
- res_close();
- goto next_ns;
-#endif
- }
-#ifdef IPV6_MINMTU
- if (af == AF_INET6) {
- const int yes = 1;
- (void)setsockopt(s, IPPROTO_IPV6,
- IPV6_USE_MIN_MTU, &yes,
- sizeof(yes));
- }
-#endif
- connected = 0;
- }
- /*
- * On a 4.3BSD+ machine (client and server,
- * actually), sending to a nameserver datagram
- * port with no nameserver will cause an
- * ICMP port unreachable message to be returned.
- * If our datagram socket is "connected" to the
- * server, we get an ECONNREFUSED error on the next
- * socket operation, and poll returns if the
- * error message is received. We can thus detect
- * the absence of a nameserver without timing out.
- * If we have sent queries to at least two servers,
- * however, we don't want to remain connected,
- * as we wish to receive answers from the first
- * server to respond.
- */
- if (!(_resp->options & RES_INSECURE1) &&
- (_resp->nscount == 1 || (try == 0 && ns == 0))) {
- /*
- * Connect only if we are sure we won't
- * receive a response from another server.
- */
- if (!connected) {
- if (connect(s, nsap, salen) < 0) {
- Aerror(stderr,
- "connect(dg)",
- errno, nsap);
- badns |= (1 << ns);
- res_close();
- goto next_ns;
- }
- connected = 1;
- }
- if (send(s, (char*)buf, buflen, 0) != buflen) {
- Perror(stderr, "send", errno);
- badns |= (1 << ns);
- res_close();
- goto next_ns;
- }
- } else {
- /*
- * Disconnect if we want to listen
- * for responses from more than one server.
- */
- if (connected) {
-#if CAN_RECONNECT
-#ifdef INET6
- /* XXX: any errornous address */
-#endif /* INET6 */
- struct sockaddr_in no_addr;
-
- no_addr.sin_family = AF_INET;
- no_addr.sin_addr.s_addr = INADDR_ANY;
- no_addr.sin_port = 0;
- (void) connect(s,
- (struct sockaddr *)
- &no_addr,
- sizeof(no_addr));
-#else
- int s1 = socket(af, SOCK_DGRAM,0);
- if (s1 < 0)
- goto bad_dg_sock;
- (void) dup2(s1, s);
- (void) close(s1);
- Dprint(_resp->options & RES_DEBUG,
- (stdout, ";; new DG socket\n"))
-#endif
-#ifdef IPV6_MINMTU
- if (af == AF_INET6) {
- const int yes = 1;
- (void)setsockopt(s, IPPROTO_IPV6,
- IPV6_USE_MIN_MTU, &yes,
- sizeof(yes));
- }
-#endif
- connected = 0;
- errno = 0;
- }
- if (sendto(s, (char*)buf, buflen, 0,
- nsap, salen) != buflen) {
- Aerror(stderr, "sendto", errno, nsap);
- badns |= (1 << ns);
- res_close();
- goto next_ns;
- }
- }
-
- /*
- * Wait for reply
- */
- timeout = 1000 * (_resp->retrans << try);
- if (try > 0)
- timeout /= _resp->nscount;
- if (timeout < 1000)
- timeout = 1000;
- wait:
- pfd.fd = s;
- pfd.events = POLLIN;
- n = poll(&pfd, 1, timeout);
- if (n < 0) {
- if (errno == EINTR)
- goto wait;
- Perror(stderr, "poll", errno);
- res_close();
- goto next_ns;
- }
- if (n == 0) {
- /*
- * timeout
- */
- Dprint(_resp->options & RES_DEBUG,
- (stdout, ";; timeout\n"));
- gotsomewhere = 1;
- res_close();
- goto next_ns;
- }
- errno = 0;
- fromlen = sizeof(from);
- resplen = recvfrom(s, (char*)ans, anssiz, 0,
- (struct sockaddr *)&from, &fromlen);
- if (resplen <= 0) {
- Perror(stderr, "recvfrom", errno);
- res_close();
- goto next_ns;
- }
- gotsomewhere = 1;
- if (hp->id != anhp->id) {
- /*
- * response from old query, ignore it.
- * XXX - potential security hazard could
- * be detected here.
- */
- DprintQ((_resp->options & RES_DEBUG) ||
- (_resp->pfcode & RES_PRF_REPLY),
- (stdout, ";; old answer:\n"),
- ans, (resplen>anssiz)?anssiz:resplen);
- goto wait;
- }
-#if CHECK_SRVR_ADDR
- if (!(_resp->options & RES_INSECURE1) &&
- !res_isourserver((struct sockaddr_in *)&from)) {
- /*
- * response from wrong server? ignore it.
- * XXX - potential security hazard could
- * be detected here.
- */
- DprintQ((_resp->options & RES_DEBUG) ||
- (_resp->pfcode & RES_PRF_REPLY),
- (stdout, ";; not our server:\n"),
- ans, (resplen>anssiz)?anssiz:resplen);
- goto wait;
- }
-#endif
- if (!(_resp->options & RES_INSECURE2) &&
- !res_queriesmatch(buf, buf + buflen,
- ans, ans + anssiz)) {
- /*
- * response contains wrong query? ignore it.
- * XXX - potential security hazard could
- * be detected here.
- */
- DprintQ((_resp->options & RES_DEBUG) ||
- (_resp->pfcode & RES_PRF_REPLY),
- (stdout, ";; wrong query name:\n"),
- ans, (resplen>anssiz)?anssiz:resplen);
- goto wait;
- }
- if (anhp->rcode == SERVFAIL ||
- anhp->rcode == NOTIMP ||
- anhp->rcode == REFUSED) {
- DprintQ(_resp->options & RES_DEBUG,
- (stdout, "server rejected query:\n"),
- ans, (resplen>anssiz)?anssiz:resplen);
- badns |= (1 << ns);
- res_close();
- /* don't retry if called from dig */
- if (!_resp->pfcode)
- goto next_ns;
- }
- if (!(_resp->options & RES_IGNTC) && anhp->tc) {
- /*
- * get rest of answer;
- * use TCP with same server.
- */
- Dprint(_resp->options & RES_DEBUG,
- (stdout, ";; truncated answer\n"));
- v_circuit = 1;
- res_close();
- goto same_ns;
- }
- } /*if vc/dg*/
- Dprint((_resp->options & RES_DEBUG) ||
- ((_resp->pfcode & RES_PRF_REPLY) &&
- (_resp->pfcode & RES_PRF_HEAD1)),
- (stdout, ";; got answer:\n"));
- DprintQ((_resp->options & RES_DEBUG) ||
- (_resp->pfcode & RES_PRF_REPLY),
- (stdout, "%s", ""),
- ans, (resplen>anssiz)?anssiz:resplen);
- /*
- * If using virtual circuits, we assume that the first server
- * is preferred over the rest (i.e. it is on the local
- * machine) and only keep that one open.
- * If we have temporarily opened a virtual circuit,
- * or if we haven't been asked to keep a socket open,
- * close the socket.
- */
- if ((v_circuit && (!(_resp->options & RES_USEVC) || ns != 0)) ||
- !(_resp->options & RES_STAYOPEN)) {
- res_close();
- }
- if (Rhook) {
- int done = 0, loops = 0;
-
- do {
- res_sendhookact act;
-
- act = (*Rhook)((struct sockaddr_in *)nsap,
- buf, buflen,
- ans, anssiz, &resplen);
- switch (act) {
- case res_goahead:
- case res_done:
- done = 1;
- break;
- case res_nextns:
- res_close();
- goto next_ns;
- case res_modified:
- /* give the hook another try */
- if (++loops < 42) /*doug adams*/
- break;
- /*FALLTHROUGH*/
- case res_error:
- /*FALLTHROUGH*/
- default:
- return (-1);
- }
- } while (!done);
-
- }
- return (resplen);
- next_ns: ;
- } /*foreach ns*/
- } /*foreach retry*/
- res_close();
- if (!v_circuit) {
- if (!gotsomewhere)
- errno = ECONNREFUSED; /* no nameservers found */
- else
- errno = ETIMEDOUT; /* no answer obtained */
- } else
- errno = terrno;
- return (-1);
-}
-
-/*
- * This routine is for closing the socket if a virtual circuit is used and
- * the program wants to close it. This provides support for endhostent()
- * which expects to close the socket.
- *
- * This routine is not expected to be user visible.
- */
-void
-res_close(void)
-{
- if (s >= 0) {
- (void) close(s);
- s = -1;
- connected = 0;
- vc = 0;
- af = 0;
- }
-}
diff --git a/lib/libc/net/sethostent.c b/lib/libc/net/sethostent.c
deleted file mode 100644
index 6f6d0e405a1..00000000000
--- a/lib/libc/net/sethostent.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* $OpenBSD: sethostent.c,v 1.9 2005/08/06 20:30:04 espie Exp $ */
-/*
- * Copyright (c) 1985, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <netdb.h>
-#include <resolv.h>
-
-#include "thread_private.h"
-
-void
-sethostent(int stayopen)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
-
- if (_res_init(0) == -1)
- return;
- if (stayopen)
- _resp->options |= RES_STAYOPEN | RES_USEVC;
-}
-
-void
-endhostent(void)
-{
- struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
-
- _resp->options &= ~(RES_STAYOPEN | RES_USEVC);
- res_close();
-}