Blame resolv/res_debug.c

Packit Service 82fcde
/*
Packit Service 82fcde
 * Copyright (c) 1985
Packit Service 82fcde
 *    The Regents of the University of California.  All rights reserved.
Packit Service 82fcde
 *
Packit Service 82fcde
 * Redistribution and use in source and binary forms, with or without
Packit Service 82fcde
 * modification, are permitted provided that the following conditions
Packit Service 82fcde
 * are met:
Packit Service 82fcde
 * 1. Redistributions of source code must retain the above copyright
Packit Service 82fcde
 *    notice, this list of conditions and the following disclaimer.
Packit Service 82fcde
 * 2. Redistributions in binary form must reproduce the above copyright
Packit Service 82fcde
 *    notice, this list of conditions and the following disclaimer in the
Packit Service 82fcde
 *    documentation and/or other materials provided with the distribution.
Packit Service 82fcde
 * 4. Neither the name of the University nor the names of its contributors
Packit Service 82fcde
 *    may be used to endorse or promote products derived from this software
Packit Service 82fcde
 *    without specific prior written permission.
Packit Service 82fcde
 *
Packit Service 82fcde
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
Packit Service 82fcde
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit Service 82fcde
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit Service 82fcde
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
Packit Service 82fcde
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit Service 82fcde
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit Service 82fcde
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit Service 82fcde
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit Service 82fcde
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
Packit Service 82fcde
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
Packit Service 82fcde
 * SUCH DAMAGE.
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
Packit Service 82fcde
 *
Packit Service 82fcde
 * Permission to use, copy, modify, and distribute this software for any
Packit Service 82fcde
 * purpose with or without fee is hereby granted, provided that the above
Packit Service 82fcde
 * copyright notice and this permission notice appear in all copies, and that
Packit Service 82fcde
 * the name of Digital Equipment Corporation not be used in advertising or
Packit Service 82fcde
 * publicity pertaining to distribution of the document or software without
Packit Service 82fcde
 * specific, written prior permission.
Packit Service 82fcde
 *
Packit Service 82fcde
 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
Packit Service 82fcde
 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
Packit Service 82fcde
 * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
Packit Service 82fcde
 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
Packit Service 82fcde
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
Packit Service 82fcde
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
Packit Service 82fcde
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
Packit Service 82fcde
 * SOFTWARE.
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Portions Copyright (c) 1995 by International Business Machines, Inc.
Packit Service 82fcde
 *
Packit Service 82fcde
 * International Business Machines, Inc. (hereinafter called IBM) grants
Packit Service 82fcde
 * permission under its copyrights to use, copy, modify, and distribute this
Packit Service 82fcde
 * Software with or without fee, provided that the above copyright notice and
Packit Service 82fcde
 * all paragraphs of this notice appear in all copies, and that the name of IBM
Packit Service 82fcde
 * not be used in connection with the marketing of any product incorporating
Packit Service 82fcde
 * the Software or modifications thereof, without specific, written prior
Packit Service 82fcde
 * permission.
Packit Service 82fcde
 *
Packit Service 82fcde
 * To the extent it has a right to do so, IBM grants an immunity from suit
Packit Service 82fcde
 * under its patents, if any, for the use, sale or manufacture of products to
Packit Service 82fcde
 * the extent that such products are used for performing Domain Name System
Packit Service 82fcde
 * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
Packit Service 82fcde
 * granted for any product per se or for any other function of any product.
Packit Service 82fcde
 *
Packit Service 82fcde
 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
Packit Service 82fcde
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
Packit Service 82fcde
 * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
Packit Service 82fcde
 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
Packit Service 82fcde
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
Packit Service 82fcde
 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
Packit Service 82fcde
 *
Packit Service 82fcde
 * Permission to use, copy, modify, and distribute this software for any
Packit Service 82fcde
 * purpose with or without fee is hereby granted, provided that the above
Packit Service 82fcde
 * copyright notice and this permission notice appear in all copies.
Packit Service 82fcde
 *
Packit Service 82fcde
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
Packit Service 82fcde
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
Packit Service 82fcde
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
Packit Service 82fcde
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
Packit Service 82fcde
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
Packit Service 82fcde
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
Packit Service 82fcde
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
Packit Service 82fcde
 * SOFTWARE.
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
#include <sys/types.h>
Packit Service 82fcde
#include <sys/param.h>
Packit Service 82fcde
#include <sys/socket.h>
Packit Service 82fcde
Packit Service 82fcde
#include <netinet/in.h>
Packit Service 82fcde
#include <arpa/inet.h>
Packit Service 82fcde
#include <arpa/nameser.h>
Packit Service 82fcde
Packit Service 82fcde
#include <ctype.h>
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <math.h>
Packit Service 82fcde
#include <netdb.h>
Packit Service 82fcde
#include <resolv/resolv-internal.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <time.h>
Packit Service 82fcde
#include <shlib-compat.h>
Packit Service 82fcde
#include <libc-diag.h>
Packit Service 82fcde
Packit Service 82fcde
#ifdef SPRINTF_CHAR
Packit Service 82fcde
# define SPRINTF(x) strlen(sprintf/**/x)
Packit Service 82fcde
#else
Packit Service 82fcde
# define SPRINTF(x) sprintf x
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
extern const char *_res_sectioncodes[] attribute_hidden;
Packit Service 82fcde
Packit Service 82fcde
/* _res_opcodes was exported by accident as a variable.  */
Packit Service 82fcde
#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_26)
Packit Service 82fcde
static const char *res_opcodes[] =
Packit Service 82fcde
#else
Packit Service 82fcde
static const char res_opcodes[][9] =
Packit Service 82fcde
#endif
Packit Service 82fcde
  {
Packit Service 82fcde
    "QUERY",
Packit Service 82fcde
    "IQUERY",
Packit Service 82fcde
    "CQUERYM",
Packit Service 82fcde
    "CQUERYU",	/* experimental */
Packit Service 82fcde
    "NOTIFY",	/* experimental */
Packit Service 82fcde
    "UPDATE",
Packit Service 82fcde
    "6",
Packit Service 82fcde
    "7",
Packit Service 82fcde
    "8",
Packit Service 82fcde
    "9",
Packit Service 82fcde
    "10",
Packit Service 82fcde
    "11",
Packit Service 82fcde
    "12",
Packit Service 82fcde
    "13",
Packit Service 82fcde
    "ZONEINIT",
Packit Service 82fcde
    "ZONEREF",
Packit Service 82fcde
  };
Packit Service 82fcde
#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_26)
Packit Service 82fcde
strong_alias (res_opcodes, _res_opcodes)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
static const char *p_section(int section, int opcode);
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Print the current options.
Packit Service 82fcde
 */
