summaryrefslogtreecommitdiffstats
path: root/contrib/bind/bin/host/host.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/bin/host/host.c')
-rw-r--r--contrib/bind/bin/host/host.c2136
1 files changed, 0 insertions, 2136 deletions
diff --git a/contrib/bind/bin/host/host.c b/contrib/bind/bin/host/host.c
deleted file mode 100644
index 7c0fa72..0000000
--- a/contrib/bind/bin/host/host.c
+++ /dev/null
@@ -1,2136 +0,0 @@
-#ifndef lint
-static const char rcsid[] = "$Id: host.c,v 8.55.8.1 2003/06/02 09:24:38 marka Exp $";
-#endif /* not lint */
-
-/*
- * Copyright (c) 1986
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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) 1996-1999 by 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.
- */
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1986 Regents of the University of California.\n\
- Portions Copyright (c) 1993 Digital Equipment Corporation.\n\
- Portions Copyright (c) 1996-1999 Internet Software Consortium.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/*
- * Actually, this program is from Rutgers University, however it is
- * based on nslookup and other pieces of named tools, so it needs
- * the above copyright notices.
- */
-
-/* Import. */
-
-#include "port_before.h"
-
-#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 <ctype.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <memory.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <isc/dst.h>
-
-#include "port_after.h"
-
-#include <resolv.h>
-
-/* Global. */
-
-#ifndef PATH_SEP
-#define PATH_SEP '/'
-#endif
-#define SIG_RDATA_BY_NAME 18
-#define NS_HEADERDATA_SIZE 10 /* type + class + ttl + rdlen */
-
-#define NUMNS 8
-#define NUMNSADDR 16
-#define NUMMX 50
-#define NUMRR 127 /* max rr's per node to verify signatures for */
-
-#define SUCCESS 0
-#define TIME_OUT -1
-#define NO_INFO -2
-#ifdef ERROR
-#undef ERROR
-#endif
-#define ERROR -3
-#define NONAUTH -4
-
-#define MY_PACKETSZ NS_MAXMSG
-
-typedef union {
- HEADER qb1;
- u_char qb2[MY_PACKETSZ];
-} querybuf;
-
-#define SD_RR 1
-#define SD_SIG 2
-#define SD_BADSIG 4
-
-typedef struct {
- u_char data[MY_PACKETSZ];
- size_t len;
-} rrstruct;
-
-static char chase_domain[NS_MAXDNAME];
-static int chase_class;
-static int chase_type;
-static char chase_sigorigttl[NS_INT32SZ];
-static rrstruct chase_rr[NUMRR];
-static int chase_rr_num;
-static char chase_lastgoodkey[NS_MAXDNAME];
-static char chase_signer[NS_MAXDNAME];
-static u_char chase_sigrdata[MY_PACKETSZ];
-static size_t chase_sigrdata_len;
-static u_char chase_signature[MY_PACKETSZ];
-static size_t chase_signature_len;
-static int chase_step;
-static int sigchase;
-
-static char cnamebuf[NS_MAXDNAME];
-static u_char hostbuf[NS_MAXDNAME];
-
-static int sockFD;
-static FILE *filePtr;
-
-static struct __res_state res;
-static char *cname = NULL;
-static const char *progname = "amnesia";
-static int getclass = ns_c_in, verbose = 0, list = 0;
-static int server_specified = 0;
-static int gettype = 0;
-static int querytype = 0;
-static char getdomain[NS_MAXDNAME];
-
-/* Forward. */
-
-static int parsetype(const char *s);
-static int parseclass(const char *s);
-static void hperror(int errnum);
-static int addrinfo(struct sockaddr_storage *addr);
-static int gethostinfo(char *name);
-static int getdomaininfo(const char *name, const char *domain);
-static int getinfo(const char *name, const char *domain,
- int type);
-static int printinfo(const querybuf *answer, const u_char *eom,
- int filter, int isls, int isinaddr);
-static const u_char * pr_rr(const u_char *cp, const u_char *msg, FILE *file,
- int filter);
-static const char * pr_type(int type);
-static const char * pr_class(int class);
-static const u_char * pr_cdname(const u_char *cp, const u_char *msg,
- char *name, int namelen);
-static int ListHosts(char *namePtr, int queryType);
-static const char * DecodeError(int result);
-
-static void
-usage(const char *msg) {
- fprintf(stderr, "%s: usage error (%s)\n", progname, msg);
- fprintf(stderr, "\
-Usage: %s [-adlrwv] [-t querytype] [-c class] host [server]\n\
-\t-a is equivalent to '-v -t *'\n\
-\t-c class to look for non-Internet data\n\
-\t-d to turn on debugging output\n\
-\t-l to turn on 'list mode'\n\
-\t-r to disable recursive processing\n\
-\t-s recursively chase signature found in answers\n\
-\t-t querytype to look for a specific type of information\n\
-\t-v for verbose output\n\
-\t-w to wait forever until reply\n\
-", progname);
- exit(1);
-}
-
-/* Public. */
-
-int
-main(int argc, char **argv) {
- struct sockaddr_storage addr;
- int ok = 0;
- char *s;
- int waitmode = 0;
- int ncnames, ch;
- int nkeychains;
- struct addrinfo *answer = NULL;
- struct addrinfo *cur = NULL;
- struct addrinfo hint;
- int ip = 0;
-
- dst_init();
-
- if ((progname = strrchr(argv[0], PATH_SEP)) == NULL)
- progname = argv[0];
- else
- progname++;
- res_ninit(&res);
- res.retrans = 5;
- while ((ch = getopt(argc, argv, "ac:dlrst:vw")) != -1) {
- switch (ch) {
- case 'a':
- verbose = 1;
- querytype = ns_t_any;
- break;
- case 'c':
- getclass = parseclass(optarg);
- break;
- case 'd':
- res.options |= RES_DEBUG;
- break;
- case 'l':
- list = 1;
- break;
- case 'r':
- res.options &= ~RES_RECURSE;
- break;
- case 's':
- sigchase = 1;
- break;
- case 't':
- querytype = parsetype(optarg);
- break;
- case 'v':
- verbose = 1;
- break;
- case 'w':
- res.retry = 1;
- res.retrans = 15;
- waitmode = 1;
- break;
- default:
- usage("unrecogized switch");
- /*NOTREACHED*/
- }
- }
- if ((querytype == 0) && (sigchase)) {
- if (verbose)
- printf ("Forcing `-t a' for signature trace.\n");
- querytype = ns_t_a;
- }
- argc -= optind;
- argv += optind;
- if (argc < 1)
- usage("missing host argument");
- strncpy(getdomain, *argv++, NS_MAXDNAME);
- getdomain[NS_MAXDNAME-1] = 0;
- argc--;
- if (argc > 1)
- usage("extra undefined arguments");
- if (argc == 1) {
- union res_sockaddr_union u[MAXNS];
- int nscount;
-
- s = *argv++;
- argc--;
- server_specified++;
- memset(&hint, 0, sizeof(hint));
- hint.ai_flags = AI_CANONNAME;
- hint.ai_family = PF_UNSPEC;
- hint.ai_socktype = SOCK_DGRAM;
-
- if (!getaddrinfo(s, NULL, &hint, &answer)) {
- nscount = 0;
- if (answer->ai_canonname != NULL) {
- printf("Using domain server:\n");
- printf("Name: %s\n", answer->ai_canonname);
- printf("Addresses:");
- } else
- printf("Using domain server");
-
- for (cur = answer; cur != NULL; cur = cur->ai_next) {
- char buf[80];
- struct sockaddr_in6 *sin6;
- struct sockaddr_in *sin;
-
- switch (cur->ai_addr->sa_family) {
- case AF_INET6:
- sin6 =
- (struct sockaddr_in6 *)cur->ai_addr;
- inet_ntop(cur->ai_addr->sa_family,
- &sin6->sin6_addr,
- buf, sizeof(buf));
- printf(" %s", buf);
- if (nscount >= MAXNS)
- break;
- u[nscount].sin6 = *sin6;
- u[nscount++].sin6.sin6_port =
- htons(NAMESERVER_PORT);
- break;
- case AF_INET:
- sin =
- (struct sockaddr_in*)cur->ai_addr;
- inet_ntop(cur->ai_addr->sa_family,
- &sin->sin_addr,
- buf, sizeof(buf));
- printf(" %s", buf);
- if (nscount >= MAXNS)
- break;
- u[nscount].sin = *sin;
- u[nscount++].sin6.sin6_port =
- htons(NAMESERVER_PORT);
- break;
- }
- }
- if (nscount != 0) {
- res_setservers(&res, u, nscount);
- }
- if (answer->ai_canonname != NULL)
- printf("\n\n");
- else
- printf(":\n\n");
- freeaddrinfo(answer);
- } else {
- fprintf(stderr, "Error in looking up server name:\n");
- exit(1);
- }
- res.retry = 2;
- }
- memset(&hint, 0, sizeof(hint));
- hint.ai_flags = AI_NUMERICHOST;
- hint.ai_socktype = SOCK_DGRAM;
- if(!getaddrinfo(getdomain, NULL, &hint, &answer)) {
- memset(&addr, 0, sizeof(addr));
- switch (answer->ai_family) {
- case AF_INET:
- memcpy(&addr, answer->ai_addr,
- sizeof(struct sockaddr_in));
- ip = 1;
- break;
- case AF_INET6:
- memcpy(&addr, answer->ai_addr,
- sizeof(struct sockaddr_in6));
- ip = 1;
- break;
- }
- freeaddrinfo(answer);
- }
- res.res_h_errno = TRY_AGAIN;
-/*
- * We handle default domains ourselves, thank you.
- */
- res.options &= ~RES_DEFNAMES;
-
- if (list)
- exit(ListHosts(getdomain, querytype ? querytype : ns_t_a));
- ncnames = 5; nkeychains = 18;
- while (ok == 0 && res.res_h_errno == TRY_AGAIN) {
- if (!ip) {
- cname = NULL;
- ok = gethostinfo(getdomain);
- getdomain[0] = 0; /* clear this query */
- if (sigchase && (chase_step & SD_RR)) {
- if (nkeychains-- == 0) {
- printf("Too many sig/key chains. Loop?\n");
- exit(1);
- }
- if (chase_step & SD_SIG) {
- /* start new query, for KEY */
- strcpy (getdomain, chase_signer);
- strcat (getdomain, ".");
- querytype = ns_t_key;
- } else if (!(chase_step & SD_BADSIG)) {
- /* start new query, for SIG */
- strcpy (getdomain, chase_domain);
- strcat (getdomain, ".");
- querytype = ns_t_sig;
- } else if (ok != 0 && !(chase_step & SD_SIG) &&
- (chase_step & SD_BADSIG)) {
- printf ("%s for %s not found, last verified key %s\n",
- chase_step & SD_SIG ? "Key" : "Signature",
- chase_step & SD_SIG ? chase_signer : chase_domain,
- chase_lastgoodkey[0] ? chase_lastgoodkey : "None");
- }
- }
- if (!getdomain[0] && cname) {
- if (ncnames-- == 0) {
- printf("Too many cnames. Loop?\n");
- exit(1);
- }
- strcpy(getdomain, cname);
- strcat(getdomain, ".");
- }
- if (getdomain[0]) {
- if (chase_step & SD_SIG) {
- printf ("Locating key for %s\n", getdomain);
- } else if (chase_step & SD_SIG) {
- printf ("Locating signature for %s record(s) on %s\n",
- sym_ntos(__p_type_syms, chase_type, NULL),
- getdomain);
- }
- ok = 0;
- res.res_h_errno = TRY_AGAIN;
- continue;
- }
- } else
- ok = addrinfo(&addr);
- if (!waitmode)
- break;
- }
-
- if (ok == 0) {
- hperror(res.res_h_errno);
- exit(1);
- }
-
- exit(0);
-}
-
-/* Private. */
-
-static int
-parsetype(const char *s) {
- int type, success;
-
- type = sym_ston(__p_type_syms, s, &success);
- if (success)
- return (type);
- if (strcmp(s, "*") == 0)
- return (ns_t_any);
- if (atoi(s))
- return (atoi(s));
- fprintf(stderr, "Invalid query type: %s\n", s);
- exit(2);
- /*NOTREACHED*/
-}
-
-static int
-parseclass(const char *s) {
- int class, success;
-
- class = sym_ston(__p_class_syms, s, &success);
- if (success)
- return (class);
- if (atoi(s))
- return (atoi(s));
- fprintf(stderr, "Invalid query class: %s\n", s);
- exit(2);
- /*NOTREACHED*/
-}
-
-static void
-hperror(int errnum) {
- switch(errnum) {
- case HOST_NOT_FOUND:
- fprintf(stderr, "Host not found.\n");
- break;
- case TRY_AGAIN:
- fprintf(stderr, "Host not found, try again.\n");
- break;
- case NO_RECOVERY:
- fprintf(stderr, "No recovery, Host not found.\n");
- break;
- case NO_ADDRESS:
- fprintf(stderr,
- "There is an entry for this host, but it doesn't have "
- );
- switch (gettype) {
- case ns_t_a:
- fprintf(stderr, "an Internet address.\n");
- break;
- case ns_t_ns:
- fprintf(stderr, "a Name Server.\n");
- break;
- case ns_t_md:
- fprintf(stderr, "a Mail Destination.\n");
- break;
- case ns_t_mf:
- fprintf(stderr, "a Mail Forwarder.\n");
- break;
- case ns_t_cname:
- fprintf(stderr, "a Canonical Name.\n");
- break;
- case ns_t_soa:
- fprintf(stderr, "a Start of Authority record.\n");
- break;
- case ns_t_mb:
- fprintf(stderr, "a Mailbox Domain Name.\n");
- break;
- case ns_t_mg:
- fprintf(stderr, "a Mail Group Member.\n");
- break;
- case ns_t_mr:
- fprintf(stderr, "a Mail Rename Name.\n");
- break;
- case ns_t_null:
- fprintf(stderr, "a Null Resource record.\n");
- break;
- case ns_t_wks:
- fprintf(stderr, "any Well Known Service information.\n");
- break;
- case ns_t_ptr:
- fprintf(stderr, "a Pointer record.\n");
- break;
- case ns_t_hinfo:
- fprintf(stderr, "any Host Information.\n");
- break;
- case ns_t_minfo:
- fprintf(stderr, "any Mailbox Information.\n");
- break;
- case ns_t_mx:
- fprintf(stderr, "a Mail Exchanger record.\n");
- break;
- case ns_t_txt:
- fprintf(stderr, "a Text record.\n");
- break;
- case ns_t_rp:
- fprintf(stderr, "a Responsible Person.\n");
- break;
- case ns_t_srv:
- fprintf(stderr, "a Server Selector.\n");
- break;
- case ns_t_naptr:
- fprintf(stderr, "a URN Naming Authority.\n");
- break;
- default:
- fprintf(stderr, "the information you requested.\n");
- break;
- }
- break;
- }
-}
-
-static int
-addrinfo(struct sockaddr_storage *addr) {
- char name[NS_MAXDNAME];
- unsigned char *p;
- struct in6_addr *addr6;
-
- switch(addr->ss_family) {
- case AF_INET:
- p = (unsigned char*)&((struct sockaddr_in *)addr)->sin_addr;
- mapped:
- sprintf(name, "%u.%u.%u.%u.IN-ADDR.ARPA.",
- p[3], p[2], p[1], p[0]);
- break;
- case AF_INET6:
- addr6 = &((struct sockaddr_in6 *)addr)->sin6_addr;
- p = (unsigned char *)addr6;
- if (IN6_IS_ADDR_V4MAPPED(addr6) ||
- IN6_IS_ADDR_V4COMPAT(addr6)) {
- p += 12;
- goto mapped;
- }
- sprintf(name,
- "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
- "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
- "IP6.ARPA",
- p[15] & 0xf, (p[15] >> 4) & 0xf,
- p[14] & 0xf, (p[14] >> 4) & 0xf,
- p[13] & 0xf, (p[13] >> 4) & 0xf,
- p[12] & 0xf, (p[12] >> 4) & 0xf,
- p[11] & 0xf, (p[11] >> 4) & 0xf,
- p[10] & 0xf, (p[10] >> 4) & 0xf,
- p[9] & 0xf, (p[9] >> 4) & 0xf,
- p[8] & 0xf, (p[8] >> 4) & 0xf,
- p[7] & 0xf, (p[7] >> 4) & 0xf,
- p[6] & 0xf, (p[6] >> 4) & 0xf,
- p[5] & 0xf, (p[5] >> 4) & 0xf,
- p[4] & 0xf, (p[4] >> 4) & 0xf,
- p[3] & 0xf, (p[3] >> 4) & 0xf,
- p[2] & 0xf, (p[2] >> 4) & 0xf,
- p[1] & 0xf, (p[1] >> 4) & 0xf,
- p[0] & 0xf, (p[0] >> 4) & 0xf);
- break;
- default:
- abort();
- }
- return (getinfo(name, NULL, ns_t_ptr));
-}
-
-static int
-gethostinfo(char *name) {
- char *cp, **domain;
- char tmp[NS_MAXDNAME];
- const char *tp;
- int hp;
- int asis = 0;
- u_int n;
-
- if (strcmp(name, ".") == 0)
- return (getdomaininfo(name, NULL));
- for (cp = name, n = 0; *cp; cp++)
- if (*cp == '.')
- n++;
- if (n && cp[-1] == '.') {
- if (cp[-1] == '.')
- cp[-1] = 0;
- hp = getdomaininfo(name, (char *)NULL);
- if (cp[-1] == 0)
- cp[-1] = '.';
- return (hp);
- }
- if (n == 0 && (tp = res_hostalias(&res, name, tmp, sizeof tmp))) {
- if (verbose)
- printf("Aliased to \"%s\"\n", tp);
- res.options |= RES_DEFNAMES;
- return (getdomaininfo(tp, (char *)NULL));
- }
- if (n >= res.ndots) {
- asis = 1;
- if (verbose)
- printf("Trying null domain\n");
- hp = getdomaininfo(name, (char*)NULL);
- if (hp)
- return (hp);
- }
- for (domain = res.dnsrch; *domain; domain++) {
- if (verbose)
- printf("Trying domain \"%s\"\n", *domain);
- hp = getdomaininfo(name, *domain);
- if (hp)
- return (hp);
- }
- if (res.res_h_errno != HOST_NOT_FOUND || (res.options & RES_DNSRCH) == 0)
- return (0);
- if (!asis)
- return (0);
- if (verbose)
- printf("Trying null domain\n");
- return (getdomaininfo(name, (char *)NULL));
-}
-
-static int
-getdomaininfo(const char *name, const char *domain) {
- int val1, val2, val3;
-
- if (querytype)
- return (getinfo(name, domain, gettype=querytype));
- else {
- val1 = getinfo(name, domain, gettype=ns_t_a);
- if (cname || verbose)
- return (val1);
- val2 = getinfo(name, domain, gettype=ns_t_aaaa);
- val3 = getinfo(name, domain, gettype=ns_t_mx);
- return (val1 || val2 || val3);
- }
-}
-
-static int
-getinfo(const char *name, const char *domain, int type) {
- u_char *eom;
- querybuf buf, answer;
- int n;
- char host[NS_MAXDNAME];
-
- if (domain == NULL ||
- (domain[0] == '.' && domain[1] == '\0'))
- sprintf(host, "%.*s", NS_MAXDNAME, name);
- else
- sprintf(host, "%.*s.%.*s",
- NS_MAXDNAME, name, NS_MAXDNAME, domain);
-
- n = res_nmkquery(&res, QUERY, host, getclass, type, NULL, 0, NULL,
- buf.qb2, sizeof buf);
- if (n < 0) {
- if (res.options & RES_DEBUG)
- printf("res_nmkquery failed\n");
- res.res_h_errno = NO_RECOVERY;
- return (0);
- }
- n = res_nsend(&res, buf.qb2, n, answer.qb2, sizeof answer);
- if (n < 0) {
- if (res.options & RES_DEBUG)
- printf("res_nsend failed\n");
- res.res_h_errno = TRY_AGAIN;
- return (0);
- }
- eom = answer.qb2 + n;
- return (printinfo(&answer, eom, ns_t_any, 0, (type == ns_t_ptr)));
-}
-
-static int
-printinfo(const querybuf *answer, const u_char *eom, int filter, int isls,
- int isinaddr)
-{
- int n, nmx, ancount, nscount, arcount, qdcount, buflen, savesigchase;
- const u_char *bp, *cp;
- const HEADER *hp;
-
- /*
- * Find first satisfactory answer.
- */
- hp = (const HEADER *) answer;
- ancount = ntohs(hp->ancount);
- qdcount = ntohs(hp->qdcount);
- nscount = ntohs(hp->nscount);
- arcount = ntohs(hp->arcount);
- if (res.options & RES_DEBUG || (verbose && isls == 0))
- printf("rcode = %d (%s), ancount=%d\n",
- hp->rcode, DecodeError(hp->rcode), ancount);
- if (hp->rcode != NOERROR || (ancount+nscount+arcount) == 0) {
- switch (hp->rcode) {
- case NXDOMAIN:
- res.res_h_errno = HOST_NOT_FOUND;
- return (0);
- case SERVFAIL:
- res.res_h_errno = TRY_AGAIN;
- return (0);
- case NOERROR:
- res.res_h_errno = NO_DATA;
- return (0);
- case FORMERR:
- case NOTIMP:
- case REFUSED:
- res.res_h_errno = NO_RECOVERY;
- return (0);
- }
- return (0);
- }
- bp = hostbuf;
- nmx = 0;
- buflen = sizeof(hostbuf);
- cp = answer->qb2 + HFIXEDSZ;
- if (qdcount > 0) {
- while (qdcount-- > 0) {
- n = dn_skipname(cp, eom);
- if (n < 0) {
- printf("Form error.\n");
- return (0);
- }
- cp += n + QFIXEDSZ;
- if (cp > eom) {
- printf("Form error.\n");
- return (0);
- }
- }
- }
- if (ancount) {
- if (!hp->aa)
- if (verbose && isls == 0)
- printf(
- "The following answer is not authoritative:\n"
- );
- if (!hp->ad)
- if (verbose && isls == 0)
- printf("The following answer is not verified as authentic by the server:\n");
- while (--ancount >= 0 && cp && cp < eom) {
- cp = pr_rr(cp, answer->qb2, stdout, filter);
- /*
- * When we ask for address and there is a CNAME, it
- * seems to return both the CNAME and the address.
- * Since we trace down the CNAME chain ourselves, we
- * don't really want to print the address at this
- * point.
- */
- if (cname && (!verbose) && (!isinaddr))
- return (1);
- }
- }
- if (!verbose)
- return (1);
-
- /* don't chase signatures for non-answer stuff */
-
- savesigchase = sigchase;
- sigchase = 0;
-
- if (nscount) {
- printf("For authoritative answers, see:\n");
- while (--nscount >= 0 && cp && cp < eom)
- cp = pr_rr(cp, answer->qb2, stdout, filter);
- }
- if (arcount) {
- printf("Additional information:\n");
- while (--arcount >= 0 && cp && cp < eom)
- cp = pr_rr(cp, answer->qb2, stdout, filter);
- }
-
- /* restore sigchase value */
-
- sigchase = savesigchase;
-
- return (1);
-}
-
-static void print_hex_field (u_int8_t field[], int length, int width,
- const char *pref)
-{
- /* Prints an arbitrary bit field, from one address for some number of
- bytes. Output is formatted via the width, and includes the raw
- hex value and (if printable) the printed value underneath. "pref"
- is a string used to start each line, e.g., " " to indent.
-
- This is very useful in gdb to see what's in a memory field.
- */
- int i, start, stop;
-
- start=0;
- do
- {
- stop=(start+width)<length?(start+width):length;
- printf ("%s", pref);
- for (i = start; i < stop; i++)
- printf ("%02x ", (u_char) field[i]);
- printf ("\n");
-
- printf ("%s", pref);
- for (i = start; i < stop; i++)
- if (isprint(field[i]))
- printf (" %c ", (u_char) field[i]);
- else
- printf (" ");
- printf ("\n");
-
- start = stop;
- } while (start < length);
-}
-
-static void memswap (void *s1, void *s2, size_t n)
-{
- void *tmp;
-
- tmp = malloc(n);
- if (!tmp) {
- printf ("Out of memory\n");
- exit (1);
- }
-
- memcpy(tmp, s1, n);
- memcpy(s1, s2, n);
- memcpy(s2, tmp, n);
-
- free (tmp);
-}
-
-/*
- * Print resource record fields in human readable form.
- */
-static const u_char *
-pr_rr(const u_char *cp, const u_char *msg, FILE *file, int filter) {
- int type, class, dlen, n, c, proto, ttl;
- struct in_addr inaddr;
- u_char in6addr[NS_IN6ADDRSZ];
- const u_char *savecp = cp;
- const u_char *cp1;
- struct protoent *protop;
- struct servent *servp;
- char punc = ' ';
- int doprint;
- char name[NS_MAXDNAME];
- char thisdomain[NS_MAXDNAME];
- char tmpbuf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
- u_char canonrr[MY_PACKETSZ];
- size_t canonrr_len = 0;
-
- cp = pr_cdname(cp, msg, name, sizeof(name));
- if (cp == NULL)
- return (NULL); /* compression error */
- strcpy(thisdomain, name);
-
- type = ns_get16(cp);
- cp += INT16SZ;
-
- class = ns_get16(cp);
- cp += INT16SZ;
-
- ttl = ns_get32(cp);
- cp += INT32SZ;
-
- if (filter == type || filter == ns_t_any ||
- (filter == ns_t_a && (type == ns_t_ptr || type == ns_t_ns)))
- doprint = 1;
- else
- doprint = 0;
-
- if (doprint) {
- if (verbose)
- fprintf(file, "%s\t%d%s\t%s",
- name, ttl, pr_class(class), pr_type(type));
- else
- fprintf(file, "%s%s %s",
- name, pr_class(class), pr_type(type));
- if (verbose)
- punc = '\t';
- else
- punc = ' ';
- }
- dlen = ns_get16(cp);
- cp += INT16SZ;
- cp1 = cp;
-
- /*
- * Print type specific data, if appropriate.
- */
- switch (type) {
- case ns_t_a:
- memcpy(&inaddr, cp, NS_INADDRSZ);
- if (doprint)
- fprintf(file,"%c%s", punc, inet_ntoa(inaddr));
- cp += dlen;
- break;
- case ns_t_aaaa:
- memcpy(in6addr, cp, NS_IN6ADDRSZ);
- if (doprint) {
- if (inet_ntop(AF_INET6, in6addr, tmpbuf,
- sizeof tmpbuf) != NULL)
- fprintf(file,"%c%s", punc, tmpbuf);
- else
- fprintf(file,"%c???", punc);
- }
- cp += dlen;
- break;
- case ns_t_cname:
- if (dn_expand(msg, msg + 512, cp, cnamebuf,
- sizeof(cnamebuf)) >= 0)
- cname = cnamebuf;
- case ns_t_mb:
- case ns_t_mg:
- case ns_t_mr:
- case ns_t_ns:
- case ns_t_ptr:
- {
- const u_char *startrdata = cp;
- u_char cdname[NS_MAXCDNAME];
-
- cp = pr_cdname(cp, msg, name, sizeof name);
- if (doprint)
- fprintf(file, "%c%s", punc, name);
-
- /* Extract DNSSEC canonical RR. */
-
- n = ns_name_unpack(msg, msg+MY_PACKETSZ, startrdata,
- cdname, sizeof cdname);
- if (n >= 0)
- n = ns_name_ntol(cdname, cdname, sizeof cdname);
- if (n >= 0) {
- /* Copy header. */
- memcpy(canonrr, cp1 - NS_HEADERDATA_SIZE, NS_HEADERDATA_SIZE);
- /* Overwrite length field. */
- ns_put16(n, canonrr + NS_HEADERDATA_SIZE - NS_INT16SZ);
- /* Copy unpacked name. */
- memcpy(canonrr + NS_HEADERDATA_SIZE, cdname, n);
- canonrr_len = NS_HEADERDATA_SIZE + n;
- }
- break;
- }
-
- case ns_t_hinfo:
- case ns_t_isdn:
- {
- const u_char *cp2 = cp + dlen;
- n = *cp++;
- if (n != 0) {
- if (doprint)
- fprintf(file,"%c%.*s", punc, n, cp);
- cp += n;
- }
- if ((cp < cp2) && (n = *cp++)) {
- if (doprint)
- fprintf(file,"%c%.*s", punc, n, cp);
- cp += n;
- } else if (type == ns_t_hinfo)
- if (doprint)
- fprintf(file,
- "\n; *** Warning *** OS-type missing"
- );
- }
- break;
-
- case ns_t_soa:
- {
- const u_char *startname = cp;
- u_char cdname[NS_MAXCDNAME];
-
- cp = pr_cdname(cp, msg, name, sizeof name);
- if (doprint)
- fprintf(file, "\t%s", name);
-
- n = ns_name_unpack(msg, msg + 512, startname,
- cdname, sizeof cdname);
- if (n >= 0)
- n = ns_name_ntol(cdname, cdname, sizeof cdname);
- if (n >= 0) {
- /* Copy header. */
- memcpy(canonrr, cp1 - NS_HEADERDATA_SIZE, NS_HEADERDATA_SIZE);
- /* Copy expanded name. */
- memcpy(canonrr + NS_HEADERDATA_SIZE, cdname, n);
- canonrr_len = NS_HEADERDATA_SIZE + n;
- }
-
- startname = cp;
- cp = pr_cdname(cp, msg, name, sizeof name);
- if (doprint)
- fprintf(file, " %s", name);
-
- n = ns_name_unpack(msg, msg + 512, startname,
- cdname, sizeof cdname);
- if (n >= 0)
- n = ns_name_ntol(cdname, cdname, sizeof cdname);
- if (n >= 0) {
- /* Copy expanded name. */
- memcpy(canonrr + canonrr_len, cdname, n);
- canonrr_len += n;
- /* Copy rest of SOA. */
- memcpy(canonrr + canonrr_len, cp, 5 * INT32SZ);
- canonrr_len += 5 * INT32SZ;
- /* Overwrite length field. */
- ns_put16(canonrr_len - NS_HEADERDATA_SIZE,
- canonrr + NS_HEADERDATA_SIZE - NS_INT16SZ);
- }
-
- if (doprint)
- fprintf(file, " (\n\t\t\t%lu\t;serial (version)",
- ns_get32(cp));
- cp += INT32SZ;
- if (doprint)
- fprintf(file, "\n\t\t\t%lu\t;refresh period",
- ns_get32(cp));
- cp += INT32SZ;
- if (doprint)
- fprintf(file,
- "\n\t\t\t%lu\t;retry refresh this often",
- ns_get32(cp));
- cp += INT32SZ;
- if (doprint)
- fprintf(file, "\n\t\t\t%lu\t;expiration period",
- ns_get32(cp));
- cp += INT32SZ;
- if (doprint)
- fprintf(file, "\n\t\t\t%lu\t;minimum TTL\n\t\t\t)",
- ns_get32(cp));
- cp += INT32SZ;
- break;
- }
- case ns_t_mx:
- case ns_t_afsdb:
- case ns_t_rt:
- {
- const u_char *startrdata = cp;
- u_char cdname[NS_MAXCDNAME];
-
- if (doprint) {
- if (type == ns_t_mx && !verbose)
- fprintf(file," (pri=%d) by ", ns_get16(cp));
- else if (verbose)
- fprintf(file,"\t%d ", ns_get16(cp));
- else
- fprintf(file," ");
- }
- cp += sizeof(u_short);
- cp = pr_cdname(cp, msg, name, sizeof(name));
- if (doprint)
- fprintf(file, "%s", name);
-
- n = ns_name_unpack(msg, msg+512, startrdata + sizeof(u_short),
- cdname, sizeof cdname);
- if (n >= 0)
- n = ns_name_ntol(cdname, cdname, sizeof cdname);
- if (n >= 0) {
- /* Copy header. */
- memcpy(canonrr, cp1 - NS_HEADERDATA_SIZE,
- NS_HEADERDATA_SIZE);
- /* Overwrite length field. */
- ns_put16(sizeof(u_short) + n,
- canonrr + NS_HEADERDATA_SIZE - NS_INT16SZ);
- /* Copy u_short. */
- memcpy(canonrr + NS_HEADERDATA_SIZE, startrdata,
- sizeof(u_short));
- /* Copy expanded name. */
- memcpy(canonrr + NS_HEADERDATA_SIZE + sizeof(u_short),
- cdname, n);
- canonrr_len = NS_HEADERDATA_SIZE + sizeof(u_short) + n;
- }
- break;
- }
-
- case ns_t_srv:
- if (doprint)
- fprintf(file," %d", ns_get16(cp));
- cp += sizeof(u_short);
- if (doprint)
- fprintf(file," %d", ns_get16(cp));
- cp += sizeof(u_short);
- if (doprint)
- fprintf(file," %d", ns_get16(cp));
- cp += sizeof(u_short);
- cp = pr_cdname(cp, msg, name, sizeof(name));
- if (doprint)
- fprintf(file, " %s", name);
- break;
-
- case ns_t_naptr:
- /* order */
- if (doprint)
- fprintf(file, " %d", ns_get16(cp));
- cp += sizeof(u_short);
- /* preference */
- if (doprint)
- fprintf(file, " %d", ns_get16(cp));
- cp += NS_INT16SZ;
- /* Flags */
- n = *cp++;
- if (doprint) {
- if (n)
- fprintf(file, "%c%.*s", punc, n, cp);
- else
- fprintf(file, "%c\"\"",punc);
- }
- cp += n;
- /* Service */
- n = *cp++;
- if (doprint) {
- if (n)
- fprintf(file, "%c%.*s", punc, n, cp);
- else
- fprintf(file,"%c\"\"",punc);
- }
- cp += n;
- /* Regexp */
- n = *cp++;
- if (doprint) {
- if (n)
- fprintf(file, "%c%.*s", punc, n, cp);
- else
- fprintf(file, "%c\"\"",punc);
- }
- cp += n;
- /* replacement */
- cp = pr_cdname(cp, msg, name, sizeof(name));
- if (doprint)
- fprintf(file, "%s", name);
- break;
-
- case ns_t_minfo:
- case ns_t_rp:
- cp = pr_cdname(cp, msg, name, sizeof name);
- if (doprint) {
- if (type == ns_t_rp) {
- char *p;
-
- p = strchr(name, '.');
- if (p != NULL)
- *p = '@';
- }
- fprintf(file, "%c%s", punc, name);
- }
- cp = pr_cdname(cp, msg, name, sizeof(name));
- if (doprint)
- fprintf(file, " %s", name);
- break;
-
- case ns_t_x25:
- n = *cp++;
- if (n != 0) {
- if (doprint)
- fprintf(file, "%c%.*s", punc, n, cp);
- cp += n;
- }
- break;
-
- case ns_t_txt:
- {
- int n, j;
- const u_char *end = cp + dlen;
-
- while (cp < end) {
- if (doprint)
- (void) fputs(" \"", file);
- n = *cp++;
- if (n != 0)
- for (j = n; j > 0 && cp < end ; j --) {
- if (doprint) {
- if (*cp == '\n' ||
- *cp == '"' ||
- *cp == '\\')
- putc('\\',
- file);
- putc(*cp, file);
- }
- cp++;
- }
- if (doprint)
- putc('"', file);
- }
- }
- break;
-
- case ns_t_wks:
- if (dlen < INT32SZ + 1)
- break;
- memcpy(&inaddr, cp, INADDRSZ);
- cp += INT32SZ;
- proto = *cp++;
- protop = getprotobynumber(proto);
- if (doprint) {
- if (protop)
- fprintf(file, "%c%s %s", punc,
- inet_ntoa(inaddr), protop->p_name);
- else
- fprintf(file, "%c%s %d", punc,
- inet_ntoa(inaddr), proto);
- }
- n = 0;
- while (cp < cp1 + dlen) {
- c = *cp++;
- do {
- if (c & 0200) {
- servp = NULL;
- if (protop)
- servp = getservbyport(htons(n),
- protop->
- p_name);
- if (doprint) {
- if (servp)
- fprintf(file, " %s",
- servp->s_name);
- else
- fprintf(file, " %d",
- n);
- }
- }
- c <<= 1;
- } while (++n & 07);
- }
- break;
- case ns_t_nxt:
- {
- const u_char *startrdata = cp;
- u_char cdname[NS_MAXCDNAME];
- size_t bitmaplen;
-
- cp = pr_cdname(cp, msg, name, sizeof name);
- if (doprint)
- fprintf(file, "%c%s", punc, name);
- bitmaplen = dlen - (cp - startrdata);
-
- /* extract dnssec canonical rr */
-
- n = ns_name_unpack(msg, msg+MY_PACKETSZ, startrdata,
- cdname, sizeof cdname);
- if (n >= 0)
- n = ns_name_ntol(cdname, cdname, sizeof cdname);
- if (n >= 0) {
- /* Copy header. */
- memcpy(canonrr, cp1 - NS_HEADERDATA_SIZE,
- NS_HEADERDATA_SIZE);
- /* Overwrite length field. */
- ns_put16(n + bitmaplen,
- canonrr + NS_HEADERDATA_SIZE - NS_INT16SZ);
- /* Copy expanded name. */
- memcpy(canonrr + NS_HEADERDATA_SIZE, cdname, n);
- /* Copy type bit map. */
- memcpy(canonrr + NS_HEADERDATA_SIZE + n, cp,
- bitmaplen);
- canonrr_len = NS_HEADERDATA_SIZE + n + bitmaplen;
- }
- cp += bitmaplen;
- break;
- }
- case ns_t_sig:
- {
- int tc;
- const u_char *origttl;
-
- /* type covered */
- tc = ns_get16(cp);
- if (doprint && verbose)
- fprintf(file, "%c%s", punc, sym_ntos(__p_type_syms, tc, NULL));
- cp += sizeof(u_short);
- /* algorithm */
- if (doprint && verbose)
- fprintf(file, " %d", *cp);
- cp++;
- /* labels */
- if (doprint && verbose)
- fprintf(file, " %d", *cp);
- cp++;
- /* original ttl */
- origttl = cp;
- if (doprint && verbose)
- fprintf(file, " %lu", ns_get32(cp));
- cp += INT32SZ;
- /* signature expiration */
- if (doprint && verbose)
- fprintf(file, " %lu", ns_get32(cp));
- cp += INT32SZ;
- /* time signed */
- if (doprint && verbose)
- fprintf(file, " %lu", ns_get32(cp));
- cp += INT32SZ;
- /* key footprint */
- if (doprint && verbose)
- fprintf(file, " %d", ns_get16(cp));
- cp += sizeof(u_short);
- /* signer's name */
- cp = pr_cdname(cp, msg, name, sizeof(name));
- if (doprint && verbose)
- fprintf(file, " %s", name);
- else if (doprint && !verbose)
- fprintf (file, " %s for type %s", name,
- sym_ntos(__p_type_syms, tc, NULL));
- /* signature */
- {
- char str[MY_PACKETSZ];
- size_t len = cp1-cp+dlen;
-
- b64_ntop (cp, len, str, MY_PACKETSZ-1);
-
- if (sigchase && !(chase_step & SD_SIG) &&
- strcmp (chase_domain, thisdomain) == 0 &&
- chase_class == class && chase_type == tc)
- {
- u_char cdname[NS_MAXCDNAME];
-
- if (doprint && !verbose)
- fprintf(file, " (chasing key)");
-
- strcpy(chase_signer, name);
-
- memcpy(&chase_sigorigttl[0], origttl,
- NS_INT32SZ);
-
- n = ns_name_ntol(cp1 + SIG_RDATA_BY_NAME,
- cdname, sizeof cdname);
- if (n >= 0) {
- memcpy(chase_sigrdata, cp1,
- SIG_RDATA_BY_NAME);
- memcpy(chase_sigrdata + SIG_RDATA_BY_NAME,
- cdname, n);
- chase_sigrdata_len = SIG_RDATA_BY_NAME + n;
- memcpy(chase_signature, cp, len);
- chase_signature_len = len;
-
- chase_step |= SD_SIG;
- }
- } else if (sigchase) {
- chase_step |= SD_BADSIG;
- }
-
- cp += len;
- if (doprint && verbose)
- fprintf (file, " %s", str);
- }
- break;
- }
- case ns_t_key:
- /* flags */
- if (doprint && verbose)
- fprintf(file, "%c%d", punc, ns_get16(cp));
- cp += sizeof(u_short);
- /* protocol */
- if (doprint && verbose)
- fprintf(file, " %d", *cp);
- cp++;
- /* algorithm */
- n = *cp;
- if (doprint && verbose)
- fprintf(file, " %d", *cp);
- cp++;
- switch (n) {
- case 1: /* MD5/RSA */
- {
- char str[MY_PACKETSZ];
- size_t len = cp1-cp+dlen;
-
- b64_ntop (cp, len, str, MY_PACKETSZ-1);
- cp += len;
-
- if (doprint && verbose)
- fprintf (file, " %s", str);
- break;
- }
-
- default:
- if (doprint && verbose)
- fprintf (stderr, "Unknown algorithm %d\n", n);
- cp = cp1 + dlen;
- break;
- }
-
- if (sigchase && (chase_step & (SD_SIG|SD_RR)) &&
- strcmp (getdomain, name) == 0 &&
- getclass == class && gettype == type)
- {
- DST_KEY *dstkey;
- int rc, len, i, j;
-
- /* convert dnskey to dstkey */
-
- dstkey = dst_dnskey_to_key (name, cp1, dlen);
-
- /* fix ttl in rr */
-
- for (i = 0; i < NUMRR && chase_rr[i].len; i++)
- {
- len = dn_skipname(chase_rr[i].data,
- chase_rr[i].data +
- chase_rr[i].len);
- if (len>=0)
- memcpy(chase_rr[i].data + len + NS_INT16SZ +
- NS_INT16SZ,
- &chase_sigorigttl, INT32SZ);
- }
-
- /* sort rr's (qsort() is too slow) */
-
- for (i = 0; i < NUMRR && chase_rr[i].len; i++)
- for (j = i + 1; j < NUMRR && chase_rr[j].len;
- j++)
- if (memcmp(chase_rr[i].data,
- chase_rr[j].data,
- MY_PACKETSZ) < 0)
- memswap(&chase_rr[i],
- &chase_rr[j],
- sizeof(rrstruct));
- /* append rr's to sigrdata */
-
- for (i = 0; i < NUMRR && chase_rr[i].len; i++)
- {
- memcpy (chase_sigrdata + chase_sigrdata_len,
- chase_rr[i].data, chase_rr[i].len);
- chase_sigrdata_len += chase_rr[i].len;
- }
-
- /* print rr-data and signature */
-
- if (verbose) {
- fprintf(file, "\n");
- print_hex_field(chase_sigrdata,
- chase_sigrdata_len,
- 21,"DATA: ");
- print_hex_field(chase_signature,
- chase_signature_len,
- 21,"SIG: ");
- }
-
- /* do the works */
-
- if (dstkey)
- rc = dst_verify_data(SIG_MODE_ALL, dstkey, NULL,
- chase_sigrdata,
- chase_sigrdata_len,
- chase_signature,
- chase_signature_len);
- else
- rc = 1;
-
- dst_free_key(dstkey);
-
- if (verbose)
- {
- fprintf(file, "\nVerification %s", rc == 0 ?
- "was SUCCESSFULL" :
- "FAILED");
- }
- else
- {
- fprintf (file,
- " that %s verify our %s "
- "record(s) on %s",
- rc == 0 ? "successfully" :
- "DOES NOT",
- sym_ntos(__p_type_syms, chase_type,
- NULL),
- chase_domain);
- }
-
- if (rc == 0)
- {
- strcpy (chase_lastgoodkey, name);
- }
- else
- {
- /* don't trace further after a failure */
- sigchase = 0;
- }
-
- chase_step = 0;
- chase_signature_len = 0;
- chase_sigrdata_len = 0;
- memset(chase_sigorigttl, 0, NS_INT32SZ);
- memset(chase_rr, 0, sizeof(chase_rr));
- chase_rr_num = 0;
- }
- break;
-
- default:
- if (doprint)
- fprintf(file, "%c???", punc);
- cp += dlen;
- break;
- }
- if (cp != cp1 + dlen)
- fprintf(file, "packet size error (%p != %p)\n",
- cp, cp1 + dlen);
-
- if (sigchase && !(chase_step & SD_SIG) &&
- strcmp (getdomain, thisdomain) == 0 && getclass == class &&
- gettype == type && type != ns_t_sig)
- {
- u_char cdname[NS_MAXCDNAME];
-
- if (doprint && !verbose)
- fprintf(file, " (chasing signature)");
-
- /* unpack rr */
-
- n = ns_name_unpack(msg, msg + MY_PACKETSZ, savecp,
- cdname, sizeof cdname);
- if (n >= 0)
- n = ns_name_ntol(cdname, cdname, sizeof cdname);
- if (n >= 0) {
- memcpy(chase_rr[chase_rr_num].data, cdname, n);
- memcpy(chase_rr[chase_rr_num].data + n,
- canonrr_len ? canonrr : cp1 - NS_HEADERDATA_SIZE,
- canonrr_len ? canonrr_len : dlen + NS_HEADERDATA_SIZE);
- chase_rr[chase_rr_num].len =
- n + (canonrr_len != 0 ? canonrr_len :
- dlen + NS_HEADERDATA_SIZE);
-
- strcpy(chase_domain, getdomain);
- chase_class = class;
- chase_type = type;
- chase_step |= SD_RR;
- chase_rr_num++;
- }
- }
-
- if (doprint)
- fprintf(file, "\n");
-
- return (cp);
-}
-
-/*
- * Return a string for the type. A few get special treatment when
- * not in verbose mode, to make the program more chatty and easier to
- * understand.
- */
-static const char *
-pr_type(int type) {
- if (!verbose) switch (type) {
- case ns_t_a:
- case ns_t_aaaa:
- return ("has address");
- case ns_t_cname:
- return ("is a nickname for");
- case ns_t_mx:
- return ("mail is handled");
- case ns_t_txt:
- return ("descriptive text");
- case ns_t_sig:
- return ("has a signature signed by");
- case ns_t_key:
- return ("has a key");
- case ns_t_nxt:
- return ("next valid name");
- case ns_t_afsdb:
- return ("DCE or AFS service from");
- }
- if (verbose)
- return (sym_ntos(__p_type_syms, type, NULL));
- else
- return (sym_ntop(__p_type_syms, type, NULL));
-}
-
-/*
- * Return a mnemonic for class
- */
-static const char *
-pr_class(int class) {
- static char spacestr[20];
-
- if (!verbose) switch (class) {
- case ns_c_in: /* internet class */
- return ("");
- case ns_c_hs: /* hesiod class */
- return ("");
- }
-
- spacestr[0] = ' ';
- strcpy(&spacestr[1], p_class(class));
- return (spacestr);
-}
-
-static const u_char *
-pr_cdname(const u_char *cp, const u_char *msg, char *name, int namelen) {
- int n = dn_expand(msg, msg + MY_PACKETSZ, cp, name, namelen - 2);
-
- if (n < 0)
- return (NULL);
- if (name[0] == '\0') {
- name[0] = '.';
- name[1] = '\0';
- }
- return (cp + n);
-}
-
-static void
-add(union res_sockaddr_union *u, int type, void *p) {
- memset(u, 0, sizeof(*u));
- switch (type) {
- case ns_t_a:
- memcpy(&u->sin.sin_addr, p, NS_INADDRSZ);
- u->sin.sin_family = AF_INET;
- u->sin.sin_port = htons(NAMESERVER_PORT);
-#ifdef HAVE_SA_LEN
- u->sin.sin_len = sizeof(u->sin);
-#endif
- break;
-
- case ns_t_aaaa:
- memcpy(&u->sin6.sin6_addr, p, 16);
- u->sin6.sin6_family = AF_INET6;
- u->sin6.sin6_port = htons(NAMESERVER_PORT);
-#ifdef HAVE_SA_LEN
- u->sin6.sin6_len = sizeof(u->sin6);
-#endif
- break;
- }
-}
-
-static int
-salen(union res_sockaddr_union *u) {
- switch (u->sin.sin_family) {
- case AF_INET6: return (sizeof(u->sin6));
- case AF_INET: return (sizeof(u->sin));
- }
- return (0);
-}
-
-static int
-ListHosts(char *namePtr, int queryType) {
- querybuf buf, answer;
- struct sockaddr_in sin;
- const HEADER *headerPtr;
- enum { NO_ERRORS, ERR_READING_LEN, ERR_READING_MSG, ERR_PRINTING }
- error = NO_ERRORS;
-
- int msglen, amtToRead, numRead, i, len, dlen, type, nscount, n;
- int numAnswers = 0, soacnt = 0, result = 0;
- u_char tmp[NS_INT16SZ];
- char name[NS_MAXDNAME], dname[2][NS_MAXDNAME], domain[NS_MAXDNAME];
- u_char *cp, *nmp, *eom;
-
- /* Names and addresses of name servers to try. */
- char nsname[NUMNS][NS_MAXDNAME];
- int nshaveaddr[NUMNS];
- union res_sockaddr_union nsipaddr[NUMNSADDR];
- int numns, numnsaddr, thisns;
- int qdcount, ancount;
-
- /*
- * Normalize to not have trailing dot. We do string compares below
- * of info from name server, and it won't have trailing dots.
- */
- i = strlen(namePtr);
- if (namePtr[i-1] == '.')
- namePtr[i-1] = 0;
-
- if (server_specified)
- numnsaddr = res_getservers(&res, nsipaddr, NUMNSADDR);
- else {
- /*
- * First we have to find out where to look. This needs a NS
- * query, possibly followed by looking up addresses for some
- * of the names.
- */
- msglen = res_nmkquery(&res, ns_o_query, namePtr,
- ns_c_in, ns_t_ns,
- NULL, 0, NULL,
- buf.qb2, sizeof buf);
- if (msglen < 0) {
- printf("res_nmkquery failed\n");
- return (ERROR);
- }
-
- msglen = res_nsend(&res, buf.qb2, msglen,
- answer.qb2, sizeof answer);
- if (msglen < 0) {
- printf("Cannot find nameserver -- try again later\n");
- return (ERROR);
- }
- if (res.options & RES_DEBUG || verbose)
- printf("rcode = %d (%s), ancount=%d\n",
- answer.qb1.rcode, DecodeError(answer.qb1.rcode),
- ntohs(answer.qb1.ancount));
-
- /*
- * Analyze response to our NS lookup.
- */
-
- nscount = ntohs(answer.qb1.ancount) +
- ntohs(answer.qb1.nscount) +
- ntohs(answer.qb1.arcount);
-
- if (answer.qb1.rcode != NOERROR || nscount == 0) {
- switch (answer.qb1.rcode) {
- case NXDOMAIN:
- /* Check if it's an authoritive answer */
- if (answer.qb1.aa)
- printf("No such domain\n");
- else
- printf("Unable to get information about domain -- try again later.\n");
- break;
- case SERVFAIL:
- printf("Unable to get information about that domain -- try again later.\n");
- break;
- case NOERROR:
- printf("That domain exists, but seems to be a leaf node.\n");
- break;
- case FORMERR:
- case NOTIMP:
- case REFUSED:
- printf("Unrecoverable error looking up domain name.\n");
- break;
- }
- return (0);
- }
-
- cp = answer.qb2 + HFIXEDSZ;
- eom = answer.qb2 + msglen;
- qdcount = ntohs(answer.qb1.qdcount);
- while (qdcount-- > 0) {
- n = dn_skipname(cp, eom);
- if (n < 0) {
- printf("Form error.\n");
- return (ERROR);
- }
- cp += n + QFIXEDSZ;
- if (cp > eom) {
- printf("Form error.\n");
- return (ERROR);
- }
- }
-
- numns = 0;
- numnsaddr = 0;
-
- /*
- * Look at response from NS lookup for NS and A records.
- */
-
- for ((void)NULL; nscount; nscount--) {
- cp += dn_expand(answer.qb2, answer.qb2 + msglen, cp,
- domain, sizeof(domain));
- if (cp + 3 * INT16SZ + INT32SZ > eom) {
- printf("Form error.\n");
- return (ERROR);
- }
- type = ns_get16(cp);
- cp += INT16SZ + INT16SZ + INT32SZ;
- dlen = ns_get16(cp);
- cp += INT16SZ;
- if (cp + dlen > eom) {
- printf("Form error.\n");
- return (ERROR);
- }
- if (type == ns_t_ns) {
- if (dn_expand(answer.qb2, eom,
- cp, name, sizeof(name)) >= 0) {
- if (numns < NUMNS &&
- ns_samename((char *)domain,
- namePtr) == 1) {
- for (i = 0; i < numns; i++)
- if (ns_samename(
- nsname[i],
- (char *)name
- ) == 1)
- /* duplicate */
- break;
- if (i >= numns) {
- strncpy(nsname[numns],
- (char *)name,
- sizeof(name));
- nshaveaddr[numns] = 0;
- numns++;
- }
- }
- }
- } else if ((type == ns_t_a || type == ns_t_aaaa) &&
- numnsaddr < NUMNSADDR) {
- for (i = 0; i < numns; i++) {
- if (ns_samename(nsname[i],
- (char *)domain)
- != 1)
- continue;
- nshaveaddr[i]++;
- add(&nsipaddr[numnsaddr++], type, cp);
- break;
- }
- }
- cp += dlen;
- }
-
- /*
- * Usually we'll get addresses for all the servers in the
- * additional info section. But in case we don't, look up
- * their addresses.
- */
-
- for (i = 0; i < numns; i++) {
- struct addrinfo *answer = NULL;
- struct addrinfo *cur = NULL;
- struct addrinfo hint;
-
- memset(&hint, 0, sizeof(hint));
- hint.ai_family = PF_UNSPEC;
- hint.ai_socktype = SOCK_STREAM;
-
- if (nshaveaddr[i] == 0 &&
- !getaddrinfo(nsname[i], NULL, &hint, &answer)) {
- int numaddrs = 0;
- for (cur = answer;
- cur != NULL;
- cur = cur->ai_next) {
- union res_sockaddr_union *u;
-
- if (numnsaddr >= NUMNSADDR)
- break;
-
- u = &nsipaddr[numnsaddr];
- switch (cur->ai_addr->sa_family) {
- case AF_INET6:
- u->sin6 =
- *(struct sockaddr_in6 *)cur->ai_addr;
- u->sin6.sin6_port =
- htons(NAMESERVER_PORT);
- numnsaddr++;
- numaddrs++;
- break;
- case AF_INET:
- u->sin =
- *(struct sockaddr_in*)cur->ai_addr;
- u->sin6.sin6_port =
- htons(NAMESERVER_PORT);
- numnsaddr++;
- numaddrs++;
- break;
- }
- }
- if (res.options & RES_DEBUG || verbose)
- printf(
- "Found %d addresses for %s by extra query\n",
- numaddrs, nsname[i]);
- freeaddrinfo(answer);
- } else if (res.options & RES_DEBUG || verbose)
- printf("Found %d addresses for %s\n",
- nshaveaddr[i], nsname[i]);
- }
- }
- /*
- * Now nsipaddr has numnsaddr addresses for name servers that
- * serve the requested domain. Now try to find one that will
- * accept a zone transfer.
- */
- thisns = 0;
-
- again:
- numAnswers = 0;
- soacnt = 0;
-
- /*
- * Create a query packet for the requested domain name.
- */
- msglen = res_nmkquery(&res, QUERY, namePtr, getclass, ns_t_axfr, NULL,
- 0, NULL, buf.qb2, sizeof buf);
- if (msglen < 0) {
- if (res.options & RES_DEBUG)
- fprintf(stderr, "ListHosts: Res_mkquery failed\n");
- return (ERROR);
- }
-
- memset(&sin, 0, sizeof sin);
- sin.sin_family = AF_INET;
- sin.sin_port = htons(NAMESERVER_PORT);
-
- /*
- * Set up a virtual circuit to the server.
- */
-
- for ((void)NULL; thisns < numnsaddr; thisns++) {
- if ((sockFD = socket(nsipaddr[thisns].sin.sin_family,
- SOCK_STREAM, 0)) < 0) {
- if (errno == EPROTONOSUPPORT)
- continue;
- perror("ListHosts");
- return (ERROR);
- }
- if (res.options & RES_DEBUG || verbose) {
- char buf[80];
- switch (nsipaddr[thisns].sin.sin_family) {
- case AF_INET:
- inet_ntop(nsipaddr[thisns].sin.sin_family,
- &nsipaddr[thisns].sin.sin_addr,
- buf, sizeof(buf));
- break;
- case AF_INET6:
- inet_ntop(nsipaddr[thisns].sin6.sin6_family,
- &nsipaddr[thisns].sin6.sin6_addr,
- buf, sizeof(buf));
- break;
- }
- printf("Trying %s\n", buf);
- }
- if (connect(sockFD, (struct sockaddr *)&nsipaddr[thisns],
- salen(&nsipaddr[thisns])) >= 0)
- break;
- if (verbose)
- perror("Connection failed, trying next server");
- close(sockFD);
- sockFD = -1;
- }
- if (thisns >= numnsaddr) {
- printf("No server for that domain responded\n");
- if (!verbose)
- perror("Error from the last server was");
- return (ERROR);
- }
-
- /*
- * Send length & message for zone transfer
- */
-
- ns_put16(msglen, tmp);
- if (write(sockFD, (char *)tmp, INT16SZ) != INT16SZ ||
- write(sockFD, (char *)buf.qb2, msglen) != msglen) {
- perror("ListHosts");
- (void) close(sockFD);
- sockFD = -1;
- return (ERROR);
- }
-
- filePtr = stdout;
-
- for (;;) {
- /*
- * Read the length of the response.
- */
- cp = buf.qb2;
- amtToRead = INT16SZ;
- while (amtToRead > 0 &&
- (numRead = read(sockFD, cp, amtToRead)) > 0) {
- cp += numRead;
- amtToRead -= numRead;
- }
- if (numRead <= 0) {
- error = ERR_READING_LEN;
- break;
- }
-
- if ((len = ns_get16(buf.qb2)) == 0)
- break; /* Protocol violation. */
-
- /*
- * Read the response.
- */
-
- amtToRead = len;
- cp = buf.qb2;
- while (amtToRead > 0 &&
- (numRead = read(sockFD, cp, amtToRead)) > 0) {
- cp += numRead;
- amtToRead -= numRead;
- }
- if (numRead <= 0) {
- error = ERR_READING_MSG;
- break;
- }
-
- i = buf.qb1.rcode;
- if (i != NOERROR || ntohs(buf.qb1.ancount) == 0) {
- if (thisns + 1 < numnsaddr &&
- (i == SERVFAIL || i == NOTIMP || i == REFUSED)) {
- if (res.options & RES_DEBUG || verbose)
- printf(
- "Server failed, trying next server: %s\n",
- i != NOERROR
- ? DecodeError(i)
- : "Premature end of data");
- (void) close(sockFD);
- sockFD = -1;
- thisns++;
- goto again;
- }
- printf("Server failed: %s\n", i != NOERROR
- ? DecodeError(i) : "Premature end of data");
- break;
- }
-
- result = printinfo(&buf, cp, queryType, 1, 0);
- if (! result) {
- error = ERR_PRINTING;
- break;
- }
- numAnswers++;
- cp = buf.qb2 + HFIXEDSZ;
- qdcount = ntohs(buf.qb1.qdcount);
- while (qdcount-- > 0) {
- n = dn_skipname(cp, buf.qb2 + len);
- if (n <= 0) {
- error = ERR_PRINTING;
- break;
- }
- if (cp + n + QFIXEDSZ > buf.qb2 + len) {
- error = ERR_PRINTING;
- break;
- }
- cp += n + QFIXEDSZ;
- }
- ancount = ntohs(buf.qb1.ancount);
- while (ancount-- > 0) {
- nmp = cp;
- n = dn_skipname(cp, buf.qb2 + len);
- if (n <= 0) {
- error = ERR_PRINTING;
- break;
- }
- cp += n;
- if (cp + INT16SZ > buf.qb2 + len) {
- error = ERR_PRINTING;
- break;
- }
- type = ns_get16(cp);
- cp += INT16SZ;
- if (type == ns_t_soa) {
- (void) dn_expand(buf.qb2, buf.qb2 + len, nmp,
- dname[soacnt], sizeof dname[0]);
- if (soacnt) {
- if (ns_samename(dname[0], dname[1]) == 1)
- goto done;
- } else
- soacnt++;
- }
- if (cp + INT16SZ*2 + INT32SZ > buf.qb2 + len) {
- error = ERR_PRINTING;
- break;
- }
- cp += INT32SZ + INT16SZ;
- dlen = ns_get16(cp);
- cp += INT16SZ;
- if (cp + dlen > buf.qb2 + len) {
- error = ERR_PRINTING;
- break;
- }
- cp += dlen;
- }
- if (error != NO_ERRORS)
- break;
- }
- done:
-
- (void) close(sockFD);
- sockFD = -1;
-
- switch (error) {
- case NO_ERRORS:
- return (SUCCESS);
-
- case ERR_READING_LEN:
- return (ERROR);
-
- case ERR_PRINTING:
- fprintf(stderr,"*** Error during listing of %s: %s\n",
- namePtr, DecodeError(result));
- return (result);
-
- case ERR_READING_MSG:
- headerPtr = (HEADER *) &buf;
- fprintf(stderr,"ListHosts: error receiving zone transfer:\n");
- fprintf(stderr,
- " result: %s, answers = %d, authority = %d, additional = %d\n",
- p_rcode(headerPtr->rcode),
- ntohs(headerPtr->ancount), ntohs(headerPtr->nscount),
- ntohs(headerPtr->arcount));
- return (ERROR);
- default:
- return (ERROR);
- }
-}
-
-static const char *
-DecodeError(int result) {
- switch(result) {
- case NOERROR: return ("Success");
- case FORMERR: return ("Format error");
- case SERVFAIL: return ("Server failed");
- case NXDOMAIN: return ("Non-existent domain");
- case NOTIMP: return ("Not implemented");
- case REFUSED: return ("Query refused");
- case NO_INFO: return ("No information");
- case ERROR: return ("Unspecified error");
- case TIME_OUT: return ("Timed out");
- case NONAUTH: return ("Non-authoritative answer");
- default: return ("BAD ERROR VALUE");
- }
- /* NOTREACHED */
-}
OpenPOWER on IntegriCloud