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