xref: /aosp_15_r20/bionic/libc/dns/nameser/ns_print.c (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
1*8d67ca89SAndroid Build Coastguard Worker /*	$NetBSD: ns_print.c,v 1.11 2012/03/13 21:13:39 christos Exp $	*/
2*8d67ca89SAndroid Build Coastguard Worker 
3*8d67ca89SAndroid Build Coastguard Worker /*
4*8d67ca89SAndroid Build Coastguard Worker  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5*8d67ca89SAndroid Build Coastguard Worker  * Copyright (c) 1996-1999 by Internet Software Consortium.
6*8d67ca89SAndroid Build Coastguard Worker  *
7*8d67ca89SAndroid Build Coastguard Worker  * Permission to use, copy, modify, and distribute this software for any
8*8d67ca89SAndroid Build Coastguard Worker  * purpose with or without fee is hereby granted, provided that the above
9*8d67ca89SAndroid Build Coastguard Worker  * copyright notice and this permission notice appear in all copies.
10*8d67ca89SAndroid Build Coastguard Worker  *
11*8d67ca89SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12*8d67ca89SAndroid Build Coastguard Worker  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13*8d67ca89SAndroid Build Coastguard Worker  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14*8d67ca89SAndroid Build Coastguard Worker  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15*8d67ca89SAndroid Build Coastguard Worker  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16*8d67ca89SAndroid Build Coastguard Worker  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17*8d67ca89SAndroid Build Coastguard Worker  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18*8d67ca89SAndroid Build Coastguard Worker  */
19*8d67ca89SAndroid Build Coastguard Worker 
20*8d67ca89SAndroid Build Coastguard Worker #include <sys/cdefs.h>
21*8d67ca89SAndroid Build Coastguard Worker #ifndef lint
22*8d67ca89SAndroid Build Coastguard Worker #ifdef notdef
23*8d67ca89SAndroid Build Coastguard Worker static const char rcsid[] = "Id: ns_print.c,v 1.12 2009/03/03 05:29:58 each Exp";
24*8d67ca89SAndroid Build Coastguard Worker #else
25*8d67ca89SAndroid Build Coastguard Worker __RCSID("$NetBSD: ns_print.c,v 1.11 2012/03/13 21:13:39 christos Exp $");
26*8d67ca89SAndroid Build Coastguard Worker #endif
27*8d67ca89SAndroid Build Coastguard Worker #endif
28*8d67ca89SAndroid Build Coastguard Worker 
29*8d67ca89SAndroid Build Coastguard Worker /* Import. */
30*8d67ca89SAndroid Build Coastguard Worker 
31*8d67ca89SAndroid Build Coastguard Worker #include <sys/types.h>
32*8d67ca89SAndroid Build Coastguard Worker #include <sys/socket.h>
33*8d67ca89SAndroid Build Coastguard Worker 
34*8d67ca89SAndroid Build Coastguard Worker #include <netinet/in.h>
35*8d67ca89SAndroid Build Coastguard Worker #include <arpa/nameser.h>
36*8d67ca89SAndroid Build Coastguard Worker #include <arpa/inet.h>
37*8d67ca89SAndroid Build Coastguard Worker 
38*8d67ca89SAndroid Build Coastguard Worker #include <isc/assertions.h>
39*8d67ca89SAndroid Build Coastguard Worker #include <isc/dst.h>
40*8d67ca89SAndroid Build Coastguard Worker #include <assert.h>
41*8d67ca89SAndroid Build Coastguard Worker #include <errno.h>
42*8d67ca89SAndroid Build Coastguard Worker #ifdef ANDROID_CHANGES
43*8d67ca89SAndroid Build Coastguard Worker #include "resolv_private.h"
44*8d67ca89SAndroid Build Coastguard Worker #else
45*8d67ca89SAndroid Build Coastguard Worker #include <resolv.h>
46*8d67ca89SAndroid Build Coastguard Worker #endif
47*8d67ca89SAndroid Build Coastguard Worker #include <stddef.h>
48*8d67ca89SAndroid Build Coastguard Worker #include <string.h>
49*8d67ca89SAndroid Build Coastguard Worker #include <ctype.h>
50*8d67ca89SAndroid Build Coastguard Worker 
51*8d67ca89SAndroid Build Coastguard Worker #ifndef MIN
52*8d67ca89SAndroid Build Coastguard Worker #define	MIN(x,y)	((x)<(y)?(x):(y))
53*8d67ca89SAndroid Build Coastguard Worker #endif
54*8d67ca89SAndroid Build Coastguard Worker 
55*8d67ca89SAndroid Build Coastguard Worker /* Forward. */
56*8d67ca89SAndroid Build Coastguard Worker 
57*8d67ca89SAndroid Build Coastguard Worker static size_t	prune_origin(const char *name, const char *origin);
58*8d67ca89SAndroid Build Coastguard Worker static int	charstr(const u_char *rdata, const u_char *edata,
59*8d67ca89SAndroid Build Coastguard Worker 			char **buf, size_t *buflen);
60*8d67ca89SAndroid Build Coastguard Worker static int	addname(const u_char *msg, size_t msglen,
61*8d67ca89SAndroid Build Coastguard Worker 			const u_char **p, const char *origin,
62*8d67ca89SAndroid Build Coastguard Worker 			char **buf, size_t *buflen);
63*8d67ca89SAndroid Build Coastguard Worker static void	addlen(size_t len, char **buf, size_t *buflen);
64*8d67ca89SAndroid Build Coastguard Worker static int	addstr(const char *src, size_t len,
65*8d67ca89SAndroid Build Coastguard Worker 		       char **buf, size_t *buflen);
66*8d67ca89SAndroid Build Coastguard Worker static int	addtab(size_t len, size_t target, int spaced,
67*8d67ca89SAndroid Build Coastguard Worker 		       char **buf, size_t *buflen);
68*8d67ca89SAndroid Build Coastguard Worker 
69*8d67ca89SAndroid Build Coastguard Worker /* Macros. */
70*8d67ca89SAndroid Build Coastguard Worker 
71*8d67ca89SAndroid Build Coastguard Worker #define	T(x) \
72*8d67ca89SAndroid Build Coastguard Worker 	do { \
73*8d67ca89SAndroid Build Coastguard Worker 		if ((x) < 0) \
74*8d67ca89SAndroid Build Coastguard Worker 			return (-1); \
75*8d67ca89SAndroid Build Coastguard Worker 	} while (/*CONSTCOND*/0)
76*8d67ca89SAndroid Build Coastguard Worker 
77*8d67ca89SAndroid Build Coastguard Worker static const char base32hex[] =
78*8d67ca89SAndroid Build Coastguard Worker         "0123456789ABCDEFGHIJKLMNOPQRSTUV=0123456789abcdefghijklmnopqrstuv";
79*8d67ca89SAndroid Build Coastguard Worker /* Public. */
80*8d67ca89SAndroid Build Coastguard Worker 
81*8d67ca89SAndroid Build Coastguard Worker /*
82*8d67ca89SAndroid Build Coastguard Worker  *	Convert an RR to presentation format.
83*8d67ca89SAndroid Build Coastguard Worker  *
84*8d67ca89SAndroid Build Coastguard Worker  * return:
85*8d67ca89SAndroid Build Coastguard Worker  *	Number of characters written to buf, or -1 (check errno).
86*8d67ca89SAndroid Build Coastguard Worker  */
87*8d67ca89SAndroid Build Coastguard Worker int
ns_sprintrr(const ns_msg * handle,const ns_rr * rr,const char * name_ctx,const char * origin,char * buf,size_t buflen)88*8d67ca89SAndroid Build Coastguard Worker ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
89*8d67ca89SAndroid Build Coastguard Worker 	    const char *name_ctx, const char *origin,
90*8d67ca89SAndroid Build Coastguard Worker 	    char *buf, size_t buflen)
91*8d67ca89SAndroid Build Coastguard Worker {
92*8d67ca89SAndroid Build Coastguard Worker 	int n;
93*8d67ca89SAndroid Build Coastguard Worker 
94*8d67ca89SAndroid Build Coastguard Worker 	n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
95*8d67ca89SAndroid Build Coastguard Worker 			 ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
96*8d67ca89SAndroid Build Coastguard Worker 			 ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
97*8d67ca89SAndroid Build Coastguard Worker 			 name_ctx, origin, buf, buflen);
98*8d67ca89SAndroid Build Coastguard Worker 	return (n);
99*8d67ca89SAndroid Build Coastguard Worker }
100*8d67ca89SAndroid Build Coastguard Worker 
101*8d67ca89SAndroid Build Coastguard Worker /*
102*8d67ca89SAndroid Build Coastguard Worker  *	Convert the fields of an RR into presentation format.
103*8d67ca89SAndroid Build Coastguard Worker  *
104*8d67ca89SAndroid Build Coastguard Worker  * return:
105*8d67ca89SAndroid Build Coastguard Worker  *	Number of characters written to buf, or -1 (check errno).
106*8d67ca89SAndroid Build Coastguard Worker  */
107*8d67ca89SAndroid Build Coastguard Worker int
ns_sprintrrf(const u_char * msg,size_t msglen,const char * name,ns_class class,ns_type type,u_long ttl,const u_char * rdata,size_t rdlen,const char * name_ctx,const char * origin,char * buf,size_t buflen)108*8d67ca89SAndroid Build Coastguard Worker ns_sprintrrf(const u_char *msg, size_t msglen,
109*8d67ca89SAndroid Build Coastguard Worker 	    const char *name, ns_class class, ns_type type,
110*8d67ca89SAndroid Build Coastguard Worker 	    u_long ttl, const u_char *rdata, size_t rdlen,
111*8d67ca89SAndroid Build Coastguard Worker 	    const char *name_ctx, const char *origin,
112*8d67ca89SAndroid Build Coastguard Worker 	    char *buf, size_t buflen)
113*8d67ca89SAndroid Build Coastguard Worker {
114*8d67ca89SAndroid Build Coastguard Worker 	const char *obuf = buf;
115*8d67ca89SAndroid Build Coastguard Worker 	const u_char *edata = rdata + rdlen;
116*8d67ca89SAndroid Build Coastguard Worker 	int spaced = 0;
117*8d67ca89SAndroid Build Coastguard Worker 
118*8d67ca89SAndroid Build Coastguard Worker 	const char *comment;
119*8d67ca89SAndroid Build Coastguard Worker 	char tmp[100];
120*8d67ca89SAndroid Build Coastguard Worker 	int len, x;
121*8d67ca89SAndroid Build Coastguard Worker 
122*8d67ca89SAndroid Build Coastguard Worker 	/*
123*8d67ca89SAndroid Build Coastguard Worker 	 * Owner.
124*8d67ca89SAndroid Build Coastguard Worker 	 */
125*8d67ca89SAndroid Build Coastguard Worker 	if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) {
126*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("\t\t\t", (size_t)3, &buf, &buflen));
127*8d67ca89SAndroid Build Coastguard Worker 	} else {
128*8d67ca89SAndroid Build Coastguard Worker 		len = (int)prune_origin(name, origin);
129*8d67ca89SAndroid Build Coastguard Worker 		if (*name == '\0') {
130*8d67ca89SAndroid Build Coastguard Worker 			goto root;
131*8d67ca89SAndroid Build Coastguard Worker 		} else if (len == 0) {
132*8d67ca89SAndroid Build Coastguard Worker 			T(addstr("@\t\t\t", (size_t)4, &buf, &buflen));
133*8d67ca89SAndroid Build Coastguard Worker 		} else {
134*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(name, (size_t)len, &buf, &buflen));
135*8d67ca89SAndroid Build Coastguard Worker 			/* Origin not used or not root, and no trailing dot? */
136*8d67ca89SAndroid Build Coastguard Worker 			if (((origin == NULL || origin[0] == '\0') ||
137*8d67ca89SAndroid Build Coastguard Worker 			    (origin[0] != '.' && origin[1] != '\0' &&
138*8d67ca89SAndroid Build Coastguard Worker 			    name[len] == '\0')) && name[len - 1] != '.') {
139*8d67ca89SAndroid Build Coastguard Worker  root:
140*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(".", (size_t)1, &buf, &buflen));
141*8d67ca89SAndroid Build Coastguard Worker 				len++;
142*8d67ca89SAndroid Build Coastguard Worker 			}
143*8d67ca89SAndroid Build Coastguard Worker 			T(spaced = addtab((size_t)len, 24, spaced, &buf, &buflen));
144*8d67ca89SAndroid Build Coastguard Worker 		}
145*8d67ca89SAndroid Build Coastguard Worker 	}
146*8d67ca89SAndroid Build Coastguard Worker 
147*8d67ca89SAndroid Build Coastguard Worker 	/*
148*8d67ca89SAndroid Build Coastguard Worker 	 * TTL, Class, Type.
149*8d67ca89SAndroid Build Coastguard Worker 	 */
150*8d67ca89SAndroid Build Coastguard Worker 	T(x = ns_format_ttl(ttl, buf, buflen));
151*8d67ca89SAndroid Build Coastguard Worker 	addlen((size_t)x, &buf, &buflen);
152*8d67ca89SAndroid Build Coastguard Worker 	len = snprintf(tmp, sizeof(tmp), " %s %s", p_class(class), p_type(type));
153*8d67ca89SAndroid Build Coastguard Worker 	T(addstr(tmp, (size_t)len, &buf, &buflen));
154*8d67ca89SAndroid Build Coastguard Worker 	T(spaced = addtab((size_t)(x + len), (size_t)16, spaced, &buf, &buflen));
155*8d67ca89SAndroid Build Coastguard Worker 
156*8d67ca89SAndroid Build Coastguard Worker 	/*
157*8d67ca89SAndroid Build Coastguard Worker 	 * RData.
158*8d67ca89SAndroid Build Coastguard Worker 	 */
159*8d67ca89SAndroid Build Coastguard Worker 	switch (type) {
160*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_a:
161*8d67ca89SAndroid Build Coastguard Worker 		if (rdlen != (size_t)NS_INADDRSZ)
162*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
163*8d67ca89SAndroid Build Coastguard Worker 		(void) inet_ntop(AF_INET, rdata, buf, (socklen_t)buflen);
164*8d67ca89SAndroid Build Coastguard Worker 		addlen(strlen(buf), &buf, &buflen);
165*8d67ca89SAndroid Build Coastguard Worker 		break;
166*8d67ca89SAndroid Build Coastguard Worker 
167*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_cname:
168*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_mb:
169*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_mg:
170*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_mr:
171*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_ns:
172*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_ptr:
173*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_dname:
174*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
175*8d67ca89SAndroid Build Coastguard Worker 		break;
176*8d67ca89SAndroid Build Coastguard Worker 
177*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_hinfo:
178*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_isdn:
179*8d67ca89SAndroid Build Coastguard Worker 		/* First word. */
180*8d67ca89SAndroid Build Coastguard Worker 		T(len = charstr(rdata, edata, &buf, &buflen));
181*8d67ca89SAndroid Build Coastguard Worker 		if (len == 0)
182*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
183*8d67ca89SAndroid Build Coastguard Worker 		rdata += len;
184*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" ", (size_t)1, &buf, &buflen));
185*8d67ca89SAndroid Build Coastguard Worker 
186*8d67ca89SAndroid Build Coastguard Worker 
187*8d67ca89SAndroid Build Coastguard Worker 		/* Second word, optional in ISDN records. */
188*8d67ca89SAndroid Build Coastguard Worker 		if (type == ns_t_isdn && rdata == edata)
189*8d67ca89SAndroid Build Coastguard Worker 			break;
190*8d67ca89SAndroid Build Coastguard Worker 
191*8d67ca89SAndroid Build Coastguard Worker 		T(len = charstr(rdata, edata, &buf, &buflen));
192*8d67ca89SAndroid Build Coastguard Worker 		if (len == 0)
193*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
194*8d67ca89SAndroid Build Coastguard Worker 		rdata += len;
195*8d67ca89SAndroid Build Coastguard Worker 		break;
196*8d67ca89SAndroid Build Coastguard Worker 
197*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_soa: {
198*8d67ca89SAndroid Build Coastguard Worker 		u_long t;
199*8d67ca89SAndroid Build Coastguard Worker 
200*8d67ca89SAndroid Build Coastguard Worker 		/* Server name. */
201*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
202*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" ", (size_t)1, &buf, &buflen));
203*8d67ca89SAndroid Build Coastguard Worker 
204*8d67ca89SAndroid Build Coastguard Worker 		/* Administrator name. */
205*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
206*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" (\n", (size_t)3, &buf, &buflen));
207*8d67ca89SAndroid Build Coastguard Worker 		spaced = 0;
208*8d67ca89SAndroid Build Coastguard Worker 
209*8d67ca89SAndroid Build Coastguard Worker 		if ((edata - rdata) != 5*NS_INT32SZ)
210*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
211*8d67ca89SAndroid Build Coastguard Worker 
212*8d67ca89SAndroid Build Coastguard Worker 		/* Serial number. */
213*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
214*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
215*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%lu", t);
216*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
217*8d67ca89SAndroid Build Coastguard Worker 		T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
218*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("; serial\n", (size_t)9, &buf, &buflen));
219*8d67ca89SAndroid Build Coastguard Worker 		spaced = 0;
220*8d67ca89SAndroid Build Coastguard Worker 
221*8d67ca89SAndroid Build Coastguard Worker 		/* Refresh interval. */
222*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
223*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
224*8d67ca89SAndroid Build Coastguard Worker 		T(len = ns_format_ttl(t, buf, buflen));
225*8d67ca89SAndroid Build Coastguard Worker 		addlen((size_t)len, &buf, &buflen);
226*8d67ca89SAndroid Build Coastguard Worker 		T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
227*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("; refresh\n", (size_t)10, &buf, &buflen));
228*8d67ca89SAndroid Build Coastguard Worker 		spaced = 0;
229*8d67ca89SAndroid Build Coastguard Worker 
230*8d67ca89SAndroid Build Coastguard Worker 		/* Retry interval. */
231*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
232*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
233*8d67ca89SAndroid Build Coastguard Worker 		T(len = ns_format_ttl(t, buf, buflen));
234*8d67ca89SAndroid Build Coastguard Worker 		addlen((size_t)len, &buf, &buflen);
235*8d67ca89SAndroid Build Coastguard Worker 		T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
236*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("; retry\n", (size_t)8, &buf, &buflen));
237*8d67ca89SAndroid Build Coastguard Worker 		spaced = 0;
238*8d67ca89SAndroid Build Coastguard Worker 
239*8d67ca89SAndroid Build Coastguard Worker 		/* Expiry. */
240*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
241*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
242*8d67ca89SAndroid Build Coastguard Worker 		T(len = ns_format_ttl(t, buf, buflen));
243*8d67ca89SAndroid Build Coastguard Worker 		addlen((size_t)len, &buf, &buflen);
244*8d67ca89SAndroid Build Coastguard Worker 		T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
245*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("; expiry\n", (size_t)9, &buf, &buflen));
246*8d67ca89SAndroid Build Coastguard Worker 		spaced = 0;
247*8d67ca89SAndroid Build Coastguard Worker 
248*8d67ca89SAndroid Build Coastguard Worker 		/* Minimum TTL. */
249*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
250*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
251*8d67ca89SAndroid Build Coastguard Worker 		T(len = ns_format_ttl(t, buf, buflen));
252*8d67ca89SAndroid Build Coastguard Worker 		addlen((size_t)len, &buf, &buflen);
253*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" )", (size_t)2, &buf, &buflen));
254*8d67ca89SAndroid Build Coastguard Worker 		T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
255*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("; minimum\n", (size_t)10, &buf, &buflen));
256*8d67ca89SAndroid Build Coastguard Worker 
257*8d67ca89SAndroid Build Coastguard Worker 		break;
258*8d67ca89SAndroid Build Coastguard Worker 	    }
259*8d67ca89SAndroid Build Coastguard Worker 
260*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_mx:
261*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_afsdb:
262*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_rt:
263*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_kx: {
264*8d67ca89SAndroid Build Coastguard Worker 		u_int t;
265*8d67ca89SAndroid Build Coastguard Worker 
266*8d67ca89SAndroid Build Coastguard Worker 		if (rdlen < (size_t)NS_INT16SZ)
267*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
268*8d67ca89SAndroid Build Coastguard Worker 
269*8d67ca89SAndroid Build Coastguard Worker 		/* Priority. */
270*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get16(rdata);
271*8d67ca89SAndroid Build Coastguard Worker 		rdata += NS_INT16SZ;
272*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u ", t);
273*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
274*8d67ca89SAndroid Build Coastguard Worker 
275*8d67ca89SAndroid Build Coastguard Worker 		/* Target. */
276*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
277*8d67ca89SAndroid Build Coastguard Worker 
278*8d67ca89SAndroid Build Coastguard Worker 		break;
279*8d67ca89SAndroid Build Coastguard Worker 	    }
280*8d67ca89SAndroid Build Coastguard Worker 
281*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_px: {
282*8d67ca89SAndroid Build Coastguard Worker 		u_int t;
283*8d67ca89SAndroid Build Coastguard Worker 
284*8d67ca89SAndroid Build Coastguard Worker 		if (rdlen < (size_t)NS_INT16SZ)
285*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
286*8d67ca89SAndroid Build Coastguard Worker 
287*8d67ca89SAndroid Build Coastguard Worker 		/* Priority. */
288*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get16(rdata);
289*8d67ca89SAndroid Build Coastguard Worker 		rdata += NS_INT16SZ;
290*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u ", t);
291*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
292*8d67ca89SAndroid Build Coastguard Worker 
293*8d67ca89SAndroid Build Coastguard Worker 		/* Name1. */
294*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
295*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" ", (size_t)1, &buf, &buflen));
296*8d67ca89SAndroid Build Coastguard Worker 
297*8d67ca89SAndroid Build Coastguard Worker 		/* Name2. */
298*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
299*8d67ca89SAndroid Build Coastguard Worker 
300*8d67ca89SAndroid Build Coastguard Worker 		break;
301*8d67ca89SAndroid Build Coastguard Worker 	    }
302*8d67ca89SAndroid Build Coastguard Worker 
303*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_x25:
304*8d67ca89SAndroid Build Coastguard Worker 		T(len = charstr(rdata, edata, &buf, &buflen));
305*8d67ca89SAndroid Build Coastguard Worker 		if (len == 0)
306*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
307*8d67ca89SAndroid Build Coastguard Worker 		rdata += len;
308*8d67ca89SAndroid Build Coastguard Worker 		break;
309*8d67ca89SAndroid Build Coastguard Worker 
310*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_txt:
311*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_spf:
312*8d67ca89SAndroid Build Coastguard Worker 		while (rdata < edata) {
313*8d67ca89SAndroid Build Coastguard Worker 			T(len = charstr(rdata, edata, &buf, &buflen));
314*8d67ca89SAndroid Build Coastguard Worker 			if (len == 0)
315*8d67ca89SAndroid Build Coastguard Worker 				goto formerr;
316*8d67ca89SAndroid Build Coastguard Worker 			rdata += len;
317*8d67ca89SAndroid Build Coastguard Worker 			if (rdata < edata)
318*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(" ", (size_t)1, &buf, &buflen));
319*8d67ca89SAndroid Build Coastguard Worker 		}
320*8d67ca89SAndroid Build Coastguard Worker 		break;
321*8d67ca89SAndroid Build Coastguard Worker 
322*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_nsap: {
323*8d67ca89SAndroid Build Coastguard Worker 		char t[2+255*3];
324*8d67ca89SAndroid Build Coastguard Worker 
325*8d67ca89SAndroid Build Coastguard Worker 		(void) inet_nsap_ntoa((int)rdlen, rdata, t);
326*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(t, strlen(t), &buf, &buflen));
327*8d67ca89SAndroid Build Coastguard Worker 		break;
328*8d67ca89SAndroid Build Coastguard Worker 	    }
329*8d67ca89SAndroid Build Coastguard Worker 
330*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_aaaa:
331*8d67ca89SAndroid Build Coastguard Worker 		if (rdlen != (size_t)NS_IN6ADDRSZ)
332*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
333*8d67ca89SAndroid Build Coastguard Worker 		(void) inet_ntop(AF_INET6, rdata, buf, (socklen_t)buflen);
334*8d67ca89SAndroid Build Coastguard Worker 		addlen(strlen(buf), &buf, &buflen);
335*8d67ca89SAndroid Build Coastguard Worker 		break;
336*8d67ca89SAndroid Build Coastguard Worker 
337*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_loc: {
338*8d67ca89SAndroid Build Coastguard Worker 		char t[255];
339*8d67ca89SAndroid Build Coastguard Worker 
340*8d67ca89SAndroid Build Coastguard Worker 		/* XXX protocol format checking? */
341*8d67ca89SAndroid Build Coastguard Worker 		(void) loc_ntoa(rdata, t, sizeof(t));
342*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(t, strlen(t), &buf, &buflen));
343*8d67ca89SAndroid Build Coastguard Worker 		break;
344*8d67ca89SAndroid Build Coastguard Worker 	    }
345*8d67ca89SAndroid Build Coastguard Worker 
346*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_naptr: {
347*8d67ca89SAndroid Build Coastguard Worker 		u_int order, preference;
348*8d67ca89SAndroid Build Coastguard Worker 		char t[50];
349*8d67ca89SAndroid Build Coastguard Worker 
350*8d67ca89SAndroid Build Coastguard Worker 		if (rdlen < 2U*NS_INT16SZ)
351*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
352*8d67ca89SAndroid Build Coastguard Worker 
353*8d67ca89SAndroid Build Coastguard Worker 		/* Order, Precedence. */
354*8d67ca89SAndroid Build Coastguard Worker 		order = ns_get16(rdata);	rdata += NS_INT16SZ;
355*8d67ca89SAndroid Build Coastguard Worker 		preference = ns_get16(rdata);	rdata += NS_INT16SZ;
356*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(t, sizeof(t), "%u %u ", order, preference);
357*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(t, (size_t)len, &buf, &buflen));
358*8d67ca89SAndroid Build Coastguard Worker 
359*8d67ca89SAndroid Build Coastguard Worker 		/* Flags. */
360*8d67ca89SAndroid Build Coastguard Worker 		T(len = charstr(rdata, edata, &buf, &buflen));
361*8d67ca89SAndroid Build Coastguard Worker 		if (len == 0)
362*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
363*8d67ca89SAndroid Build Coastguard Worker 		rdata += len;
364*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" ", (size_t)1, &buf, &buflen));
365*8d67ca89SAndroid Build Coastguard Worker 
366*8d67ca89SAndroid Build Coastguard Worker 		/* Service. */
367*8d67ca89SAndroid Build Coastguard Worker 		T(len = charstr(rdata, edata, &buf, &buflen));
368*8d67ca89SAndroid Build Coastguard Worker 		if (len == 0)
369*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
370*8d67ca89SAndroid Build Coastguard Worker 		rdata += len;
371*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" ", (size_t)1, &buf, &buflen));
372*8d67ca89SAndroid Build Coastguard Worker 
373*8d67ca89SAndroid Build Coastguard Worker 		/* Regexp. */
374*8d67ca89SAndroid Build Coastguard Worker 		T(len = charstr(rdata, edata, &buf, &buflen));
375*8d67ca89SAndroid Build Coastguard Worker 		if (len < 0)
376*8d67ca89SAndroid Build Coastguard Worker 			return (-1);
377*8d67ca89SAndroid Build Coastguard Worker 		if (len == 0)
378*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
379*8d67ca89SAndroid Build Coastguard Worker 		rdata += len;
380*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" ", (size_t)1, &buf, &buflen));
381*8d67ca89SAndroid Build Coastguard Worker 
382*8d67ca89SAndroid Build Coastguard Worker 		/* Server. */
383*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
384*8d67ca89SAndroid Build Coastguard Worker 		break;
385*8d67ca89SAndroid Build Coastguard Worker 	    }
386*8d67ca89SAndroid Build Coastguard Worker 
387*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_srv: {
388*8d67ca89SAndroid Build Coastguard Worker 		u_int priority, weight, port;
389*8d67ca89SAndroid Build Coastguard Worker 		char t[50];
390*8d67ca89SAndroid Build Coastguard Worker 
391*8d67ca89SAndroid Build Coastguard Worker 		if (rdlen < 3U*NS_INT16SZ)
392*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
393*8d67ca89SAndroid Build Coastguard Worker 
394*8d67ca89SAndroid Build Coastguard Worker 		/* Priority, Weight, Port. */
395*8d67ca89SAndroid Build Coastguard Worker 		priority = ns_get16(rdata);  rdata += NS_INT16SZ;
396*8d67ca89SAndroid Build Coastguard Worker 		weight   = ns_get16(rdata);  rdata += NS_INT16SZ;
397*8d67ca89SAndroid Build Coastguard Worker 		port     = ns_get16(rdata);  rdata += NS_INT16SZ;
398*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(t, sizeof(t), "%u %u %u ", priority, weight, port);
399*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(t, (size_t)len, &buf, &buflen));
400*8d67ca89SAndroid Build Coastguard Worker 
401*8d67ca89SAndroid Build Coastguard Worker 		/* Server. */
402*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
403*8d67ca89SAndroid Build Coastguard Worker 		break;
404*8d67ca89SAndroid Build Coastguard Worker 	    }
405*8d67ca89SAndroid Build Coastguard Worker 
406*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_minfo:
407*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_rp:
408*8d67ca89SAndroid Build Coastguard Worker 		/* Name1. */
409*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
410*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" ", (size_t)1, &buf, &buflen));
411*8d67ca89SAndroid Build Coastguard Worker 
412*8d67ca89SAndroid Build Coastguard Worker 		/* Name2. */
413*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
414*8d67ca89SAndroid Build Coastguard Worker 
415*8d67ca89SAndroid Build Coastguard Worker 		break;
416*8d67ca89SAndroid Build Coastguard Worker 
417*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_wks: {
418*8d67ca89SAndroid Build Coastguard Worker 		int n, lcnt;
419*8d67ca89SAndroid Build Coastguard Worker 
420*8d67ca89SAndroid Build Coastguard Worker 		if (rdlen < 1U + NS_INT32SZ)
421*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
422*8d67ca89SAndroid Build Coastguard Worker 
423*8d67ca89SAndroid Build Coastguard Worker 		/* Address. */
424*8d67ca89SAndroid Build Coastguard Worker 		(void) inet_ntop(AF_INET, rdata, buf, (socklen_t)buflen);
425*8d67ca89SAndroid Build Coastguard Worker 		addlen(strlen(buf), &buf, &buflen);
426*8d67ca89SAndroid Build Coastguard Worker 		rdata += NS_INADDRSZ;
427*8d67ca89SAndroid Build Coastguard Worker 
428*8d67ca89SAndroid Build Coastguard Worker 		/* Protocol. */
429*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), " %u ( ", *rdata);
430*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
431*8d67ca89SAndroid Build Coastguard Worker 		rdata += NS_INT8SZ;
432*8d67ca89SAndroid Build Coastguard Worker 
433*8d67ca89SAndroid Build Coastguard Worker 		/* Bit map. */
434*8d67ca89SAndroid Build Coastguard Worker 		n = 0;
435*8d67ca89SAndroid Build Coastguard Worker 		lcnt = 0;
436*8d67ca89SAndroid Build Coastguard Worker 		while (rdata < edata) {
437*8d67ca89SAndroid Build Coastguard Worker 			u_int c = *rdata++;
438*8d67ca89SAndroid Build Coastguard Worker 			do {
439*8d67ca89SAndroid Build Coastguard Worker 				if (c & 0200) {
440*8d67ca89SAndroid Build Coastguard Worker 					if (lcnt == 0) {
441*8d67ca89SAndroid Build Coastguard Worker 						T(addstr("\n\t\t\t\t", (size_t)5,
442*8d67ca89SAndroid Build Coastguard Worker 							 &buf, &buflen));
443*8d67ca89SAndroid Build Coastguard Worker 						lcnt = 10;
444*8d67ca89SAndroid Build Coastguard Worker 						spaced = 0;
445*8d67ca89SAndroid Build Coastguard Worker 					}
446*8d67ca89SAndroid Build Coastguard Worker 					len = snprintf(tmp, sizeof(tmp), "%d ", n);
447*8d67ca89SAndroid Build Coastguard Worker 					T(addstr(tmp, (size_t)len, &buf, &buflen));
448*8d67ca89SAndroid Build Coastguard Worker 					lcnt--;
449*8d67ca89SAndroid Build Coastguard Worker 				}
450*8d67ca89SAndroid Build Coastguard Worker 				c <<= 1;
451*8d67ca89SAndroid Build Coastguard Worker 			} while (++n & 07);
452*8d67ca89SAndroid Build Coastguard Worker 		}
453*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(")", (size_t)1, &buf, &buflen));
454*8d67ca89SAndroid Build Coastguard Worker 
455*8d67ca89SAndroid Build Coastguard Worker 		break;
456*8d67ca89SAndroid Build Coastguard Worker 	    }
457*8d67ca89SAndroid Build Coastguard Worker 
458*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_key:
459*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_dnskey: {
460*8d67ca89SAndroid Build Coastguard Worker 		char base64_key[NS_MD5RSA_MAX_BASE64];
461*8d67ca89SAndroid Build Coastguard Worker 		u_int keyflags, protocol, algorithm, key_id;
462*8d67ca89SAndroid Build Coastguard Worker 		const char *leader;
463*8d67ca89SAndroid Build Coastguard Worker 		int n;
464*8d67ca89SAndroid Build Coastguard Worker 
465*8d67ca89SAndroid Build Coastguard Worker 		if (rdlen < 0U + NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
466*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
467*8d67ca89SAndroid Build Coastguard Worker 
468*8d67ca89SAndroid Build Coastguard Worker 		/* Key flags, Protocol, Algorithm. */
469*8d67ca89SAndroid Build Coastguard Worker #ifndef _LIBC
470*8d67ca89SAndroid Build Coastguard Worker 		key_id = dst_s_dns_key_id(rdata, edata-rdata);
471*8d67ca89SAndroid Build Coastguard Worker #else
472*8d67ca89SAndroid Build Coastguard Worker 		key_id = 0;
473*8d67ca89SAndroid Build Coastguard Worker #endif
474*8d67ca89SAndroid Build Coastguard Worker 		keyflags = ns_get16(rdata);  rdata += NS_INT16SZ;
475*8d67ca89SAndroid Build Coastguard Worker 		protocol = *rdata++;
476*8d67ca89SAndroid Build Coastguard Worker 		algorithm = *rdata++;
477*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "0x%04x %u %u",
478*8d67ca89SAndroid Build Coastguard Worker 			       keyflags, protocol, algorithm);
479*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
480*8d67ca89SAndroid Build Coastguard Worker 
481*8d67ca89SAndroid Build Coastguard Worker 		/* Public key data. */
482*8d67ca89SAndroid Build Coastguard Worker 		len = b64_ntop(rdata, (size_t)(edata - rdata),
483*8d67ca89SAndroid Build Coastguard Worker 			       base64_key, sizeof base64_key);
484*8d67ca89SAndroid Build Coastguard Worker 		if (len < 0)
485*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
486*8d67ca89SAndroid Build Coastguard Worker 		if (len > 15) {
487*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(" (", (size_t)2, &buf, &buflen));
488*8d67ca89SAndroid Build Coastguard Worker 			leader = "\n\t\t";
489*8d67ca89SAndroid Build Coastguard Worker 			spaced = 0;
490*8d67ca89SAndroid Build Coastguard Worker 		} else
491*8d67ca89SAndroid Build Coastguard Worker 			leader = " ";
492*8d67ca89SAndroid Build Coastguard Worker 		for (n = 0; n < len; n += 48) {
493*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(leader, strlen(leader), &buf, &buflen));
494*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(base64_key + n, (size_t)MIN(len - n, 48),
495*8d67ca89SAndroid Build Coastguard Worker 				 &buf, &buflen));
496*8d67ca89SAndroid Build Coastguard Worker 		}
497*8d67ca89SAndroid Build Coastguard Worker 		if (len > 15)
498*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(" )", (size_t)2, &buf, &buflen));
499*8d67ca89SAndroid Build Coastguard Worker 		n = snprintf(tmp, sizeof(tmp), " ; key_tag= %u", key_id);
500*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)n, &buf, &buflen));
501*8d67ca89SAndroid Build Coastguard Worker 
502*8d67ca89SAndroid Build Coastguard Worker 		break;
503*8d67ca89SAndroid Build Coastguard Worker 	    }
504*8d67ca89SAndroid Build Coastguard Worker 
505*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_sig:
506*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_rrsig: {
507*8d67ca89SAndroid Build Coastguard Worker 		char base64_key[NS_MD5RSA_MAX_BASE64];
508*8d67ca89SAndroid Build Coastguard Worker 		u_int typ, algorithm, labels, footprint;
509*8d67ca89SAndroid Build Coastguard Worker 		const char *leader;
510*8d67ca89SAndroid Build Coastguard Worker 		u_long t;
511*8d67ca89SAndroid Build Coastguard Worker 		int n;
512*8d67ca89SAndroid Build Coastguard Worker 
513*8d67ca89SAndroid Build Coastguard Worker 		if (rdlen < 22U)
514*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
515*8d67ca89SAndroid Build Coastguard Worker 
516*8d67ca89SAndroid Build Coastguard Worker 		/* Type covered, Algorithm, Label count, Original TTL. */
517*8d67ca89SAndroid Build Coastguard Worker 	        typ = ns_get16(rdata);  rdata += NS_INT16SZ;
518*8d67ca89SAndroid Build Coastguard Worker 		algorithm = *rdata++;
519*8d67ca89SAndroid Build Coastguard Worker 		labels = *rdata++;
520*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
521*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%s %d %d %lu ",
522*8d67ca89SAndroid Build Coastguard Worker 			       p_type((int)typ), algorithm, labels, t);
523*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
524*8d67ca89SAndroid Build Coastguard Worker 		if (labels > (u_int)dn_count_labels(name))
525*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
526*8d67ca89SAndroid Build Coastguard Worker 
527*8d67ca89SAndroid Build Coastguard Worker 		/* Signature expiry. */
528*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
529*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%s ", p_secstodate(t));
530*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
531*8d67ca89SAndroid Build Coastguard Worker 
532*8d67ca89SAndroid Build Coastguard Worker 		/* Time signed. */
533*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
534*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%s ", p_secstodate(t));
535*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
536*8d67ca89SAndroid Build Coastguard Worker 
537*8d67ca89SAndroid Build Coastguard Worker 		/* Signature Footprint. */
538*8d67ca89SAndroid Build Coastguard Worker 		footprint = ns_get16(rdata);  rdata += NS_INT16SZ;
539*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u ", footprint);
540*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
541*8d67ca89SAndroid Build Coastguard Worker 
542*8d67ca89SAndroid Build Coastguard Worker 		/* Signer's name. */
543*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
544*8d67ca89SAndroid Build Coastguard Worker 
545*8d67ca89SAndroid Build Coastguard Worker 		/* Signature. */
546*8d67ca89SAndroid Build Coastguard Worker 		len = b64_ntop(rdata, (size_t)(edata - rdata),
547*8d67ca89SAndroid Build Coastguard Worker 			       base64_key, sizeof base64_key);
548*8d67ca89SAndroid Build Coastguard Worker 		if (len > 15) {
549*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(" (", (size_t)2, &buf, &buflen));
550*8d67ca89SAndroid Build Coastguard Worker 			leader = "\n\t\t";
551*8d67ca89SAndroid Build Coastguard Worker 			spaced = 0;
552*8d67ca89SAndroid Build Coastguard Worker 		} else
553*8d67ca89SAndroid Build Coastguard Worker 			leader = " ";
554*8d67ca89SAndroid Build Coastguard Worker 		if (len < 0)
555*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
556*8d67ca89SAndroid Build Coastguard Worker 		for (n = 0; n < len; n += 48) {
557*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(leader, strlen(leader), &buf, &buflen));
558*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(base64_key + n, (size_t)MIN(len - n, 48),
559*8d67ca89SAndroid Build Coastguard Worker 				 &buf, &buflen));
560*8d67ca89SAndroid Build Coastguard Worker 		}
561*8d67ca89SAndroid Build Coastguard Worker 		if (len > 15)
562*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(" )", (size_t)2, &buf, &buflen));
563*8d67ca89SAndroid Build Coastguard Worker 		break;
564*8d67ca89SAndroid Build Coastguard Worker 	    }
565*8d67ca89SAndroid Build Coastguard Worker 
566*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_nxt: {
567*8d67ca89SAndroid Build Coastguard Worker 		ptrdiff_t n, c;
568*8d67ca89SAndroid Build Coastguard Worker 
569*8d67ca89SAndroid Build Coastguard Worker 		/* Next domain name. */
570*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
571*8d67ca89SAndroid Build Coastguard Worker 
572*8d67ca89SAndroid Build Coastguard Worker 		/* Type bit map. */
573*8d67ca89SAndroid Build Coastguard Worker 		n = edata - rdata;
574*8d67ca89SAndroid Build Coastguard Worker 		for (c = 0; c < n*8; c++)
575*8d67ca89SAndroid Build Coastguard Worker 			if (NS_NXT_BIT_ISSET(c, rdata)) {
576*8d67ca89SAndroid Build Coastguard Worker 				len = snprintf(tmp, sizeof(tmp), " %s", p_type((int)c));
577*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(tmp, (size_t)len, &buf, &buflen));
578*8d67ca89SAndroid Build Coastguard Worker 			}
579*8d67ca89SAndroid Build Coastguard Worker 		break;
580*8d67ca89SAndroid Build Coastguard Worker 	    }
581*8d67ca89SAndroid Build Coastguard Worker 
582*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_cert: {
583*8d67ca89SAndroid Build Coastguard Worker 		u_int c_type, key_tag, alg;
584*8d67ca89SAndroid Build Coastguard Worker 		int n;
585*8d67ca89SAndroid Build Coastguard Worker 		size_t siz;
586*8d67ca89SAndroid Build Coastguard Worker 		char base64_cert[8192], tmp1[40];
587*8d67ca89SAndroid Build Coastguard Worker 		const char *leader;
588*8d67ca89SAndroid Build Coastguard Worker 
589*8d67ca89SAndroid Build Coastguard Worker 		c_type  = ns_get16(rdata); rdata += NS_INT16SZ;
590*8d67ca89SAndroid Build Coastguard Worker 		key_tag = ns_get16(rdata); rdata += NS_INT16SZ;
591*8d67ca89SAndroid Build Coastguard Worker 		alg = (u_int) *rdata++;
592*8d67ca89SAndroid Build Coastguard Worker 
593*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp1, sizeof(tmp1), "%d %d %d ", c_type, key_tag, alg);
594*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp1, (size_t)len, &buf, &buflen));
595*8d67ca89SAndroid Build Coastguard Worker 		siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
596*8d67ca89SAndroid Build Coastguard Worker 		if (siz > sizeof(base64_cert) * 3/4) {
597*8d67ca89SAndroid Build Coastguard Worker 			const char *str = "record too long to print";
598*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(str, strlen(str), &buf, &buflen));
599*8d67ca89SAndroid Build Coastguard Worker 		}
600*8d67ca89SAndroid Build Coastguard Worker 		else {
601*8d67ca89SAndroid Build Coastguard Worker 			len = b64_ntop(rdata, (size_t)(edata-rdata),
602*8d67ca89SAndroid Build Coastguard Worker 			    base64_cert, siz);
603*8d67ca89SAndroid Build Coastguard Worker 
604*8d67ca89SAndroid Build Coastguard Worker 			if (len < 0)
605*8d67ca89SAndroid Build Coastguard Worker 				goto formerr;
606*8d67ca89SAndroid Build Coastguard Worker 			else if (len > 15) {
607*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(" (", (size_t)2, &buf, &buflen));
608*8d67ca89SAndroid Build Coastguard Worker 				leader = "\n\t\t";
609*8d67ca89SAndroid Build Coastguard Worker 				spaced = 0;
610*8d67ca89SAndroid Build Coastguard Worker 			}
611*8d67ca89SAndroid Build Coastguard Worker 			else
612*8d67ca89SAndroid Build Coastguard Worker 				leader = " ";
613*8d67ca89SAndroid Build Coastguard Worker 
614*8d67ca89SAndroid Build Coastguard Worker 			for (n = 0; n < len; n += 48) {
615*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(leader, strlen(leader),
616*8d67ca89SAndroid Build Coastguard Worker 					 &buf, &buflen));
617*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(base64_cert + n, (size_t)MIN(len - n, 48),
618*8d67ca89SAndroid Build Coastguard Worker 					 &buf, &buflen));
619*8d67ca89SAndroid Build Coastguard Worker 			}
620*8d67ca89SAndroid Build Coastguard Worker 			if (len > 15)
621*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(" )", (size_t)2, &buf, &buflen));
622*8d67ca89SAndroid Build Coastguard Worker 		}
623*8d67ca89SAndroid Build Coastguard Worker 		break;
624*8d67ca89SAndroid Build Coastguard Worker 	    }
625*8d67ca89SAndroid Build Coastguard Worker 
626*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_tkey: {
627*8d67ca89SAndroid Build Coastguard Worker 		/* KJD - need to complete this */
628*8d67ca89SAndroid Build Coastguard Worker 		u_long t;
629*8d67ca89SAndroid Build Coastguard Worker 		int mode, err, keysize;
630*8d67ca89SAndroid Build Coastguard Worker 
631*8d67ca89SAndroid Build Coastguard Worker 		/* Algorithm name. */
632*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
633*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" ", (size_t)1, &buf, &buflen));
634*8d67ca89SAndroid Build Coastguard Worker 
635*8d67ca89SAndroid Build Coastguard Worker 		/* Inception. */
636*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
637*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%s ", p_secstodate(t));
638*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
639*8d67ca89SAndroid Build Coastguard Worker 
640*8d67ca89SAndroid Build Coastguard Worker 		/* Experation. */
641*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
642*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%s ", p_secstodate(t));
643*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
644*8d67ca89SAndroid Build Coastguard Worker 
645*8d67ca89SAndroid Build Coastguard Worker 		/* Mode , Error, Key Size. */
646*8d67ca89SAndroid Build Coastguard Worker 		/* Priority, Weight, Port. */
647*8d67ca89SAndroid Build Coastguard Worker 		mode = ns_get16(rdata);  rdata += NS_INT16SZ;
648*8d67ca89SAndroid Build Coastguard Worker 		err  = ns_get16(rdata);  rdata += NS_INT16SZ;
649*8d67ca89SAndroid Build Coastguard Worker 		keysize  = ns_get16(rdata);  rdata += NS_INT16SZ;
650*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u %u %u ", mode, err, keysize);
651*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
652*8d67ca89SAndroid Build Coastguard Worker 
653*8d67ca89SAndroid Build Coastguard Worker 		/* XXX need to dump key, print otherdata length & other data */
654*8d67ca89SAndroid Build Coastguard Worker 		break;
655*8d67ca89SAndroid Build Coastguard Worker 	    }
656*8d67ca89SAndroid Build Coastguard Worker 
657*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_tsig: {
658*8d67ca89SAndroid Build Coastguard Worker 		/* BEW - need to complete this */
659*8d67ca89SAndroid Build Coastguard Worker 		int n;
660*8d67ca89SAndroid Build Coastguard Worker 
661*8d67ca89SAndroid Build Coastguard Worker 		T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen));
662*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" ", (size_t)1, &buf, &buflen));
663*8d67ca89SAndroid Build Coastguard Worker 		rdata += 8; /* time */
664*8d67ca89SAndroid Build Coastguard Worker 		n = ns_get16(rdata); rdata += INT16SZ;
665*8d67ca89SAndroid Build Coastguard Worker 		rdata += n; /* sig */
666*8d67ca89SAndroid Build Coastguard Worker 		n = ns_get16(rdata); rdata += INT16SZ; /* original id */
667*8d67ca89SAndroid Build Coastguard Worker 		snprintf(buf, buflen, "%d", ns_get16(rdata));
668*8d67ca89SAndroid Build Coastguard Worker 		rdata += INT16SZ;
669*8d67ca89SAndroid Build Coastguard Worker 		addlen(strlen(buf), &buf, &buflen);
670*8d67ca89SAndroid Build Coastguard Worker 		break;
671*8d67ca89SAndroid Build Coastguard Worker 	    }
672*8d67ca89SAndroid Build Coastguard Worker 
673*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_a6: {
674*8d67ca89SAndroid Build Coastguard Worker 		struct in6_addr a;
675*8d67ca89SAndroid Build Coastguard Worker 		int pbyte, pbit;
676*8d67ca89SAndroid Build Coastguard Worker 
677*8d67ca89SAndroid Build Coastguard Worker 		/* prefix length */
678*8d67ca89SAndroid Build Coastguard Worker 		if (rdlen == 0U) goto formerr;
679*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%d ", *rdata);
680*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
681*8d67ca89SAndroid Build Coastguard Worker 		pbit = *rdata;
682*8d67ca89SAndroid Build Coastguard Worker 		if (pbit > 128) goto formerr;
683*8d67ca89SAndroid Build Coastguard Worker 		pbyte = (pbit & ~7) / 8;
684*8d67ca89SAndroid Build Coastguard Worker 		rdata++;
685*8d67ca89SAndroid Build Coastguard Worker 
686*8d67ca89SAndroid Build Coastguard Worker 		/* address suffix: provided only when prefix len != 128 */
687*8d67ca89SAndroid Build Coastguard Worker 		if (pbit < 128) {
688*8d67ca89SAndroid Build Coastguard Worker 			if (rdata + pbyte >= edata) goto formerr;
689*8d67ca89SAndroid Build Coastguard Worker 			memset(&a, 0, sizeof(a));
690*8d67ca89SAndroid Build Coastguard Worker 			memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte);
691*8d67ca89SAndroid Build Coastguard Worker 			(void) inet_ntop(AF_INET6, &a, buf, (socklen_t)buflen);
692*8d67ca89SAndroid Build Coastguard Worker 			addlen(strlen(buf), &buf, &buflen);
693*8d67ca89SAndroid Build Coastguard Worker 			rdata += sizeof(a) - pbyte;
694*8d67ca89SAndroid Build Coastguard Worker 		}
695*8d67ca89SAndroid Build Coastguard Worker 
696*8d67ca89SAndroid Build Coastguard Worker 		/* prefix name: provided only when prefix len > 0 */
697*8d67ca89SAndroid Build Coastguard Worker 		if (pbit == 0)
698*8d67ca89SAndroid Build Coastguard Worker 			break;
699*8d67ca89SAndroid Build Coastguard Worker 		if (rdata >= edata) goto formerr;
700*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" ", (size_t)1, &buf, &buflen));
701*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
702*8d67ca89SAndroid Build Coastguard Worker 
703*8d67ca89SAndroid Build Coastguard Worker 		break;
704*8d67ca89SAndroid Build Coastguard Worker 	    }
705*8d67ca89SAndroid Build Coastguard Worker 
706*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_opt: {
707*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u bytes", class);
708*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
709*8d67ca89SAndroid Build Coastguard Worker 		break;
710*8d67ca89SAndroid Build Coastguard Worker 	    }
711*8d67ca89SAndroid Build Coastguard Worker 
712*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_ds:
713*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_dlv:
714*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_sshfp: {
715*8d67ca89SAndroid Build Coastguard Worker 		u_int t;
716*8d67ca89SAndroid Build Coastguard Worker 
717*8d67ca89SAndroid Build Coastguard Worker 		if (type == ns_t_ds || type == ns_t_dlv) {
718*8d67ca89SAndroid Build Coastguard Worker 			if (rdlen < 4U) goto formerr;
719*8d67ca89SAndroid Build Coastguard Worker 			t = ns_get16(rdata);
720*8d67ca89SAndroid Build Coastguard Worker 			rdata += NS_INT16SZ;
721*8d67ca89SAndroid Build Coastguard Worker 			len = snprintf(tmp, sizeof(tmp), "%u ", t);
722*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(tmp, (size_t)len, &buf, &buflen));
723*8d67ca89SAndroid Build Coastguard Worker 		} else
724*8d67ca89SAndroid Build Coastguard Worker 			if (rdlen < 2U) goto formerr;
725*8d67ca89SAndroid Build Coastguard Worker 
726*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
727*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
728*8d67ca89SAndroid Build Coastguard Worker 		rdata++;
729*8d67ca89SAndroid Build Coastguard Worker 
730*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
731*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
732*8d67ca89SAndroid Build Coastguard Worker 		rdata++;
733*8d67ca89SAndroid Build Coastguard Worker 
734*8d67ca89SAndroid Build Coastguard Worker 		while (rdata < edata) {
735*8d67ca89SAndroid Build Coastguard Worker 			len = snprintf(tmp, sizeof(tmp), "%02X", *rdata);
736*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(tmp, (size_t)len, &buf, &buflen));
737*8d67ca89SAndroid Build Coastguard Worker 			rdata++;
738*8d67ca89SAndroid Build Coastguard Worker 		}
739*8d67ca89SAndroid Build Coastguard Worker 		break;
740*8d67ca89SAndroid Build Coastguard Worker 	    }
741*8d67ca89SAndroid Build Coastguard Worker 
742*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_nsec3:
743*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_nsec3param: {
744*8d67ca89SAndroid Build Coastguard Worker 		u_int t, w, l, j, k, c;
745*8d67ca89SAndroid Build Coastguard Worker 
746*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
747*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
748*8d67ca89SAndroid Build Coastguard Worker 		rdata++;
749*8d67ca89SAndroid Build Coastguard Worker 
750*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
751*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
752*8d67ca89SAndroid Build Coastguard Worker 		rdata++;
753*8d67ca89SAndroid Build Coastguard Worker 
754*8d67ca89SAndroid Build Coastguard Worker 		t = ns_get16(rdata);
755*8d67ca89SAndroid Build Coastguard Worker 		rdata += NS_INT16SZ;
756*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u ", t);
757*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
758*8d67ca89SAndroid Build Coastguard Worker 
759*8d67ca89SAndroid Build Coastguard Worker 		t = *rdata++;
760*8d67ca89SAndroid Build Coastguard Worker 		if (t == 0) {
761*8d67ca89SAndroid Build Coastguard Worker 			T(addstr("-", 1, &buf, &buflen));
762*8d67ca89SAndroid Build Coastguard Worker 		} else {
763*8d67ca89SAndroid Build Coastguard Worker 			while (t-- > 0) {
764*8d67ca89SAndroid Build Coastguard Worker 				len = snprintf(tmp, sizeof(tmp), "%02X", *rdata);
765*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(tmp, (size_t)len, &buf, &buflen));
766*8d67ca89SAndroid Build Coastguard Worker 				rdata++;
767*8d67ca89SAndroid Build Coastguard Worker 			}
768*8d67ca89SAndroid Build Coastguard Worker 		}
769*8d67ca89SAndroid Build Coastguard Worker 		if (type == ns_t_nsec3param)
770*8d67ca89SAndroid Build Coastguard Worker 			break;
771*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(" ", 1, &buf, &buflen));
772*8d67ca89SAndroid Build Coastguard Worker 
773*8d67ca89SAndroid Build Coastguard Worker 		t = *rdata++;
774*8d67ca89SAndroid Build Coastguard Worker 		while (t > 0) {
775*8d67ca89SAndroid Build Coastguard Worker 			switch (t) {
776*8d67ca89SAndroid Build Coastguard Worker 			case 1:
777*8d67ca89SAndroid Build Coastguard Worker 				tmp[0] = base32hex[(((uint32_t)rdata[0]>>3)&0x1f)];
778*8d67ca89SAndroid Build Coastguard Worker 				tmp[1] = base32hex[(((uint32_t)rdata[0]<<2)&0x1c)];
779*8d67ca89SAndroid Build Coastguard Worker 				tmp[2] = tmp[3] = tmp[4] = '=';
780*8d67ca89SAndroid Build Coastguard Worker 				tmp[5] = tmp[6] = tmp[7] = '=';
781*8d67ca89SAndroid Build Coastguard Worker 				break;
782*8d67ca89SAndroid Build Coastguard Worker 			case 2:
783*8d67ca89SAndroid Build Coastguard Worker 				tmp[0] = base32hex[(((uint32_t)rdata[0]>>3)&0x1f)];
784*8d67ca89SAndroid Build Coastguard Worker 				tmp[1] = base32hex[(((uint32_t)rdata[0]<<2)&0x1c)|
785*8d67ca89SAndroid Build Coastguard Worker 						   (((uint32_t)rdata[1]>>6)&0x03)];
786*8d67ca89SAndroid Build Coastguard Worker 				tmp[2] = base32hex[(((uint32_t)rdata[1]>>1)&0x1f)];
787*8d67ca89SAndroid Build Coastguard Worker 				tmp[3] = base32hex[(((uint32_t)rdata[1]<<4)&0x10)];
788*8d67ca89SAndroid Build Coastguard Worker 				tmp[4] = tmp[5] = tmp[6] = tmp[7] = '=';
789*8d67ca89SAndroid Build Coastguard Worker 				break;
790*8d67ca89SAndroid Build Coastguard Worker 			case 3:
791*8d67ca89SAndroid Build Coastguard Worker 				tmp[0] = base32hex[(((uint32_t)rdata[0]>>3)&0x1f)];
792*8d67ca89SAndroid Build Coastguard Worker 				tmp[1] = base32hex[(((uint32_t)rdata[0]<<2)&0x1c)|
793*8d67ca89SAndroid Build Coastguard Worker 						   (((uint32_t)rdata[1]>>6)&0x03)];
794*8d67ca89SAndroid Build Coastguard Worker 				tmp[2] = base32hex[(((uint32_t)rdata[1]>>1)&0x1f)];
795*8d67ca89SAndroid Build Coastguard Worker 				tmp[3] = base32hex[(((uint32_t)rdata[1]<<4)&0x10)|
796*8d67ca89SAndroid Build Coastguard Worker 						   (((uint32_t)rdata[2]>>4)&0x0f)];
797*8d67ca89SAndroid Build Coastguard Worker 				tmp[4] = base32hex[(((uint32_t)rdata[2]<<1)&0x1e)];
798*8d67ca89SAndroid Build Coastguard Worker 				tmp[5] = tmp[6] = tmp[7] = '=';
799*8d67ca89SAndroid Build Coastguard Worker 				break;
800*8d67ca89SAndroid Build Coastguard Worker 			case 4:
801*8d67ca89SAndroid Build Coastguard Worker 				tmp[0] = base32hex[(((uint32_t)rdata[0]>>3)&0x1f)];
802*8d67ca89SAndroid Build Coastguard Worker 				tmp[1] = base32hex[(((uint32_t)rdata[0]<<2)&0x1c)|
803*8d67ca89SAndroid Build Coastguard Worker 						   (((uint32_t)rdata[1]>>6)&0x03)];
804*8d67ca89SAndroid Build Coastguard Worker 				tmp[2] = base32hex[(((uint32_t)rdata[1]>>1)&0x1f)];
805*8d67ca89SAndroid Build Coastguard Worker 				tmp[3] = base32hex[(((uint32_t)rdata[1]<<4)&0x10)|
806*8d67ca89SAndroid Build Coastguard Worker 						   (((uint32_t)rdata[2]>>4)&0x0f)];
807*8d67ca89SAndroid Build Coastguard Worker 				tmp[4] = base32hex[(((uint32_t)rdata[2]<<1)&0x1e)|
808*8d67ca89SAndroid Build Coastguard Worker 						   (((uint32_t)rdata[3]>>7)&0x01)];
809*8d67ca89SAndroid Build Coastguard Worker 				tmp[5] = base32hex[(((uint32_t)rdata[3]>>2)&0x1f)];
810*8d67ca89SAndroid Build Coastguard Worker 				tmp[6] = base32hex[((uint32_t)rdata[3]<<3)&0x18];
811*8d67ca89SAndroid Build Coastguard Worker 				tmp[7] = '=';
812*8d67ca89SAndroid Build Coastguard Worker 				break;
813*8d67ca89SAndroid Build Coastguard Worker 			default:
814*8d67ca89SAndroid Build Coastguard Worker 				tmp[0] = base32hex[(((uint32_t)rdata[0]>>3)&0x1f)];
815*8d67ca89SAndroid Build Coastguard Worker 				tmp[1] = base32hex[(((uint32_t)rdata[0]<<2)&0x1c)|
816*8d67ca89SAndroid Build Coastguard Worker 						   (((uint32_t)rdata[1]>>6)&0x03)];
817*8d67ca89SAndroid Build Coastguard Worker 				tmp[2] = base32hex[(((uint32_t)rdata[1]>>1)&0x1f)];
818*8d67ca89SAndroid Build Coastguard Worker 				tmp[3] = base32hex[(((uint32_t)rdata[1]<<4)&0x10)|
819*8d67ca89SAndroid Build Coastguard Worker 						   (((uint32_t)rdata[2]>>4)&0x0f)];
820*8d67ca89SAndroid Build Coastguard Worker 				tmp[4] = base32hex[(((uint32_t)rdata[2]<<1)&0x1e)|
821*8d67ca89SAndroid Build Coastguard Worker 						   (((uint32_t)rdata[3]>>7)&0x01)];
822*8d67ca89SAndroid Build Coastguard Worker 				tmp[5] = base32hex[(((uint32_t)rdata[3]>>2)&0x1f)];
823*8d67ca89SAndroid Build Coastguard Worker 				tmp[6] = base32hex[(((uint32_t)rdata[3]<<3)&0x18)|
824*8d67ca89SAndroid Build Coastguard Worker 						   (((uint32_t)rdata[4]>>5)&0x07)];
825*8d67ca89SAndroid Build Coastguard Worker 				tmp[7] = base32hex[(rdata[4]&0x1f)];
826*8d67ca89SAndroid Build Coastguard Worker 				break;
827*8d67ca89SAndroid Build Coastguard Worker 			}
828*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(tmp, 8, &buf, &buflen));
829*8d67ca89SAndroid Build Coastguard Worker 			if (t >= 5) {
830*8d67ca89SAndroid Build Coastguard Worker 				rdata += 5;
831*8d67ca89SAndroid Build Coastguard Worker 				t -= 5;
832*8d67ca89SAndroid Build Coastguard Worker 			} else {
833*8d67ca89SAndroid Build Coastguard Worker 				rdata += t;
834*8d67ca89SAndroid Build Coastguard Worker 				t -= t;
835*8d67ca89SAndroid Build Coastguard Worker 			}
836*8d67ca89SAndroid Build Coastguard Worker 		}
837*8d67ca89SAndroid Build Coastguard Worker 
838*8d67ca89SAndroid Build Coastguard Worker 		while (rdata < edata) {
839*8d67ca89SAndroid Build Coastguard Worker 			w = *rdata++;
840*8d67ca89SAndroid Build Coastguard Worker 			l = *rdata++;
841*8d67ca89SAndroid Build Coastguard Worker 			for (j = 0; j < l; j++) {
842*8d67ca89SAndroid Build Coastguard Worker 				if (rdata[j] == 0)
843*8d67ca89SAndroid Build Coastguard Worker 					continue;
844*8d67ca89SAndroid Build Coastguard Worker 				for (k = 0; k < 8; k++) {
845*8d67ca89SAndroid Build Coastguard Worker 					if ((rdata[j] & (0x80 >> k)) == 0)
846*8d67ca89SAndroid Build Coastguard Worker 						continue;
847*8d67ca89SAndroid Build Coastguard Worker 					c = w * 256 + j * 8 + k;
848*8d67ca89SAndroid Build Coastguard Worker 					len = snprintf(tmp, sizeof(tmp), " %s", p_type((ns_type)c));
849*8d67ca89SAndroid Build Coastguard Worker 					T(addstr(tmp, (size_t)len, &buf, &buflen));
850*8d67ca89SAndroid Build Coastguard Worker 				}
851*8d67ca89SAndroid Build Coastguard Worker 			}
852*8d67ca89SAndroid Build Coastguard Worker 			rdata += l;
853*8d67ca89SAndroid Build Coastguard Worker 		}
854*8d67ca89SAndroid Build Coastguard Worker 		break;
855*8d67ca89SAndroid Build Coastguard Worker 	    }
856*8d67ca89SAndroid Build Coastguard Worker 
857*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_nsec: {
858*8d67ca89SAndroid Build Coastguard Worker 		u_int w, l, j, k, c;
859*8d67ca89SAndroid Build Coastguard Worker 
860*8d67ca89SAndroid Build Coastguard Worker 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
861*8d67ca89SAndroid Build Coastguard Worker 
862*8d67ca89SAndroid Build Coastguard Worker 		while (rdata < edata) {
863*8d67ca89SAndroid Build Coastguard Worker 			w = *rdata++;
864*8d67ca89SAndroid Build Coastguard Worker 			l = *rdata++;
865*8d67ca89SAndroid Build Coastguard Worker 			for (j = 0; j < l; j++) {
866*8d67ca89SAndroid Build Coastguard Worker 				if (rdata[j] == 0)
867*8d67ca89SAndroid Build Coastguard Worker 					continue;
868*8d67ca89SAndroid Build Coastguard Worker 				for (k = 0; k < 8; k++) {
869*8d67ca89SAndroid Build Coastguard Worker 					if ((rdata[j] & (0x80 >> k)) == 0)
870*8d67ca89SAndroid Build Coastguard Worker 						continue;
871*8d67ca89SAndroid Build Coastguard Worker 					c = w * 256 + j * 8 + k;
872*8d67ca89SAndroid Build Coastguard Worker 					len = snprintf(tmp, sizeof(tmp), " %s", p_type((ns_type)c));
873*8d67ca89SAndroid Build Coastguard Worker 					T(addstr(tmp, (size_t)len, &buf, &buflen));
874*8d67ca89SAndroid Build Coastguard Worker 				}
875*8d67ca89SAndroid Build Coastguard Worker 			}
876*8d67ca89SAndroid Build Coastguard Worker 			rdata += l;
877*8d67ca89SAndroid Build Coastguard Worker 		}
878*8d67ca89SAndroid Build Coastguard Worker 		break;
879*8d67ca89SAndroid Build Coastguard Worker 	    }
880*8d67ca89SAndroid Build Coastguard Worker 
881*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_dhcid: {
882*8d67ca89SAndroid Build Coastguard Worker 		int n;
883*8d67ca89SAndroid Build Coastguard Worker 		unsigned int siz;
884*8d67ca89SAndroid Build Coastguard Worker 		char base64_dhcid[8192];
885*8d67ca89SAndroid Build Coastguard Worker 		const char *leader;
886*8d67ca89SAndroid Build Coastguard Worker 
887*8d67ca89SAndroid Build Coastguard Worker 		siz = (int)(edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
888*8d67ca89SAndroid Build Coastguard Worker 		if (siz > sizeof(base64_dhcid) * 3/4) {
889*8d67ca89SAndroid Build Coastguard Worker 			const char *str = "record too long to print";
890*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(str, strlen(str), &buf, &buflen));
891*8d67ca89SAndroid Build Coastguard Worker 		} else {
892*8d67ca89SAndroid Build Coastguard Worker 			len = b64_ntop(rdata, (size_t)(edata-rdata),
893*8d67ca89SAndroid Build Coastguard Worker 			    base64_dhcid, siz);
894*8d67ca89SAndroid Build Coastguard Worker 
895*8d67ca89SAndroid Build Coastguard Worker 			if (len < 0)
896*8d67ca89SAndroid Build Coastguard Worker 				goto formerr;
897*8d67ca89SAndroid Build Coastguard Worker 
898*8d67ca89SAndroid Build Coastguard Worker 			else if (len > 15) {
899*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(" (", 2, &buf, &buflen));
900*8d67ca89SAndroid Build Coastguard Worker 				leader = "\n\t\t";
901*8d67ca89SAndroid Build Coastguard Worker 				spaced = 0;
902*8d67ca89SAndroid Build Coastguard Worker 			}
903*8d67ca89SAndroid Build Coastguard Worker 			else
904*8d67ca89SAndroid Build Coastguard Worker 				leader = " ";
905*8d67ca89SAndroid Build Coastguard Worker 
906*8d67ca89SAndroid Build Coastguard Worker 			for (n = 0; n < len; n += 48) {
907*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(leader, strlen(leader),
908*8d67ca89SAndroid Build Coastguard Worker 					 &buf, &buflen));
909*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(base64_dhcid + n,
910*8d67ca89SAndroid Build Coastguard Worker 				    (size_t)MIN(len - n, 48), &buf, &buflen));
911*8d67ca89SAndroid Build Coastguard Worker 			}
912*8d67ca89SAndroid Build Coastguard Worker 			if (len > 15)
913*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(" )", 2, &buf, &buflen));
914*8d67ca89SAndroid Build Coastguard Worker 		}
915*8d67ca89SAndroid Build Coastguard Worker 		break;
916*8d67ca89SAndroid Build Coastguard Worker 	}
917*8d67ca89SAndroid Build Coastguard Worker 
918*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_ipseckey: {
919*8d67ca89SAndroid Build Coastguard Worker 		int n;
920*8d67ca89SAndroid Build Coastguard Worker 		unsigned int siz;
921*8d67ca89SAndroid Build Coastguard Worker 		char base64_key[8192];
922*8d67ca89SAndroid Build Coastguard Worker 		const char *leader;
923*8d67ca89SAndroid Build Coastguard Worker 
924*8d67ca89SAndroid Build Coastguard Worker 		if (rdlen < 2)
925*8d67ca89SAndroid Build Coastguard Worker 			goto formerr;
926*8d67ca89SAndroid Build Coastguard Worker 
927*8d67ca89SAndroid Build Coastguard Worker 		switch (rdata[1]) {
928*8d67ca89SAndroid Build Coastguard Worker 		case 0:
929*8d67ca89SAndroid Build Coastguard Worker 		case 3:
930*8d67ca89SAndroid Build Coastguard Worker 			if (rdlen < 3)
931*8d67ca89SAndroid Build Coastguard Worker 				goto formerr;
932*8d67ca89SAndroid Build Coastguard Worker 			break;
933*8d67ca89SAndroid Build Coastguard Worker 		case 1:
934*8d67ca89SAndroid Build Coastguard Worker 			if (rdlen < 7)
935*8d67ca89SAndroid Build Coastguard Worker 				goto formerr;
936*8d67ca89SAndroid Build Coastguard Worker 			break;
937*8d67ca89SAndroid Build Coastguard Worker 		case 2:
938*8d67ca89SAndroid Build Coastguard Worker 			if (rdlen < 19)
939*8d67ca89SAndroid Build Coastguard Worker 				goto formerr;
940*8d67ca89SAndroid Build Coastguard Worker 			break;
941*8d67ca89SAndroid Build Coastguard Worker 		default:
942*8d67ca89SAndroid Build Coastguard Worker 			comment = "unknown IPSECKEY gateway type";
943*8d67ca89SAndroid Build Coastguard Worker 			goto hexify;
944*8d67ca89SAndroid Build Coastguard Worker 		}
945*8d67ca89SAndroid Build Coastguard Worker 
946*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
947*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
948*8d67ca89SAndroid Build Coastguard Worker 		rdata++;
949*8d67ca89SAndroid Build Coastguard Worker 
950*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
951*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
952*8d67ca89SAndroid Build Coastguard Worker 		rdata++;
953*8d67ca89SAndroid Build Coastguard Worker 
954*8d67ca89SAndroid Build Coastguard Worker 		len = snprintf(tmp, sizeof(tmp), "%u ", *rdata);
955*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)len, &buf, &buflen));
956*8d67ca89SAndroid Build Coastguard Worker 		rdata++;
957*8d67ca89SAndroid Build Coastguard Worker 
958*8d67ca89SAndroid Build Coastguard Worker 		switch (rdata[-2]) {
959*8d67ca89SAndroid Build Coastguard Worker 		case 0:
960*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(".", 1, &buf, &buflen));
961*8d67ca89SAndroid Build Coastguard Worker 			break;
962*8d67ca89SAndroid Build Coastguard Worker 		case 1:
963*8d67ca89SAndroid Build Coastguard Worker 			(void) inet_ntop(AF_INET, rdata, buf, (socklen_t)buflen);
964*8d67ca89SAndroid Build Coastguard Worker 			addlen(strlen(buf), &buf, &buflen);
965*8d67ca89SAndroid Build Coastguard Worker 			rdata += 4;
966*8d67ca89SAndroid Build Coastguard Worker 			break;
967*8d67ca89SAndroid Build Coastguard Worker 		case 2:
968*8d67ca89SAndroid Build Coastguard Worker 			(void) inet_ntop(AF_INET6, rdata, buf, (socklen_t)buflen);
969*8d67ca89SAndroid Build Coastguard Worker 			addlen(strlen(buf), &buf, &buflen);
970*8d67ca89SAndroid Build Coastguard Worker 			rdata += 16;
971*8d67ca89SAndroid Build Coastguard Worker 			break;
972*8d67ca89SAndroid Build Coastguard Worker 		case 3:
973*8d67ca89SAndroid Build Coastguard Worker 			T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
974*8d67ca89SAndroid Build Coastguard Worker 			break;
975*8d67ca89SAndroid Build Coastguard Worker 		}
976*8d67ca89SAndroid Build Coastguard Worker 
977*8d67ca89SAndroid Build Coastguard Worker 		if (rdata >= edata)
978*8d67ca89SAndroid Build Coastguard Worker 			break;
979*8d67ca89SAndroid Build Coastguard Worker 
980*8d67ca89SAndroid Build Coastguard Worker 		siz = (int)(edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
981*8d67ca89SAndroid Build Coastguard Worker 		if (siz > sizeof(base64_key) * 3/4) {
982*8d67ca89SAndroid Build Coastguard Worker 			const char *str = "record too long to print";
983*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(str, strlen(str), &buf, &buflen));
984*8d67ca89SAndroid Build Coastguard Worker 		} else {
985*8d67ca89SAndroid Build Coastguard Worker 			len = b64_ntop(rdata, (size_t)(edata-rdata),
986*8d67ca89SAndroid Build Coastguard Worker 			    base64_key, siz);
987*8d67ca89SAndroid Build Coastguard Worker 
988*8d67ca89SAndroid Build Coastguard Worker 			if (len < 0)
989*8d67ca89SAndroid Build Coastguard Worker 				goto formerr;
990*8d67ca89SAndroid Build Coastguard Worker 
991*8d67ca89SAndroid Build Coastguard Worker 			else if (len > 15) {
992*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(" (", 2, &buf, &buflen));
993*8d67ca89SAndroid Build Coastguard Worker 				leader = "\n\t\t";
994*8d67ca89SAndroid Build Coastguard Worker 				spaced = 0;
995*8d67ca89SAndroid Build Coastguard Worker 			}
996*8d67ca89SAndroid Build Coastguard Worker 			else
997*8d67ca89SAndroid Build Coastguard Worker 				leader = " ";
998*8d67ca89SAndroid Build Coastguard Worker 
999*8d67ca89SAndroid Build Coastguard Worker 			for (n = 0; n < len; n += 48) {
1000*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(leader, strlen(leader),
1001*8d67ca89SAndroid Build Coastguard Worker 					 &buf, &buflen));
1002*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(base64_key + n,
1003*8d67ca89SAndroid Build Coastguard Worker 				    (size_t)MIN(len - n, 48), &buf, &buflen));
1004*8d67ca89SAndroid Build Coastguard Worker 			}
1005*8d67ca89SAndroid Build Coastguard Worker 			if (len > 15)
1006*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(" )", 2, &buf, &buflen));
1007*8d67ca89SAndroid Build Coastguard Worker 		}
1008*8d67ca89SAndroid Build Coastguard Worker 		break;
1009*8d67ca89SAndroid Build Coastguard Worker 	}
1010*8d67ca89SAndroid Build Coastguard Worker 
1011*8d67ca89SAndroid Build Coastguard Worker 	case ns_t_hip: {
1012*8d67ca89SAndroid Build Coastguard Worker 		unsigned int i, hip_len, algorithm, key_len;
1013*8d67ca89SAndroid Build Coastguard Worker 		char base64_key[NS_MD5RSA_MAX_BASE64];
1014*8d67ca89SAndroid Build Coastguard Worker 		unsigned int siz;
1015*8d67ca89SAndroid Build Coastguard Worker 		const char *leader = "\n\t\t\t\t\t";
1016*8d67ca89SAndroid Build Coastguard Worker 
1017*8d67ca89SAndroid Build Coastguard Worker 		hip_len = *rdata++;
1018*8d67ca89SAndroid Build Coastguard Worker 		algorithm = *rdata++;
1019*8d67ca89SAndroid Build Coastguard Worker 		key_len = ns_get16(rdata);
1020*8d67ca89SAndroid Build Coastguard Worker 		rdata += NS_INT16SZ;
1021*8d67ca89SAndroid Build Coastguard Worker 
1022*8d67ca89SAndroid Build Coastguard Worker 		siz = key_len*4/3 + 4; /* "+4" accounts for trailing \0 */
1023*8d67ca89SAndroid Build Coastguard Worker 		if (siz > sizeof(base64_key) * 3/4) {
1024*8d67ca89SAndroid Build Coastguard Worker 			const char *str = "record too long to print";
1025*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(str, strlen(str), &buf, &buflen));
1026*8d67ca89SAndroid Build Coastguard Worker 		} else {
1027*8d67ca89SAndroid Build Coastguard Worker 			len = snprintf(tmp, sizeof(tmp), "( %u ", algorithm);
1028*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(tmp, (size_t)len, &buf, &buflen));
1029*8d67ca89SAndroid Build Coastguard Worker 
1030*8d67ca89SAndroid Build Coastguard Worker 			for (i = 0; i < hip_len; i++) {
1031*8d67ca89SAndroid Build Coastguard Worker 				len = snprintf(tmp, sizeof(tmp), "%02X", *rdata);
1032*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(tmp, (size_t)len, &buf, &buflen));
1033*8d67ca89SAndroid Build Coastguard Worker 				rdata++;
1034*8d67ca89SAndroid Build Coastguard Worker 			}
1035*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(leader, strlen(leader), &buf, &buflen));
1036*8d67ca89SAndroid Build Coastguard Worker 
1037*8d67ca89SAndroid Build Coastguard Worker 			len = b64_ntop(rdata, key_len, base64_key, siz);
1038*8d67ca89SAndroid Build Coastguard Worker 			if (len < 0)
1039*8d67ca89SAndroid Build Coastguard Worker 				goto formerr;
1040*8d67ca89SAndroid Build Coastguard Worker 
1041*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(base64_key, (size_t)len, &buf, &buflen));
1042*8d67ca89SAndroid Build Coastguard Worker 
1043*8d67ca89SAndroid Build Coastguard Worker 			rdata += key_len;
1044*8d67ca89SAndroid Build Coastguard Worker 			while (rdata < edata) {
1045*8d67ca89SAndroid Build Coastguard Worker 				T(addstr(leader, strlen(leader), &buf, &buflen));
1046*8d67ca89SAndroid Build Coastguard Worker 				T(addname(msg, msglen, &rdata, origin,
1047*8d67ca89SAndroid Build Coastguard Worker 					  &buf, &buflen));
1048*8d67ca89SAndroid Build Coastguard Worker 			}
1049*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(" )", 2, &buf, &buflen));
1050*8d67ca89SAndroid Build Coastguard Worker 		}
1051*8d67ca89SAndroid Build Coastguard Worker 		break;
1052*8d67ca89SAndroid Build Coastguard Worker 	    }
1053*8d67ca89SAndroid Build Coastguard Worker 
1054*8d67ca89SAndroid Build Coastguard Worker 	default:
1055*8d67ca89SAndroid Build Coastguard Worker 		comment = "unknown RR type";
1056*8d67ca89SAndroid Build Coastguard Worker 		goto hexify;
1057*8d67ca89SAndroid Build Coastguard Worker 	}
1058*8d67ca89SAndroid Build Coastguard Worker 	_DIAGASSERT(__type_fit(int, buf - obuf));
1059*8d67ca89SAndroid Build Coastguard Worker 	return (int)(buf - obuf);
1060*8d67ca89SAndroid Build Coastguard Worker  formerr:
1061*8d67ca89SAndroid Build Coastguard Worker 	comment = "RR format error";
1062*8d67ca89SAndroid Build Coastguard Worker  hexify: {
1063*8d67ca89SAndroid Build Coastguard Worker 	int n, m;
1064*8d67ca89SAndroid Build Coastguard Worker 	char *p;
1065*8d67ca89SAndroid Build Coastguard Worker 
1066*8d67ca89SAndroid Build Coastguard Worker 	len = snprintf(tmp, sizeof(tmp), "\\# %u%s\t; %s", (unsigned)(edata - rdata),
1067*8d67ca89SAndroid Build Coastguard Worker 		       rdlen != 0U ? " (" : "", comment);
1068*8d67ca89SAndroid Build Coastguard Worker 	T(addstr(tmp, (size_t)len, &buf, &buflen));
1069*8d67ca89SAndroid Build Coastguard Worker 	while (rdata < edata) {
1070*8d67ca89SAndroid Build Coastguard Worker 		p = tmp;
1071*8d67ca89SAndroid Build Coastguard Worker 		p += snprintf(p, sizeof(tmp), "\n\t");
1072*8d67ca89SAndroid Build Coastguard Worker 		spaced = 0;
1073*8d67ca89SAndroid Build Coastguard Worker 		n = MIN(16, (int)(edata - rdata));
1074*8d67ca89SAndroid Build Coastguard Worker 		for (m = 0; m < n; m++)
1075*8d67ca89SAndroid Build Coastguard Worker 			p += snprintf(p, sizeof(tmp) - (p - tmp), "%02x ", rdata[m]);
1076*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)(p - tmp), &buf, &buflen));
1077*8d67ca89SAndroid Build Coastguard Worker 		if (n < 16) {
1078*8d67ca89SAndroid Build Coastguard Worker 			T(addstr(")", (size_t)1, &buf, &buflen));
1079*8d67ca89SAndroid Build Coastguard Worker 			T(addtab((size_t)(p - tmp + 1), (size_t)48, spaced, &buf, &buflen));
1080*8d67ca89SAndroid Build Coastguard Worker 		}
1081*8d67ca89SAndroid Build Coastguard Worker 		p = tmp;
1082*8d67ca89SAndroid Build Coastguard Worker 		p += snprintf(p, sizeof(tmp), "; ");
1083*8d67ca89SAndroid Build Coastguard Worker 		for (m = 0; m < n; m++)
1084*8d67ca89SAndroid Build Coastguard Worker 			*p++ = (isascii(rdata[m]) && isprint(rdata[m]))
1085*8d67ca89SAndroid Build Coastguard Worker 				? rdata[m]
1086*8d67ca89SAndroid Build Coastguard Worker 				: '.';
1087*8d67ca89SAndroid Build Coastguard Worker 		T(addstr(tmp, (size_t)(p - tmp), &buf, &buflen));
1088*8d67ca89SAndroid Build Coastguard Worker 		rdata += n;
1089*8d67ca89SAndroid Build Coastguard Worker 	}
1090*8d67ca89SAndroid Build Coastguard Worker 	_DIAGASSERT(__type_fit(int, buf - obuf));
1091*8d67ca89SAndroid Build Coastguard Worker 	return (int)(buf - obuf);
1092*8d67ca89SAndroid Build Coastguard Worker     }
1093*8d67ca89SAndroid Build Coastguard Worker }
1094*8d67ca89SAndroid Build Coastguard Worker 
1095*8d67ca89SAndroid Build Coastguard Worker /* Private. */
1096*8d67ca89SAndroid Build Coastguard Worker 
1097*8d67ca89SAndroid Build Coastguard Worker /*
1098*8d67ca89SAndroid Build Coastguard Worker  * size_t
1099*8d67ca89SAndroid Build Coastguard Worker  * prune_origin(name, origin)
1100*8d67ca89SAndroid Build Coastguard Worker  *	Find out if the name is at or under the current origin.
1101*8d67ca89SAndroid Build Coastguard Worker  * return:
1102*8d67ca89SAndroid Build Coastguard Worker  *	Number of characters in name before start of origin,
1103*8d67ca89SAndroid Build Coastguard Worker  *	or length of name if origin does not match.
1104*8d67ca89SAndroid Build Coastguard Worker  * notes:
1105*8d67ca89SAndroid Build Coastguard Worker  *	This function should share code with samedomain().
1106*8d67ca89SAndroid Build Coastguard Worker  */
1107*8d67ca89SAndroid Build Coastguard Worker static size_t
prune_origin(const char * name,const char * origin)1108*8d67ca89SAndroid Build Coastguard Worker prune_origin(const char *name, const char *origin) {
1109*8d67ca89SAndroid Build Coastguard Worker 	const char *oname = name;
1110*8d67ca89SAndroid Build Coastguard Worker 
1111*8d67ca89SAndroid Build Coastguard Worker 	while (*name != '\0') {
1112*8d67ca89SAndroid Build Coastguard Worker 		if (origin != NULL && ns_samename(name, origin) == 1)
1113*8d67ca89SAndroid Build Coastguard Worker 			return (name - oname - (name > oname));
1114*8d67ca89SAndroid Build Coastguard Worker 		while (*name != '\0') {
1115*8d67ca89SAndroid Build Coastguard Worker 			if (*name == '\\') {
1116*8d67ca89SAndroid Build Coastguard Worker 				name++;
1117*8d67ca89SAndroid Build Coastguard Worker 				/* XXX need to handle \nnn form. */
1118*8d67ca89SAndroid Build Coastguard Worker 				if (*name == '\0')
1119*8d67ca89SAndroid Build Coastguard Worker 					break;
1120*8d67ca89SAndroid Build Coastguard Worker 			} else if (*name == '.') {
1121*8d67ca89SAndroid Build Coastguard Worker 				name++;
1122*8d67ca89SAndroid Build Coastguard Worker 				break;
1123*8d67ca89SAndroid Build Coastguard Worker 			}
1124*8d67ca89SAndroid Build Coastguard Worker 			name++;
1125*8d67ca89SAndroid Build Coastguard Worker 		}
1126*8d67ca89SAndroid Build Coastguard Worker 	}
1127*8d67ca89SAndroid Build Coastguard Worker 	return (name - oname);
1128*8d67ca89SAndroid Build Coastguard Worker }
1129*8d67ca89SAndroid Build Coastguard Worker 
1130*8d67ca89SAndroid Build Coastguard Worker /*
1131*8d67ca89SAndroid Build Coastguard Worker  * int
1132*8d67ca89SAndroid Build Coastguard Worker  * charstr(rdata, edata, buf, buflen)
1133*8d67ca89SAndroid Build Coastguard Worker  *	Format a <character-string> into the presentation buffer.
1134*8d67ca89SAndroid Build Coastguard Worker  * return:
1135*8d67ca89SAndroid Build Coastguard Worker  *	Number of rdata octets consumed
1136*8d67ca89SAndroid Build Coastguard Worker  *	0 for protocol format error
1137*8d67ca89SAndroid Build Coastguard Worker  *	-1 for output buffer error
1138*8d67ca89SAndroid Build Coastguard Worker  * side effects:
1139*8d67ca89SAndroid Build Coastguard Worker  *	buffer is advanced on success.
1140*8d67ca89SAndroid Build Coastguard Worker  */
1141*8d67ca89SAndroid Build Coastguard Worker static int
charstr(const u_char * rdata,const u_char * edata,char ** buf,size_t * buflen)1142*8d67ca89SAndroid Build Coastguard Worker charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
1143*8d67ca89SAndroid Build Coastguard Worker 	const u_char *odata = rdata;
1144*8d67ca89SAndroid Build Coastguard Worker 	size_t save_buflen = *buflen;
1145*8d67ca89SAndroid Build Coastguard Worker 	char *save_buf = *buf;
1146*8d67ca89SAndroid Build Coastguard Worker 
1147*8d67ca89SAndroid Build Coastguard Worker 	if (addstr("\"", (size_t)1, buf, buflen) < 0)
1148*8d67ca89SAndroid Build Coastguard Worker 		goto enospc;
1149*8d67ca89SAndroid Build Coastguard Worker 	if (rdata < edata) {
1150*8d67ca89SAndroid Build Coastguard Worker 		int n = *rdata;
1151*8d67ca89SAndroid Build Coastguard Worker 
1152*8d67ca89SAndroid Build Coastguard Worker 		if (rdata + 1 + n <= edata) {
1153*8d67ca89SAndroid Build Coastguard Worker 			rdata++;
1154*8d67ca89SAndroid Build Coastguard Worker 			while (n-- > 0) {
1155*8d67ca89SAndroid Build Coastguard Worker 				if (strchr("\n\"\\", *rdata) != NULL)
1156*8d67ca89SAndroid Build Coastguard Worker 					if (addstr("\\", (size_t)1, buf, buflen) < 0)
1157*8d67ca89SAndroid Build Coastguard Worker 						goto enospc;
1158*8d67ca89SAndroid Build Coastguard Worker 				if (addstr((const char *)rdata, (size_t)1,
1159*8d67ca89SAndroid Build Coastguard Worker 					   buf, buflen) < 0)
1160*8d67ca89SAndroid Build Coastguard Worker 					goto enospc;
1161*8d67ca89SAndroid Build Coastguard Worker 				rdata++;
1162*8d67ca89SAndroid Build Coastguard Worker 			}
1163*8d67ca89SAndroid Build Coastguard Worker 		}
1164*8d67ca89SAndroid Build Coastguard Worker 	}
1165*8d67ca89SAndroid Build Coastguard Worker 	if (addstr("\"", (size_t)1, buf, buflen) < 0)
1166*8d67ca89SAndroid Build Coastguard Worker 		goto enospc;
1167*8d67ca89SAndroid Build Coastguard Worker 	_DIAGASSERT(__type_fit(int, rdata - odata));
1168*8d67ca89SAndroid Build Coastguard Worker 	return (int)(rdata - odata);
1169*8d67ca89SAndroid Build Coastguard Worker  enospc:
1170*8d67ca89SAndroid Build Coastguard Worker 	errno = ENOSPC;
1171*8d67ca89SAndroid Build Coastguard Worker 	*buf = save_buf;
1172*8d67ca89SAndroid Build Coastguard Worker 	*buflen = save_buflen;
1173*8d67ca89SAndroid Build Coastguard Worker 	return (-1);
1174*8d67ca89SAndroid Build Coastguard Worker }
1175*8d67ca89SAndroid Build Coastguard Worker 
1176*8d67ca89SAndroid Build Coastguard Worker static int
addname(const u_char * msg,size_t msglen,const u_char ** pp,const char * origin,char ** buf,size_t * buflen)1177*8d67ca89SAndroid Build Coastguard Worker addname(const u_char *msg, size_t msglen,
1178*8d67ca89SAndroid Build Coastguard Worker 	const u_char **pp, const char *origin,
1179*8d67ca89SAndroid Build Coastguard Worker 	char **buf, size_t *buflen)
1180*8d67ca89SAndroid Build Coastguard Worker {
1181*8d67ca89SAndroid Build Coastguard Worker 	size_t newlen, save_buflen = *buflen;
1182*8d67ca89SAndroid Build Coastguard Worker 	char *save_buf = *buf;
1183*8d67ca89SAndroid Build Coastguard Worker 	int n;
1184*8d67ca89SAndroid Build Coastguard Worker 
1185*8d67ca89SAndroid Build Coastguard Worker 	n = dn_expand(msg, msg + msglen, *pp, *buf, (int)*buflen);
1186*8d67ca89SAndroid Build Coastguard Worker 	if (n < 0)
1187*8d67ca89SAndroid Build Coastguard Worker 		goto enospc;	/* Guess. */
1188*8d67ca89SAndroid Build Coastguard Worker 	newlen = prune_origin(*buf, origin);
1189*8d67ca89SAndroid Build Coastguard Worker 	if (**buf == '\0') {
1190*8d67ca89SAndroid Build Coastguard Worker 		goto root;
1191*8d67ca89SAndroid Build Coastguard Worker 	} else if (newlen == 0U) {
1192*8d67ca89SAndroid Build Coastguard Worker 		/* Use "@" instead of name. */
1193*8d67ca89SAndroid Build Coastguard Worker 		if (newlen + 2 > *buflen)
1194*8d67ca89SAndroid Build Coastguard Worker 			goto enospc;        /* No room for "@\0". */
1195*8d67ca89SAndroid Build Coastguard Worker 		(*buf)[newlen++] = '@';
1196*8d67ca89SAndroid Build Coastguard Worker 		(*buf)[newlen] = '\0';
1197*8d67ca89SAndroid Build Coastguard Worker 	} else {
1198*8d67ca89SAndroid Build Coastguard Worker 		if (((origin == NULL || origin[0] == '\0') ||
1199*8d67ca89SAndroid Build Coastguard Worker 		    (origin[0] != '.' && origin[1] != '\0' &&
1200*8d67ca89SAndroid Build Coastguard Worker 		    (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') {
1201*8d67ca89SAndroid Build Coastguard Worker 			/* No trailing dot. */
1202*8d67ca89SAndroid Build Coastguard Worker  root:
1203*8d67ca89SAndroid Build Coastguard Worker 			if (newlen + 2 > *buflen)
1204*8d67ca89SAndroid Build Coastguard Worker 				goto enospc;	/* No room for ".\0". */
1205*8d67ca89SAndroid Build Coastguard Worker 			(*buf)[newlen++] = '.';
1206*8d67ca89SAndroid Build Coastguard Worker 			(*buf)[newlen] = '\0';
1207*8d67ca89SAndroid Build Coastguard Worker 		}
1208*8d67ca89SAndroid Build Coastguard Worker 	}
1209*8d67ca89SAndroid Build Coastguard Worker 	*pp += n;
1210*8d67ca89SAndroid Build Coastguard Worker 	addlen(newlen, buf, buflen);
1211*8d67ca89SAndroid Build Coastguard Worker 	**buf = '\0';
1212*8d67ca89SAndroid Build Coastguard Worker 	_DIAGASSERT(__type_fit(int, newlen));
1213*8d67ca89SAndroid Build Coastguard Worker 	return (int)newlen;
1214*8d67ca89SAndroid Build Coastguard Worker  enospc:
1215*8d67ca89SAndroid Build Coastguard Worker 	errno = ENOSPC;
1216*8d67ca89SAndroid Build Coastguard Worker 	*buf = save_buf;
1217*8d67ca89SAndroid Build Coastguard Worker 	*buflen = save_buflen;
1218*8d67ca89SAndroid Build Coastguard Worker 	return (-1);
1219*8d67ca89SAndroid Build Coastguard Worker }
1220*8d67ca89SAndroid Build Coastguard Worker 
1221*8d67ca89SAndroid Build Coastguard Worker static void
addlen(size_t len,char ** buf,size_t * buflen)1222*8d67ca89SAndroid Build Coastguard Worker addlen(size_t len, char **buf, size_t *buflen) {
1223*8d67ca89SAndroid Build Coastguard Worker 	assert(len <= *buflen);
1224*8d67ca89SAndroid Build Coastguard Worker 	*buf += len;
1225*8d67ca89SAndroid Build Coastguard Worker 	*buflen -= len;
1226*8d67ca89SAndroid Build Coastguard Worker }
1227*8d67ca89SAndroid Build Coastguard Worker 
1228*8d67ca89SAndroid Build Coastguard Worker static int
addstr(const char * src,size_t len,char ** buf,size_t * buflen)1229*8d67ca89SAndroid Build Coastguard Worker addstr(const char *src, size_t len, char **buf, size_t *buflen) {
1230*8d67ca89SAndroid Build Coastguard Worker 	if (len >= *buflen) {
1231*8d67ca89SAndroid Build Coastguard Worker 		errno = ENOSPC;
1232*8d67ca89SAndroid Build Coastguard Worker 		return (-1);
1233*8d67ca89SAndroid Build Coastguard Worker 	}
1234*8d67ca89SAndroid Build Coastguard Worker 	memcpy(*buf, src, len);
1235*8d67ca89SAndroid Build Coastguard Worker 	addlen(len, buf, buflen);
1236*8d67ca89SAndroid Build Coastguard Worker 	**buf = '\0';
1237*8d67ca89SAndroid Build Coastguard Worker 	return (0);
1238*8d67ca89SAndroid Build Coastguard Worker }
1239*8d67ca89SAndroid Build Coastguard Worker 
1240*8d67ca89SAndroid Build Coastguard Worker static int
addtab(size_t len,size_t target,int spaced,char ** buf,size_t * buflen)1241*8d67ca89SAndroid Build Coastguard Worker addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
1242*8d67ca89SAndroid Build Coastguard Worker 	size_t save_buflen = *buflen;
1243*8d67ca89SAndroid Build Coastguard Worker 	char *save_buf = *buf;
1244*8d67ca89SAndroid Build Coastguard Worker 	ptrdiff_t t;
1245*8d67ca89SAndroid Build Coastguard Worker 
1246*8d67ca89SAndroid Build Coastguard Worker 	if (spaced || len >= target - 1) {
1247*8d67ca89SAndroid Build Coastguard Worker 		T(addstr("  ", (size_t)2, buf, buflen));
1248*8d67ca89SAndroid Build Coastguard Worker 		spaced = 1;
1249*8d67ca89SAndroid Build Coastguard Worker 	} else {
1250*8d67ca89SAndroid Build Coastguard Worker 		for (t = (target - len - 1) / 8; t >= 0; t--)
1251*8d67ca89SAndroid Build Coastguard Worker 			if (addstr("\t", (size_t)1, buf, buflen) < 0) {
1252*8d67ca89SAndroid Build Coastguard Worker 				*buflen = save_buflen;
1253*8d67ca89SAndroid Build Coastguard Worker 				*buf = save_buf;
1254*8d67ca89SAndroid Build Coastguard Worker 				return (-1);
1255*8d67ca89SAndroid Build Coastguard Worker 			}
1256*8d67ca89SAndroid Build Coastguard Worker 		spaced = 0;
1257*8d67ca89SAndroid Build Coastguard Worker 	}
1258*8d67ca89SAndroid Build Coastguard Worker 	return (spaced);
1259*8d67ca89SAndroid Build Coastguard Worker }
1260