Packit Service 82fcde
void
Packit Service 82fcde
fp_resstat(const res_state statp, FILE *file) {
Packit Service 82fcde
	u_long mask;
Packit Service 82fcde
Packit Service 82fcde
	fprintf(file, ";; res options:");
Packit Service 82fcde
	for (mask = 1;  mask != 0;  mask <<= 1)
Packit Service 82fcde
		if (statp->options & mask)
Packit Service 82fcde
			fprintf(file, " %s", p_option(mask));
Packit Service 82fcde
	putc('\n', file);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
do_section (int pfcode, ns_msg *handle, ns_sect section, int pflag, FILE *file)
Packit Service 82fcde
{
Packit Service 82fcde
	int n, sflag, rrnum;
Packit Service 82fcde
	static int buflen = 2048;
Packit Service 82fcde
	char *buf;
Packit Service 82fcde
	ns_opcode opcode;
Packit Service 82fcde
	ns_rr rr;
Packit Service 82fcde
Packit Service 82fcde
	/*
Packit Service 82fcde
	 * Print answer records.
Packit Service 82fcde
	 */
Packit Service 82fcde
	sflag = (pfcode & pflag);
Packit Service 82fcde
	if (pfcode && !sflag)
Packit Service 82fcde
		return;
Packit Service 82fcde
Packit Service 82fcde
	buf = malloc(buflen);
Packit Service 82fcde
	if (buf == NULL) {
Packit Service 82fcde
		fprintf(file, ";; memory allocation failure\n");
Packit Service 82fcde
		return;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
	opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
Packit Service 82fcde
	rrnum = 0;
Packit Service 82fcde
	for (;;) {
Packit Service 82fcde
		if (ns_parserr(handle, section, rrnum, &rr)) {
Packit Service 82fcde
			if (errno != ENODEV)
Packit Service 82fcde
				fprintf(file, ";; ns_parserr: %s\n",
Packit Service 82fcde
					strerror(errno));
Packit Service 82fcde
			else if (rrnum > 0 && sflag != 0 &&
Packit Service 82fcde
				 (pfcode & RES_PRF_HEAD1))
Packit Service 82fcde
				putc('\n', file);
Packit Service 82fcde
			goto cleanup;
Packit Service 82fcde
		}
Packit Service 82fcde
		if (rrnum == 0 && sflag != 0 && (pfcode & RES_PRF_HEAD1))
Packit Service 82fcde
			fprintf(file, ";; %s SECTION:\n",
Packit Service 82fcde
				p_section(section, opcode));
Packit Service 82fcde
		if (section == ns_s_qd)
Packit Service 82fcde
			fprintf(file, ";;\t%s, type = %s, class = %s\n",
Packit Service 82fcde
				ns_rr_name(rr),
Packit Service 82fcde
				p_type(ns_rr_type(rr)),
Packit Service 82fcde
				p_class(ns_rr_class(rr)));
Packit Service 82fcde
		else {
Packit Service 82fcde
			n = ns_sprintrr(handle, &rr, NULL, NULL,
Packit Service 82fcde
					buf, buflen);
Packit Service 82fcde
			if (n < 0) {
Packit Service 82fcde
				if (errno == ENOSPC) {
Packit Service 82fcde
					free(buf);
Packit Service 82fcde
					buf = NULL;
Packit Service 82fcde
					if (buflen < 131072)
Packit Service 82fcde
						buf = malloc(buflen += 1024);
Packit Service 82fcde
					if (buf == NULL) {
Packit Service 82fcde
						fprintf(file,
Packit Service 82fcde
					      ";; memory allocation failure\n");
Packit Service 82fcde
					      return;
Packit Service 82fcde
					}
Packit Service 82fcde
					continue;
Packit Service 82fcde
				}
Packit Service 82fcde
				fprintf(file, ";; ns_sprintrr: %s\n",
Packit Service 82fcde
					strerror(errno));
Packit Service 82fcde
				goto cleanup;
Packit Service 82fcde
			}
Packit Service 82fcde
			fputs(buf, file);
Packit Service 82fcde
			fputc('\n', file);
Packit Service 82fcde
		}
Packit Service 82fcde
		rrnum++;
Packit Service 82fcde
	}
Packit Service 82fcde
 cleanup:
Packit Service 82fcde
	free(buf);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Print the contents of a query.
Packit Service 82fcde
 * This is intended to be primarily a debugging routine.
Packit Service 82fcde
 */
Packit Service 82fcde
void
Packit Service 82fcde
fp_nquery (const unsigned char *msg, int len, FILE *file)
Packit Service 82fcde
{
Packit Service 82fcde
	ns_msg handle;
Packit Service 82fcde
	int qdcount, ancount, nscount, arcount;
Packit Service 82fcde
	u_int opcode, rcode, id;
Packit Service 82fcde
Packit Service 82fcde
	/* There is no need to initialize _res: If _res is not yet
Packit Service 82fcde
	   initialized, _res.pfcode is zero.  But initialization will
Packit Service 82fcde
	   leave it at zero, too.  _res.pfcode is an unsigned long,
Packit Service 82fcde
	   but the code here assumes that the flags fit into an int,
Packit Service 82fcde
	   so use that.  */
Packit Service 82fcde
	int pfcode = _res.pfcode;
Packit Service 82fcde
Packit Service 82fcde
	if (ns_initparse(msg, len, &handle) < 0) {
Packit Service 82fcde
		fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
Packit Service 82fcde
		return;
Packit Service 82fcde
	}
Packit Service 82fcde
	opcode = ns_msg_getflag(handle, ns_f_opcode);
Packit Service 82fcde
	rcode = ns_msg_getflag(handle, ns_f_rcode);
Packit Service 82fcde
	id = ns_msg_id(handle);
Packit Service 82fcde
	qdcount = ns_msg_count(handle, ns_s_qd);
Packit Service 82fcde
	ancount = ns_msg_count(handle, ns_s_an);
Packit Service 82fcde
	nscount = ns_msg_count(handle, ns_s_ns);
Packit Service 82fcde
	arcount = ns_msg_count(handle, ns_s_ar);
Packit Service 82fcde
Packit Service 82fcde
	/*
Packit Service 82fcde
	 * Print header fields.
Packit Service 82fcde
	 */
Packit Service 82fcde
	if ((!pfcode) || (pfcode & RES_PRF_HEADX) || rcode)
Packit Service 82fcde
		fprintf(file,
Packit Service 82fcde
			";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
Packit Service 82fcde
			res_opcodes[opcode], p_rcode(rcode), id);
Packit Service 82fcde
	if ((!pfcode) || (pfcode & RES_PRF_HEADX))
Packit Service 82fcde
		putc(';', file);
Packit Service 82fcde
	if ((!pfcode) || (pfcode & RES_PRF_HEAD2)) {
Packit Service 82fcde
		fprintf(file, "; flags:");
Packit Service 82fcde
		if (ns_msg_getflag(handle, ns_f_qr))
Packit Service 82fcde
			fprintf(file, " qr");
Packit Service 82fcde
		if (ns_msg_getflag(handle, ns_f_aa))
Packit Service 82fcde
			fprintf(file, " aa");
Packit Service 82fcde
		if (ns_msg_getflag(handle, ns_f_tc))
Packit Service 82fcde
			fprintf(file, " tc");
Packit Service 82fcde
		if (ns_msg_getflag(handle, ns_f_rd))
Packit Service 82fcde
			fprintf(file, " rd");
Packit Service 82fcde
		if (ns_msg_getflag(handle, ns_f_ra))
Packit Service 82fcde
			fprintf(file, " ra");
Packit Service 82fcde
		if (ns_msg_getflag(handle, ns_f_z))
Packit Service 82fcde
			fprintf(file, " ??");
Packit Service 82fcde
		if (ns_msg_getflag(handle, ns_f_ad))
Packit Service 82fcde
			fprintf(file, " ad");
Packit Service 82fcde
		if (ns_msg_getflag(handle, ns_f_cd))
Packit Service 82fcde
			fprintf(file, " cd");
Packit Service 82fcde
	}
Packit Service 82fcde
	if ((!pfcode) || (pfcode & RES_PRF_HEAD1)) {
Packit Service 82fcde
		fprintf(file, "; %s: %d",
Packit Service 82fcde
			p_section(ns_s_qd, opcode), qdcount);
Packit Service 82fcde
		fprintf(file, ", %s: %d",
Packit Service 82fcde
			p_section(ns_s_an, opcode), ancount);
Packit Service 82fcde
		fprintf(file, ", %s: %d",
Packit Service 82fcde
			p_section(ns_s_ns, opcode), nscount);
Packit Service 82fcde
		fprintf(file, ", %s: %d",
Packit Service 82fcde
			p_section(ns_s_ar, opcode), arcount);
Packit Service 82fcde
	}
Packit Service 82fcde
	if ((!pfcode) || (pfcode &
Packit Service 82fcde
		(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
Packit Service 82fcde
		putc('\n',file);
Packit Service 82fcde
	}
Packit Service 82fcde
	/*
Packit Service 82fcde
	 * Print the various sections.
Packit Service 82fcde
	 */
Packit Service 82fcde
	do_section (pfcode, &handle, ns_s_qd, RES_PRF_QUES, file);
Packit Service 82fcde
	do_section (pfcode, &handle, ns_s_an, RES_PRF_ANS, file);
Packit Service 82fcde
	do_section (pfcode, &handle, ns_s_ns, RES_PRF_AUTH, file);
Packit Service 82fcde
	do_section (pfcode, &handle, ns_s_ar, RES_PRF_ADD, file);
Packit Service 82fcde
	if (qdcount == 0 && ancount == 0 &&
Packit Service 82fcde
	    nscount == 0 && arcount == 0)
Packit Service 82fcde
		putc('\n', file);
Packit Service 82fcde
}
Packit Service 82fcde
libresolv_hidden_def (fp_nquery)
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
fp_query (const unsigned char *msg, FILE *file)
Packit Service 82fcde
{
Packit Service 82fcde
  fp_nquery (msg, PACKETSZ, file);
Packit Service 82fcde
}
Packit Service 82fcde
libresolv_hidden_def (fp_query)
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
p_query (const unsigned char *msg)
Packit Service 82fcde
{
Packit Service 82fcde
  fp_query (msg, stdout);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
const u_char *
Packit Service 82fcde
p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {
Packit Service 82fcde
	char name[MAXDNAME];
Packit Service 82fcde
	int n;
Packit Service 82fcde
Packit Service 82fcde
	if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
Packit Service 82fcde
		return (NULL);
Packit Service 82fcde
	if (name[0] == '\0')
Packit Service 82fcde
		putc('.', file);
Packit Service 82fcde
	else
Packit Service 82fcde
		fputs(name, file);
Packit Service 82fcde
	return (cp + n);
Packit Service 82fcde
}
Packit Service 82fcde
libresolv_hidden_def (p_cdnname)
Packit Service 82fcde
Packit Service 82fcde
const u_char *
Packit Service 82fcde
p_cdname(const u_char *cp, const u_char *msg, FILE *file) {
Packit Service 82fcde
	return (p_cdnname(cp, msg, PACKETSZ, file));
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Return a fully-qualified domain name from a compressed name (with
Packit Service 82fcde
   length supplied).  */
Packit Service 82fcde
Packit Service 82fcde
const u_char *
Packit Service 82fcde
p_fqnname (const u_char *cp, const u_char *msg, int msglen, char *name,
Packit Service 82fcde
	   int namelen)
Packit Service 82fcde
{
Packit Service 82fcde
	int n, newlen;
Packit Service 82fcde
Packit Service 82fcde
	if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
Packit Service 82fcde
		return (NULL);
Packit Service 82fcde
	newlen = strlen(name);
Packit Service 82fcde
	if (newlen == 0 || name[newlen - 1] != '.') {
Packit Service 82fcde
		if (newlen + 1 >= namelen)	/* Lack space for final dot */
Packit Service 82fcde
			return (NULL);
Packit Service 82fcde
		else
Packit Service 82fcde
			strcpy(name + newlen, ".");
Packit Service 82fcde
	}
Packit Service 82fcde
	return (cp + n);
Packit Service 82fcde
}
Packit Service 82fcde
libresolv_hidden_def (p_fqnname)
Packit Service 82fcde
Packit Service 82fcde
/* XXX:	the rest of these functions need to become length-limited, too. */
Packit Service 82fcde
Packit Service 82fcde
const u_char *
Packit Service 82fcde
p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
Packit Service 82fcde
	char name[MAXDNAME];
Packit Service 82fcde
	const u_char *n;
Packit Service 82fcde
Packit Service 82fcde
	n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
Packit Service 82fcde
	if (n == NULL)
Packit Service 82fcde
		return (NULL);
Packit Service 82fcde
	fputs(name, file);
Packit Service 82fcde
	return (n);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Names of RR classes and qclasses.  Classes and qclasses are the same, except
Packit Service 82fcde
 * that C_ANY is a qclass but not a class.  (You can ask for records of class
Packit Service 82fcde
 * C_ANY, but you can't have any records of that class in the database.)
Packit Service 82fcde
 */
Packit Service 82fcde
extern const struct res_sym __p_class_syms[];
Packit Service 82fcde
libresolv_hidden_proto (__p_class_syms)
Packit Service 82fcde
const struct res_sym __p_class_syms[] = {
Packit Service 82fcde
  {C_IN,    (char *) "IN"},
Packit Service 82fcde
  {C_CHAOS, (char *) "CHAOS"},
Packit Service 82fcde
  {C_HS,    (char *) "HS"},
Packit Service 82fcde
  {C_HS,    (char *) "HESIOD"},
Packit Service 82fcde
  {C_ANY,   (char *) "ANY"},
Packit Service 82fcde
  {C_NONE,  (char *) "NONE"},
Packit Service 82fcde
  {C_IN, NULL, NULL}
Packit Service 82fcde
};
Packit Service 82fcde
libresolv_hidden_data_def (__p_class_syms)
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Names of message sections.
Packit Service 82fcde
 */
Packit Service 82fcde
const struct res_sym __p_default_section_syms[] attribute_hidden = {
Packit Service 82fcde
  {ns_s_qd, (char *) "QUERY"},
Packit Service 82fcde
  {ns_s_an, (char *) "ANSWER"},
Packit Service 82fcde
  {ns_s_ns, (char *) "AUTHORITY"},
Packit Service 82fcde
  {ns_s_ar, (char *) "ADDITIONAL"},
Packit Service 82fcde
  {0, NULL, NULL}
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
const struct res_sym __p_update_section_syms[] attribute_hidden = {
Packit Service 82fcde
  {S_ZONE,   (char *) "ZONE"},
Packit Service 82fcde
  {S_PREREQ, (char *) "PREREQUISITE"},
Packit Service 82fcde
  {S_UPDATE, (char *) "UPDATE"},
Packit Service 82fcde
  {S_ADDT,   (char *) "ADDITIONAL"},
Packit Service 82fcde
  {0, NULL, NULL}
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Names of RR types and qtypes.  The list is incomplete because its
Packit Service 82fcde
 * size is part of the ABI.
Packit Service 82fcde
 */
Packit Service 82fcde
extern const struct res_sym __p_type_syms[];
Packit Service 82fcde
libresolv_hidden_proto (__p_type_syms)
Packit Service 82fcde
const struct res_sym __p_type_syms[] = {
Packit Service 82fcde
  {ns_t_a,      (char *) "A",     (char *) "address"},
Packit Service 82fcde
  {ns_t_ns,     (char *) "NS",    (char *) "name server"},
Packit Service 82fcde
  {ns_t_md,     (char *) "MD",    (char *) "mail destination (deprecated)"},
Packit Service 82fcde
  {ns_t_mf,     (char *) "MF",    (char *) "mail forwarder (deprecated)"},
Packit Service 82fcde
  {ns_t_cname,  (char *) "CNAME", (char *) "canonical name"},
Packit Service 82fcde
  {ns_t_soa,    (char *) "SOA",   (char *) "start of authority"},
Packit Service 82fcde
  {ns_t_mb,     (char *) "MB",    (char *) "mailbox"},
Packit Service 82fcde
  {ns_t_mg,     (char *) "MG",    (char *) "mail group member"},
Packit Service 82fcde
  {ns_t_mr,     (char *) "MR",    (char *) "mail rename"},
Packit Service 82fcde
  {ns_t_null,   (char *) "NULL",  (char *) "null"},
Packit Service 82fcde
  {ns_t_wks,    (char *) "WKS",   (char *) "well-known service (deprecated)"},
Packit Service 82fcde
  {ns_t_ptr,    (char *) "PTR",   (char *) "domain name pointer"},
Packit Service 82fcde
  {ns_t_hinfo,  (char *) "HINFO", (char *) "host information"},
Packit Service 82fcde
  {ns_t_minfo,  (char *) "MINFO", (char *) "mailbox information"},
Packit Service 82fcde
  {ns_t_mx,     (char *) "MX",    (char *) "mail exchanger"},
Packit Service 82fcde
  {ns_t_txt,    (char *) "TXT",   (char *) "text"},
Packit Service 82fcde
  {ns_t_rp,     (char *) "RP",    (char *) "responsible person"},
Packit Service 82fcde
  {ns_t_afsdb,  (char *) "AFSDB", (char *) "DCE or AFS server"},
Packit Service 82fcde
  {ns_t_x25,    (char *) "X25",   (char *) "X25 address"},
Packit Service 82fcde
  {ns_t_isdn,   (char *) "ISDN",  (char *) "ISDN address"},
Packit Service 82fcde
  {ns_t_rt,     (char *) "RT",    (char *) "router"},
Packit Service 82fcde
  {ns_t_nsap,   (char *) "NSAP",  (char *) "nsap address"},
Packit Service 82fcde
  {ns_t_nsap_ptr, (char *) "NSAP_PTR", (char *) "domain name pointer"},
Packit Service 82fcde
  {ns_t_sig,    (char *) "SIG",   (char *) "signature"},
Packit Service 82fcde
  {ns_t_key,    (char *) "KEY",   (char *) "key"},
Packit Service 82fcde
  {ns_t_px,     (char *) "PX",    (char *) "mapping information"},
Packit Service 82fcde
  {ns_t_gpos,   (char *) "GPOS",
Packit Service 82fcde
   (char *) "geographical position (withdrawn)"},
Packit Service 82fcde
  {ns_t_aaaa,   (char *) "AAAA",  (char *) "IPv6 address"},
Packit Service 82fcde
  {ns_t_loc,    (char *) "LOC",   (char *) "location"},
Packit Service 82fcde
  {ns_t_nxt,    (char *) "NXT",   (char *) "next valid name (unimplemented)"},
Packit Service 82fcde
  {ns_t_eid,    (char *) "EID",   (char *) "endpoint identifier (unimplemented)"},
Packit Service 82fcde
  {ns_t_nimloc, (char *) "NIMLOC", (char *) "NIMROD locator (unimplemented)"},
Packit Service 82fcde
  {ns_t_srv,    (char *) "SRV",   (char *) "server selection"},
Packit Service 82fcde
  {ns_t_atma,   (char *) "ATMA",  (char *) "ATM address (unimplemented)"},
Packit Service 82fcde
  {ns_t_dname,  (char *) "DNAME", (char *) "Non-terminal DNAME (for IPv6)"},
Packit Service 82fcde
  {ns_t_tsig,   (char *) "TSIG",  (char *) "transaction signature"},
Packit Service 82fcde
  {ns_t_ixfr,   (char *) "IXFR",  (char *) "incremental zone transfer"},
Packit Service 82fcde
  {ns_t_axfr,   (char *) "AXFR",  (char *) "zone transfer"},
Packit Service 82fcde
  {ns_t_mailb,  (char *) "MAILB", (char *) "mailbox-related data (deprecated)"},
Packit Service 82fcde
  {ns_t_maila,  (char *) "MAILA", (char *) "mail agent (deprecated)"},
Packit Service 82fcde
  {ns_t_naptr,  (char *) "NAPTR", (char *) "URN Naming Authority"},
Packit Service 82fcde
  {ns_t_kx,     (char *) "KX",    (char *) "Key Exchange"},
Packit Service 82fcde
  {ns_t_cert,   (char *) "CERT",  (char *) "Certificate"},
Packit Service 82fcde
  {ns_t_any,    (char *) "ANY",   (char *) "\"any\""},
Packit Service 82fcde
  {0, NULL, NULL},		/* Padding to preserve ABI.  */
Packit Service 82fcde
  {0, NULL, NULL}
Packit Service 82fcde
};
Packit Service 82fcde
libresolv_hidden_data_def (__p_type_syms)
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Names of DNS rcodes.
Packit Service 82fcde
 */
Packit Service 82fcde
const struct res_sym __p_rcode_syms[] attribute_hidden = {
Packit Service 82fcde
  {ns_r_noerror,  (char *) "NOERROR",  (char *) "no error"},
Packit Service 82fcde
  {ns_r_formerr,  (char *) "FORMERR",  (char *) "format error"},
Packit Service 82fcde
  {ns_r_servfail, (char *) "SERVFAIL", (char *) "server failed"},
Packit Service 82fcde
  {ns_r_nxdomain, (char *) "NXDOMAIN", (char *) "no such domain name"},
Packit Service 82fcde
  {ns_r_notimpl,  (char *) "NOTIMP",   (char *) "not implemented"},
Packit Service 82fcde
  {ns_r_refused,  (char *) "REFUSED",  (char *) "refused"},
Packit Service 82fcde
  {ns_r_yxdomain, (char *) "YXDOMAIN", (char *) "domain name exists"},
Packit Service 82fcde
  {ns_r_yxrrset,  (char *) "YXRRSET",  (char *) "rrset exists"},
Packit Service 82fcde
  {ns_r_nxrrset,  (char *) "NXRRSET",  (char *) "rrset doesn't exist"},
Packit Service 82fcde
  {ns_r_notauth,  (char *) "NOTAUTH",  (char *) "not authoritative"},
Packit Service 82fcde
  {ns_r_notzone,  (char *) "NOTZONE",  (char *) "Not in zone"},
Packit Service 82fcde
  {ns_r_max,      (char *) "",         (char *) ""},
Packit Service 82fcde
  {ns_r_badsig,   (char *) "BADSIG",   (char *) "bad signature"},
Packit Service 82fcde
  {ns_r_badkey,   (char *) "BADKEY",   (char *) "bad key"},
Packit Service 82fcde
  {ns_r_badtime,  (char *) "BADTIME",  (char *) "bad time"},
Packit Service 82fcde
  {0, NULL, NULL}
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
sym_ston(const struct res_sym *syms, const char *name, int *success) {
Packit Service 82fcde
	for ((void)NULL; syms->name != 0; syms++) {
Packit Service 82fcde
		if (strcasecmp (name, syms->name) == 0) {
Packit Service 82fcde
			if (success)
Packit Service 82fcde
				*success = 1;
Packit Service 82fcde
			return (syms->number);
Packit Service 82fcde
		}
Packit Service 82fcde
	}
Packit Service 82fcde
	if (success)
Packit Service 82fcde
		*success = 0;
Packit Service 82fcde
	return (syms->number);		/* The default value. */
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
const char *
Packit Service 82fcde
sym_ntos(const struct res_sym *syms, int number, int *success) {
Packit Service 82fcde
	static char unname[20];
Packit Service 82fcde
Packit Service 82fcde
	for ((void)NULL; syms->name != 0; syms++) {
Packit Service 82fcde
		if (number == syms->number) {
Packit Service 82fcde
			if (success)
Packit Service 82fcde
				*success = 1;
Packit Service 82fcde
			return (syms->name);
Packit Service 82fcde
		}
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
	sprintf(unname, "%d", number);		/* XXX nonreentrant */
Packit Service 82fcde
	if (success)
Packit Service 82fcde
		*success = 0;
Packit Service 82fcde
	return (unname);
Packit Service 82fcde
}
Packit Service 82fcde
libresolv_hidden_def (sym_ntos)
Packit Service 82fcde
Packit Service 82fcde
const char *
Packit Service 82fcde
sym_ntop(const struct res_sym *syms, int number, int *success) {
Packit Service 82fcde
	static char unname[20];
Packit Service 82fcde
Packit Service 82fcde
	for ((void)NULL; syms->name != 0; syms++) {
Packit Service 82fcde
		if (number == syms->number) {
Packit Service 82fcde
			if (success)
Packit Service 82fcde
				*success = 1;
Packit Service 82fcde
			return (syms->humanname);
Packit Service 82fcde
		}
Packit Service 82fcde
	}
Packit Service 82fcde
	sprintf(unname, "%d", number);		/* XXX nonreentrant */
Packit Service 82fcde
	if (success)
Packit Service 82fcde
		*success = 0;
Packit Service 82fcde
	return (unname);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Return a string for the type.
Packit Service 82fcde
 */
Packit Service 82fcde
const char *
Packit Service 82fcde
p_type(int type) {
Packit Service 82fcde
	return (sym_ntos(__p_type_syms, type, (int *)0));
Packit Service 82fcde
}
Packit Service 82fcde
libresolv_hidden_def (p_type)
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Return a string for the type.
Packit Service 82fcde
 */
Packit Service 82fcde
static const char *
Packit Service 82fcde
p_section(int section, int opcode) {
Packit Service 82fcde
	const struct res_sym *symbols;
Packit Service 82fcde
Packit Service 82fcde
	switch (opcode) {
Packit Service 82fcde
	case ns_o_update:
Packit Service 82fcde
		symbols = __p_update_section_syms;
Packit Service 82fcde
		break;
Packit Service 82fcde
	default:
Packit Service 82fcde
		symbols = __p_default_section_syms;
Packit Service 82fcde
		break;
Packit Service 82fcde
	}
Packit Service 82fcde
	return (sym_ntos(symbols, section, (int *)0));
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Return a mnemonic for class.
Packit Service 82fcde
 */
Packit Service 82fcde
const char *
Packit Service 82fcde
p_class(int class) {
Packit Service 82fcde
	return (sym_ntos(__p_class_syms, class, (int *)0));
Packit Service 82fcde
}
Packit Service 82fcde
libresolv_hidden_def (p_class)
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Return a mnemonic for an option
Packit Service 82fcde
 */
Packit Service 82fcde
const char *
Packit Service 82fcde
p_option(u_long option) {
Packit Service 82fcde
	static char nbuf[40];
Packit Service 82fcde
Packit Service 82fcde
	switch (option) {
Packit Service 82fcde
	case RES_INIT:		return "init";
Packit Service 82fcde
	case RES_DEBUG:		return "debug";
Packit Service 82fcde
	case RES_USEVC:		return "use-vc";
Packit Service 82fcde
	case RES_IGNTC:		return "igntc";
Packit Service 82fcde
	case RES_RECURSE:	return "recurs";
Packit Service 82fcde
	case RES_DEFNAMES:	return "defnam";
Packit Service 82fcde
	case RES_STAYOPEN:	return "styopn";
Packit Service 82fcde
	case RES_DNSRCH:	return "dnsrch";
Packit Service 82fcde
	case RES_INSECURE1:	return "insecure1";
Packit Service 82fcde
	case RES_INSECURE2:	return "insecure2";
Packit Service 82fcde
	case RES_NOALIASES:	return "noaliases";
Packit Service 82fcde
	case DEPRECATED_RES_USE_INET6:	return "inet6";
Packit Service 82fcde
	case RES_ROTATE:	return "rotate";
Packit Service 82fcde
	case RES_USE_EDNS0:	return "edns0";
Packit Service 82fcde
	case RES_SNGLKUP:	return "single-request";
Packit Service 82fcde
	case RES_SNGLKUPREOP:	return "single-request-reopen";
Packit Service 82fcde
	case RES_USE_DNSSEC:	return "dnssec";
Packit Service 82fcde
	case RES_NOTLDQUERY:	return "no-tld-query";
Packit Service 82fcde
	case RES_NORELOAD:	return "no-reload";
Packit Service 82fcde
				/* XXX nonreentrant */
Packit Service 82fcde
	default:		sprintf(nbuf, "?0x%lx?", (u_long)option);
Packit Service 82fcde
				return (nbuf);
Packit Service 82fcde
	}
Packit Service 82fcde
}
Packit Service 82fcde
libresolv_hidden_def (p_option)
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Return a mnemonic for a time to live.
Packit Service 82fcde
 */
Packit Service 82fcde
const char *
Packit Service 82fcde
p_time(uint32_t value) {
Packit Service 82fcde
	static char nbuf[40];		/* XXX nonreentrant */
Packit Service 82fcde
Packit Service 82fcde
	if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0)
Packit Service 82fcde
		sprintf(nbuf, "%u", value);
Packit Service 82fcde
	return (nbuf);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Return a string for the rcode.
Packit Service 82fcde
 */
Packit Service 82fcde
const char *
Packit Service 82fcde
p_rcode(int rcode) {
Packit Service 82fcde
	return (sym_ntos(__p_rcode_syms, rcode, (int *)0));
Packit Service 82fcde
}
Packit Service 82fcde
libresolv_hidden_def (p_rcode)
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * routines to convert between on-the-wire RR format and zone file format.
Packit Service 82fcde
 * Does not contain conversion to/from decimal degrees; divide or multiply
Packit Service 82fcde
 * by 60*60*1000 for that.
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
static const unsigned int poweroften[10]=
Packit Service 82fcde
  { 1, 10, 100, 1000, 10000, 100000,
Packit Service 82fcde
    1000000,10000000,100000000,1000000000};
Packit Service 82fcde
Packit Service 82fcde
/* takes an XeY precision/size value, returns a string representation. */
Packit Service 82fcde
static const char *
Packit Service 82fcde
precsize_ntoa (uint8_t prec)
Packit Service 82fcde
{
Packit Service 82fcde
	static char retbuf[sizeof "90000000.00"];	/* XXX nonreentrant */
Packit Service 82fcde
	unsigned long val;
Packit Service 82fcde
	int mantissa, exponent;
Packit Service 82fcde
Packit Service 82fcde
	mantissa = (int)((prec >> 4) & 0x0f) % 10;
Packit Service 82fcde
	exponent = (int)((prec >> 0) & 0x0f) % 10;
Packit Service 82fcde
Packit Service 82fcde
	val = mantissa * poweroften[exponent];
Packit Service 82fcde
Packit Service 82fcde
	(void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);
Packit Service 82fcde
	return (retbuf);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* converts ascii size/precision X * 10**Y(cm) to 0xXY.  moves pointer. */
Packit Service 82fcde
static uint8_t
Packit Service 82fcde
precsize_aton (const char **strptr)
Packit Service 82fcde
{
Packit Service 82fcde
	unsigned int mval = 0, cmval = 0;
Packit Service 82fcde
	uint8_t retval = 0;
Packit Service 82fcde
	const char *cp;
Packit Service 82fcde
	int exponent;
Packit Service 82fcde
	int mantissa;
Packit Service 82fcde
Packit Service 82fcde
	cp = *strptr;
Packit Service 82fcde
Packit Service 82fcde
	while (isdigit(*cp))
Packit Service 82fcde
		mval = mval * 10 + (*cp++ - '0');
Packit Service 82fcde
Packit Service 82fcde
	if (*cp == '.') {		/* centimeters */
Packit Service 82fcde
		cp++;
Packit Service 82fcde
		if (isdigit(*cp)) {
Packit Service 82fcde
			cmval = (*cp++ - '0') * 10;
Packit Service 82fcde
			if (isdigit(*cp)) {
Packit Service 82fcde
				cmval += (*cp++ - '0');
Packit Service 82fcde
			}
Packit Service 82fcde
		}
Packit Service 82fcde
	}
Packit Service 82fcde
	cmval = (mval * 100) + cmval;
Packit Service 82fcde
Packit Service 82fcde
	for (exponent = 0; exponent < 9; exponent++)
Packit Service 82fcde
		if (cmval < poweroften[exponent+1])
Packit Service 82fcde
			break;
Packit Service 82fcde
Packit Service 82fcde
	mantissa = cmval / poweroften[exponent];
Packit Service 82fcde
	if (mantissa > 9)
Packit Service 82fcde
		mantissa = 9;
Packit Service 82fcde
Packit Service 82fcde
	retval = (mantissa << 4) | exponent;
Packit Service 82fcde
Packit Service 82fcde
	*strptr = cp;
Packit Service 82fcde
Packit Service 82fcde
	return (retval);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* converts ascii lat/lon to unsigned encoded 32-bit number.  moves pointer. */
Packit Service 82fcde
static uint32_t
Packit Service 82fcde
latlon2ul (const char **latlonstrptr, int *which)
Packit Service 82fcde
{
Packit Service 82fcde
	const char *cp;
Packit Service 82fcde
	uint32_t retval;
Packit Service 82fcde
	int deg = 0, min = 0, secs = 0, secsfrac = 0;
Packit Service 82fcde
Packit Service 82fcde
	cp = *latlonstrptr;
Packit Service 82fcde
Packit Service 82fcde
	while (isdigit(*cp))
Packit Service 82fcde
		deg = deg * 10 + (*cp++ - '0');
Packit Service 82fcde
Packit Service 82fcde
	while (isspace(*cp))
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	if (!(isdigit(*cp)))
Packit Service 82fcde
		goto fndhemi;
Packit Service 82fcde
Packit Service 82fcde
	while (isdigit(*cp))
Packit Service 82fcde
		min = min * 10 + (*cp++ - '0');
Packit Service 82fcde
Packit Service 82fcde
	while (isspace(*cp))
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	if (!(isdigit(*cp)))
Packit Service 82fcde
		goto fndhemi;
Packit Service 82fcde
Packit Service 82fcde
	while (isdigit(*cp))
Packit Service 82fcde
		secs = secs * 10 + (*cp++ - '0');
Packit Service 82fcde
Packit Service 82fcde
	if (*cp == '.') {		/* decimal seconds */
Packit Service 82fcde
		cp++;
Packit Service 82fcde
		if (isdigit(*cp)) {
Packit Service 82fcde
			secsfrac = (*cp++ - '0') * 100;
Packit Service 82fcde
			if (isdigit(*cp)) {
Packit Service 82fcde
				secsfrac += (*cp++ - '0') * 10;
Packit Service 82fcde
				if (isdigit(*cp)) {
Packit Service 82fcde
					secsfrac += (*cp++ - '0');
Packit Service 82fcde
				}
Packit Service 82fcde
			}
Packit Service 82fcde
		}
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
	while (!isspace(*cp))	/* if any trailing garbage */
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	while (isspace(*cp))
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
 fndhemi:
Packit Service 82fcde
	switch (*cp) {
Packit Service 82fcde
	case 'N': case 'n':
Packit Service 82fcde
	case 'E': case 'e':
Packit Service 82fcde
		retval = ((unsigned)1<<31)
Packit Service 82fcde
			+ (((((deg * 60) + min) * 60) + secs) * 1000)
Packit Service 82fcde
			+ secsfrac;
Packit Service 82fcde
		break;
Packit Service 82fcde
	case 'S': case 's':
Packit Service 82fcde
	case 'W': case 'w':
Packit Service 82fcde
		retval = ((unsigned)1<<31)
Packit Service 82fcde
			- (((((deg * 60) + min) * 60) + secs) * 1000)
Packit Service 82fcde
			- secsfrac;
Packit Service 82fcde
		break;
Packit Service 82fcde
	default:
Packit Service 82fcde
		retval = 0;	/* invalid value -- indicates error */
Packit Service 82fcde
		break;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
	switch (*cp) {
Packit Service 82fcde
	case 'N': case 'n':
Packit Service 82fcde
	case 'S': case 's':
Packit Service 82fcde
		*which = 1;	/* latitude */
Packit Service 82fcde
		break;
Packit Service 82fcde
	case 'E': case 'e':
Packit Service 82fcde
	case 'W': case 'w':
Packit Service 82fcde
		*which = 2;	/* longitude */
Packit Service 82fcde
		break;
Packit Service 82fcde
	default:
Packit Service 82fcde
		*which = 0;	/* error */
Packit Service 82fcde
		break;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
	cp++;			/* skip the hemisphere */
Packit Service 82fcde
Packit Service 82fcde
	while (!isspace(*cp))	/* if any trailing garbage */
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	while (isspace(*cp))	/* move to next field */
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	*latlonstrptr = cp;
Packit Service 82fcde
Packit Service 82fcde
	return (retval);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* converts a zone file representation in a string to an RDATA on-the-wire
Packit Service 82fcde
 * representation. */
Packit Service 82fcde
int
Packit Service 82fcde
loc_aton (const char *ascii, u_char *binary)
Packit Service 82fcde
{
Packit Service 82fcde
	const char *cp, *maxcp;
Packit Service 82fcde
	u_char *bcp;
Packit Service 82fcde
Packit Service 82fcde
	uint32_t latit = 0, longit = 0, alt = 0;
Packit Service 82fcde
	uint32_t lltemp1 = 0, lltemp2 = 0;
Packit Service 82fcde
	int altmeters = 0, altfrac = 0, altsign = 1;
Packit Service 82fcde
	uint8_t hp = 0x16;	/* default = 1e6 cm = 10000.00m = 10km */
Packit Service 82fcde
	uint8_t vp = 0x13;	/* default = 1e3 cm = 10.00m */
Packit Service 82fcde
	uint8_t siz = 0x12;	/* default = 1e2 cm = 1.00m */
Packit Service 82fcde
	int which1 = 0, which2 = 0;
Packit Service 82fcde
Packit Service 82fcde
	cp = ascii;
Packit Service 82fcde
	maxcp = cp + strlen(ascii);
Packit Service 82fcde
Packit Service 82fcde
	lltemp1 = latlon2ul(&cp, &which1);
Packit Service 82fcde
Packit Service 82fcde
	lltemp2 = latlon2ul(&cp, &which2);
Packit Service 82fcde
Packit Service 82fcde
	switch (which1 + which2) {
Packit Service 82fcde
	case 3:			/* 1 + 2, the only valid combination */
Packit Service 82fcde
		if ((which1 == 1) && (which2 == 2)) { /* normal case */
Packit Service 82fcde
			latit = lltemp1;
Packit Service 82fcde
			longit = lltemp2;
Packit Service 82fcde
		} else if ((which1 == 2) && (which2 == 1)) { /* reversed */
Packit Service 82fcde
			longit = lltemp1;
Packit Service 82fcde
			latit = lltemp2;
Packit Service 82fcde
		} else {	/* some kind of brokenness */
Packit Service 82fcde
			return (0);
Packit Service 82fcde
		}
Packit Service 82fcde
		break;
Packit Service 82fcde
	default:		/* we didn't get one of each */
Packit Service 82fcde
		return (0);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
	/* altitude */
Packit Service 82fcde
	if (*cp == '-') {
Packit Service 82fcde
		altsign = -1;
Packit Service 82fcde
		cp++;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
	if (*cp == '+')
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	while (isdigit(*cp))
Packit Service 82fcde
		altmeters = altmeters * 10 + (*cp++ - '0');
Packit Service 82fcde
Packit Service 82fcde
	if (*cp == '.') {		/* decimal meters */
Packit Service 82fcde
		cp++;
Packit Service 82fcde
		if (isdigit(*cp)) {
Packit Service 82fcde
			altfrac = (*cp++ - '0') * 10;
Packit Service 82fcde
			if (isdigit(*cp)) {
Packit Service 82fcde
				altfrac += (*cp++ - '0');
Packit Service 82fcde
			}
Packit Service 82fcde
		}
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
	alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
Packit Service 82fcde
Packit Service 82fcde
	while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	while (isspace(*cp) && (cp < maxcp))
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	if (cp >= maxcp)
Packit Service 82fcde
		goto defaults;
Packit Service 82fcde
Packit Service 82fcde
	siz = precsize_aton(&cp;;
Packit Service 82fcde
Packit Service 82fcde
	while (!isspace(*cp) && (cp < maxcp))	/* if trailing garbage or m */
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	while (isspace(*cp) && (cp < maxcp))
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	if (cp >= maxcp)
Packit Service 82fcde
		goto defaults;
Packit Service 82fcde
Packit Service 82fcde
	hp = precsize_aton(&cp;;
Packit Service 82fcde
Packit Service 82fcde
	while (!isspace(*cp) && (cp < maxcp))	/* if trailing garbage or m */
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	while (isspace(*cp) && (cp < maxcp))
Packit Service 82fcde
		cp++;
Packit Service 82fcde
Packit Service 82fcde
	if (cp >= maxcp)
Packit Service 82fcde
		goto defaults;
Packit Service 82fcde
Packit Service 82fcde
	vp = precsize_aton(&cp;;
Packit Service 82fcde
Packit Service 82fcde
 defaults:
Packit Service 82fcde
Packit Service 82fcde
	bcp = binary;
Packit Service 82fcde
	*bcp++ = (uint8_t) 0;	/* version byte */
Packit Service 82fcde
	*bcp++ = siz;
Packit Service 82fcde
	*bcp++ = hp;
Packit Service 82fcde
	*bcp++ = vp;
Packit Service 82fcde
	PUTLONG(latit,bcp);
Packit Service 82fcde
	PUTLONG(longit,bcp);
Packit Service 82fcde
	PUTLONG(alt,bcp);
Packit Service 82fcde
Packit Service 82fcde
	return (16);		/* size of RR in octets */
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* takes an on-the-wire LOC RR and formats it in a human readable format. */
Packit Service 82fcde
const char *
Packit Service 82fcde
loc_ntoa (const u_char *binary, char *ascii)
Packit Service 82fcde
{
Packit Service 82fcde
	static const char error[] = "?";
Packit Service 82fcde
	static char tmpbuf[sizeof
Packit Service 82fcde
"1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"];
Packit Service 82fcde
	const u_char *cp = binary;
Packit Service 82fcde
Packit Service 82fcde
	int latdeg, latmin, latsec, latsecfrac;
Packit Service 82fcde
	int longdeg, longmin, longsec, longsecfrac;
Packit Service 82fcde
	char northsouth, eastwest;
Packit Service 82fcde
	int altmeters, altfrac, altsign;
Packit Service 82fcde
Packit Service 82fcde
	const uint32_t referencealt = 100000 * 100;
Packit Service 82fcde
Packit Service 82fcde
	int32_t latval, longval, altval;
Packit Service 82fcde
	uint32_t templ;
Packit Service 82fcde
	uint8_t sizeval, hpval, vpval, versionval;
Packit Service 82fcde
Packit Service 82fcde
	char *sizestr, *hpstr, *vpstr;
Packit Service 82fcde
Packit Service 82fcde
	versionval = *cp++;
Packit Service 82fcde
Packit Service 82fcde
	if (ascii == NULL)
Packit Service 82fcde
		ascii = tmpbuf;
Packit Service 82fcde
Packit Service 82fcde
	if (versionval) {
Packit Service 82fcde
		(void) sprintf(ascii, "; error: unknown LOC RR version");
Packit Service 82fcde
		return (ascii);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
	sizeval = *cp++;
Packit Service 82fcde
Packit Service 82fcde
	hpval = *cp++;
Packit Service 82fcde
	vpval = *cp++;
Packit Service 82fcde
Packit Service 82fcde
	GETLONG(templ, cp);
Packit Service 82fcde
	latval = (templ - ((unsigned)1<<31));
Packit Service 82fcde
Packit Service 82fcde
	GETLONG(templ, cp);
Packit Service 82fcde
	longval = (templ - ((unsigned)1<<31));
Packit Service 82fcde
Packit Service 82fcde
	GETLONG(templ, cp);
Packit Service 82fcde
	if (templ < referencealt) { /* below WGS 84 spheroid */
Packit Service 82fcde
		altval = referencealt - templ;
Packit Service 82fcde
		altsign = -1;
Packit Service 82fcde
	} else {
Packit Service 82fcde
		altval = templ - referencealt;
Packit Service 82fcde
		altsign = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
	if (latval < 0) {
Packit Service 82fcde
		northsouth = 'S';
Packit Service 82fcde
		latval = -latval;
Packit Service 82fcde
	} else
Packit Service 82fcde
		northsouth = 'N';
Packit Service 82fcde
Packit Service 82fcde
	latsecfrac = latval % 1000;
Packit Service 82fcde
	latval = latval / 1000;
Packit Service 82fcde
	latsec = latval % 60;
Packit Service 82fcde
	latval = latval / 60;
Packit Service 82fcde
	latmin = latval % 60;
Packit Service 82fcde
	latval = latval / 60;
Packit Service 82fcde
	latdeg = latval;
Packit Service 82fcde
Packit Service 82fcde
	if (longval < 0) {
Packit Service 82fcde
		eastwest = 'W';
Packit Service 82fcde
		longval = -longval;
Packit Service 82fcde
	} else
Packit Service 82fcde
		eastwest = 'E';
Packit Service 82fcde
Packit Service 82fcde
	longsecfrac = longval % 1000;
Packit Service 82fcde
	longval = longval / 1000;
Packit Service 82fcde
	longsec = longval % 60;
Packit Service 82fcde
	longval = longval / 60;
Packit Service 82fcde
	longmin = longval % 60;
Packit Service 82fcde
	longval = longval / 60;
Packit Service 82fcde
	longdeg = longval;
Packit Service 82fcde
Packit Service 82fcde
	altfrac = altval % 100;
Packit Service 82fcde
	altmeters = (altval / 100) * altsign;
Packit Service 82fcde
Packit Service 82fcde
	if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
Packit Service 82fcde
		sizestr = (char *) error;
Packit Service 82fcde
	if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
Packit Service 82fcde
		hpstr = (char *) error;
Packit Service 82fcde
	if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
Packit Service 82fcde
		vpstr = (char *) error;
Packit Service 82fcde
Packit Service 82fcde
	sprintf(ascii,
Packit Service 82fcde
	      "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
Packit Service 82fcde
		latdeg, latmin, latsec, latsecfrac, northsouth,
Packit Service 82fcde
		longdeg, longmin, longsec, longsecfrac, eastwest,
Packit Service 82fcde
		altmeters, altfrac, sizestr, hpstr, vpstr);
Packit Service 82fcde
Packit Service 82fcde
	if (sizestr != (char *) error)
Packit Service 82fcde
		free(sizestr);
Packit Service 82fcde
	if (hpstr != (char *) error)
Packit Service 82fcde
		free(hpstr);
Packit Service 82fcde
	if (vpstr != (char *) error)
Packit Service 82fcde
		free(vpstr);
Packit Service 82fcde
Packit Service 82fcde
	return (ascii);
Packit Service 82fcde
}
Packit Service 82fcde
libresolv_hidden_def (loc_ntoa)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Return the number of DNS hierarchy levels in the name. */
Packit Service 82fcde
int
Packit Service 82fcde
dn_count_labels(const char *name) {
Packit Service 82fcde
	int i, len, count;
Packit Service 82fcde
Packit Service 82fcde
	len = strlen(name);
Packit Service 82fcde
	for (i = 0, count = 0; i < len; i++) {
Packit Service 82fcde
		/* XXX need to check for \. or use named's nlabels(). */
Packit Service 82fcde
		if (name[i] == '.')
Packit Service 82fcde
			count++;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
	/* don't count initial wildcard */
Packit Service 82fcde
	if (name[0] == '*')
Packit Service 82fcde
		if (count)
Packit Service 82fcde
			count--;
Packit Service 82fcde
Packit Service 82fcde
	/* don't count the null label for root. */
Packit Service 82fcde
	/* if terminating '.' not found, must adjust */
Packit Service 82fcde
	/* count to include last label */
Packit Service 82fcde
	if (len > 0 && name[len-1] != '.')
Packit Service 82fcde
		count++;
Packit Service 82fcde
	return (count);
Packit Service 82fcde
}
Packit Service 82fcde
libresolv_hidden_def (__dn_count_labels)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_27)
Packit Service 82fcde
/*
Packit Service 82fcde
 * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
Packit Service 82fcde
 * SIG records are required to be printed like this, by the Secure DNS RFC.
Packit Service 82fcde
 * This is an obsolescent function and does not handle dates outside the
Packit Service 82fcde
 * signed 32-bit range.
Packit Service 82fcde
 */
Packit Service 82fcde
char *
Packit Service 82fcde
__p_secstodate (u_long secs) {
Packit Service 82fcde
	/* XXX nonreentrant */
Packit Service 82fcde
	static char output[15];		/* YYYYMMDDHHMMSS and null */
Packit Service 82fcde
	time_t clock = secs;
Packit Service 82fcde
	struct tm *time;
Packit Service 82fcde
Packit Service 82fcde
	struct tm timebuf;
Packit Service 82fcde
	/* The call to __gmtime_r can never produce a year overflowing
Packit Service 82fcde
	   the range of int, given the check on SECS, but check for a
Packit Service 82fcde
	   NULL return anyway to avoid a null pointer dereference in
Packit Service 82fcde
	   case there are any other unspecified errors.  */
Packit Service 82fcde
	if (secs > 0x7fffffff
Packit Service 82fcde
	    || (time = __gmtime_r (&clock, &timebuf)) == NULL) {
Packit Service 82fcde
		strcpy (output, "<overflow>");
Packit Service 82fcde
		__set_errno (EOVERFLOW);
Packit Service 82fcde
		return output;
Packit Service 82fcde
	}
Packit Service 82fcde
	time->tm_year += 1900;
Packit Service 82fcde
	time->tm_mon += 1;
Packit Service 82fcde
	/* The struct tm fields, given the above range check,
Packit Service 82fcde
	   must have values that mean this sprintf exactly fills the
Packit Service 82fcde
	   buffer.  But as of GCC 8 of 2017-11-21, GCC cannot tell
Packit Service 82fcde
	   that, even given range checks on all fields with
Packit Service 82fcde
	   __builtin_unreachable called for out-of-range values.  */
Packit Service 82fcde
	DIAG_PUSH_NEEDS_COMMENT;
Packit Service 82fcde
# if __GNUC_PREREQ (7, 0)
Packit Service 82fcde
	DIAG_IGNORE_NEEDS_COMMENT (8, "-Wformat-overflow=");
Packit Service 82fcde
# endif
Packit Service 82fcde
	sprintf(output, "%04d%02d%02d%02d%02d%02d",
Packit Service 82fcde
		time->tm_year, time->tm_mon, time->tm_mday,
Packit Service 82fcde
		time->tm_hour, time->tm_min, time->tm_sec);
Packit Service 82fcde
	DIAG_POP_NEEDS_COMMENT;
Packit Service 82fcde
	return (output);
Packit Service 82fcde
}
Packit Service 82fcde
compat_symbol (libresolv, __p_secstodate, __p_secstodate, GLIBC_2_0);
Packit Service 82fcde
#endif