1d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
2d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Copyright (c) 1996, 1998 by Internet Software Consortium.
3d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
4d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Permission to use, copy, modify, and distribute this software for any
5d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * purpose with or without fee is hereby granted, provided that the above
6d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * copyright notice and this permission notice appear in all copies.
7d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
8d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
10d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
11d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
13d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * SOFTWARE.
16d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
17d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
18d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
190164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel * Portions copyright (c) 1999, 2000 - 2014
20d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Intel Corporation.
21d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * All rights reserved.
220164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *
23d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Redistribution and use in source and binary forms, with or without
24d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * modification, are permitted provided that the following conditions
25d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * are met:
260164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *
27d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 1. Redistributions of source code must retain the above copyright
28d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    notice, this list of conditions and the following disclaimer.
290164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *
30d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 2. Redistributions in binary form must reproduce the above copyright
31d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    notice, this list of conditions and the following disclaimer in the
32d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    documentation and/or other materials provided with the distribution.
330164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *
34d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 3. All advertising materials mentioning features or use of this software
35d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    must display the following acknowledgement:
360164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *
37d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    This product includes software developed by Intel Corporation and
38d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    its contributors.
390164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *
40d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 4. Neither the name of Intel Corporation or its contributors may be
41d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    used to endorse or promote products derived from this software
42d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    without specific prior written permission.
430164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *
44d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''
45d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE
48d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
50d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
51d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
52d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
54d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THE POSSIBILITY OF SUCH DAMAGE.
550164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *
56d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
57d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
58d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/* Import. */
59d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
60d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <sys/types.h>
61d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <sys/socket.h>
62d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
63d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <netinet/in.h>
64d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <arpa/nameser.h>
65d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <arpa/inet.h>
66d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
67d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <assert.h>
68d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <errno.h>
69d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <resolv.h>
70d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <string.h>
71d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <ctype.h>
72d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
73d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define SPRINTF(x) (sprintf x)
74d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
75d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/* Forward. */
76d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
770164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdanielstatic size_t prune_origin(const char *name, const char *origin);
780164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdanielstatic int  charstr(const u_char *rdata, const u_char *edata,
790164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      char **buf, size_t *buflen);
800164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdanielstatic int  addname(const u_char *msg, size_t msglen,
810164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      const u_char **p, const char *origin,
820164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      char **buf, size_t *buflen);
830164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdanielstatic void addlen(size_t len, char **buf, size_t *buflen);
840164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdanielstatic int  addstr(const char *src, size_t len,
850164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel           char **buf, size_t *buflen);
860164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdanielstatic int  addtab(size_t len, size_t target, int spaced,
870164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel           char **buf, size_t *buflen);
88d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
89d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/* Macros. */
90d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
910164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel#define T(x) \
920164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  do { \
930164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if ((ssize_t)(x) < 0) \
940164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      return (-1); \
950164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  } while (0)
96d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
97d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/* Public. */
98d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
99d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
100d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * int
101d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen)
1020164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  Convert an RR to presentation format.
103d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * return:
1040164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  Number of characters written to buf, or -1 (check errno).
105d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
106d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint
107d7ce700605e1af0e455e31ec11f19ff21d26b525darylmns_sprintrr(const ns_msg *handle, const ns_rr *rr,
1080164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      const char *name_ctx, const char *origin,
1090164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      char *buf, size_t buflen)
110d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
1110164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  int n;
112d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
1130164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
1140164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel       ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
1150164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel       ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
1160164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel       name_ctx, origin, buf, buflen);
1170164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  return (n);
118d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
119d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
120d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
121d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * int
122d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen,
1230164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *         name_ctx, origin, buf, buflen)
1240164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  Convert the fields of an RR into presentation format.
125d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * return:
1260164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  Number of characters written to buf, or -1 (check errno).
127d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
128d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint
129d7ce700605e1af0e455e31ec11f19ff21d26b525darylmns_sprintrrf(const u_char *msg, size_t msglen,
1300164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      const char *name, ns_class class, ns_type type,
1310164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      u_long ttl, const u_char *rdata, size_t rdlen,
1320164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      const char *name_ctx, const char *origin,
1330164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      char *buf, size_t buflen)
134d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
1350164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  const char *obuf = buf;
1360164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  const u_char *edata = rdata + rdlen;
1370164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  int spaced = 0;
1380164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
1390164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  const char *comment;
1400164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  char tmp[100];
1410164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  int x;
1420164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  size_t len;
1430164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
1440164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  static  char base64_key[NS_MD5RSA_MAX_BASE64];
1450164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  static  char t[255*3];
1460164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
1470164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  /*
1480164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel   * Owner.
1490164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel   */
1500164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  if (name_ctx != NULL && strcasecmp(name_ctx, name) == 0) {
1510164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("\t\t\t", 3, &buf, &buflen));
1520164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  } else {
1530164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = prune_origin(name, origin);
1540164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (len == 0) {
1550164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addstr("@\t\t\t", 4, &buf, &buflen));
1560164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    } else {
1570164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addstr(name, len, &buf, &buflen));
1580164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      /* Origin not used and no trailing dot? */
1590164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      if ((!origin || !origin[0] || name[len] == '\0') &&
1600164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel          name[len - 1] != '.') {
1610164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        T(addstr(".", 1, &buf, &buflen));
1620164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        len++;
1630164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
1640164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(spaced = addtab(len, 24, spaced, &buf, &buflen));
1650164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    }
1660164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  }
1670164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
1680164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  /*
1690164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel   * TTL, Class, Type.
1700164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel   */
1710164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  T(x = ns_format_ttl(ttl, buf, buflen));
1720164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  addlen(x, &buf, &buflen);
1730164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
1740164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  T(addstr(tmp, len, &buf, &buflen));
1750164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
1760164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
1770164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  /*
1780164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel   * RData.
1790164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel   */
1800164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  switch (type) {
1810164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_a:
1820164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (rdlen != NS_INADDRSZ)
1830164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
1840164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    (void) inet_ntop(AF_INET, rdata, buf, (socklen_t)buflen);
1850164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    addlen(strlen(buf), &buf, &buflen);
1860164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
1870164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
1880164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_cname:
1890164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_mb:
1900164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_mg:
1910164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_mr:
1920164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_ns:
1930164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_ptr:
1940164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1950164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
1960164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
1970164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_hinfo:
1980164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_isdn:
1990164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* First word. */
2000164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(len = charstr(rdata, edata, &buf, &buflen));
2010164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (len == 0)
2020164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
2030164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    rdata += len;
2040164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(" ", 1, &buf, &buflen));
2050164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2060164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Second word. */
2070164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(len = charstr(rdata, edata, &buf, &buflen));
2080164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (len == 0)
2090164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
2100164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    rdata += len;
2110164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
2120164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2130164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_soa: {
2140164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    u_long t;
2150164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2160164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Server name. */
2170164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
2180164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(" ", 1, &buf, &buflen));
2190164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2200164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Administrator name. */
2210164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
2220164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(" (\n", 3, &buf, &buflen));
2230164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    spaced = 0;
2240164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2250164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if ((edata - rdata) != 5*NS_INT32SZ)
2260164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
2270164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2280164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Serial number. */
2290164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    t = ns_get32(rdata);  rdata += NS_INT32SZ;
2300164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
2319d66ee4d177307ca59f08d242e592ec95a325d26Stefan Kaeser    len = SPRINTF((tmp, "%lu", (unsigned long)t));
2320164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(tmp, len, &buf, &buflen));
2330164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(spaced = addtab(len, 16, spaced, &buf, &buflen));
2340164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("; serial\n", 9, &buf, &buflen));
2350164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    spaced = 0;
2360164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2370164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Refresh interval. */
2380164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    t = ns_get32(rdata);  rdata += NS_INT32SZ;
2390164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
2400164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(len = ns_format_ttl(t, buf, buflen));
2410164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    addlen(len, &buf, &buflen);
2420164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(spaced = addtab(len, 16, spaced, &buf, &buflen));
2430164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("; refresh\n", 10, &buf, &buflen));
2440164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    spaced = 0;
2450164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2460164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Retry interval. */
2470164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    t = ns_get32(rdata);  rdata += NS_INT32SZ;
2480164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
2490164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(len = ns_format_ttl(t, buf, buflen));
2500164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    addlen(len, &buf, &buflen);
2510164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(spaced = addtab(len, 16, spaced, &buf, &buflen));
2520164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("; retry\n", 8, &buf, &buflen));
2530164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    spaced = 0;
2540164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2550164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Expiry. */
2560164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    t = ns_get32(rdata);  rdata += NS_INT32SZ;
2570164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
2580164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(len = ns_format_ttl(t, buf, buflen));
2590164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    addlen(len, &buf, &buflen);
2600164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(spaced = addtab(len, 16, spaced, &buf, &buflen));
2610164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("; expiry\n", 9, &buf, &buflen));
2620164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    spaced = 0;
2630164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2640164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Minimum TTL. */
2650164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    t = ns_get32(rdata);  rdata += NS_INT32SZ;
2660164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
2670164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(len = ns_format_ttl(t, buf, buflen));
2680164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    addlen(len, &buf, &buflen);
2690164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(" )", 2, &buf, &buflen));
2700164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(spaced = addtab(len, 16, spaced, &buf, &buflen));
2710164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("; minimum\n", 10, &buf, &buflen));
2720164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2730164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
2740164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
2750164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2760164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_mx:
2770164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_afsdb:
2780164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_rt: {
2790164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    u_int t;
2800164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2810164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (rdlen < NS_INT16SZ)
2820164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
2830164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2840164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Priority. */
2850164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    t = ns_get16(rdata);
2860164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    rdata += NS_INT16SZ;
2870164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = SPRINTF((tmp, "%u ", (unsigned int)t));
2880164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(tmp, len, &buf, &buflen));
2890164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2900164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Target. */
2910164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
2920164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2930164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
2940164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
2950164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2960164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_px: {
2970164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    u_int t;
2980164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
2990164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (rdlen < NS_INT16SZ)
3000164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
3010164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3020164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Priority. */
3030164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    t = ns_get16(rdata);
3040164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    rdata += NS_INT16SZ;
3050164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = SPRINTF((tmp, "%u ", (unsigned int)t));
3060164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(tmp, len, &buf, &buflen));
3070164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3080164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Name1. */
3090164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
3100164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(" ", 1, &buf, &buflen));
3110164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3120164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Name2. */
3130164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
3140164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3150164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
3160164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
3170164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3180164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_x25:
3190164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(len = charstr(rdata, edata, &buf, &buflen));
3200164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (len == 0)
3210164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
3220164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    rdata += len;
3230164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
3240164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3250164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_txt:
3260164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    while (rdata < edata) {
3270164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(len = charstr(rdata, edata, &buf, &buflen));
3280164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      if (len == 0)
3290164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        goto formerr;
3300164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      rdata += len;
3310164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      if (rdata < edata)
3320164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        T(addstr(" ", 1, &buf, &buflen));
3330164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    }
3340164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
3350164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3360164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_nsap: {
3370164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3380164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    (void) inet_nsap_ntoa((int)rdlen, rdata, t);
3390164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(t, strlen(t), &buf, &buflen));
3400164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
3410164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
3420164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3430164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_aaaa:
3440164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (rdlen != NS_IN6ADDRSZ)
3450164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
3460164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    (void) inet_ntop(AF_INET6, rdata, buf, (socklen_t)buflen);
3470164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    addlen(strlen(buf), &buf, &buflen);
3480164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
3490164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3500164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_loc: {
3510164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* XXX protocol format checking? */
3520164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    (void) loc_ntoa(rdata, t);
3530164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(t, strlen(t), &buf, &buflen));
3540164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
3550164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
3560164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3570164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_naptr: {
3580164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    u_int order, preference;
3590164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3600164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (rdlen < 2*NS_INT16SZ)
3610164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
3620164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3630164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Order, Precedence. */
3640164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    order = ns_get16(rdata);  rdata += NS_INT16SZ;
3650164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    preference = ns_get16(rdata); rdata += NS_INT16SZ;
3660164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = SPRINTF((t, "%u %u ", (unsigned int)order, (unsigned int)preference));
3670164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(t, len, &buf, &buflen));
3680164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3690164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Flags. */
3700164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(len = charstr(rdata, edata, &buf, &buflen));
3710164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (len == 0)
3720164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
3730164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    rdata += len;
3740164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(" ", 1, &buf, &buflen));
3750164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3760164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Service. */
3770164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(len = charstr(rdata, edata, &buf, &buflen));
3780164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (len == 0)
3790164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
3800164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    rdata += len;
3810164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(" ", 1, &buf, &buflen));
3820164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3830164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Regexp. */
3840164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(len = charstr(rdata, edata, &buf, &buflen));
3850164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if ((ssize_t)len < 0)
3860164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      return (-1);
3870164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (len == 0)
3880164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
3890164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    rdata += len;
3900164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(" ", 1, &buf, &buflen));
3910164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3920164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Server. */
3930164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
3940164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
3950164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
3960164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
3970164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_srv: {
3980164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    u_int priority, weight, port;
3990164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4000164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (rdlen < NS_INT16SZ*3)
4010164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
4020164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4030164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Priority, Weight, Port. */
4040164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    priority = ns_get16(rdata);  rdata += NS_INT16SZ;
4050164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    weight   = ns_get16(rdata);  rdata += NS_INT16SZ;
4060164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    port     = ns_get16(rdata);  rdata += NS_INT16SZ;
4070164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = SPRINTF((t, "%u %u %u ", (unsigned int)priority, (unsigned int)weight, (unsigned int)port));
4080164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(t, len, &buf, &buflen));
4090164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4100164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Server. */
4110164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
4120164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
4130164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
4140164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4150164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_minfo:
4160164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_rp:
4170164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Name1. */
4180164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
4190164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(" ", 1, &buf, &buflen));
4200164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4210164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Name2. */
4220164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
4230164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4240164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
4250164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4260164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_wks: {
4270164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    int n, lcnt;
4280164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4290164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (rdlen < NS_INT32SZ + 1)
4300164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
4310164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4320164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Address. */
4330164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    (void) inet_ntop(AF_INET, rdata, buf, (socklen_t)buflen);
4340164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    addlen(strlen(buf), &buf, &buflen);
4350164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    rdata += NS_INADDRSZ;
4360164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4370164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Protocol. */
4380164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = SPRINTF((tmp, " %u ( ", (unsigned int)*rdata));
4390164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(tmp, len, &buf, &buflen));
4400164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    rdata += NS_INT8SZ;
4410164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4420164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Bit map. */
4430164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    n = 0;
4440164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    lcnt = 0;
4450164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    while (rdata < edata) {
4460164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      u_int c = *rdata++;
4470164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      do {
4480164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        if (c & 0200) {
4490164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel          if (lcnt == 0) {
4500164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel            T(addstr("\n\t\t\t\t", 5,
4510164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel               &buf, &buflen));
4520164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel            lcnt = 10;
4530164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel            spaced = 0;
4540164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel          }
4550164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel          len = SPRINTF((tmp, "%d ", n));
4560164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel          T(addstr(tmp, len, &buf, &buflen));
4570164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel          lcnt--;
4580164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        }
4590164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        c <<= 1;
4600164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      } while (++n & 07);
4610164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    }
4620164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(")", 1, &buf, &buflen));
4630164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4640164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
4650164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
4660164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4670164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_key: {
4680164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    u_int keyflags, protocol, algorithm;
4690164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    const char *leader;
4700164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    int n;
4710164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4720164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
4730164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
4740164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4750164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Key flags, Protocol, Algorithm. */
4760164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    keyflags = ns_get16(rdata);  rdata += NS_INT16SZ;
4770164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    protocol = *rdata++;
4780164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    algorithm = *rdata++;
4790164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = SPRINTF((tmp, "0x%04x %u %u",
4800164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel             (unsigned int)keyflags, (unsigned int)protocol, (unsigned int)algorithm));
4810164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(tmp, len, &buf, &buflen));
4820164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
4830164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Public key data. */
4840164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = b64_ntop(rdata, edata - rdata,
4850164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel             base64_key, sizeof base64_key);
4860164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if ((ssize_t)len < 0)
4870164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
4880164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (len > 15) {
4890164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addstr(" (", 2, &buf, &buflen));
4900164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      leader = "\n\t\t";
4910164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      spaced = 0;
4920164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    } else
4930164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      leader = " ";
4940164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    for (n = 0; n < (int)len; n += 48) {
4950164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addstr(leader, strlen(leader), &buf, &buflen));
4960164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addstr(base64_key + n, MIN(len - n, 48),
4970164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel         &buf, &buflen));
4980164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    }
4990164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (len > 15)
5000164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addstr(" )", 2, &buf, &buflen));
5010164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5020164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
5030164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
5040164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5050164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_sig: {
5060164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    u_int type, algorithm, labels, footprint;
5070164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    const char *leader;
5080164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    u_long t;
5090164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    int n;
5100164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5110164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (rdlen < 22)
5120164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
5130164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5140164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Type covered, Algorithm, Label count, Original TTL. */
5150164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel          type = ns_get16(rdata);  rdata += NS_INT16SZ;
5160164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    algorithm = *rdata++;
5170164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    labels = *rdata++;
5180164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    t = ns_get32(rdata);  rdata += NS_INT32SZ;
5190164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = SPRINTF((tmp, " %s %d %lu ",
5209d66ee4d177307ca59f08d242e592ec95a325d26Stefan Kaeser                   p_type((int)type), (int)algorithm, (unsigned long)t));
5210164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(tmp, len, &buf, &buflen));
5220164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (labels != (u_int)dn_count_labels(name))
5230164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
5240164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5250164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Signature expiry. */
5260164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    t = ns_get32(rdata);  rdata += NS_INT32SZ;
5270164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = SPRINTF((tmp, "%s ", p_secstodate(t)));
5280164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(tmp, len, &buf, &buflen));
5290164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5300164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Time signed. */
5310164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    t = ns_get32(rdata);  rdata += NS_INT32SZ;
5320164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = SPRINTF((tmp, "%s ", p_secstodate(t)));
5330164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(tmp, len, &buf, &buflen));
5340164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5350164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Signature Footprint. */
5360164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    footprint = ns_get16(rdata);  rdata += NS_INT16SZ;
5370164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = SPRINTF((tmp, "%u ", (unsigned int)footprint));
5380164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(tmp, len, &buf, &buflen));
5390164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5400164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Signer's name. */
5410164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
5420164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5430164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Signature. */
5440164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    len = b64_ntop(rdata, edata - rdata,
5450164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel             base64_key, sizeof base64_key);
5460164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (len > 15) {
5470164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addstr(" (", 2, &buf, &buflen));
5480164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      leader = "\n\t\t";
5490164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      spaced = 0;
5500164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    } else
5510164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      leader = " ";
5520164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if ((ssize_t)len < 0)
5530164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto formerr;
5540164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    for (n = 0; n < (int)len; n += 48) {
5550164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addstr(leader, strlen(leader), &buf, &buflen));
5560164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addstr(base64_key + n, MIN(len - n, 48),
5570164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel         &buf, &buflen));
5580164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    }
5590164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (len > 15)
5600164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addstr(" )", 2, &buf, &buflen));
5610164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5620164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
5630164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
5640164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5650164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  case ns_t_nxt: {
5660164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    int n, c;
5670164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5680164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Next domain name. */
5690164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
5700164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5710164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Type bit map. */
5720164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    n = (int)(edata - rdata);
5730164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    for (c = 0; c < n*8; c++)
5740164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      if (NS_NXT_BIT_ISSET(c, rdata)) {
5750164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        len = SPRINTF((tmp, " %s", p_type(c)));
5760164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        T(addstr(tmp, len, &buf, &buflen));
5770164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
5780164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    break;
5790164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
5800164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5810164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  default:
5820164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    comment = "unknown RR type";
5830164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    goto hexify;
5840164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  }
5850164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  return ((int)(buf - obuf));
586d7ce700605e1af0e455e31ec11f19ff21d26b525darylm formerr:
5870164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  comment = "RR format error";
588d7ce700605e1af0e455e31ec11f19ff21d26b525darylm hexify: {
5890164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  int n, m;
5900164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  char *p;
5910164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
5920164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  len = SPRINTF((tmp, "\\#(\t\t; %s", comment));
5930164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  T(addstr(tmp, len, &buf, &buflen));
5940164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  while (rdata < edata) {
5950164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    p = tmp;
5960164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    p += SPRINTF((p, "\n\t"));
5970164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    spaced = 0;
5980164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    n = MIN(16, (int)(edata - rdata));
5990164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    for (m = 0; m < n; m++)
6000164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      p += SPRINTF((p, "%02x ", rdata[m]));
6010164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(tmp, (u_int)(p - tmp), &buf, &buflen));
6020164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (n < 16) {
6030164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addstr(")", 1, &buf, &buflen));
6040164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      T(addtab((u_int)(p - tmp) + 1, 48, spaced, &buf, &buflen));
6050164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    }
6060164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    p = tmp;
6070164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    p += SPRINTF((p, "; "));
6080164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    for (m = 0; m < n; m++)
6090164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      *p++ = (isascii(rdata[m]) && isprint(rdata[m]))
6100164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        ? rdata[m]
6110164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        : '.';
6120164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr(tmp, (u_int)(p - tmp), &buf, &buflen));
6130164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    rdata += n;
6140164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  }
6150164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  return ((int)(buf - obuf));
616d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
617d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
618d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
619d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/* Private. */
620d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
621d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
622d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * size_t
623d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * prune_origin(name, origin)
6240164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  Find out if the name is at or under the current origin.
625d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * return:
6260164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  Number of characters in name before start of origin,
6270164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  or length of name if origin does not match.
628d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * notes:
6290164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  This function should share code with samedomain().
630d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
631d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic size_t
632d7ce700605e1af0e455e31ec11f19ff21d26b525darylmprune_origin(const char *name, const char *origin) {
6330164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  const char *oname = name;
6340164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
6350164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  while (*name != '\0') {
6360164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (origin != NULL && strcasecmp(name, origin) == 0)
6370164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      return ((size_t)(name - oname) - (name > oname));
6380164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    while (*name != '\0') {
6390164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      if (*name == '\\') {
6400164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        name++;
6410164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        /* XXX need to handle \nnn form. */
6420164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        if (*name == '\0')
6430164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel          break;
6440164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      } else if (*name == '.') {
6450164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        name++;
6460164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        break;
6470164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
6480164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      name++;
6490164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    }
6500164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  }
6510164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  return ((size_t)(name - oname));
652d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
653d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
654d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
655d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * int
656d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * charstr(rdata, edata, buf, buflen)
6570164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  Format a <character-string> into the presentation buffer.
658d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * return:
6590164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  Number of rdata octets consumed
6600164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  0 for protocol format error
6610164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  -1 for output buffer error
662d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * side effects:
6630164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel *  buffer is advanced on success.
664d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
665d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic int
666d7ce700605e1af0e455e31ec11f19ff21d26b525darylmcharstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
6670164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  const u_char *odata = rdata;
6680164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  size_t save_buflen = *buflen;
6690164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  char *save_buf = *buf;
6700164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
6710164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  if (addstr("\"", 1, buf, buflen) < 0)
6720164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    goto enospc;
6730164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  if (rdata < edata) {
6740164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    int n = *rdata;
6750164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
6760164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (rdata + 1 + n <= edata) {
6770164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      rdata++;
6780164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      while (n-- > 0) {
6790164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        if (strchr("\n\"\\", *rdata) != NULL)
6800164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel          if (addstr("\\", 1, buf, buflen) < 0)
6810164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel            goto enospc;
6820164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        if (addstr((const char *)rdata, 1,
6830164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel             buf, buflen) < 0)
6840164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel          goto enospc;
6850164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        rdata++;
6860164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
6870164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    }
6880164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  }
6890164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  if (addstr("\"", 1, buf, buflen) < 0)
6900164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    goto enospc;
6910164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  return ((int)(rdata - odata));
692d7ce700605e1af0e455e31ec11f19ff21d26b525darylm enospc:
6930164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  errno = ENOSPC;
6940164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  *buf = save_buf;
6950164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  *buflen = save_buflen;
6960164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  return (-1);
697d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
698d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
699d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic int
700d7ce700605e1af0e455e31ec11f19ff21d26b525darylmaddname(const u_char *msg, size_t msglen,
7010164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  const u_char **pp, const char *origin,
7020164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  char **buf, size_t *buflen)
703d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
7040164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  size_t newlen, save_buflen = *buflen;
7050164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  char *save_buf = *buf;
7060164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  int n;
7070164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
7080164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  n = dn_expand(msg, msg + msglen, *pp, *buf, (int)(*buflen));
7090164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  if (n < 0)
7100164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    goto enospc;  /* Guess. */
7110164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  newlen = prune_origin(*buf, origin);
7120164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  if ((origin == NULL || origin[0] == '\0' || (*buf)[newlen] == '\0') &&
7130164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      (newlen == 0 || (*buf)[newlen - 1] != '.')) {
7140164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* No trailing dot. */
7150164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (newlen + 2 > *buflen)
7160164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto enospc;  /* No room for ".\0". */
7170164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    (*buf)[newlen++] = '.';
7180164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    (*buf)[newlen] = '\0';
7190164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  }
7200164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  if (newlen == 0) {
7210164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    /* Use "@" instead of name. */
7220164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    if (newlen + 2 > *buflen)
7230164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      goto enospc;        /* No room for "@\0". */
7240164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    (*buf)[newlen++] = '@';
7250164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    (*buf)[newlen] = '\0';
7260164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  }
7270164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  *pp += n;
7280164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  addlen(newlen, buf, buflen);
7290164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  **buf = '\0';
7300164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  return ((int)newlen);
731d7ce700605e1af0e455e31ec11f19ff21d26b525darylm enospc:
7320164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  errno = ENOSPC;
7330164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  *buf = save_buf;
7340164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  *buflen = save_buflen;
7350164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  return (-1);
736d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
737d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
738d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic void
739d7ce700605e1af0e455e31ec11f19ff21d26b525darylmaddlen(size_t len, char **buf, size_t *buflen) {
7400164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  assert(len <= *buflen);
7410164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  *buf += len;
7420164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  *buflen -= len;
743d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
744d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
745d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic int
746d7ce700605e1af0e455e31ec11f19ff21d26b525darylmaddstr(const char *src, size_t len, char **buf, size_t *buflen) {
7470164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  if (len > *buflen) {
7480164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    errno = ENOSPC;
7490164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    return (-1);
7500164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  }
7510164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  memcpy(*buf, src, len);
7520164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  addlen(len, buf, buflen);
7530164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  **buf = '\0';
7540164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  return (0);
755d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
756d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
757d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic int
758d7ce700605e1af0e455e31ec11f19ff21d26b525darylmaddtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
7590164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  size_t save_buflen = *buflen;
7600164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  char *save_buf = *buf;
7610164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  int t;
7620164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel
7630164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  if (spaced || len >= target - 1) {
7640164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    T(addstr("  ", 2, buf, buflen));
7650164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    spaced = 1;
7660164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  } else {
7670164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    for (t = (int)(target - len - 1) / 8; t >= 0; t--)
7680164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      if (addstr("\t", 1, buf, buflen) < 0) {
7690164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        *buflen = save_buflen;
7700164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        *buf = save_buf;
7710164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel        return (-1);
7720164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel      }
7730164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel    spaced = 0;
7740164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  }
7750164fc8e76b6ca9023c893940ddb00ef0b6bee5adaryl.mcdaniel  return (spaced);
776d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
777