xref: /onnv-gate/usr/src/lib/libresolv2/common/nameser/ns_print.c (revision 11038:74b12212b8a2)
10Sstevel@tonic-gate /*
2*11038SRao.Shoaib@Sun.COM  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
30Sstevel@tonic-gate  * Copyright (c) 1996-1999 by Internet Software Consortium.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * Permission to use, copy, modify, and distribute this software for any
60Sstevel@tonic-gate  * purpose with or without fee is hereby granted, provided that the above
70Sstevel@tonic-gate  * copyright notice and this permission notice appear in all copies.
80Sstevel@tonic-gate  *
9*11038SRao.Shoaib@Sun.COM  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
10*11038SRao.Shoaib@Sun.COM  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*11038SRao.Shoaib@Sun.COM  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
12*11038SRao.Shoaib@Sun.COM  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*11038SRao.Shoaib@Sun.COM  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*11038SRao.Shoaib@Sun.COM  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15*11038SRao.Shoaib@Sun.COM  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
160Sstevel@tonic-gate  */
170Sstevel@tonic-gate 
180Sstevel@tonic-gate #ifndef lint
19*11038SRao.Shoaib@Sun.COM static const char rcsid[] = "$Id: ns_print.c,v 1.12 2009/03/03 05:29:58 each Exp $";
200Sstevel@tonic-gate #endif
210Sstevel@tonic-gate 
220Sstevel@tonic-gate /* Import. */
230Sstevel@tonic-gate 
240Sstevel@tonic-gate #include "port_before.h"
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <sys/types.h>
270Sstevel@tonic-gate #include <sys/socket.h>
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <netinet/in.h>
300Sstevel@tonic-gate #include <arpa/nameser.h>
310Sstevel@tonic-gate #include <arpa/inet.h>
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #include <isc/assertions.h>
340Sstevel@tonic-gate #include <isc/dst.h>
350Sstevel@tonic-gate #include <errno.h>
360Sstevel@tonic-gate #include <resolv.h>
370Sstevel@tonic-gate #include <string.h>
380Sstevel@tonic-gate #include <ctype.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #include "port_after.h"
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #ifdef SPRINTF_CHAR
430Sstevel@tonic-gate # define SPRINTF(x) strlen(sprintf/**/x)
440Sstevel@tonic-gate #else
450Sstevel@tonic-gate # define SPRINTF(x) ((size_t)sprintf x)
460Sstevel@tonic-gate #endif
470Sstevel@tonic-gate 
480Sstevel@tonic-gate /* Forward. */
490Sstevel@tonic-gate 
500Sstevel@tonic-gate static size_t	prune_origin(const char *name, const char *origin);
510Sstevel@tonic-gate static int	charstr(const u_char *rdata, const u_char *edata,
520Sstevel@tonic-gate 			char **buf, size_t *buflen);
530Sstevel@tonic-gate static int	addname(const u_char *msg, size_t msglen,
540Sstevel@tonic-gate 			const u_char **p, const char *origin,
550Sstevel@tonic-gate 			char **buf, size_t *buflen);
560Sstevel@tonic-gate static void	addlen(size_t len, char **buf, size_t *buflen);
570Sstevel@tonic-gate static int	addstr(const char *src, size_t len,
580Sstevel@tonic-gate 		       char **buf, size_t *buflen);
590Sstevel@tonic-gate static int	addtab(size_t len, size_t target, int spaced,
600Sstevel@tonic-gate 		       char **buf, size_t *buflen);
610Sstevel@tonic-gate 
620Sstevel@tonic-gate /* Macros. */
630Sstevel@tonic-gate 
640Sstevel@tonic-gate #define	T(x) \
650Sstevel@tonic-gate 	do { \
660Sstevel@tonic-gate 		if ((x) < 0) \
670Sstevel@tonic-gate 			return (-1); \
680Sstevel@tonic-gate 	} while (0)
690Sstevel@tonic-gate 
70*11038SRao.Shoaib@Sun.COM static const char base32hex[] =
71*11038SRao.Shoaib@Sun.COM         "0123456789ABCDEFGHIJKLMNOPQRSTUV=0123456789abcdefghijklmnopqrstuv";
72*11038SRao.Shoaib@Sun.COM 
730Sstevel@tonic-gate /* Public. */
740Sstevel@tonic-gate 
75*11038SRao.Shoaib@Sun.COM /*%
760Sstevel@tonic-gate  *	Convert an RR to presentation format.
77*11038SRao.Shoaib@Sun.COM  *
780Sstevel@tonic-gate  * return:
79*11038SRao.Shoaib@Sun.COM  *\li	Number of characters written to buf, or -1 (check errno).
800Sstevel@tonic-gate  */
810Sstevel@tonic-gate int
ns_sprintrr(const ns_msg * handle,const ns_rr * rr,const char * name_ctx,const char * origin,char * buf,size_t buflen)820Sstevel@tonic-gate ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
830Sstevel@tonic-gate 	    const char *name_ctx, const char *origin,
840Sstevel@tonic-gate 	    char *buf, size_t buflen)
850Sstevel@tonic-gate {
860Sstevel@tonic-gate 	int n;
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 	n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
890Sstevel@tonic-gate 			 ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
900Sstevel@tonic-gate 			 ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
910Sstevel@tonic-gate 			 name_ctx, origin, buf, buflen);
920Sstevel@tonic-gate 	return (n);
930Sstevel@tonic-gate }
940Sstevel@tonic-gate 
95*11038SRao.Shoaib@Sun.COM /*%
960Sstevel@tonic-gate  *	Convert the fields of an RR into presentation format.
97*11038SRao.Shoaib@Sun.COM  *
980Sstevel@tonic-gate  * return:
99*11038SRao.Shoaib@Sun.COM  *\li	Number of characters written to buf, or -1 (check errno).
1000Sstevel@tonic-gate  */
1010Sstevel@tonic-gate 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)1020Sstevel@tonic-gate ns_sprintrrf(const u_char *msg, size_t msglen,
1030Sstevel@tonic-gate 	    const char *name, ns_class class, ns_type type,
1040Sstevel@tonic-gate 	    u_long ttl, const u_char *rdata, size_t rdlen,
1050Sstevel@tonic-gate 	    const char *name_ctx, const char *origin,
1060Sstevel@tonic-gate 	    char *buf, size_t buflen)
1070Sstevel@tonic-gate {
1080Sstevel@tonic-gate 	const char *obuf = buf;
1090Sstevel@tonic-gate 	const u_char *edata = rdata + rdlen;
1100Sstevel@tonic-gate 	int spaced = 0;
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate 	const char *comment;
1130Sstevel@tonic-gate 	char tmp[100];
1140Sstevel@tonic-gate 	int len, x;
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate 	/*
1170Sstevel@tonic-gate 	 * Owner.
1180Sstevel@tonic-gate 	 */
1190Sstevel@tonic-gate 	if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) {
1200Sstevel@tonic-gate 		T(addstr("\t\t\t", 3, &buf, &buflen));
1210Sstevel@tonic-gate 	} else {
1220Sstevel@tonic-gate 		len = prune_origin(name, origin);
1230Sstevel@tonic-gate 		if (*name == '\0') {
1240Sstevel@tonic-gate 			goto root;
1250Sstevel@tonic-gate 		} else if (len == 0) {
1260Sstevel@tonic-gate 			T(addstr("@\t\t\t", 4, &buf, &buflen));
1270Sstevel@tonic-gate 		} else {
1280Sstevel@tonic-gate 			T(addstr(name, len, &buf, &buflen));
1290Sstevel@tonic-gate 			/* Origin not used or not root, and no trailing dot? */
1300Sstevel@tonic-gate 			if (((origin == NULL || origin[0] == '\0') ||
1310Sstevel@tonic-gate 			    (origin[0] != '.' && origin[1] != '\0' &&
1320Sstevel@tonic-gate 			    name[len] == '\0')) && name[len - 1] != '.') {
1330Sstevel@tonic-gate  root:
1340Sstevel@tonic-gate 				T(addstr(".", 1, &buf, &buflen));
1350Sstevel@tonic-gate 				len++;
1360Sstevel@tonic-gate 			}
1370Sstevel@tonic-gate 			T(spaced = addtab(len, 24, spaced, &buf, &buflen));
1380Sstevel@tonic-gate 		}
1390Sstevel@tonic-gate 	}
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 	/*
1420Sstevel@tonic-gate 	 * TTL, Class, Type.
1430Sstevel@tonic-gate 	 */
1440Sstevel@tonic-gate 	T(x = ns_format_ttl(ttl, buf, buflen));
1450Sstevel@tonic-gate 	addlen(x, &buf, &buflen);
1460Sstevel@tonic-gate 	len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
1470Sstevel@tonic-gate 	T(addstr(tmp, len, &buf, &buflen));
1480Sstevel@tonic-gate 	T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate 	/*
1510Sstevel@tonic-gate 	 * RData.
1520Sstevel@tonic-gate 	 */
1530Sstevel@tonic-gate 	switch (type) {
1540Sstevel@tonic-gate 	case ns_t_a:
155*11038SRao.Shoaib@Sun.COM 		if (rdlen != (size_t)NS_INADDRSZ)
1560Sstevel@tonic-gate 			goto formerr;
1570Sstevel@tonic-gate 		(void) inet_ntop(AF_INET, rdata, buf, buflen);
1580Sstevel@tonic-gate 		addlen(strlen(buf), &buf, &buflen);
1590Sstevel@tonic-gate 		break;
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 	case ns_t_cname:
1620Sstevel@tonic-gate 	case ns_t_mb:
1630Sstevel@tonic-gate 	case ns_t_mg:
1640Sstevel@tonic-gate 	case ns_t_mr:
1650Sstevel@tonic-gate 	case ns_t_ns:
1660Sstevel@tonic-gate 	case ns_t_ptr:
1670Sstevel@tonic-gate 	case ns_t_dname:
1680Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1690Sstevel@tonic-gate 		break;
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 	case ns_t_hinfo:
1720Sstevel@tonic-gate 	case ns_t_isdn:
1730Sstevel@tonic-gate 		/* First word. */
1740Sstevel@tonic-gate 		T(len = charstr(rdata, edata, &buf, &buflen));
1750Sstevel@tonic-gate 		if (len == 0)
1760Sstevel@tonic-gate 			goto formerr;
1770Sstevel@tonic-gate 		rdata += len;
1780Sstevel@tonic-gate 		T(addstr(" ", 1, &buf, &buflen));
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate 		/* Second word, optional in ISDN records. */
1820Sstevel@tonic-gate 		if (type == ns_t_isdn && rdata == edata)
1830Sstevel@tonic-gate 			break;
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 		T(len = charstr(rdata, edata, &buf, &buflen));
1860Sstevel@tonic-gate 		if (len == 0)
1870Sstevel@tonic-gate 			goto formerr;
1880Sstevel@tonic-gate 		rdata += len;
1890Sstevel@tonic-gate 		break;
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	case ns_t_soa: {
1920Sstevel@tonic-gate 		u_long t;
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate 		/* Server name. */
1950Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1960Sstevel@tonic-gate 		T(addstr(" ", 1, &buf, &buflen));
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 		/* Administrator name. */
1990Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
2000Sstevel@tonic-gate 		T(addstr(" (\n", 3, &buf, &buflen));
2010Sstevel@tonic-gate 		spaced = 0;
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 		if ((edata - rdata) != 5*NS_INT32SZ)
2040Sstevel@tonic-gate 			goto formerr;
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 		/* Serial number. */
2070Sstevel@tonic-gate 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
2080Sstevel@tonic-gate 		T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
2090Sstevel@tonic-gate 		len = SPRINTF((tmp, "%lu", t));
2100Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
2110Sstevel@tonic-gate 		T(spaced = addtab(len, 16, spaced, &buf, &buflen));
2120Sstevel@tonic-gate 		T(addstr("; serial\n", 9, &buf, &buflen));
2130Sstevel@tonic-gate 		spaced = 0;
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 		/* Refresh interval. */
2160Sstevel@tonic-gate 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
2170Sstevel@tonic-gate 		T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
2180Sstevel@tonic-gate 		T(len = ns_format_ttl(t, buf, buflen));
2190Sstevel@tonic-gate 		addlen(len, &buf, &buflen);
2200Sstevel@tonic-gate 		T(spaced = addtab(len, 16, spaced, &buf, &buflen));
2210Sstevel@tonic-gate 		T(addstr("; refresh\n", 10, &buf, &buflen));
2220Sstevel@tonic-gate 		spaced = 0;
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate 		/* Retry interval. */
2250Sstevel@tonic-gate 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
2260Sstevel@tonic-gate 		T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
2270Sstevel@tonic-gate 		T(len = ns_format_ttl(t, buf, buflen));
2280Sstevel@tonic-gate 		addlen(len, &buf, &buflen);
2290Sstevel@tonic-gate 		T(spaced = addtab(len, 16, spaced, &buf, &buflen));
2300Sstevel@tonic-gate 		T(addstr("; retry\n", 8, &buf, &buflen));
2310Sstevel@tonic-gate 		spaced = 0;
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate 		/* Expiry. */
2340Sstevel@tonic-gate 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
2350Sstevel@tonic-gate 		T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
2360Sstevel@tonic-gate 		T(len = ns_format_ttl(t, buf, buflen));
2370Sstevel@tonic-gate 		addlen(len, &buf, &buflen);
2380Sstevel@tonic-gate 		T(spaced = addtab(len, 16, spaced, &buf, &buflen));
2390Sstevel@tonic-gate 		T(addstr("; expiry\n", 9, &buf, &buflen));
2400Sstevel@tonic-gate 		spaced = 0;
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate 		/* Minimum TTL. */
2430Sstevel@tonic-gate 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
2440Sstevel@tonic-gate 		T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
2450Sstevel@tonic-gate 		T(len = ns_format_ttl(t, buf, buflen));
2460Sstevel@tonic-gate 		addlen(len, &buf, &buflen);
2470Sstevel@tonic-gate 		T(addstr(" )", 2, &buf, &buflen));
2480Sstevel@tonic-gate 		T(spaced = addtab(len, 16, spaced, &buf, &buflen));
2490Sstevel@tonic-gate 		T(addstr("; minimum\n", 10, &buf, &buflen));
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 		break;
2520Sstevel@tonic-gate 	    }
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	case ns_t_mx:
2550Sstevel@tonic-gate 	case ns_t_afsdb:
256*11038SRao.Shoaib@Sun.COM 	case ns_t_rt:
257*11038SRao.Shoaib@Sun.COM 	case ns_t_kx: {
2580Sstevel@tonic-gate 		u_int t;
2590Sstevel@tonic-gate 
260*11038SRao.Shoaib@Sun.COM 		if (rdlen < (size_t)NS_INT16SZ)
2610Sstevel@tonic-gate 			goto formerr;
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate 		/* Priority. */
2640Sstevel@tonic-gate 		t = ns_get16(rdata);
2650Sstevel@tonic-gate 		rdata += NS_INT16SZ;
2660Sstevel@tonic-gate 		len = SPRINTF((tmp, "%u ", t));
2670Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
2680Sstevel@tonic-gate 
2690Sstevel@tonic-gate 		/* Target. */
2700Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate 		break;
2730Sstevel@tonic-gate 	    }
2740Sstevel@tonic-gate 
2750Sstevel@tonic-gate 	case ns_t_px: {
2760Sstevel@tonic-gate 		u_int t;
2770Sstevel@tonic-gate 
278*11038SRao.Shoaib@Sun.COM 		if (rdlen < (size_t)NS_INT16SZ)
2790Sstevel@tonic-gate 			goto formerr;
2800Sstevel@tonic-gate 
2810Sstevel@tonic-gate 		/* Priority. */
2820Sstevel@tonic-gate 		t = ns_get16(rdata);
2830Sstevel@tonic-gate 		rdata += NS_INT16SZ;
2840Sstevel@tonic-gate 		len = SPRINTF((tmp, "%u ", t));
2850Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate 		/* Name1. */
2880Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
2890Sstevel@tonic-gate 		T(addstr(" ", 1, &buf, &buflen));
2900Sstevel@tonic-gate 
2910Sstevel@tonic-gate 		/* Name2. */
2920Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate 		break;
2950Sstevel@tonic-gate 	    }
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate 	case ns_t_x25:
2980Sstevel@tonic-gate 		T(len = charstr(rdata, edata, &buf, &buflen));
2990Sstevel@tonic-gate 		if (len == 0)
3000Sstevel@tonic-gate 			goto formerr;
3010Sstevel@tonic-gate 		rdata += len;
3020Sstevel@tonic-gate 		break;
3030Sstevel@tonic-gate 
3040Sstevel@tonic-gate 	case ns_t_txt:
305*11038SRao.Shoaib@Sun.COM 	case ns_t_spf:
3060Sstevel@tonic-gate 		while (rdata < edata) {
3070Sstevel@tonic-gate 			T(len = charstr(rdata, edata, &buf, &buflen));
3080Sstevel@tonic-gate 			if (len == 0)
3090Sstevel@tonic-gate 				goto formerr;
3100Sstevel@tonic-gate 			rdata += len;
3110Sstevel@tonic-gate 			if (rdata < edata)
3120Sstevel@tonic-gate 				T(addstr(" ", 1, &buf, &buflen));
3130Sstevel@tonic-gate 		}
3140Sstevel@tonic-gate 		break;
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 	case ns_t_nsap: {
3170Sstevel@tonic-gate 		char t[2+255*3];
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 		(void) inet_nsap_ntoa(rdlen, rdata, t);
3200Sstevel@tonic-gate 		T(addstr(t, strlen(t), &buf, &buflen));
3210Sstevel@tonic-gate 		break;
3220Sstevel@tonic-gate 	    }
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 	case ns_t_aaaa:
325*11038SRao.Shoaib@Sun.COM 		if (rdlen != (size_t)NS_IN6ADDRSZ)
3260Sstevel@tonic-gate 			goto formerr;
3270Sstevel@tonic-gate 		(void) inet_ntop(AF_INET6, rdata, buf, buflen);
3280Sstevel@tonic-gate 		addlen(strlen(buf), &buf, &buflen);
3290Sstevel@tonic-gate 		break;
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate 	case ns_t_loc: {
3320Sstevel@tonic-gate 		char t[255];
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate 		/* XXX protocol format checking? */
3350Sstevel@tonic-gate 		(void) loc_ntoa(rdata, t);
3360Sstevel@tonic-gate 		T(addstr(t, strlen(t), &buf, &buflen));
3370Sstevel@tonic-gate 		break;
3380Sstevel@tonic-gate 	    }
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 	case ns_t_naptr: {
3410Sstevel@tonic-gate 		u_int order, preference;
3420Sstevel@tonic-gate 		char t[50];
3430Sstevel@tonic-gate 
344*11038SRao.Shoaib@Sun.COM 		if (rdlen < 2U*NS_INT16SZ)
3450Sstevel@tonic-gate 			goto formerr;
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate 		/* Order, Precedence. */
3480Sstevel@tonic-gate 		order = ns_get16(rdata);	rdata += NS_INT16SZ;
3490Sstevel@tonic-gate 		preference = ns_get16(rdata);	rdata += NS_INT16SZ;
3500Sstevel@tonic-gate 		len = SPRINTF((t, "%u %u ", order, preference));
3510Sstevel@tonic-gate 		T(addstr(t, len, &buf, &buflen));
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 		/* Flags. */
3540Sstevel@tonic-gate 		T(len = charstr(rdata, edata, &buf, &buflen));
3550Sstevel@tonic-gate 		if (len == 0)
3560Sstevel@tonic-gate 			goto formerr;
3570Sstevel@tonic-gate 		rdata += len;
3580Sstevel@tonic-gate 		T(addstr(" ", 1, &buf, &buflen));
3590Sstevel@tonic-gate 
3600Sstevel@tonic-gate 		/* Service. */
3610Sstevel@tonic-gate 		T(len = charstr(rdata, edata, &buf, &buflen));
3620Sstevel@tonic-gate 		if (len == 0)
3630Sstevel@tonic-gate 			goto formerr;
3640Sstevel@tonic-gate 		rdata += len;
3650Sstevel@tonic-gate 		T(addstr(" ", 1, &buf, &buflen));
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate 		/* Regexp. */
3680Sstevel@tonic-gate 		T(len = charstr(rdata, edata, &buf, &buflen));
3690Sstevel@tonic-gate 		if (len < 0)
3700Sstevel@tonic-gate 			return (-1);
3710Sstevel@tonic-gate 		if (len == 0)
3720Sstevel@tonic-gate 			goto formerr;
3730Sstevel@tonic-gate 		rdata += len;
3740Sstevel@tonic-gate 		T(addstr(" ", 1, &buf, &buflen));
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate 		/* Server. */
3770Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
3780Sstevel@tonic-gate 		break;
3790Sstevel@tonic-gate 	    }
3800Sstevel@tonic-gate 
3810Sstevel@tonic-gate 	case ns_t_srv: {
3820Sstevel@tonic-gate 		u_int priority, weight, port;
3830Sstevel@tonic-gate 		char t[50];
3840Sstevel@tonic-gate 
385*11038SRao.Shoaib@Sun.COM 		if (rdlen < 3U*NS_INT16SZ)
3860Sstevel@tonic-gate 			goto formerr;
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate 		/* Priority, Weight, Port. */
3890Sstevel@tonic-gate 		priority = ns_get16(rdata);  rdata += NS_INT16SZ;
3900Sstevel@tonic-gate 		weight   = ns_get16(rdata);  rdata += NS_INT16SZ;
3910Sstevel@tonic-gate 		port     = ns_get16(rdata);  rdata += NS_INT16SZ;
3920Sstevel@tonic-gate 		len = SPRINTF((t, "%u %u %u ", priority, weight, port));
3930Sstevel@tonic-gate 		T(addstr(t, len, &buf, &buflen));
3940Sstevel@tonic-gate 
3950Sstevel@tonic-gate 		/* Server. */
3960Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
3970Sstevel@tonic-gate 		break;
3980Sstevel@tonic-gate 	    }
3990Sstevel@tonic-gate 
4000Sstevel@tonic-gate 	case ns_t_minfo:
4010Sstevel@tonic-gate 	case ns_t_rp:
4020Sstevel@tonic-gate 		/* Name1. */
4030Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
4040Sstevel@tonic-gate 		T(addstr(" ", 1, &buf, &buflen));
4050Sstevel@tonic-gate 
4060Sstevel@tonic-gate 		/* Name2. */
4070Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate 		break;
4100Sstevel@tonic-gate 
4110Sstevel@tonic-gate 	case ns_t_wks: {
4120Sstevel@tonic-gate 		int n, lcnt;
4130Sstevel@tonic-gate 
414*11038SRao.Shoaib@Sun.COM 		if (rdlen < 1U + NS_INT32SZ)
4150Sstevel@tonic-gate 			goto formerr;
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate 		/* Address. */
4180Sstevel@tonic-gate 		(void) inet_ntop(AF_INET, rdata, buf, buflen);
4190Sstevel@tonic-gate 		addlen(strlen(buf), &buf, &buflen);
4200Sstevel@tonic-gate 		rdata += NS_INADDRSZ;
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 		/* Protocol. */
4230Sstevel@tonic-gate 		len = SPRINTF((tmp, " %u ( ", *rdata));
4240Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
4250Sstevel@tonic-gate 		rdata += NS_INT8SZ;
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate 		/* Bit map. */
4280Sstevel@tonic-gate 		n = 0;
4290Sstevel@tonic-gate 		lcnt = 0;
4300Sstevel@tonic-gate 		while (rdata < edata) {
4310Sstevel@tonic-gate 			u_int c = *rdata++;
4320Sstevel@tonic-gate 			do {
4330Sstevel@tonic-gate 				if (c & 0200) {
4340Sstevel@tonic-gate 					if (lcnt == 0) {
4350Sstevel@tonic-gate 						T(addstr("\n\t\t\t\t", 5,
4360Sstevel@tonic-gate 							 &buf, &buflen));
4370Sstevel@tonic-gate 						lcnt = 10;
4380Sstevel@tonic-gate 						spaced = 0;
4390Sstevel@tonic-gate 					}
4400Sstevel@tonic-gate 					len = SPRINTF((tmp, "%d ", n));
4410Sstevel@tonic-gate 					T(addstr(tmp, len, &buf, &buflen));
4420Sstevel@tonic-gate 					lcnt--;
4430Sstevel@tonic-gate 				}
4440Sstevel@tonic-gate 				c <<= 1;
4450Sstevel@tonic-gate 			} while (++n & 07);
4460Sstevel@tonic-gate 		}
4470Sstevel@tonic-gate 		T(addstr(")", 1, &buf, &buflen));
4480Sstevel@tonic-gate 
4490Sstevel@tonic-gate 		break;
4500Sstevel@tonic-gate 	    }
4510Sstevel@tonic-gate 
452*11038SRao.Shoaib@Sun.COM 	case ns_t_key:
453*11038SRao.Shoaib@Sun.COM 	case ns_t_dnskey: {
4540Sstevel@tonic-gate 		char base64_key[NS_MD5RSA_MAX_BASE64];
4550Sstevel@tonic-gate 		u_int keyflags, protocol, algorithm, key_id;
4560Sstevel@tonic-gate 		const char *leader;
4570Sstevel@tonic-gate 		int n;
4580Sstevel@tonic-gate 
459*11038SRao.Shoaib@Sun.COM 		if (rdlen < 0U + NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
4600Sstevel@tonic-gate 			goto formerr;
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate 		/* Key flags, Protocol, Algorithm. */
4630Sstevel@tonic-gate 		key_id = dst_s_dns_key_id(rdata, edata-rdata);
4640Sstevel@tonic-gate 		keyflags = ns_get16(rdata);  rdata += NS_INT16SZ;
4650Sstevel@tonic-gate 		protocol = *rdata++;
4660Sstevel@tonic-gate 		algorithm = *rdata++;
4670Sstevel@tonic-gate 		len = SPRINTF((tmp, "0x%04x %u %u",
4680Sstevel@tonic-gate 			       keyflags, protocol, algorithm));
4690Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate 		/* Public key data. */
4720Sstevel@tonic-gate 		len = b64_ntop(rdata, edata - rdata,
4730Sstevel@tonic-gate 			       base64_key, sizeof base64_key);
4740Sstevel@tonic-gate 		if (len < 0)
4750Sstevel@tonic-gate 			goto formerr;
4760Sstevel@tonic-gate 		if (len > 15) {
4770Sstevel@tonic-gate 			T(addstr(" (", 2, &buf, &buflen));
4780Sstevel@tonic-gate 			leader = "\n\t\t";
4790Sstevel@tonic-gate 			spaced = 0;
4800Sstevel@tonic-gate 		} else
4810Sstevel@tonic-gate 			leader = " ";
4820Sstevel@tonic-gate 		for (n = 0; n < len; n += 48) {
4830Sstevel@tonic-gate 			T(addstr(leader, strlen(leader), &buf, &buflen));
4840Sstevel@tonic-gate 			T(addstr(base64_key + n, MIN(len - n, 48),
4850Sstevel@tonic-gate 				 &buf, &buflen));
4860Sstevel@tonic-gate 		}
4870Sstevel@tonic-gate 		if (len > 15)
4880Sstevel@tonic-gate 			T(addstr(" )", 2, &buf, &buflen));
4890Sstevel@tonic-gate 		n = SPRINTF((tmp, " ; key_tag= %u", key_id));
4900Sstevel@tonic-gate 		T(addstr(tmp, n, &buf, &buflen));
4910Sstevel@tonic-gate 
4920Sstevel@tonic-gate 		break;
4930Sstevel@tonic-gate 	    }
4940Sstevel@tonic-gate 
495*11038SRao.Shoaib@Sun.COM 	case ns_t_sig:
496*11038SRao.Shoaib@Sun.COM 	case ns_t_rrsig: {
4970Sstevel@tonic-gate 		char base64_key[NS_MD5RSA_MAX_BASE64];
4980Sstevel@tonic-gate 		u_int type, algorithm, labels, footprint;
4990Sstevel@tonic-gate 		const char *leader;
5000Sstevel@tonic-gate 		u_long t;
5010Sstevel@tonic-gate 		int n;
5020Sstevel@tonic-gate 
503*11038SRao.Shoaib@Sun.COM 		if (rdlen < 22U)
5040Sstevel@tonic-gate 			goto formerr;
5050Sstevel@tonic-gate 
5060Sstevel@tonic-gate 		/* Type covered, Algorithm, Label count, Original TTL. */
507*11038SRao.Shoaib@Sun.COM 		type = ns_get16(rdata);  rdata += NS_INT16SZ;
5080Sstevel@tonic-gate 		algorithm = *rdata++;
5090Sstevel@tonic-gate 		labels = *rdata++;
5100Sstevel@tonic-gate 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
5110Sstevel@tonic-gate 		len = SPRINTF((tmp, "%s %d %d %lu ",
5120Sstevel@tonic-gate 			       p_type(type), algorithm, labels, t));
5130Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
5140Sstevel@tonic-gate 		if (labels > (u_int)dn_count_labels(name))
5150Sstevel@tonic-gate 			goto formerr;
5160Sstevel@tonic-gate 
5170Sstevel@tonic-gate 		/* Signature expiry. */
5180Sstevel@tonic-gate 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
5190Sstevel@tonic-gate 		len = SPRINTF((tmp, "%s ", p_secstodate(t)));
5200Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
5210Sstevel@tonic-gate 
5220Sstevel@tonic-gate 		/* Time signed. */
5230Sstevel@tonic-gate 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
5240Sstevel@tonic-gate 		len = SPRINTF((tmp, "%s ", p_secstodate(t)));
5250Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
5260Sstevel@tonic-gate 
5270Sstevel@tonic-gate 		/* Signature Footprint. */
5280Sstevel@tonic-gate 		footprint = ns_get16(rdata);  rdata += NS_INT16SZ;
5290Sstevel@tonic-gate 		len = SPRINTF((tmp, "%u ", footprint));
5300Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
5310Sstevel@tonic-gate 
5320Sstevel@tonic-gate 		/* Signer's name. */
5330Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
5340Sstevel@tonic-gate 
5350Sstevel@tonic-gate 		/* Signature. */
5360Sstevel@tonic-gate 		len = b64_ntop(rdata, edata - rdata,
5370Sstevel@tonic-gate 			       base64_key, sizeof base64_key);
5380Sstevel@tonic-gate 		if (len > 15) {
5390Sstevel@tonic-gate 			T(addstr(" (", 2, &buf, &buflen));
5400Sstevel@tonic-gate 			leader = "\n\t\t";
5410Sstevel@tonic-gate 			spaced = 0;
5420Sstevel@tonic-gate 		} else
5430Sstevel@tonic-gate 			leader = " ";
5440Sstevel@tonic-gate 		if (len < 0)
5450Sstevel@tonic-gate 			goto formerr;
5460Sstevel@tonic-gate 		for (n = 0; n < len; n += 48) {
5470Sstevel@tonic-gate 			T(addstr(leader, strlen(leader), &buf, &buflen));
5480Sstevel@tonic-gate 			T(addstr(base64_key + n, MIN(len - n, 48),
5490Sstevel@tonic-gate 				 &buf, &buflen));
5500Sstevel@tonic-gate 		}
5510Sstevel@tonic-gate 		if (len > 15)
5520Sstevel@tonic-gate 			T(addstr(" )", 2, &buf, &buflen));
5530Sstevel@tonic-gate 		break;
5540Sstevel@tonic-gate 	    }
5550Sstevel@tonic-gate 
5560Sstevel@tonic-gate 	case ns_t_nxt: {
5570Sstevel@tonic-gate 		int n, c;
5580Sstevel@tonic-gate 
5590Sstevel@tonic-gate 		/* Next domain name. */
5600Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
5610Sstevel@tonic-gate 
5620Sstevel@tonic-gate 		/* Type bit map. */
5630Sstevel@tonic-gate 		n = edata - rdata;
5640Sstevel@tonic-gate 		for (c = 0; c < n*8; c++)
5650Sstevel@tonic-gate 			if (NS_NXT_BIT_ISSET(c, rdata)) {
5660Sstevel@tonic-gate 				len = SPRINTF((tmp, " %s", p_type(c)));
5670Sstevel@tonic-gate 				T(addstr(tmp, len, &buf, &buflen));
5680Sstevel@tonic-gate 			}
5690Sstevel@tonic-gate 		break;
5700Sstevel@tonic-gate 	    }
5710Sstevel@tonic-gate 
5720Sstevel@tonic-gate 	case ns_t_cert: {
5730Sstevel@tonic-gate 		u_int c_type, key_tag, alg;
5740Sstevel@tonic-gate 		int n;
5750Sstevel@tonic-gate 		unsigned int siz;
5760Sstevel@tonic-gate 		char base64_cert[8192], tmp[40];
5770Sstevel@tonic-gate 		const char *leader;
5780Sstevel@tonic-gate 
5790Sstevel@tonic-gate 		c_type  = ns_get16(rdata); rdata += NS_INT16SZ;
5800Sstevel@tonic-gate 		key_tag = ns_get16(rdata); rdata += NS_INT16SZ;
5810Sstevel@tonic-gate 		alg = (u_int) *rdata++;
5820Sstevel@tonic-gate 
5830Sstevel@tonic-gate 		len = SPRINTF((tmp, "%d %d %d ", c_type, key_tag, alg));
5840Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
5850Sstevel@tonic-gate 		siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
5860Sstevel@tonic-gate 		if (siz > sizeof(base64_cert) * 3/4) {
5870Sstevel@tonic-gate 			const char *str = "record too long to print";
5880Sstevel@tonic-gate 			T(addstr(str, strlen(str), &buf, &buflen));
5890Sstevel@tonic-gate 		}
5900Sstevel@tonic-gate 		else {
5910Sstevel@tonic-gate 			len = b64_ntop(rdata, edata-rdata, base64_cert, siz);
5920Sstevel@tonic-gate 
5930Sstevel@tonic-gate 			if (len < 0)
5940Sstevel@tonic-gate 				goto formerr;
5950Sstevel@tonic-gate 			else if (len > 15) {
5960Sstevel@tonic-gate 				T(addstr(" (", 2, &buf, &buflen));
5970Sstevel@tonic-gate 				leader = "\n\t\t";
5980Sstevel@tonic-gate 				spaced = 0;
5990Sstevel@tonic-gate 			}
6000Sstevel@tonic-gate 			else
6010Sstevel@tonic-gate 				leader = " ";
6020Sstevel@tonic-gate 
6030Sstevel@tonic-gate 			for (n = 0; n < len; n += 48) {
6040Sstevel@tonic-gate 				T(addstr(leader, strlen(leader),
6050Sstevel@tonic-gate 					 &buf, &buflen));
6060Sstevel@tonic-gate 				T(addstr(base64_cert + n, MIN(len - n, 48),
6070Sstevel@tonic-gate 					 &buf, &buflen));
6080Sstevel@tonic-gate 			}
6090Sstevel@tonic-gate 			if (len > 15)
6100Sstevel@tonic-gate 				T(addstr(" )", 2, &buf, &buflen));
6110Sstevel@tonic-gate 		}
6120Sstevel@tonic-gate 		break;
6130Sstevel@tonic-gate 	    }
6140Sstevel@tonic-gate 
6150Sstevel@tonic-gate 	case ns_t_tkey: {
6160Sstevel@tonic-gate 		/* KJD - need to complete this */
6170Sstevel@tonic-gate 		u_long t;
6180Sstevel@tonic-gate 		int mode, err, keysize;
6190Sstevel@tonic-gate 
6200Sstevel@tonic-gate 		/* Algorithm name. */
6210Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
6220Sstevel@tonic-gate 		T(addstr(" ", 1, &buf, &buflen));
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate 		/* Inception. */
6250Sstevel@tonic-gate 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
6260Sstevel@tonic-gate 		len = SPRINTF((tmp, "%s ", p_secstodate(t)));
6270Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
6280Sstevel@tonic-gate 
6290Sstevel@tonic-gate 		/* Experation. */
6300Sstevel@tonic-gate 		t = ns_get32(rdata);  rdata += NS_INT32SZ;
6310Sstevel@tonic-gate 		len = SPRINTF((tmp, "%s ", p_secstodate(t)));
6320Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
6330Sstevel@tonic-gate 
6340Sstevel@tonic-gate 		/* Mode , Error, Key Size. */
6350Sstevel@tonic-gate 		/* Priority, Weight, Port. */
6360Sstevel@tonic-gate 		mode = ns_get16(rdata);  rdata += NS_INT16SZ;
6370Sstevel@tonic-gate 		err  = ns_get16(rdata);  rdata += NS_INT16SZ;
6380Sstevel@tonic-gate 		keysize  = ns_get16(rdata);  rdata += NS_INT16SZ;
6390Sstevel@tonic-gate 		len = SPRINTF((tmp, "%u %u %u ", mode, err, keysize));
6400Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
6410Sstevel@tonic-gate 
642*11038SRao.Shoaib@Sun.COM 		/* XXX need to dump key, print otherdata length & other data */
6430Sstevel@tonic-gate 		break;
6440Sstevel@tonic-gate 	    }
6450Sstevel@tonic-gate 
6460Sstevel@tonic-gate 	case ns_t_tsig: {
6470Sstevel@tonic-gate 		/* BEW - need to complete this */
6480Sstevel@tonic-gate 		int n;
6490Sstevel@tonic-gate 
6500Sstevel@tonic-gate 		T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen));
6510Sstevel@tonic-gate 		T(addstr(" ", 1, &buf, &buflen));
652*11038SRao.Shoaib@Sun.COM 		rdata += 8; /*%< time */
6530Sstevel@tonic-gate 		n = ns_get16(rdata); rdata += INT16SZ;
654*11038SRao.Shoaib@Sun.COM 		rdata += n; /*%< sig */
655*11038SRao.Shoaib@Sun.COM 		n = ns_get16(rdata); rdata += INT16SZ; /*%< original id */
6560Sstevel@tonic-gate 		sprintf(buf, "%d", ns_get16(rdata));
6570Sstevel@tonic-gate 		rdata += INT16SZ;
6580Sstevel@tonic-gate 		addlen(strlen(buf), &buf, &buflen);
6590Sstevel@tonic-gate 		break;
6600Sstevel@tonic-gate 	    }
6610Sstevel@tonic-gate 
6620Sstevel@tonic-gate 	case ns_t_a6: {
6630Sstevel@tonic-gate 		struct in6_addr a;
6640Sstevel@tonic-gate 		int pbyte, pbit;
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate 		/* prefix length */
667*11038SRao.Shoaib@Sun.COM 		if (rdlen == 0U) goto formerr;
6680Sstevel@tonic-gate 		len = SPRINTF((tmp, "%d ", *rdata));
6690Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
6700Sstevel@tonic-gate 		pbit = *rdata;
6710Sstevel@tonic-gate 		if (pbit > 128) goto formerr;
6720Sstevel@tonic-gate 		pbyte = (pbit & ~7) / 8;
6730Sstevel@tonic-gate 		rdata++;
6740Sstevel@tonic-gate 
6750Sstevel@tonic-gate 		/* address suffix: provided only when prefix len != 128 */
6760Sstevel@tonic-gate 		if (pbit < 128) {
6770Sstevel@tonic-gate 			if (rdata + pbyte >= edata) goto formerr;
6780Sstevel@tonic-gate 			memset(&a, 0, sizeof(a));
6790Sstevel@tonic-gate 			memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte);
6800Sstevel@tonic-gate 			(void) inet_ntop(AF_INET6, &a, buf, buflen);
6810Sstevel@tonic-gate 			addlen(strlen(buf), &buf, &buflen);
6820Sstevel@tonic-gate 			rdata += sizeof(a) - pbyte;
6830Sstevel@tonic-gate 		}
6840Sstevel@tonic-gate 
6850Sstevel@tonic-gate 		/* prefix name: provided only when prefix len > 0 */
6860Sstevel@tonic-gate 		if (pbit == 0)
6870Sstevel@tonic-gate 			break;
6880Sstevel@tonic-gate 		if (rdata >= edata) goto formerr;
6890Sstevel@tonic-gate 		T(addstr(" ", 1, &buf, &buflen));
6900Sstevel@tonic-gate 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
6910Sstevel@tonic-gate 
6920Sstevel@tonic-gate 		break;
693*11038SRao.Shoaib@Sun.COM 	    }
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate 	case ns_t_opt: {
6960Sstevel@tonic-gate 		len = SPRINTF((tmp, "%u bytes", class));
6970Sstevel@tonic-gate 		T(addstr(tmp, len, &buf, &buflen));
6980Sstevel@tonic-gate 		break;
699*11038SRao.Shoaib@Sun.COM 	    }
700*11038SRao.Shoaib@Sun.COM 
701*11038SRao.Shoaib@Sun.COM 	case ns_t_ds:
702*11038SRao.Shoaib@Sun.COM 	case ns_t_dlv:
703*11038SRao.Shoaib@Sun.COM 	case ns_t_sshfp: {
704*11038SRao.Shoaib@Sun.COM 		u_int t;
705*11038SRao.Shoaib@Sun.COM 
706*11038SRao.Shoaib@Sun.COM 		if (type == ns_t_ds || type == ns_t_dlv) {
707*11038SRao.Shoaib@Sun.COM 			if (rdlen < 4U) goto formerr;
708*11038SRao.Shoaib@Sun.COM 			t = ns_get16(rdata);
709*11038SRao.Shoaib@Sun.COM 			rdata += NS_INT16SZ;
710*11038SRao.Shoaib@Sun.COM 			len = SPRINTF((tmp, "%u ", t));
711*11038SRao.Shoaib@Sun.COM 			T(addstr(tmp, len, &buf, &buflen));
712*11038SRao.Shoaib@Sun.COM 		} else
713*11038SRao.Shoaib@Sun.COM 			if (rdlen < 2U) goto formerr;
714*11038SRao.Shoaib@Sun.COM 
715*11038SRao.Shoaib@Sun.COM 		len = SPRINTF((tmp, "%u ", *rdata));
716*11038SRao.Shoaib@Sun.COM 		T(addstr(tmp, len, &buf, &buflen));
717*11038SRao.Shoaib@Sun.COM 		rdata++;
718*11038SRao.Shoaib@Sun.COM 
719*11038SRao.Shoaib@Sun.COM 		len = SPRINTF((tmp, "%u ", *rdata));
720*11038SRao.Shoaib@Sun.COM 		T(addstr(tmp, len, &buf, &buflen));
721*11038SRao.Shoaib@Sun.COM 		rdata++;
722*11038SRao.Shoaib@Sun.COM 
723*11038SRao.Shoaib@Sun.COM 		while (rdata < edata) {
724*11038SRao.Shoaib@Sun.COM 			len = SPRINTF((tmp, "%02X", *rdata));
725*11038SRao.Shoaib@Sun.COM 			T(addstr(tmp, len, &buf, &buflen));
726*11038SRao.Shoaib@Sun.COM 			rdata++;
727*11038SRao.Shoaib@Sun.COM 		}
728*11038SRao.Shoaib@Sun.COM 		break;
729*11038SRao.Shoaib@Sun.COM 	    }
730*11038SRao.Shoaib@Sun.COM 
731*11038SRao.Shoaib@Sun.COM 	case ns_t_nsec3:
732*11038SRao.Shoaib@Sun.COM 	case ns_t_nsec3param: {
733*11038SRao.Shoaib@Sun.COM 		u_int t, w, l, j, k, c;
734*11038SRao.Shoaib@Sun.COM 
735*11038SRao.Shoaib@Sun.COM 		len = SPRINTF((tmp, "%u ", *rdata));
736*11038SRao.Shoaib@Sun.COM 		T(addstr(tmp, len, &buf, &buflen));
737*11038SRao.Shoaib@Sun.COM 		rdata++;
738*11038SRao.Shoaib@Sun.COM 
739*11038SRao.Shoaib@Sun.COM 		len = SPRINTF((tmp, "%u ", *rdata));
740*11038SRao.Shoaib@Sun.COM 		T(addstr(tmp, len, &buf, &buflen));
741*11038SRao.Shoaib@Sun.COM 		rdata++;
742*11038SRao.Shoaib@Sun.COM 
743*11038SRao.Shoaib@Sun.COM 		t = ns_get16(rdata);
744*11038SRao.Shoaib@Sun.COM 		rdata += NS_INT16SZ;
745*11038SRao.Shoaib@Sun.COM 		len = SPRINTF((tmp, "%u ", t));
746*11038SRao.Shoaib@Sun.COM 		T(addstr(tmp, len, &buf, &buflen));
747*11038SRao.Shoaib@Sun.COM 
748*11038SRao.Shoaib@Sun.COM 		t = *rdata++;
749*11038SRao.Shoaib@Sun.COM 		if (t == 0) {
750*11038SRao.Shoaib@Sun.COM 			T(addstr("-", 1, &buf, &buflen));
751*11038SRao.Shoaib@Sun.COM 		} else {
752*11038SRao.Shoaib@Sun.COM 			while (t-- > 0) {
753*11038SRao.Shoaib@Sun.COM 				len = SPRINTF((tmp, "%02X", *rdata));
754*11038SRao.Shoaib@Sun.COM 				T(addstr(tmp, len, &buf, &buflen));
755*11038SRao.Shoaib@Sun.COM 				rdata++;
756*11038SRao.Shoaib@Sun.COM 			}
757*11038SRao.Shoaib@Sun.COM 		}
758*11038SRao.Shoaib@Sun.COM 		if (type == ns_t_nsec3param)
759*11038SRao.Shoaib@Sun.COM 			break;
760*11038SRao.Shoaib@Sun.COM 		T(addstr(" ", 1, &buf, &buflen));
761*11038SRao.Shoaib@Sun.COM 
762*11038SRao.Shoaib@Sun.COM 		t = *rdata++;
763*11038SRao.Shoaib@Sun.COM 		while (t > 0) {
764*11038SRao.Shoaib@Sun.COM 			switch (t) {
765*11038SRao.Shoaib@Sun.COM 			case 1:
766*11038SRao.Shoaib@Sun.COM 				tmp[0] = base32hex[((rdata[0]>>3)&0x1f)];
767*11038SRao.Shoaib@Sun.COM 				tmp[1] = base32hex[((rdata[0]<<2)&0x1c)];
768*11038SRao.Shoaib@Sun.COM 				tmp[2] = tmp[3] = tmp[4] = '=';
769*11038SRao.Shoaib@Sun.COM 				tmp[5] = tmp[6] = tmp[7] = '=';
770*11038SRao.Shoaib@Sun.COM 				break;
771*11038SRao.Shoaib@Sun.COM 			case 2:
772*11038SRao.Shoaib@Sun.COM 				tmp[0] = base32hex[((rdata[0]>>3)&0x1f)];
773*11038SRao.Shoaib@Sun.COM 				tmp[1] = base32hex[((rdata[0]<<2)&0x1c)|
774*11038SRao.Shoaib@Sun.COM 						   ((rdata[1]>>6)&0x03)];
775*11038SRao.Shoaib@Sun.COM 				tmp[2] = base32hex[((rdata[1]>>1)&0x1f)];
776*11038SRao.Shoaib@Sun.COM 				tmp[3] = base32hex[((rdata[1]<<4)&0x10)];
777*11038SRao.Shoaib@Sun.COM 				tmp[4] = tmp[5] = tmp[6] = tmp[7] = '=';
778*11038SRao.Shoaib@Sun.COM 				break;
779*11038SRao.Shoaib@Sun.COM 			case 3:
780*11038SRao.Shoaib@Sun.COM 				tmp[0] = base32hex[((rdata[0]>>3)&0x1f)];
781*11038SRao.Shoaib@Sun.COM 				tmp[1] = base32hex[((rdata[0]<<2)&0x1c)|
782*11038SRao.Shoaib@Sun.COM 						   ((rdata[1]>>6)&0x03)];
783*11038SRao.Shoaib@Sun.COM 				tmp[2] = base32hex[((rdata[1]>>1)&0x1f)];
784*11038SRao.Shoaib@Sun.COM 				tmp[3] = base32hex[((rdata[1]<<4)&0x10)|
785*11038SRao.Shoaib@Sun.COM 						   ((rdata[2]>>4)&0x0f)];
786*11038SRao.Shoaib@Sun.COM 				tmp[4] = base32hex[((rdata[2]<<1)&0x1e)];
787*11038SRao.Shoaib@Sun.COM 				tmp[5] = tmp[6] = tmp[7] = '=';
788*11038SRao.Shoaib@Sun.COM 				break;
789*11038SRao.Shoaib@Sun.COM 			case 4:
790*11038SRao.Shoaib@Sun.COM 				tmp[0] = base32hex[((rdata[0]>>3)&0x1f)];
791*11038SRao.Shoaib@Sun.COM 				tmp[1] = base32hex[((rdata[0]<<2)&0x1c)|
792*11038SRao.Shoaib@Sun.COM 						   ((rdata[1]>>6)&0x03)];
793*11038SRao.Shoaib@Sun.COM 				tmp[2] = base32hex[((rdata[1]>>1)&0x1f)];
794*11038SRao.Shoaib@Sun.COM 				tmp[3] = base32hex[((rdata[1]<<4)&0x10)|
795*11038SRao.Shoaib@Sun.COM 						   ((rdata[2]>>4)&0x0f)];
796*11038SRao.Shoaib@Sun.COM 				tmp[4] = base32hex[((rdata[2]<<1)&0x1e)|
797*11038SRao.Shoaib@Sun.COM 						   ((rdata[3]>>7)&0x01)];
798*11038SRao.Shoaib@Sun.COM 				tmp[5] = base32hex[((rdata[3]>>2)&0x1f)];
799*11038SRao.Shoaib@Sun.COM 				tmp[6] = base32hex[(rdata[3]<<3)&0x18];
800*11038SRao.Shoaib@Sun.COM 				tmp[7] = '=';
801*11038SRao.Shoaib@Sun.COM 				break;
802*11038SRao.Shoaib@Sun.COM 			default:
803*11038SRao.Shoaib@Sun.COM 				tmp[0] = base32hex[((rdata[0]>>3)&0x1f)];
804*11038SRao.Shoaib@Sun.COM 				tmp[1] = base32hex[((rdata[0]<<2)&0x1c)|
805*11038SRao.Shoaib@Sun.COM 						   ((rdata[1]>>6)&0x03)];
806*11038SRao.Shoaib@Sun.COM 				tmp[2] = base32hex[((rdata[1]>>1)&0x1f)];
807*11038SRao.Shoaib@Sun.COM 				tmp[3] = base32hex[((rdata[1]<<4)&0x10)|
808*11038SRao.Shoaib@Sun.COM 						   ((rdata[2]>>4)&0x0f)];
809*11038SRao.Shoaib@Sun.COM 				tmp[4] = base32hex[((rdata[2]<<1)&0x1e)|
810*11038SRao.Shoaib@Sun.COM 						   ((rdata[3]>>7)&0x01)];
811*11038SRao.Shoaib@Sun.COM 				tmp[5] = base32hex[((rdata[3]>>2)&0x1f)];
812*11038SRao.Shoaib@Sun.COM 				tmp[6] = base32hex[((rdata[3]<<3)&0x18)|
813*11038SRao.Shoaib@Sun.COM 						   ((rdata[4]>>5)&0x07)];
814*11038SRao.Shoaib@Sun.COM 				tmp[7] = base32hex[(rdata[4]&0x1f)];
815*11038SRao.Shoaib@Sun.COM 				break;
816*11038SRao.Shoaib@Sun.COM 			}
817*11038SRao.Shoaib@Sun.COM 			T(addstr(tmp, 8, &buf, &buflen));
818*11038SRao.Shoaib@Sun.COM 			if (t >= 5) {
819*11038SRao.Shoaib@Sun.COM 				rdata += 5;
820*11038SRao.Shoaib@Sun.COM 				t -= 5;
821*11038SRao.Shoaib@Sun.COM 			} else {
822*11038SRao.Shoaib@Sun.COM 				rdata += t;
823*11038SRao.Shoaib@Sun.COM 				t -= t;
824*11038SRao.Shoaib@Sun.COM 			}
825*11038SRao.Shoaib@Sun.COM 		}
826*11038SRao.Shoaib@Sun.COM 
827*11038SRao.Shoaib@Sun.COM 		while (rdata < edata) {
828*11038SRao.Shoaib@Sun.COM 			w = *rdata++;
829*11038SRao.Shoaib@Sun.COM 			l = *rdata++;
830*11038SRao.Shoaib@Sun.COM 			for (j = 0; j < l; j++) {
831*11038SRao.Shoaib@Sun.COM 				if (rdata[j] == 0)
832*11038SRao.Shoaib@Sun.COM 					continue;
833*11038SRao.Shoaib@Sun.COM 				for (k = 0; k < 8; k++) {
834*11038SRao.Shoaib@Sun.COM 					if ((rdata[j] & (0x80 >> k)) == 0)
835*11038SRao.Shoaib@Sun.COM 						continue;
836*11038SRao.Shoaib@Sun.COM 					c = w * 256 + j * 8 + k;
837*11038SRao.Shoaib@Sun.COM 					len = SPRINTF((tmp, " %s", p_type(c)));
838*11038SRao.Shoaib@Sun.COM 					T(addstr(tmp, len, &buf, &buflen));
839*11038SRao.Shoaib@Sun.COM 				}
840*11038SRao.Shoaib@Sun.COM 			}
841*11038SRao.Shoaib@Sun.COM 			rdata += l;
842*11038SRao.Shoaib@Sun.COM 		}
843*11038SRao.Shoaib@Sun.COM 		break;
844*11038SRao.Shoaib@Sun.COM 	    }
845*11038SRao.Shoaib@Sun.COM 
846*11038SRao.Shoaib@Sun.COM 	case ns_t_nsec: {
847*11038SRao.Shoaib@Sun.COM 		u_int w, l, j, k, c;
848*11038SRao.Shoaib@Sun.COM 
849*11038SRao.Shoaib@Sun.COM 		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
850*11038SRao.Shoaib@Sun.COM 
851*11038SRao.Shoaib@Sun.COM 		while (rdata < edata) {
852*11038SRao.Shoaib@Sun.COM 			w = *rdata++;
853*11038SRao.Shoaib@Sun.COM 			l = *rdata++;
854*11038SRao.Shoaib@Sun.COM 			for (j = 0; j < l; j++) {
855*11038SRao.Shoaib@Sun.COM 				if (rdata[j] == 0)
856*11038SRao.Shoaib@Sun.COM 					continue;
857*11038SRao.Shoaib@Sun.COM 				for (k = 0; k < 8; k++) {
858*11038SRao.Shoaib@Sun.COM 					if ((rdata[j] & (0x80 >> k)) == 0)
859*11038SRao.Shoaib@Sun.COM 						continue;
860*11038SRao.Shoaib@Sun.COM 					c = w * 256 + j * 8 + k;
861*11038SRao.Shoaib@Sun.COM 					len = SPRINTF((tmp, " %s", p_type(c)));
862*11038SRao.Shoaib@Sun.COM 					T(addstr(tmp, len, &buf, &buflen));
863*11038SRao.Shoaib@Sun.COM 				}
864*11038SRao.Shoaib@Sun.COM 			}
865*11038SRao.Shoaib@Sun.COM 			rdata += l;
866*11038SRao.Shoaib@Sun.COM 		}
867*11038SRao.Shoaib@Sun.COM 		break;
868*11038SRao.Shoaib@Sun.COM 	    }
869*11038SRao.Shoaib@Sun.COM 
870*11038SRao.Shoaib@Sun.COM 	case ns_t_dhcid: {
871*11038SRao.Shoaib@Sun.COM 		int n;
872*11038SRao.Shoaib@Sun.COM 		unsigned int siz;
873*11038SRao.Shoaib@Sun.COM 		char base64_dhcid[8192];
874*11038SRao.Shoaib@Sun.COM 		const char *leader;
875*11038SRao.Shoaib@Sun.COM 
876*11038SRao.Shoaib@Sun.COM 		siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
877*11038SRao.Shoaib@Sun.COM 		if (siz > sizeof(base64_dhcid) * 3/4) {
878*11038SRao.Shoaib@Sun.COM 			const char *str = "record too long to print";
879*11038SRao.Shoaib@Sun.COM 			T(addstr(str, strlen(str), &buf, &buflen));
880*11038SRao.Shoaib@Sun.COM 		} else {
881*11038SRao.Shoaib@Sun.COM 			len = b64_ntop(rdata, edata-rdata, base64_dhcid, siz);
882*11038SRao.Shoaib@Sun.COM 
883*11038SRao.Shoaib@Sun.COM 			if (len < 0)
884*11038SRao.Shoaib@Sun.COM 				goto formerr;
885*11038SRao.Shoaib@Sun.COM 
886*11038SRao.Shoaib@Sun.COM 			else if (len > 15) {
887*11038SRao.Shoaib@Sun.COM 				T(addstr(" (", 2, &buf, &buflen));
888*11038SRao.Shoaib@Sun.COM 				leader = "\n\t\t";
889*11038SRao.Shoaib@Sun.COM 				spaced = 0;
890*11038SRao.Shoaib@Sun.COM 			}
891*11038SRao.Shoaib@Sun.COM 			else
892*11038SRao.Shoaib@Sun.COM 				leader = " ";
893*11038SRao.Shoaib@Sun.COM 
894*11038SRao.Shoaib@Sun.COM 			for (n = 0; n < len; n += 48) {
895*11038SRao.Shoaib@Sun.COM 				T(addstr(leader, strlen(leader),
896*11038SRao.Shoaib@Sun.COM 					 &buf, &buflen));
897*11038SRao.Shoaib@Sun.COM 				T(addstr(base64_dhcid + n, MIN(len - n, 48),
898*11038SRao.Shoaib@Sun.COM 					 &buf, &buflen));
899*11038SRao.Shoaib@Sun.COM 			}
900*11038SRao.Shoaib@Sun.COM 			if (len > 15)
901*11038SRao.Shoaib@Sun.COM 				T(addstr(" )", 2, &buf, &buflen));
902*11038SRao.Shoaib@Sun.COM 		}
903*11038SRao.Shoaib@Sun.COM 	}
904*11038SRao.Shoaib@Sun.COM 
905*11038SRao.Shoaib@Sun.COM 	case ns_t_ipseckey: {
906*11038SRao.Shoaib@Sun.COM 		int n;
907*11038SRao.Shoaib@Sun.COM 		unsigned int siz;
908*11038SRao.Shoaib@Sun.COM 		char base64_key[8192];
909*11038SRao.Shoaib@Sun.COM 		const char *leader;
910*11038SRao.Shoaib@Sun.COM 
911*11038SRao.Shoaib@Sun.COM 		if (rdlen < 2)
912*11038SRao.Shoaib@Sun.COM 			goto formerr;
913*11038SRao.Shoaib@Sun.COM 
914*11038SRao.Shoaib@Sun.COM 		switch (rdata[1]) {
915*11038SRao.Shoaib@Sun.COM 		case 0:
916*11038SRao.Shoaib@Sun.COM 		case 3:
917*11038SRao.Shoaib@Sun.COM 			if (rdlen < 3)
918*11038SRao.Shoaib@Sun.COM 				goto formerr;
919*11038SRao.Shoaib@Sun.COM 			break;
920*11038SRao.Shoaib@Sun.COM 		case 1:
921*11038SRao.Shoaib@Sun.COM 			if (rdlen < 7)
922*11038SRao.Shoaib@Sun.COM 				goto formerr;
923*11038SRao.Shoaib@Sun.COM 			break;
924*11038SRao.Shoaib@Sun.COM 		case 2:
925*11038SRao.Shoaib@Sun.COM 			if (rdlen < 19)
926*11038SRao.Shoaib@Sun.COM 				goto formerr;
927*11038SRao.Shoaib@Sun.COM 			break;
928*11038SRao.Shoaib@Sun.COM 		default:
929*11038SRao.Shoaib@Sun.COM 			comment = "unknown IPSECKEY gateway type";
930*11038SRao.Shoaib@Sun.COM 			goto hexify;
931*11038SRao.Shoaib@Sun.COM 		}
932*11038SRao.Shoaib@Sun.COM 
933*11038SRao.Shoaib@Sun.COM 		len = SPRINTF((tmp, "%u ", *rdata));
934*11038SRao.Shoaib@Sun.COM 		T(addstr(tmp, len, &buf, &buflen));
935*11038SRao.Shoaib@Sun.COM 		rdata++;
936*11038SRao.Shoaib@Sun.COM 
937*11038SRao.Shoaib@Sun.COM 		len = SPRINTF((tmp, "%u ", *rdata));
938*11038SRao.Shoaib@Sun.COM 		T(addstr(tmp, len, &buf, &buflen));
939*11038SRao.Shoaib@Sun.COM 		rdata++;
940*11038SRao.Shoaib@Sun.COM 
941*11038SRao.Shoaib@Sun.COM 		len = SPRINTF((tmp, "%u ", *rdata));
942*11038SRao.Shoaib@Sun.COM 		T(addstr(tmp, len, &buf, &buflen));
943*11038SRao.Shoaib@Sun.COM 		rdata++;
944*11038SRao.Shoaib@Sun.COM 
945*11038SRao.Shoaib@Sun.COM 		switch (rdata[-2]) {
946*11038SRao.Shoaib@Sun.COM 		case 0:
947*11038SRao.Shoaib@Sun.COM 			T(addstr(".", 1, &buf, &buflen));
948*11038SRao.Shoaib@Sun.COM 			break;
949*11038SRao.Shoaib@Sun.COM 		case 1:
950*11038SRao.Shoaib@Sun.COM 			(void) inet_ntop(AF_INET, rdata, buf, buflen);
951*11038SRao.Shoaib@Sun.COM 			addlen(strlen(buf), &buf, &buflen);
952*11038SRao.Shoaib@Sun.COM 			rdata += 4;
953*11038SRao.Shoaib@Sun.COM 			break;
954*11038SRao.Shoaib@Sun.COM 		case 2:
955*11038SRao.Shoaib@Sun.COM 			(void) inet_ntop(AF_INET6, rdata, buf, buflen);
956*11038SRao.Shoaib@Sun.COM 			addlen(strlen(buf), &buf, &buflen);
957*11038SRao.Shoaib@Sun.COM 			rdata += 16;
958*11038SRao.Shoaib@Sun.COM 			break;
959*11038SRao.Shoaib@Sun.COM 		case 3:
960*11038SRao.Shoaib@Sun.COM 			T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
961*11038SRao.Shoaib@Sun.COM 			break;
962*11038SRao.Shoaib@Sun.COM 		}
963*11038SRao.Shoaib@Sun.COM 
964*11038SRao.Shoaib@Sun.COM 		if (rdata >= edata)
965*11038SRao.Shoaib@Sun.COM 			break;
966*11038SRao.Shoaib@Sun.COM 
967*11038SRao.Shoaib@Sun.COM 		siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
968*11038SRao.Shoaib@Sun.COM 		if (siz > sizeof(base64_key) * 3/4) {
969*11038SRao.Shoaib@Sun.COM 			const char *str = "record too long to print";
970*11038SRao.Shoaib@Sun.COM 			T(addstr(str, strlen(str), &buf, &buflen));
971*11038SRao.Shoaib@Sun.COM 		} else {
972*11038SRao.Shoaib@Sun.COM 			len = b64_ntop(rdata, edata-rdata, base64_key, siz);
973*11038SRao.Shoaib@Sun.COM 
974*11038SRao.Shoaib@Sun.COM 			if (len < 0)
975*11038SRao.Shoaib@Sun.COM 				goto formerr;
976*11038SRao.Shoaib@Sun.COM 
977*11038SRao.Shoaib@Sun.COM 			else if (len > 15) {
978*11038SRao.Shoaib@Sun.COM 				T(addstr(" (", 2, &buf, &buflen));
979*11038SRao.Shoaib@Sun.COM 				leader = "\n\t\t";
980*11038SRao.Shoaib@Sun.COM 				spaced = 0;
981*11038SRao.Shoaib@Sun.COM 			}
982*11038SRao.Shoaib@Sun.COM 			else
983*11038SRao.Shoaib@Sun.COM 				leader = " ";
984*11038SRao.Shoaib@Sun.COM 
985*11038SRao.Shoaib@Sun.COM 			for (n = 0; n < len; n += 48) {
986*11038SRao.Shoaib@Sun.COM 				T(addstr(leader, strlen(leader),
987*11038SRao.Shoaib@Sun.COM 					 &buf, &buflen));
988*11038SRao.Shoaib@Sun.COM 				T(addstr(base64_key + n, MIN(len - n, 48),
989*11038SRao.Shoaib@Sun.COM 					 &buf, &buflen));
990*11038SRao.Shoaib@Sun.COM 			}
991*11038SRao.Shoaib@Sun.COM 			if (len > 15)
992*11038SRao.Shoaib@Sun.COM 				T(addstr(" )", 2, &buf, &buflen));
993*11038SRao.Shoaib@Sun.COM 		}
994*11038SRao.Shoaib@Sun.COM 	}
995*11038SRao.Shoaib@Sun.COM 
996*11038SRao.Shoaib@Sun.COM 	case ns_t_hip: {
997*11038SRao.Shoaib@Sun.COM 		unsigned int i, hip_len, algorithm, key_len;
998*11038SRao.Shoaib@Sun.COM 		char base64_key[NS_MD5RSA_MAX_BASE64];
999*11038SRao.Shoaib@Sun.COM 		unsigned int siz;
1000*11038SRao.Shoaib@Sun.COM 		const char *leader = "\n\t\t\t\t\t";
1001*11038SRao.Shoaib@Sun.COM 
1002*11038SRao.Shoaib@Sun.COM 		hip_len = *rdata++;
1003*11038SRao.Shoaib@Sun.COM 		algorithm = *rdata++;
1004*11038SRao.Shoaib@Sun.COM 		key_len = ns_get16(rdata);
1005*11038SRao.Shoaib@Sun.COM 		rdata += NS_INT16SZ;
1006*11038SRao.Shoaib@Sun.COM 
1007*11038SRao.Shoaib@Sun.COM 		siz = key_len*4/3 + 4; /* "+4" accounts for trailing \0 */
1008*11038SRao.Shoaib@Sun.COM 		if (siz > sizeof(base64_key) * 3/4) {
1009*11038SRao.Shoaib@Sun.COM 			const char *str = "record too long to print";
1010*11038SRao.Shoaib@Sun.COM 			T(addstr(str, strlen(str), &buf, &buflen));
1011*11038SRao.Shoaib@Sun.COM 		} else {
1012*11038SRao.Shoaib@Sun.COM 			len = sprintf(tmp, "( %u ", algorithm);
1013*11038SRao.Shoaib@Sun.COM 			T(addstr(tmp, len, &buf, &buflen));
1014*11038SRao.Shoaib@Sun.COM 
1015*11038SRao.Shoaib@Sun.COM 			for (i = 0; i < hip_len; i++) {
1016*11038SRao.Shoaib@Sun.COM 				len = sprintf(tmp, "%02X", *rdata);
1017*11038SRao.Shoaib@Sun.COM 				T(addstr(tmp, len, &buf, &buflen));
1018*11038SRao.Shoaib@Sun.COM 				rdata++;
1019*11038SRao.Shoaib@Sun.COM 			}
1020*11038SRao.Shoaib@Sun.COM 			T(addstr(leader, strlen(leader), &buf, &buflen));
1021*11038SRao.Shoaib@Sun.COM 
1022*11038SRao.Shoaib@Sun.COM 			len = b64_ntop(rdata, key_len, base64_key, siz);
1023*11038SRao.Shoaib@Sun.COM 			if (len < 0)
1024*11038SRao.Shoaib@Sun.COM 				goto formerr;
1025*11038SRao.Shoaib@Sun.COM 
1026*11038SRao.Shoaib@Sun.COM 			T(addstr(base64_key, len, &buf, &buflen));
1027*11038SRao.Shoaib@Sun.COM 
1028*11038SRao.Shoaib@Sun.COM 			rdata += key_len;
1029*11038SRao.Shoaib@Sun.COM 			while (rdata < edata) {
1030*11038SRao.Shoaib@Sun.COM 				T(addstr(leader, strlen(leader), &buf, &buflen));
1031*11038SRao.Shoaib@Sun.COM 				T(addname(msg, msglen, &rdata, origin,
1032*11038SRao.Shoaib@Sun.COM 					  &buf, &buflen));
1033*11038SRao.Shoaib@Sun.COM 			}
1034*11038SRao.Shoaib@Sun.COM 			T(addstr(" )", 2, &buf, &buflen));
1035*11038SRao.Shoaib@Sun.COM 		}
1036*11038SRao.Shoaib@Sun.COM 		break;
10370Sstevel@tonic-gate 	}
10380Sstevel@tonic-gate 
10390Sstevel@tonic-gate 	default:
10400Sstevel@tonic-gate 		comment = "unknown RR type";
10410Sstevel@tonic-gate 		goto hexify;
10420Sstevel@tonic-gate 	}
10430Sstevel@tonic-gate 	return (buf - obuf);
10440Sstevel@tonic-gate  formerr:
10450Sstevel@tonic-gate 	comment = "RR format error";
10460Sstevel@tonic-gate  hexify: {
10470Sstevel@tonic-gate 	int n, m;
10480Sstevel@tonic-gate 	char *p;
10490Sstevel@tonic-gate 
1050*11038SRao.Shoaib@Sun.COM 	len = SPRINTF((tmp, "\\# %u%s\t; %s", (unsigned)(edata - rdata),
1051*11038SRao.Shoaib@Sun.COM 		       rdlen != 0U ? " (" : "", comment));
10520Sstevel@tonic-gate 	T(addstr(tmp, len, &buf, &buflen));
10530Sstevel@tonic-gate 	while (rdata < edata) {
10540Sstevel@tonic-gate 		p = tmp;
10550Sstevel@tonic-gate 		p += SPRINTF((p, "\n\t"));
10560Sstevel@tonic-gate 		spaced = 0;
10570Sstevel@tonic-gate 		n = MIN(16, edata - rdata);
10580Sstevel@tonic-gate 		for (m = 0; m < n; m++)
10590Sstevel@tonic-gate 			p += SPRINTF((p, "%02x ", rdata[m]));
10600Sstevel@tonic-gate 		T(addstr(tmp, p - tmp, &buf, &buflen));
10610Sstevel@tonic-gate 		if (n < 16) {
10620Sstevel@tonic-gate 			T(addstr(")", 1, &buf, &buflen));
10630Sstevel@tonic-gate 			T(addtab(p - tmp + 1, 48, spaced, &buf, &buflen));
10640Sstevel@tonic-gate 		}
10650Sstevel@tonic-gate 		p = tmp;
10660Sstevel@tonic-gate 		p += SPRINTF((p, "; "));
10670Sstevel@tonic-gate 		for (m = 0; m < n; m++)
10680Sstevel@tonic-gate 			*p++ = (isascii(rdata[m]) && isprint(rdata[m]))
10690Sstevel@tonic-gate 				? rdata[m]
10700Sstevel@tonic-gate 				: '.';
10710Sstevel@tonic-gate 		T(addstr(tmp, p - tmp, &buf, &buflen));
10720Sstevel@tonic-gate 		rdata += n;
10730Sstevel@tonic-gate 	}
10740Sstevel@tonic-gate 	return (buf - obuf);
10750Sstevel@tonic-gate     }
10760Sstevel@tonic-gate }
10770Sstevel@tonic-gate 
10780Sstevel@tonic-gate /* Private. */
10790Sstevel@tonic-gate 
1080*11038SRao.Shoaib@Sun.COM /*%
10810Sstevel@tonic-gate  * size_t
10820Sstevel@tonic-gate  * prune_origin(name, origin)
10830Sstevel@tonic-gate  *	Find out if the name is at or under the current origin.
10840Sstevel@tonic-gate  * return:
10850Sstevel@tonic-gate  *	Number of characters in name before start of origin,
10860Sstevel@tonic-gate  *	or length of name if origin does not match.
10870Sstevel@tonic-gate  * notes:
10880Sstevel@tonic-gate  *	This function should share code with samedomain().
10890Sstevel@tonic-gate  */
10900Sstevel@tonic-gate static size_t
prune_origin(const char * name,const char * origin)10910Sstevel@tonic-gate prune_origin(const char *name, const char *origin) {
10920Sstevel@tonic-gate 	const char *oname = name;
10930Sstevel@tonic-gate 
10940Sstevel@tonic-gate 	while (*name != '\0') {
10950Sstevel@tonic-gate 		if (origin != NULL && ns_samename(name, origin) == 1)
10960Sstevel@tonic-gate 			return (name - oname - (name > oname));
10970Sstevel@tonic-gate 		while (*name != '\0') {
10980Sstevel@tonic-gate 			if (*name == '\\') {
10990Sstevel@tonic-gate 				name++;
11000Sstevel@tonic-gate 				/* XXX need to handle \nnn form. */
11010Sstevel@tonic-gate 				if (*name == '\0')
11020Sstevel@tonic-gate 					break;
11030Sstevel@tonic-gate 			} else if (*name == '.') {
11040Sstevel@tonic-gate 				name++;
11050Sstevel@tonic-gate 				break;
11060Sstevel@tonic-gate 			}
11070Sstevel@tonic-gate 			name++;
11080Sstevel@tonic-gate 		}
11090Sstevel@tonic-gate 	}
11100Sstevel@tonic-gate 	return (name - oname);
11110Sstevel@tonic-gate }
11120Sstevel@tonic-gate 
1113*11038SRao.Shoaib@Sun.COM /*%
11140Sstevel@tonic-gate  * int
11150Sstevel@tonic-gate  * charstr(rdata, edata, buf, buflen)
11160Sstevel@tonic-gate  *	Format a <character-string> into the presentation buffer.
11170Sstevel@tonic-gate  * return:
11180Sstevel@tonic-gate  *	Number of rdata octets consumed
11190Sstevel@tonic-gate  *	0 for protocol format error
11200Sstevel@tonic-gate  *	-1 for output buffer error
11210Sstevel@tonic-gate  * side effects:
11220Sstevel@tonic-gate  *	buffer is advanced on success.
11230Sstevel@tonic-gate  */
11240Sstevel@tonic-gate static int
charstr(const u_char * rdata,const u_char * edata,char ** buf,size_t * buflen)11250Sstevel@tonic-gate charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
11260Sstevel@tonic-gate 	const u_char *odata = rdata;
11270Sstevel@tonic-gate 	size_t save_buflen = *buflen;
11280Sstevel@tonic-gate 	char *save_buf = *buf;
11290Sstevel@tonic-gate 
11300Sstevel@tonic-gate 	if (addstr("\"", 1, buf, buflen) < 0)
11310Sstevel@tonic-gate 		goto enospc;
11320Sstevel@tonic-gate 	if (rdata < edata) {
11330Sstevel@tonic-gate 		int n = *rdata;
11340Sstevel@tonic-gate 
11350Sstevel@tonic-gate 		if (rdata + 1 + n <= edata) {
11360Sstevel@tonic-gate 			rdata++;
11370Sstevel@tonic-gate 			while (n-- > 0) {
11380Sstevel@tonic-gate 				if (strchr("\n\"\\", *rdata) != NULL)
11390Sstevel@tonic-gate 					if (addstr("\\", 1, buf, buflen) < 0)
11400Sstevel@tonic-gate 						goto enospc;
11410Sstevel@tonic-gate 				if (addstr((const char *)rdata, 1,
11420Sstevel@tonic-gate 					   buf, buflen) < 0)
11430Sstevel@tonic-gate 					goto enospc;
11440Sstevel@tonic-gate 				rdata++;
11450Sstevel@tonic-gate 			}
11460Sstevel@tonic-gate 		}
11470Sstevel@tonic-gate 	}
11480Sstevel@tonic-gate 	if (addstr("\"", 1, buf, buflen) < 0)
11490Sstevel@tonic-gate 		goto enospc;
11500Sstevel@tonic-gate 	return (rdata - odata);
11510Sstevel@tonic-gate  enospc:
11520Sstevel@tonic-gate 	errno = ENOSPC;
11530Sstevel@tonic-gate 	*buf = save_buf;
11540Sstevel@tonic-gate 	*buflen = save_buflen;
11550Sstevel@tonic-gate 	return (-1);
11560Sstevel@tonic-gate }
11570Sstevel@tonic-gate 
11580Sstevel@tonic-gate static int
addname(const u_char * msg,size_t msglen,const u_char ** pp,const char * origin,char ** buf,size_t * buflen)11590Sstevel@tonic-gate addname(const u_char *msg, size_t msglen,
11600Sstevel@tonic-gate 	const u_char **pp, const char *origin,
11610Sstevel@tonic-gate 	char **buf, size_t *buflen)
11620Sstevel@tonic-gate {
11630Sstevel@tonic-gate 	size_t newlen, save_buflen = *buflen;
11640Sstevel@tonic-gate 	char *save_buf = *buf;
11650Sstevel@tonic-gate 	int n;
11660Sstevel@tonic-gate 
11670Sstevel@tonic-gate 	n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen);
11680Sstevel@tonic-gate 	if (n < 0)
1169*11038SRao.Shoaib@Sun.COM 		goto enospc;	/*%< Guess. */
11700Sstevel@tonic-gate 	newlen = prune_origin(*buf, origin);
11710Sstevel@tonic-gate 	if (**buf == '\0') {
11720Sstevel@tonic-gate 		goto root;
1173*11038SRao.Shoaib@Sun.COM 	} else if (newlen == 0U) {
11740Sstevel@tonic-gate 		/* Use "@" instead of name. */
11750Sstevel@tonic-gate 		if (newlen + 2 > *buflen)
11760Sstevel@tonic-gate 			goto enospc;        /* No room for "@\0". */
11770Sstevel@tonic-gate 		(*buf)[newlen++] = '@';
11780Sstevel@tonic-gate 		(*buf)[newlen] = '\0';
11790Sstevel@tonic-gate 	} else {
11800Sstevel@tonic-gate 		if (((origin == NULL || origin[0] == '\0') ||
11810Sstevel@tonic-gate 		    (origin[0] != '.' && origin[1] != '\0' &&
11820Sstevel@tonic-gate 		    (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') {
11830Sstevel@tonic-gate 			/* No trailing dot. */
11840Sstevel@tonic-gate  root:
11850Sstevel@tonic-gate 			if (newlen + 2 > *buflen)
11860Sstevel@tonic-gate 				goto enospc;	/* No room for ".\0". */
11870Sstevel@tonic-gate 			(*buf)[newlen++] = '.';
11880Sstevel@tonic-gate 			(*buf)[newlen] = '\0';
11890Sstevel@tonic-gate 		}
11900Sstevel@tonic-gate 	}
11910Sstevel@tonic-gate 	*pp += n;
11920Sstevel@tonic-gate 	addlen(newlen, buf, buflen);
11930Sstevel@tonic-gate 	**buf = '\0';
11940Sstevel@tonic-gate 	return (newlen);
11950Sstevel@tonic-gate  enospc:
11960Sstevel@tonic-gate 	errno = ENOSPC;
11970Sstevel@tonic-gate 	*buf = save_buf;
11980Sstevel@tonic-gate 	*buflen = save_buflen;
11990Sstevel@tonic-gate 	return (-1);
12000Sstevel@tonic-gate }
12010Sstevel@tonic-gate 
12020Sstevel@tonic-gate static void
addlen(size_t len,char ** buf,size_t * buflen)12030Sstevel@tonic-gate addlen(size_t len, char **buf, size_t *buflen) {
12040Sstevel@tonic-gate 	INSIST(len <= *buflen);
12050Sstevel@tonic-gate 	*buf += len;
12060Sstevel@tonic-gate 	*buflen -= len;
12070Sstevel@tonic-gate }
12080Sstevel@tonic-gate 
12090Sstevel@tonic-gate static int
addstr(const char * src,size_t len,char ** buf,size_t * buflen)12100Sstevel@tonic-gate addstr(const char *src, size_t len, char **buf, size_t *buflen) {
12110Sstevel@tonic-gate 	if (len >= *buflen) {
12120Sstevel@tonic-gate 		errno = ENOSPC;
12130Sstevel@tonic-gate 		return (-1);
12140Sstevel@tonic-gate 	}
12150Sstevel@tonic-gate 	memcpy(*buf, src, len);
12160Sstevel@tonic-gate 	addlen(len, buf, buflen);
12170Sstevel@tonic-gate 	**buf = '\0';
12180Sstevel@tonic-gate 	return (0);
12190Sstevel@tonic-gate }
12200Sstevel@tonic-gate 
12210Sstevel@tonic-gate static int
addtab(size_t len,size_t target,int spaced,char ** buf,size_t * buflen)12220Sstevel@tonic-gate addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
12230Sstevel@tonic-gate 	size_t save_buflen = *buflen;
12240Sstevel@tonic-gate 	char *save_buf = *buf;
12250Sstevel@tonic-gate 	int t;
12260Sstevel@tonic-gate 
12270Sstevel@tonic-gate 	if (spaced || len >= target - 1) {
12280Sstevel@tonic-gate 		T(addstr("  ", 2, buf, buflen));
12290Sstevel@tonic-gate 		spaced = 1;
12300Sstevel@tonic-gate 	} else {
12310Sstevel@tonic-gate 		for (t = (target - len - 1) / 8; t >= 0; t--)
12320Sstevel@tonic-gate 			if (addstr("\t", 1, buf, buflen) < 0) {
12330Sstevel@tonic-gate 				*buflen = save_buflen;
12340Sstevel@tonic-gate 				*buf = save_buf;
12350Sstevel@tonic-gate 				return (-1);
12360Sstevel@tonic-gate 			}
12370Sstevel@tonic-gate 		spaced = 0;
12380Sstevel@tonic-gate 	}
12390Sstevel@tonic-gate 	return (spaced);
12400Sstevel@tonic-gate }
1241*11038SRao.Shoaib@Sun.COM 
1242*11038SRao.Shoaib@Sun.COM /*! \file */
1243