17c478bd9Sstevel@tonic-gate /* 29525b14bSRao Shoaib * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 37c478bd9Sstevel@tonic-gate * Copyright (c) 1996-1999 by Internet Software Consortium. 4*a5d83f5bSJohn Levon * Copyright 2018 Joyent, Inc. 57c478bd9Sstevel@tonic-gate * 67c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 77c478bd9Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 87c478bd9Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 97c478bd9Sstevel@tonic-gate * 109525b14bSRao Shoaib * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 119525b14bSRao Shoaib * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 129525b14bSRao Shoaib * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 139525b14bSRao Shoaib * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 149525b14bSRao Shoaib * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 159525b14bSRao Shoaib * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 169525b14bSRao Shoaib * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 177c478bd9Sstevel@tonic-gate */ 187c478bd9Sstevel@tonic-gate 197c478bd9Sstevel@tonic-gate #include "port_before.h" 207c478bd9Sstevel@tonic-gate 217c478bd9Sstevel@tonic-gate #include <sys/types.h> 227c478bd9Sstevel@tonic-gate #include <sys/socket.h> 237c478bd9Sstevel@tonic-gate 247c478bd9Sstevel@tonic-gate #include <netinet/in.h> 257c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 267c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <isc/assertions.h> 297c478bd9Sstevel@tonic-gate #include <isc/dst.h> 307c478bd9Sstevel@tonic-gate #include <errno.h> 317c478bd9Sstevel@tonic-gate #include <resolv.h> 327c478bd9Sstevel@tonic-gate #include <string.h> 337c478bd9Sstevel@tonic-gate #include <ctype.h> 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include "port_after.h" 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #ifdef SPRINTF_CHAR 387c478bd9Sstevel@tonic-gate # define SPRINTF(x) strlen(sprintf/**/x) 397c478bd9Sstevel@tonic-gate #else 407c478bd9Sstevel@tonic-gate # define SPRINTF(x) ((size_t)sprintf x) 417c478bd9Sstevel@tonic-gate #endif 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate /* Forward. */ 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate static size_t prune_origin(const char *name, const char *origin); 467c478bd9Sstevel@tonic-gate static int charstr(const u_char *rdata, const u_char *edata, 477c478bd9Sstevel@tonic-gate char **buf, size_t *buflen); 487c478bd9Sstevel@tonic-gate static int addname(const u_char *msg, size_t msglen, 497c478bd9Sstevel@tonic-gate const u_char **p, const char *origin, 507c478bd9Sstevel@tonic-gate char **buf, size_t *buflen); 517c478bd9Sstevel@tonic-gate static void addlen(size_t len, char **buf, size_t *buflen); 527c478bd9Sstevel@tonic-gate static int addstr(const char *src, size_t len, 537c478bd9Sstevel@tonic-gate char **buf, size_t *buflen); 547c478bd9Sstevel@tonic-gate static int addtab(size_t len, size_t target, int spaced, 557c478bd9Sstevel@tonic-gate char **buf, size_t *buflen); 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate /* Macros. */ 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate #define T(x) \ 607c478bd9Sstevel@tonic-gate do { \ 617c478bd9Sstevel@tonic-gate if ((x) < 0) \ 627c478bd9Sstevel@tonic-gate return (-1); \ 637c478bd9Sstevel@tonic-gate } while (0) 647c478bd9Sstevel@tonic-gate 659525b14bSRao Shoaib static const char base32hex[] = 669525b14bSRao Shoaib "0123456789ABCDEFGHIJKLMNOPQRSTUV=0123456789abcdefghijklmnopqrstuv"; 679525b14bSRao Shoaib 687c478bd9Sstevel@tonic-gate /* Public. */ 697c478bd9Sstevel@tonic-gate 709525b14bSRao Shoaib /*% 717c478bd9Sstevel@tonic-gate * Convert an RR to presentation format. 729525b14bSRao Shoaib * 737c478bd9Sstevel@tonic-gate * return: 749525b14bSRao Shoaib *\li Number of characters written to buf, or -1 (check errno). 757c478bd9Sstevel@tonic-gate */ 767c478bd9Sstevel@tonic-gate int 777c478bd9Sstevel@tonic-gate ns_sprintrr(const ns_msg *handle, const ns_rr *rr, 787c478bd9Sstevel@tonic-gate const char *name_ctx, const char *origin, 797c478bd9Sstevel@tonic-gate char *buf, size_t buflen) 807c478bd9Sstevel@tonic-gate { 817c478bd9Sstevel@tonic-gate int n; 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle), 847c478bd9Sstevel@tonic-gate ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr), 857c478bd9Sstevel@tonic-gate ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr), 867c478bd9Sstevel@tonic-gate name_ctx, origin, buf, buflen); 877c478bd9Sstevel@tonic-gate return (n); 887c478bd9Sstevel@tonic-gate } 897c478bd9Sstevel@tonic-gate 909525b14bSRao Shoaib /*% 917c478bd9Sstevel@tonic-gate * Convert the fields of an RR into presentation format. 929525b14bSRao Shoaib * 937c478bd9Sstevel@tonic-gate * return: 949525b14bSRao Shoaib *\li Number of characters written to buf, or -1 (check errno). 957c478bd9Sstevel@tonic-gate */ 967c478bd9Sstevel@tonic-gate int 977c478bd9Sstevel@tonic-gate ns_sprintrrf(const u_char *msg, size_t msglen, 987c478bd9Sstevel@tonic-gate const char *name, ns_class class, ns_type type, 997c478bd9Sstevel@tonic-gate u_long ttl, const u_char *rdata, size_t rdlen, 1007c478bd9Sstevel@tonic-gate const char *name_ctx, const char *origin, 1017c478bd9Sstevel@tonic-gate char *buf, size_t buflen) 1027c478bd9Sstevel@tonic-gate { 1037c478bd9Sstevel@tonic-gate const char *obuf = buf; 1047c478bd9Sstevel@tonic-gate const u_char *edata = rdata + rdlen; 1057c478bd9Sstevel@tonic-gate int spaced = 0; 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate const char *comment; 1087c478bd9Sstevel@tonic-gate char tmp[100]; 1097c478bd9Sstevel@tonic-gate int len, x; 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate /* 1127c478bd9Sstevel@tonic-gate * Owner. 1137c478bd9Sstevel@tonic-gate */ 1147c478bd9Sstevel@tonic-gate if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) { 1157c478bd9Sstevel@tonic-gate T(addstr("\t\t\t", 3, &buf, &buflen)); 1167c478bd9Sstevel@tonic-gate } else { 1177c478bd9Sstevel@tonic-gate len = prune_origin(name, origin); 1187c478bd9Sstevel@tonic-gate if (*name == '\0') { 1197c478bd9Sstevel@tonic-gate goto root; 1207c478bd9Sstevel@tonic-gate } else if (len == 0) { 1217c478bd9Sstevel@tonic-gate T(addstr("@\t\t\t", 4, &buf, &buflen)); 1227c478bd9Sstevel@tonic-gate } else { 1237c478bd9Sstevel@tonic-gate T(addstr(name, len, &buf, &buflen)); 1247c478bd9Sstevel@tonic-gate /* Origin not used or not root, and no trailing dot? */ 1257c478bd9Sstevel@tonic-gate if (((origin == NULL || origin[0] == '\0') || 1267c478bd9Sstevel@tonic-gate (origin[0] != '.' && origin[1] != '\0' && 1277c478bd9Sstevel@tonic-gate name[len] == '\0')) && name[len - 1] != '.') { 1287c478bd9Sstevel@tonic-gate root: 1297c478bd9Sstevel@tonic-gate T(addstr(".", 1, &buf, &buflen)); 1307c478bd9Sstevel@tonic-gate len++; 1317c478bd9Sstevel@tonic-gate } 1327c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 24, spaced, &buf, &buflen)); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate /* 1377c478bd9Sstevel@tonic-gate * TTL, Class, Type. 1387c478bd9Sstevel@tonic-gate */ 1397c478bd9Sstevel@tonic-gate T(x = ns_format_ttl(ttl, buf, buflen)); 1407c478bd9Sstevel@tonic-gate addlen(x, &buf, &buflen); 1417c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type))); 1427c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 1437c478bd9Sstevel@tonic-gate T(spaced = addtab(x + len, 16, spaced, &buf, &buflen)); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate /* 1467c478bd9Sstevel@tonic-gate * RData. 1477c478bd9Sstevel@tonic-gate */ 1487c478bd9Sstevel@tonic-gate switch (type) { 1497c478bd9Sstevel@tonic-gate case ns_t_a: 1509525b14bSRao Shoaib if (rdlen != (size_t)NS_INADDRSZ) 1517c478bd9Sstevel@tonic-gate goto formerr; 1527c478bd9Sstevel@tonic-gate (void) inet_ntop(AF_INET, rdata, buf, buflen); 1537c478bd9Sstevel@tonic-gate addlen(strlen(buf), &buf, &buflen); 1547c478bd9Sstevel@tonic-gate break; 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate case ns_t_cname: 1577c478bd9Sstevel@tonic-gate case ns_t_mb: 1587c478bd9Sstevel@tonic-gate case ns_t_mg: 1597c478bd9Sstevel@tonic-gate case ns_t_mr: 1607c478bd9Sstevel@tonic-gate case ns_t_ns: 1617c478bd9Sstevel@tonic-gate case ns_t_ptr: 1627c478bd9Sstevel@tonic-gate case ns_t_dname: 1637c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1647c478bd9Sstevel@tonic-gate break; 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate case ns_t_hinfo: 1677c478bd9Sstevel@tonic-gate case ns_t_isdn: 1687c478bd9Sstevel@tonic-gate /* First word. */ 1697c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 1707c478bd9Sstevel@tonic-gate if (len == 0) 1717c478bd9Sstevel@tonic-gate goto formerr; 1727c478bd9Sstevel@tonic-gate rdata += len; 1737c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate /* Second word, optional in ISDN records. */ 1777c478bd9Sstevel@tonic-gate if (type == ns_t_isdn && rdata == edata) 1787c478bd9Sstevel@tonic-gate break; 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 1817c478bd9Sstevel@tonic-gate if (len == 0) 1827c478bd9Sstevel@tonic-gate goto formerr; 1837c478bd9Sstevel@tonic-gate rdata += len; 1847c478bd9Sstevel@tonic-gate break; 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate case ns_t_soa: { 1877c478bd9Sstevel@tonic-gate u_long t; 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate /* Server name. */ 1907c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1917c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate /* Administrator name. */ 1947c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1957c478bd9Sstevel@tonic-gate T(addstr(" (\n", 3, &buf, &buflen)); 1967c478bd9Sstevel@tonic-gate spaced = 0; 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate if ((edata - rdata) != 5*NS_INT32SZ) 1997c478bd9Sstevel@tonic-gate goto formerr; 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate /* Serial number. */ 2027c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 2037c478bd9Sstevel@tonic-gate T(addstr("\t\t\t\t\t", 5, &buf, &buflen)); 2047c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%lu", t)); 2057c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 2067c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 16, spaced, &buf, &buflen)); 2077c478bd9Sstevel@tonic-gate T(addstr("; serial\n", 9, &buf, &buflen)); 2087c478bd9Sstevel@tonic-gate spaced = 0; 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate /* Refresh interval. */ 2117c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 2127c478bd9Sstevel@tonic-gate T(addstr("\t\t\t\t\t", 5, &buf, &buflen)); 2137c478bd9Sstevel@tonic-gate T(len = ns_format_ttl(t, buf, buflen)); 2147c478bd9Sstevel@tonic-gate addlen(len, &buf, &buflen); 2157c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 16, spaced, &buf, &buflen)); 2167c478bd9Sstevel@tonic-gate T(addstr("; refresh\n", 10, &buf, &buflen)); 2177c478bd9Sstevel@tonic-gate spaced = 0; 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate /* Retry interval. */ 2207c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 2217c478bd9Sstevel@tonic-gate T(addstr("\t\t\t\t\t", 5, &buf, &buflen)); 2227c478bd9Sstevel@tonic-gate T(len = ns_format_ttl(t, buf, buflen)); 2237c478bd9Sstevel@tonic-gate addlen(len, &buf, &buflen); 2247c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 16, spaced, &buf, &buflen)); 2257c478bd9Sstevel@tonic-gate T(addstr("; retry\n", 8, &buf, &buflen)); 2267c478bd9Sstevel@tonic-gate spaced = 0; 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate /* Expiry. */ 2297c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 2307c478bd9Sstevel@tonic-gate T(addstr("\t\t\t\t\t", 5, &buf, &buflen)); 2317c478bd9Sstevel@tonic-gate T(len = ns_format_ttl(t, buf, buflen)); 2327c478bd9Sstevel@tonic-gate addlen(len, &buf, &buflen); 2337c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 16, spaced, &buf, &buflen)); 2347c478bd9Sstevel@tonic-gate T(addstr("; expiry\n", 9, &buf, &buflen)); 2357c478bd9Sstevel@tonic-gate spaced = 0; 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate /* Minimum TTL. */ 2387c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 2397c478bd9Sstevel@tonic-gate T(addstr("\t\t\t\t\t", 5, &buf, &buflen)); 2407c478bd9Sstevel@tonic-gate T(len = ns_format_ttl(t, buf, buflen)); 2417c478bd9Sstevel@tonic-gate addlen(len, &buf, &buflen); 2427c478bd9Sstevel@tonic-gate T(addstr(" )", 2, &buf, &buflen)); 2437c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 16, spaced, &buf, &buflen)); 2447c478bd9Sstevel@tonic-gate T(addstr("; minimum\n", 10, &buf, &buflen)); 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate break; 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate case ns_t_mx: 2507c478bd9Sstevel@tonic-gate case ns_t_afsdb: 2519525b14bSRao Shoaib case ns_t_rt: 2529525b14bSRao Shoaib case ns_t_kx: { 2537c478bd9Sstevel@tonic-gate u_int t; 2547c478bd9Sstevel@tonic-gate 2559525b14bSRao Shoaib if (rdlen < (size_t)NS_INT16SZ) 2567c478bd9Sstevel@tonic-gate goto formerr; 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate /* Priority. */ 2597c478bd9Sstevel@tonic-gate t = ns_get16(rdata); 2607c478bd9Sstevel@tonic-gate rdata += NS_INT16SZ; 2617c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%u ", t)); 2627c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* Target. */ 2657c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate break; 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate case ns_t_px: { 2717c478bd9Sstevel@tonic-gate u_int t; 2727c478bd9Sstevel@tonic-gate 2739525b14bSRao Shoaib if (rdlen < (size_t)NS_INT16SZ) 2747c478bd9Sstevel@tonic-gate goto formerr; 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate /* Priority. */ 2777c478bd9Sstevel@tonic-gate t = ns_get16(rdata); 2787c478bd9Sstevel@tonic-gate rdata += NS_INT16SZ; 2797c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%u ", t)); 2807c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate /* Name1. */ 2837c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 2847c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate /* Name2. */ 2877c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate break; 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate case ns_t_x25: 2937c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 2947c478bd9Sstevel@tonic-gate if (len == 0) 2957c478bd9Sstevel@tonic-gate goto formerr; 2967c478bd9Sstevel@tonic-gate rdata += len; 2977c478bd9Sstevel@tonic-gate break; 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate case ns_t_txt: 3009525b14bSRao Shoaib case ns_t_spf: 3017c478bd9Sstevel@tonic-gate while (rdata < edata) { 3027c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 3037c478bd9Sstevel@tonic-gate if (len == 0) 3047c478bd9Sstevel@tonic-gate goto formerr; 3057c478bd9Sstevel@tonic-gate rdata += len; 3067c478bd9Sstevel@tonic-gate if (rdata < edata) 3077c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate break; 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate case ns_t_nsap: { 3127c478bd9Sstevel@tonic-gate char t[2+255*3]; 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate (void) inet_nsap_ntoa(rdlen, rdata, t); 3157c478bd9Sstevel@tonic-gate T(addstr(t, strlen(t), &buf, &buflen)); 3167c478bd9Sstevel@tonic-gate break; 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate case ns_t_aaaa: 3209525b14bSRao Shoaib if (rdlen != (size_t)NS_IN6ADDRSZ) 3217c478bd9Sstevel@tonic-gate goto formerr; 3227c478bd9Sstevel@tonic-gate (void) inet_ntop(AF_INET6, rdata, buf, buflen); 3237c478bd9Sstevel@tonic-gate addlen(strlen(buf), &buf, &buflen); 3247c478bd9Sstevel@tonic-gate break; 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate case ns_t_loc: { 3277c478bd9Sstevel@tonic-gate char t[255]; 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate /* XXX protocol format checking? */ 3307c478bd9Sstevel@tonic-gate (void) loc_ntoa(rdata, t); 3317c478bd9Sstevel@tonic-gate T(addstr(t, strlen(t), &buf, &buflen)); 3327c478bd9Sstevel@tonic-gate break; 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate case ns_t_naptr: { 3367c478bd9Sstevel@tonic-gate u_int order, preference; 3377c478bd9Sstevel@tonic-gate char t[50]; 3387c478bd9Sstevel@tonic-gate 3399525b14bSRao Shoaib if (rdlen < 2U*NS_INT16SZ) 3407c478bd9Sstevel@tonic-gate goto formerr; 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate /* Order, Precedence. */ 3437c478bd9Sstevel@tonic-gate order = ns_get16(rdata); rdata += NS_INT16SZ; 3447c478bd9Sstevel@tonic-gate preference = ns_get16(rdata); rdata += NS_INT16SZ; 3457c478bd9Sstevel@tonic-gate len = SPRINTF((t, "%u %u ", order, preference)); 3467c478bd9Sstevel@tonic-gate T(addstr(t, len, &buf, &buflen)); 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate /* Flags. */ 3497c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 3507c478bd9Sstevel@tonic-gate if (len == 0) 3517c478bd9Sstevel@tonic-gate goto formerr; 3527c478bd9Sstevel@tonic-gate rdata += len; 3537c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate /* Service. */ 3567c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 3577c478bd9Sstevel@tonic-gate if (len == 0) 3587c478bd9Sstevel@tonic-gate goto formerr; 3597c478bd9Sstevel@tonic-gate rdata += len; 3607c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate /* Regexp. */ 3637c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 3647c478bd9Sstevel@tonic-gate if (len < 0) 3657c478bd9Sstevel@tonic-gate return (-1); 3667c478bd9Sstevel@tonic-gate if (len == 0) 3677c478bd9Sstevel@tonic-gate goto formerr; 3687c478bd9Sstevel@tonic-gate rdata += len; 3697c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate /* Server. */ 3727c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 3737c478bd9Sstevel@tonic-gate break; 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate case ns_t_srv: { 3777c478bd9Sstevel@tonic-gate u_int priority, weight, port; 3787c478bd9Sstevel@tonic-gate char t[50]; 3797c478bd9Sstevel@tonic-gate 3809525b14bSRao Shoaib if (rdlen < 3U*NS_INT16SZ) 3817c478bd9Sstevel@tonic-gate goto formerr; 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate /* Priority, Weight, Port. */ 3847c478bd9Sstevel@tonic-gate priority = ns_get16(rdata); rdata += NS_INT16SZ; 3857c478bd9Sstevel@tonic-gate weight = ns_get16(rdata); rdata += NS_INT16SZ; 3867c478bd9Sstevel@tonic-gate port = ns_get16(rdata); rdata += NS_INT16SZ; 3877c478bd9Sstevel@tonic-gate len = SPRINTF((t, "%u %u %u ", priority, weight, port)); 3887c478bd9Sstevel@tonic-gate T(addstr(t, len, &buf, &buflen)); 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate /* Server. */ 3917c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 3927c478bd9Sstevel@tonic-gate break; 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate case ns_t_minfo: 3967c478bd9Sstevel@tonic-gate case ns_t_rp: 3977c478bd9Sstevel@tonic-gate /* Name1. */ 3987c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 3997c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate /* Name2. */ 4027c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate break; 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate case ns_t_wks: { 4077c478bd9Sstevel@tonic-gate int n, lcnt; 4087c478bd9Sstevel@tonic-gate 4099525b14bSRao Shoaib if (rdlen < 1U + NS_INT32SZ) 4107c478bd9Sstevel@tonic-gate goto formerr; 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate /* Address. */ 4137c478bd9Sstevel@tonic-gate (void) inet_ntop(AF_INET, rdata, buf, buflen); 4147c478bd9Sstevel@tonic-gate addlen(strlen(buf), &buf, &buflen); 4157c478bd9Sstevel@tonic-gate rdata += NS_INADDRSZ; 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate /* Protocol. */ 4187c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, " %u ( ", *rdata)); 4197c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 4207c478bd9Sstevel@tonic-gate rdata += NS_INT8SZ; 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate /* Bit map. */ 4237c478bd9Sstevel@tonic-gate n = 0; 4247c478bd9Sstevel@tonic-gate lcnt = 0; 4257c478bd9Sstevel@tonic-gate while (rdata < edata) { 4267c478bd9Sstevel@tonic-gate u_int c = *rdata++; 4277c478bd9Sstevel@tonic-gate do { 4287c478bd9Sstevel@tonic-gate if (c & 0200) { 4297c478bd9Sstevel@tonic-gate if (lcnt == 0) { 4307c478bd9Sstevel@tonic-gate T(addstr("\n\t\t\t\t", 5, 4317c478bd9Sstevel@tonic-gate &buf, &buflen)); 4327c478bd9Sstevel@tonic-gate lcnt = 10; 4337c478bd9Sstevel@tonic-gate spaced = 0; 4347c478bd9Sstevel@tonic-gate } 4357c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%d ", n)); 4367c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 4377c478bd9Sstevel@tonic-gate lcnt--; 4387c478bd9Sstevel@tonic-gate } 4397c478bd9Sstevel@tonic-gate c <<= 1; 4407c478bd9Sstevel@tonic-gate } while (++n & 07); 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate T(addstr(")", 1, &buf, &buflen)); 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate break; 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate 4479525b14bSRao Shoaib case ns_t_key: 4489525b14bSRao Shoaib case ns_t_dnskey: { 4497c478bd9Sstevel@tonic-gate char base64_key[NS_MD5RSA_MAX_BASE64]; 4507c478bd9Sstevel@tonic-gate u_int keyflags, protocol, algorithm, key_id; 4517c478bd9Sstevel@tonic-gate const char *leader; 4527c478bd9Sstevel@tonic-gate int n; 4537c478bd9Sstevel@tonic-gate 4549525b14bSRao Shoaib if (rdlen < 0U + NS_INT16SZ + NS_INT8SZ + NS_INT8SZ) 4557c478bd9Sstevel@tonic-gate goto formerr; 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate /* Key flags, Protocol, Algorithm. */ 4587c478bd9Sstevel@tonic-gate key_id = dst_s_dns_key_id(rdata, edata-rdata); 4597c478bd9Sstevel@tonic-gate keyflags = ns_get16(rdata); rdata += NS_INT16SZ; 4607c478bd9Sstevel@tonic-gate protocol = *rdata++; 4617c478bd9Sstevel@tonic-gate algorithm = *rdata++; 4627c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "0x%04x %u %u", 4637c478bd9Sstevel@tonic-gate keyflags, protocol, algorithm)); 4647c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate /* Public key data. */ 4677c478bd9Sstevel@tonic-gate len = b64_ntop(rdata, edata - rdata, 4687c478bd9Sstevel@tonic-gate base64_key, sizeof base64_key); 4697c478bd9Sstevel@tonic-gate if (len < 0) 4707c478bd9Sstevel@tonic-gate goto formerr; 4717c478bd9Sstevel@tonic-gate if (len > 15) { 4727c478bd9Sstevel@tonic-gate T(addstr(" (", 2, &buf, &buflen)); 4737c478bd9Sstevel@tonic-gate leader = "\n\t\t"; 4747c478bd9Sstevel@tonic-gate spaced = 0; 4757c478bd9Sstevel@tonic-gate } else 4767c478bd9Sstevel@tonic-gate leader = " "; 4777c478bd9Sstevel@tonic-gate for (n = 0; n < len; n += 48) { 4787c478bd9Sstevel@tonic-gate T(addstr(leader, strlen(leader), &buf, &buflen)); 4797c478bd9Sstevel@tonic-gate T(addstr(base64_key + n, MIN(len - n, 48), 4807c478bd9Sstevel@tonic-gate &buf, &buflen)); 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate if (len > 15) 4837c478bd9Sstevel@tonic-gate T(addstr(" )", 2, &buf, &buflen)); 4847c478bd9Sstevel@tonic-gate n = SPRINTF((tmp, " ; key_tag= %u", key_id)); 4857c478bd9Sstevel@tonic-gate T(addstr(tmp, n, &buf, &buflen)); 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate break; 4887c478bd9Sstevel@tonic-gate } 4897c478bd9Sstevel@tonic-gate 4909525b14bSRao Shoaib case ns_t_sig: 4919525b14bSRao Shoaib case ns_t_rrsig: { 4927c478bd9Sstevel@tonic-gate char base64_key[NS_MD5RSA_MAX_BASE64]; 4937c478bd9Sstevel@tonic-gate u_int type, algorithm, labels, footprint; 4947c478bd9Sstevel@tonic-gate const char *leader; 4957c478bd9Sstevel@tonic-gate u_long t; 4967c478bd9Sstevel@tonic-gate int n; 4977c478bd9Sstevel@tonic-gate 4989525b14bSRao Shoaib if (rdlen < 22U) 4997c478bd9Sstevel@tonic-gate goto formerr; 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate /* Type covered, Algorithm, Label count, Original TTL. */ 5029525b14bSRao Shoaib type = ns_get16(rdata); rdata += NS_INT16SZ; 5037c478bd9Sstevel@tonic-gate algorithm = *rdata++; 5047c478bd9Sstevel@tonic-gate labels = *rdata++; 5057c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 5067c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%s %d %d %lu ", 5077c478bd9Sstevel@tonic-gate p_type(type), algorithm, labels, t)); 5087c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 5097c478bd9Sstevel@tonic-gate if (labels > (u_int)dn_count_labels(name)) 5107c478bd9Sstevel@tonic-gate goto formerr; 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate /* Signature expiry. */ 5137c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 5147c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%s ", p_secstodate(t))); 5157c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate /* Time signed. */ 5187c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 5197c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%s ", p_secstodate(t))); 5207c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate /* Signature Footprint. */ 5237c478bd9Sstevel@tonic-gate footprint = ns_get16(rdata); rdata += NS_INT16SZ; 5247c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%u ", footprint)); 5257c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate /* Signer's name. */ 5287c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate /* Signature. */ 5317c478bd9Sstevel@tonic-gate len = b64_ntop(rdata, edata - rdata, 5327c478bd9Sstevel@tonic-gate base64_key, sizeof base64_key); 5337c478bd9Sstevel@tonic-gate if (len > 15) { 5347c478bd9Sstevel@tonic-gate T(addstr(" (", 2, &buf, &buflen)); 5357c478bd9Sstevel@tonic-gate leader = "\n\t\t"; 5367c478bd9Sstevel@tonic-gate spaced = 0; 5377c478bd9Sstevel@tonic-gate } else 5387c478bd9Sstevel@tonic-gate leader = " "; 5397c478bd9Sstevel@tonic-gate if (len < 0) 5407c478bd9Sstevel@tonic-gate goto formerr; 5417c478bd9Sstevel@tonic-gate for (n = 0; n < len; n += 48) { 5427c478bd9Sstevel@tonic-gate T(addstr(leader, strlen(leader), &buf, &buflen)); 5437c478bd9Sstevel@tonic-gate T(addstr(base64_key + n, MIN(len - n, 48), 5447c478bd9Sstevel@tonic-gate &buf, &buflen)); 5457c478bd9Sstevel@tonic-gate } 5467c478bd9Sstevel@tonic-gate if (len > 15) 5477c478bd9Sstevel@tonic-gate T(addstr(" )", 2, &buf, &buflen)); 5487c478bd9Sstevel@tonic-gate break; 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate case ns_t_nxt: { 5527c478bd9Sstevel@tonic-gate int n, c; 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate /* Next domain name. */ 5557c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate /* Type bit map. */ 5587c478bd9Sstevel@tonic-gate n = edata - rdata; 5597c478bd9Sstevel@tonic-gate for (c = 0; c < n*8; c++) 5607c478bd9Sstevel@tonic-gate if (NS_NXT_BIT_ISSET(c, rdata)) { 5617c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, " %s", p_type(c))); 5627c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate break; 5657c478bd9Sstevel@tonic-gate } 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate case ns_t_cert: { 5687c478bd9Sstevel@tonic-gate u_int c_type, key_tag, alg; 5697c478bd9Sstevel@tonic-gate int n; 5707c478bd9Sstevel@tonic-gate unsigned int siz; 5717c478bd9Sstevel@tonic-gate char base64_cert[8192], tmp[40]; 5727c478bd9Sstevel@tonic-gate const char *leader; 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate c_type = ns_get16(rdata); rdata += NS_INT16SZ; 5757c478bd9Sstevel@tonic-gate key_tag = ns_get16(rdata); rdata += NS_INT16SZ; 5767c478bd9Sstevel@tonic-gate alg = (u_int) *rdata++; 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%d %d %d ", c_type, key_tag, alg)); 5797c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 5807c478bd9Sstevel@tonic-gate siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */ 5817c478bd9Sstevel@tonic-gate if (siz > sizeof(base64_cert) * 3/4) { 5827c478bd9Sstevel@tonic-gate const char *str = "record too long to print"; 5837c478bd9Sstevel@tonic-gate T(addstr(str, strlen(str), &buf, &buflen)); 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate else { 5867c478bd9Sstevel@tonic-gate len = b64_ntop(rdata, edata-rdata, base64_cert, siz); 5877c478bd9Sstevel@tonic-gate 5887c478bd9Sstevel@tonic-gate if (len < 0) 5897c478bd9Sstevel@tonic-gate goto formerr; 5907c478bd9Sstevel@tonic-gate else if (len > 15) { 5917c478bd9Sstevel@tonic-gate T(addstr(" (", 2, &buf, &buflen)); 5927c478bd9Sstevel@tonic-gate leader = "\n\t\t"; 5937c478bd9Sstevel@tonic-gate spaced = 0; 5947c478bd9Sstevel@tonic-gate } 5957c478bd9Sstevel@tonic-gate else 5967c478bd9Sstevel@tonic-gate leader = " "; 5977c478bd9Sstevel@tonic-gate 5987c478bd9Sstevel@tonic-gate for (n = 0; n < len; n += 48) { 5997c478bd9Sstevel@tonic-gate T(addstr(leader, strlen(leader), 6007c478bd9Sstevel@tonic-gate &buf, &buflen)); 6017c478bd9Sstevel@tonic-gate T(addstr(base64_cert + n, MIN(len - n, 48), 6027c478bd9Sstevel@tonic-gate &buf, &buflen)); 6037c478bd9Sstevel@tonic-gate } 6047c478bd9Sstevel@tonic-gate if (len > 15) 6057c478bd9Sstevel@tonic-gate T(addstr(" )", 2, &buf, &buflen)); 6067c478bd9Sstevel@tonic-gate } 6077c478bd9Sstevel@tonic-gate break; 6087c478bd9Sstevel@tonic-gate } 6097c478bd9Sstevel@tonic-gate 6107c478bd9Sstevel@tonic-gate case ns_t_tkey: { 6117c478bd9Sstevel@tonic-gate /* KJD - need to complete this */ 6127c478bd9Sstevel@tonic-gate u_long t; 6137c478bd9Sstevel@tonic-gate int mode, err, keysize; 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate /* Algorithm name. */ 6167c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 6177c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate /* Inception. */ 6207c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 6217c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%s ", p_secstodate(t))); 6227c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate /* Experation. */ 6257c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 6267c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%s ", p_secstodate(t))); 6277c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate /* Mode , Error, Key Size. */ 6307c478bd9Sstevel@tonic-gate /* Priority, Weight, Port. */ 6317c478bd9Sstevel@tonic-gate mode = ns_get16(rdata); rdata += NS_INT16SZ; 6327c478bd9Sstevel@tonic-gate err = ns_get16(rdata); rdata += NS_INT16SZ; 6337c478bd9Sstevel@tonic-gate keysize = ns_get16(rdata); rdata += NS_INT16SZ; 6347c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%u %u %u ", mode, err, keysize)); 6357c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 6367c478bd9Sstevel@tonic-gate 6379525b14bSRao Shoaib /* XXX need to dump key, print otherdata length & other data */ 6387c478bd9Sstevel@tonic-gate break; 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate case ns_t_tsig: { 6427c478bd9Sstevel@tonic-gate /* BEW - need to complete this */ 6437c478bd9Sstevel@tonic-gate int n; 6447c478bd9Sstevel@tonic-gate 6457c478bd9Sstevel@tonic-gate T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen)); 6467c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 6479525b14bSRao Shoaib rdata += 8; /*%< time */ 6487c478bd9Sstevel@tonic-gate n = ns_get16(rdata); rdata += INT16SZ; 6499525b14bSRao Shoaib rdata += n; /*%< sig */ 6509525b14bSRao Shoaib n = ns_get16(rdata); rdata += INT16SZ; /*%< original id */ 6517c478bd9Sstevel@tonic-gate sprintf(buf, "%d", ns_get16(rdata)); 6527c478bd9Sstevel@tonic-gate rdata += INT16SZ; 6537c478bd9Sstevel@tonic-gate addlen(strlen(buf), &buf, &buflen); 6547c478bd9Sstevel@tonic-gate break; 6557c478bd9Sstevel@tonic-gate } 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate case ns_t_a6: { 6587c478bd9Sstevel@tonic-gate struct in6_addr a; 6597c478bd9Sstevel@tonic-gate int pbyte, pbit; 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate /* prefix length */ 6629525b14bSRao Shoaib if (rdlen == 0U) goto formerr; 6637c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%d ", *rdata)); 6647c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 6657c478bd9Sstevel@tonic-gate pbit = *rdata; 6667c478bd9Sstevel@tonic-gate if (pbit > 128) goto formerr; 6677c478bd9Sstevel@tonic-gate pbyte = (pbit & ~7) / 8; 6687c478bd9Sstevel@tonic-gate rdata++; 6697c478bd9Sstevel@tonic-gate 6707c478bd9Sstevel@tonic-gate /* address suffix: provided only when prefix len != 128 */ 6717c478bd9Sstevel@tonic-gate if (pbit < 128) { 6727c478bd9Sstevel@tonic-gate if (rdata + pbyte >= edata) goto formerr; 6737c478bd9Sstevel@tonic-gate memset(&a, 0, sizeof(a)); 6747c478bd9Sstevel@tonic-gate memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte); 6757c478bd9Sstevel@tonic-gate (void) inet_ntop(AF_INET6, &a, buf, buflen); 6767c478bd9Sstevel@tonic-gate addlen(strlen(buf), &buf, &buflen); 6777c478bd9Sstevel@tonic-gate rdata += sizeof(a) - pbyte; 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate /* prefix name: provided only when prefix len > 0 */ 6817c478bd9Sstevel@tonic-gate if (pbit == 0) 6827c478bd9Sstevel@tonic-gate break; 6837c478bd9Sstevel@tonic-gate if (rdata >= edata) goto formerr; 6847c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 6857c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate break; 6889525b14bSRao Shoaib } 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate case ns_t_opt: { 6917c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%u bytes", class)); 6927c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 6937c478bd9Sstevel@tonic-gate break; 6949525b14bSRao Shoaib } 6959525b14bSRao Shoaib 6969525b14bSRao Shoaib case ns_t_ds: 6979525b14bSRao Shoaib case ns_t_dlv: 6989525b14bSRao Shoaib case ns_t_sshfp: { 6999525b14bSRao Shoaib u_int t; 7009525b14bSRao Shoaib 7019525b14bSRao Shoaib if (type == ns_t_ds || type == ns_t_dlv) { 7029525b14bSRao Shoaib if (rdlen < 4U) goto formerr; 7039525b14bSRao Shoaib t = ns_get16(rdata); 7049525b14bSRao Shoaib rdata += NS_INT16SZ; 7059525b14bSRao Shoaib len = SPRINTF((tmp, "%u ", t)); 7069525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 7079525b14bSRao Shoaib } else 7089525b14bSRao Shoaib if (rdlen < 2U) goto formerr; 7099525b14bSRao Shoaib 7109525b14bSRao Shoaib len = SPRINTF((tmp, "%u ", *rdata)); 7119525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 7129525b14bSRao Shoaib rdata++; 7139525b14bSRao Shoaib 7149525b14bSRao Shoaib len = SPRINTF((tmp, "%u ", *rdata)); 7159525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 7169525b14bSRao Shoaib rdata++; 7179525b14bSRao Shoaib 7189525b14bSRao Shoaib while (rdata < edata) { 7199525b14bSRao Shoaib len = SPRINTF((tmp, "%02X", *rdata)); 7209525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 7219525b14bSRao Shoaib rdata++; 7229525b14bSRao Shoaib } 7239525b14bSRao Shoaib break; 7249525b14bSRao Shoaib } 7259525b14bSRao Shoaib 7269525b14bSRao Shoaib case ns_t_nsec3: 7279525b14bSRao Shoaib case ns_t_nsec3param: { 7289525b14bSRao Shoaib u_int t, w, l, j, k, c; 7299525b14bSRao Shoaib 7309525b14bSRao Shoaib len = SPRINTF((tmp, "%u ", *rdata)); 7319525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 7329525b14bSRao Shoaib rdata++; 7339525b14bSRao Shoaib 7349525b14bSRao Shoaib len = SPRINTF((tmp, "%u ", *rdata)); 7359525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 7369525b14bSRao Shoaib rdata++; 7379525b14bSRao Shoaib 7389525b14bSRao Shoaib t = ns_get16(rdata); 7399525b14bSRao Shoaib rdata += NS_INT16SZ; 7409525b14bSRao Shoaib len = SPRINTF((tmp, "%u ", t)); 7419525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 7429525b14bSRao Shoaib 7439525b14bSRao Shoaib t = *rdata++; 7449525b14bSRao Shoaib if (t == 0) { 7459525b14bSRao Shoaib T(addstr("-", 1, &buf, &buflen)); 7469525b14bSRao Shoaib } else { 7479525b14bSRao Shoaib while (t-- > 0) { 7489525b14bSRao Shoaib len = SPRINTF((tmp, "%02X", *rdata)); 7499525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 7509525b14bSRao Shoaib rdata++; 7519525b14bSRao Shoaib } 7529525b14bSRao Shoaib } 7539525b14bSRao Shoaib if (type == ns_t_nsec3param) 7549525b14bSRao Shoaib break; 7559525b14bSRao Shoaib T(addstr(" ", 1, &buf, &buflen)); 7569525b14bSRao Shoaib 7579525b14bSRao Shoaib t = *rdata++; 7589525b14bSRao Shoaib while (t > 0) { 7599525b14bSRao Shoaib switch (t) { 7609525b14bSRao Shoaib case 1: 7619525b14bSRao Shoaib tmp[0] = base32hex[((rdata[0]>>3)&0x1f)]; 7629525b14bSRao Shoaib tmp[1] = base32hex[((rdata[0]<<2)&0x1c)]; 7639525b14bSRao Shoaib tmp[2] = tmp[3] = tmp[4] = '='; 7649525b14bSRao Shoaib tmp[5] = tmp[6] = tmp[7] = '='; 7659525b14bSRao Shoaib break; 7669525b14bSRao Shoaib case 2: 7679525b14bSRao Shoaib tmp[0] = base32hex[((rdata[0]>>3)&0x1f)]; 7689525b14bSRao Shoaib tmp[1] = base32hex[((rdata[0]<<2)&0x1c)| 7699525b14bSRao Shoaib ((rdata[1]>>6)&0x03)]; 7709525b14bSRao Shoaib tmp[2] = base32hex[((rdata[1]>>1)&0x1f)]; 7719525b14bSRao Shoaib tmp[3] = base32hex[((rdata[1]<<4)&0x10)]; 7729525b14bSRao Shoaib tmp[4] = tmp[5] = tmp[6] = tmp[7] = '='; 7739525b14bSRao Shoaib break; 7749525b14bSRao Shoaib case 3: 7759525b14bSRao Shoaib tmp[0] = base32hex[((rdata[0]>>3)&0x1f)]; 7769525b14bSRao Shoaib tmp[1] = base32hex[((rdata[0]<<2)&0x1c)| 7779525b14bSRao Shoaib ((rdata[1]>>6)&0x03)]; 7789525b14bSRao Shoaib tmp[2] = base32hex[((rdata[1]>>1)&0x1f)]; 7799525b14bSRao Shoaib tmp[3] = base32hex[((rdata[1]<<4)&0x10)| 7809525b14bSRao Shoaib ((rdata[2]>>4)&0x0f)]; 7819525b14bSRao Shoaib tmp[4] = base32hex[((rdata[2]<<1)&0x1e)]; 7829525b14bSRao Shoaib tmp[5] = tmp[6] = tmp[7] = '='; 7839525b14bSRao Shoaib break; 7849525b14bSRao Shoaib case 4: 7859525b14bSRao Shoaib tmp[0] = base32hex[((rdata[0]>>3)&0x1f)]; 7869525b14bSRao Shoaib tmp[1] = base32hex[((rdata[0]<<2)&0x1c)| 7879525b14bSRao Shoaib ((rdata[1]>>6)&0x03)]; 7889525b14bSRao Shoaib tmp[2] = base32hex[((rdata[1]>>1)&0x1f)]; 7899525b14bSRao Shoaib tmp[3] = base32hex[((rdata[1]<<4)&0x10)| 7909525b14bSRao Shoaib ((rdata[2]>>4)&0x0f)]; 7919525b14bSRao Shoaib tmp[4] = base32hex[((rdata[2]<<1)&0x1e)| 7929525b14bSRao Shoaib ((rdata[3]>>7)&0x01)]; 7939525b14bSRao Shoaib tmp[5] = base32hex[((rdata[3]>>2)&0x1f)]; 7949525b14bSRao Shoaib tmp[6] = base32hex[(rdata[3]<<3)&0x18]; 7959525b14bSRao Shoaib tmp[7] = '='; 7969525b14bSRao Shoaib break; 7979525b14bSRao Shoaib default: 7989525b14bSRao Shoaib tmp[0] = base32hex[((rdata[0]>>3)&0x1f)]; 7999525b14bSRao Shoaib tmp[1] = base32hex[((rdata[0]<<2)&0x1c)| 8009525b14bSRao Shoaib ((rdata[1]>>6)&0x03)]; 8019525b14bSRao Shoaib tmp[2] = base32hex[((rdata[1]>>1)&0x1f)]; 8029525b14bSRao Shoaib tmp[3] = base32hex[((rdata[1]<<4)&0x10)| 8039525b14bSRao Shoaib ((rdata[2]>>4)&0x0f)]; 8049525b14bSRao Shoaib tmp[4] = base32hex[((rdata[2]<<1)&0x1e)| 8059525b14bSRao Shoaib ((rdata[3]>>7)&0x01)]; 8069525b14bSRao Shoaib tmp[5] = base32hex[((rdata[3]>>2)&0x1f)]; 8079525b14bSRao Shoaib tmp[6] = base32hex[((rdata[3]<<3)&0x18)| 8089525b14bSRao Shoaib ((rdata[4]>>5)&0x07)]; 8099525b14bSRao Shoaib tmp[7] = base32hex[(rdata[4]&0x1f)]; 8109525b14bSRao Shoaib break; 8119525b14bSRao Shoaib } 8129525b14bSRao Shoaib T(addstr(tmp, 8, &buf, &buflen)); 8139525b14bSRao Shoaib if (t >= 5) { 8149525b14bSRao Shoaib rdata += 5; 8159525b14bSRao Shoaib t -= 5; 8169525b14bSRao Shoaib } else { 8179525b14bSRao Shoaib rdata += t; 8189525b14bSRao Shoaib t -= t; 8199525b14bSRao Shoaib } 8209525b14bSRao Shoaib } 8219525b14bSRao Shoaib 8229525b14bSRao Shoaib while (rdata < edata) { 8239525b14bSRao Shoaib w = *rdata++; 8249525b14bSRao Shoaib l = *rdata++; 8259525b14bSRao Shoaib for (j = 0; j < l; j++) { 8269525b14bSRao Shoaib if (rdata[j] == 0) 8279525b14bSRao Shoaib continue; 8289525b14bSRao Shoaib for (k = 0; k < 8; k++) { 8299525b14bSRao Shoaib if ((rdata[j] & (0x80 >> k)) == 0) 8309525b14bSRao Shoaib continue; 8319525b14bSRao Shoaib c = w * 256 + j * 8 + k; 8329525b14bSRao Shoaib len = SPRINTF((tmp, " %s", p_type(c))); 8339525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 8349525b14bSRao Shoaib } 8359525b14bSRao Shoaib } 8369525b14bSRao Shoaib rdata += l; 8379525b14bSRao Shoaib } 8389525b14bSRao Shoaib break; 8399525b14bSRao Shoaib } 8409525b14bSRao Shoaib 8419525b14bSRao Shoaib case ns_t_nsec: { 8429525b14bSRao Shoaib u_int w, l, j, k, c; 8439525b14bSRao Shoaib 8449525b14bSRao Shoaib T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 8459525b14bSRao Shoaib 8469525b14bSRao Shoaib while (rdata < edata) { 8479525b14bSRao Shoaib w = *rdata++; 8489525b14bSRao Shoaib l = *rdata++; 8499525b14bSRao Shoaib for (j = 0; j < l; j++) { 8509525b14bSRao Shoaib if (rdata[j] == 0) 8519525b14bSRao Shoaib continue; 8529525b14bSRao Shoaib for (k = 0; k < 8; k++) { 8539525b14bSRao Shoaib if ((rdata[j] & (0x80 >> k)) == 0) 8549525b14bSRao Shoaib continue; 8559525b14bSRao Shoaib c = w * 256 + j * 8 + k; 8569525b14bSRao Shoaib len = SPRINTF((tmp, " %s", p_type(c))); 8579525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 8589525b14bSRao Shoaib } 8599525b14bSRao Shoaib } 8609525b14bSRao Shoaib rdata += l; 8619525b14bSRao Shoaib } 8629525b14bSRao Shoaib break; 8639525b14bSRao Shoaib } 8649525b14bSRao Shoaib 8659525b14bSRao Shoaib case ns_t_dhcid: { 8669525b14bSRao Shoaib int n; 8679525b14bSRao Shoaib unsigned int siz; 8689525b14bSRao Shoaib char base64_dhcid[8192]; 8699525b14bSRao Shoaib const char *leader; 8709525b14bSRao Shoaib 8719525b14bSRao Shoaib siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */ 8729525b14bSRao Shoaib if (siz > sizeof(base64_dhcid) * 3/4) { 8739525b14bSRao Shoaib const char *str = "record too long to print"; 8749525b14bSRao Shoaib T(addstr(str, strlen(str), &buf, &buflen)); 8759525b14bSRao Shoaib } else { 8769525b14bSRao Shoaib len = b64_ntop(rdata, edata-rdata, base64_dhcid, siz); 8779525b14bSRao Shoaib 8789525b14bSRao Shoaib if (len < 0) 8799525b14bSRao Shoaib goto formerr; 8809525b14bSRao Shoaib 8819525b14bSRao Shoaib else if (len > 15) { 8829525b14bSRao Shoaib T(addstr(" (", 2, &buf, &buflen)); 8839525b14bSRao Shoaib leader = "\n\t\t"; 8849525b14bSRao Shoaib spaced = 0; 8859525b14bSRao Shoaib } 8869525b14bSRao Shoaib else 8879525b14bSRao Shoaib leader = " "; 8889525b14bSRao Shoaib 8899525b14bSRao Shoaib for (n = 0; n < len; n += 48) { 8909525b14bSRao Shoaib T(addstr(leader, strlen(leader), 8919525b14bSRao Shoaib &buf, &buflen)); 8929525b14bSRao Shoaib T(addstr(base64_dhcid + n, MIN(len - n, 48), 8939525b14bSRao Shoaib &buf, &buflen)); 8949525b14bSRao Shoaib } 8959525b14bSRao Shoaib if (len > 15) 8969525b14bSRao Shoaib T(addstr(" )", 2, &buf, &buflen)); 8979525b14bSRao Shoaib } 898*a5d83f5bSJohn Levon break; 8999525b14bSRao Shoaib } 9009525b14bSRao Shoaib 9019525b14bSRao Shoaib case ns_t_ipseckey: { 9029525b14bSRao Shoaib int n; 9039525b14bSRao Shoaib unsigned int siz; 9049525b14bSRao Shoaib char base64_key[8192]; 9059525b14bSRao Shoaib const char *leader; 9069525b14bSRao Shoaib 9079525b14bSRao Shoaib if (rdlen < 2) 9089525b14bSRao Shoaib goto formerr; 9099525b14bSRao Shoaib 9109525b14bSRao Shoaib switch (rdata[1]) { 9119525b14bSRao Shoaib case 0: 9129525b14bSRao Shoaib case 3: 9139525b14bSRao Shoaib if (rdlen < 3) 9149525b14bSRao Shoaib goto formerr; 9159525b14bSRao Shoaib break; 9169525b14bSRao Shoaib case 1: 9179525b14bSRao Shoaib if (rdlen < 7) 9189525b14bSRao Shoaib goto formerr; 9199525b14bSRao Shoaib break; 9209525b14bSRao Shoaib case 2: 9219525b14bSRao Shoaib if (rdlen < 19) 9229525b14bSRao Shoaib goto formerr; 9239525b14bSRao Shoaib break; 9249525b14bSRao Shoaib default: 9259525b14bSRao Shoaib comment = "unknown IPSECKEY gateway type"; 9269525b14bSRao Shoaib goto hexify; 9279525b14bSRao Shoaib } 9289525b14bSRao Shoaib 9299525b14bSRao Shoaib len = SPRINTF((tmp, "%u ", *rdata)); 9309525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 9319525b14bSRao Shoaib rdata++; 9329525b14bSRao Shoaib 9339525b14bSRao Shoaib len = SPRINTF((tmp, "%u ", *rdata)); 9349525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 9359525b14bSRao Shoaib rdata++; 9369525b14bSRao Shoaib 9379525b14bSRao Shoaib len = SPRINTF((tmp, "%u ", *rdata)); 9389525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 9399525b14bSRao Shoaib rdata++; 9409525b14bSRao Shoaib 9419525b14bSRao Shoaib switch (rdata[-2]) { 9429525b14bSRao Shoaib case 0: 9439525b14bSRao Shoaib T(addstr(".", 1, &buf, &buflen)); 9449525b14bSRao Shoaib break; 9459525b14bSRao Shoaib case 1: 9469525b14bSRao Shoaib (void) inet_ntop(AF_INET, rdata, buf, buflen); 9479525b14bSRao Shoaib addlen(strlen(buf), &buf, &buflen); 9489525b14bSRao Shoaib rdata += 4; 9499525b14bSRao Shoaib break; 9509525b14bSRao Shoaib case 2: 9519525b14bSRao Shoaib (void) inet_ntop(AF_INET6, rdata, buf, buflen); 9529525b14bSRao Shoaib addlen(strlen(buf), &buf, &buflen); 9539525b14bSRao Shoaib rdata += 16; 9549525b14bSRao Shoaib break; 9559525b14bSRao Shoaib case 3: 9569525b14bSRao Shoaib T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 9579525b14bSRao Shoaib break; 9589525b14bSRao Shoaib } 9599525b14bSRao Shoaib 9609525b14bSRao Shoaib if (rdata >= edata) 9619525b14bSRao Shoaib break; 9629525b14bSRao Shoaib 9639525b14bSRao Shoaib siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */ 9649525b14bSRao Shoaib if (siz > sizeof(base64_key) * 3/4) { 9659525b14bSRao Shoaib const char *str = "record too long to print"; 9669525b14bSRao Shoaib T(addstr(str, strlen(str), &buf, &buflen)); 9679525b14bSRao Shoaib } else { 9689525b14bSRao Shoaib len = b64_ntop(rdata, edata-rdata, base64_key, siz); 9699525b14bSRao Shoaib 9709525b14bSRao Shoaib if (len < 0) 9719525b14bSRao Shoaib goto formerr; 9729525b14bSRao Shoaib 9739525b14bSRao Shoaib else if (len > 15) { 9749525b14bSRao Shoaib T(addstr(" (", 2, &buf, &buflen)); 9759525b14bSRao Shoaib leader = "\n\t\t"; 9769525b14bSRao Shoaib spaced = 0; 9779525b14bSRao Shoaib } 9789525b14bSRao Shoaib else 9799525b14bSRao Shoaib leader = " "; 9809525b14bSRao Shoaib 9819525b14bSRao Shoaib for (n = 0; n < len; n += 48) { 9829525b14bSRao Shoaib T(addstr(leader, strlen(leader), 9839525b14bSRao Shoaib &buf, &buflen)); 9849525b14bSRao Shoaib T(addstr(base64_key + n, MIN(len - n, 48), 9859525b14bSRao Shoaib &buf, &buflen)); 9869525b14bSRao Shoaib } 9879525b14bSRao Shoaib if (len > 15) 9889525b14bSRao Shoaib T(addstr(" )", 2, &buf, &buflen)); 9899525b14bSRao Shoaib } 990*a5d83f5bSJohn Levon break; 9919525b14bSRao Shoaib } 9929525b14bSRao Shoaib 9939525b14bSRao Shoaib case ns_t_hip: { 9949525b14bSRao Shoaib unsigned int i, hip_len, algorithm, key_len; 9959525b14bSRao Shoaib char base64_key[NS_MD5RSA_MAX_BASE64]; 9969525b14bSRao Shoaib unsigned int siz; 9979525b14bSRao Shoaib const char *leader = "\n\t\t\t\t\t"; 9989525b14bSRao Shoaib 9999525b14bSRao Shoaib hip_len = *rdata++; 10009525b14bSRao Shoaib algorithm = *rdata++; 10019525b14bSRao Shoaib key_len = ns_get16(rdata); 10029525b14bSRao Shoaib rdata += NS_INT16SZ; 10039525b14bSRao Shoaib 10049525b14bSRao Shoaib siz = key_len*4/3 + 4; /* "+4" accounts for trailing \0 */ 10059525b14bSRao Shoaib if (siz > sizeof(base64_key) * 3/4) { 10069525b14bSRao Shoaib const char *str = "record too long to print"; 10079525b14bSRao Shoaib T(addstr(str, strlen(str), &buf, &buflen)); 10089525b14bSRao Shoaib } else { 10099525b14bSRao Shoaib len = sprintf(tmp, "( %u ", algorithm); 10109525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 10119525b14bSRao Shoaib 10129525b14bSRao Shoaib for (i = 0; i < hip_len; i++) { 10139525b14bSRao Shoaib len = sprintf(tmp, "%02X", *rdata); 10149525b14bSRao Shoaib T(addstr(tmp, len, &buf, &buflen)); 10159525b14bSRao Shoaib rdata++; 10169525b14bSRao Shoaib } 10179525b14bSRao Shoaib T(addstr(leader, strlen(leader), &buf, &buflen)); 10189525b14bSRao Shoaib 10199525b14bSRao Shoaib len = b64_ntop(rdata, key_len, base64_key, siz); 10209525b14bSRao Shoaib if (len < 0) 10219525b14bSRao Shoaib goto formerr; 10229525b14bSRao Shoaib 10239525b14bSRao Shoaib T(addstr(base64_key, len, &buf, &buflen)); 10249525b14bSRao Shoaib 10259525b14bSRao Shoaib rdata += key_len; 10269525b14bSRao Shoaib while (rdata < edata) { 10279525b14bSRao Shoaib T(addstr(leader, strlen(leader), &buf, &buflen)); 10289525b14bSRao Shoaib T(addname(msg, msglen, &rdata, origin, 10299525b14bSRao Shoaib &buf, &buflen)); 10309525b14bSRao Shoaib } 10319525b14bSRao Shoaib T(addstr(" )", 2, &buf, &buflen)); 10329525b14bSRao Shoaib } 10339525b14bSRao Shoaib break; 10347c478bd9Sstevel@tonic-gate } 10357c478bd9Sstevel@tonic-gate 10367c478bd9Sstevel@tonic-gate default: 10377c478bd9Sstevel@tonic-gate comment = "unknown RR type"; 10387c478bd9Sstevel@tonic-gate goto hexify; 10397c478bd9Sstevel@tonic-gate } 10407c478bd9Sstevel@tonic-gate return (buf - obuf); 10417c478bd9Sstevel@tonic-gate formerr: 10427c478bd9Sstevel@tonic-gate comment = "RR format error"; 10437c478bd9Sstevel@tonic-gate hexify: { 10447c478bd9Sstevel@tonic-gate int n, m; 10457c478bd9Sstevel@tonic-gate char *p; 10467c478bd9Sstevel@tonic-gate 10479525b14bSRao Shoaib len = SPRINTF((tmp, "\\# %u%s\t; %s", (unsigned)(edata - rdata), 10489525b14bSRao Shoaib rdlen != 0U ? " (" : "", comment)); 10497c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 10507c478bd9Sstevel@tonic-gate while (rdata < edata) { 10517c478bd9Sstevel@tonic-gate p = tmp; 10527c478bd9Sstevel@tonic-gate p += SPRINTF((p, "\n\t")); 10537c478bd9Sstevel@tonic-gate spaced = 0; 10547c478bd9Sstevel@tonic-gate n = MIN(16, edata - rdata); 10557c478bd9Sstevel@tonic-gate for (m = 0; m < n; m++) 10567c478bd9Sstevel@tonic-gate p += SPRINTF((p, "%02x ", rdata[m])); 10577c478bd9Sstevel@tonic-gate T(addstr(tmp, p - tmp, &buf, &buflen)); 10587c478bd9Sstevel@tonic-gate if (n < 16) { 10597c478bd9Sstevel@tonic-gate T(addstr(")", 1, &buf, &buflen)); 10607c478bd9Sstevel@tonic-gate T(addtab(p - tmp + 1, 48, spaced, &buf, &buflen)); 10617c478bd9Sstevel@tonic-gate } 10627c478bd9Sstevel@tonic-gate p = tmp; 10637c478bd9Sstevel@tonic-gate p += SPRINTF((p, "; ")); 10647c478bd9Sstevel@tonic-gate for (m = 0; m < n; m++) 10657c478bd9Sstevel@tonic-gate *p++ = (isascii(rdata[m]) && isprint(rdata[m])) 10667c478bd9Sstevel@tonic-gate ? rdata[m] 10677c478bd9Sstevel@tonic-gate : '.'; 10687c478bd9Sstevel@tonic-gate T(addstr(tmp, p - tmp, &buf, &buflen)); 10697c478bd9Sstevel@tonic-gate rdata += n; 10707c478bd9Sstevel@tonic-gate } 10717c478bd9Sstevel@tonic-gate return (buf - obuf); 10727c478bd9Sstevel@tonic-gate } 10737c478bd9Sstevel@tonic-gate } 10747c478bd9Sstevel@tonic-gate 10757c478bd9Sstevel@tonic-gate /* Private. */ 10767c478bd9Sstevel@tonic-gate 10779525b14bSRao Shoaib /*% 10787c478bd9Sstevel@tonic-gate * size_t 10797c478bd9Sstevel@tonic-gate * prune_origin(name, origin) 10807c478bd9Sstevel@tonic-gate * Find out if the name is at or under the current origin. 10817c478bd9Sstevel@tonic-gate * return: 10827c478bd9Sstevel@tonic-gate * Number of characters in name before start of origin, 10837c478bd9Sstevel@tonic-gate * or length of name if origin does not match. 10847c478bd9Sstevel@tonic-gate * notes: 10857c478bd9Sstevel@tonic-gate * This function should share code with samedomain(). 10867c478bd9Sstevel@tonic-gate */ 10877c478bd9Sstevel@tonic-gate static size_t 10887c478bd9Sstevel@tonic-gate prune_origin(const char *name, const char *origin) { 10897c478bd9Sstevel@tonic-gate const char *oname = name; 10907c478bd9Sstevel@tonic-gate 10917c478bd9Sstevel@tonic-gate while (*name != '\0') { 10927c478bd9Sstevel@tonic-gate if (origin != NULL && ns_samename(name, origin) == 1) 10937c478bd9Sstevel@tonic-gate return (name - oname - (name > oname)); 10947c478bd9Sstevel@tonic-gate while (*name != '\0') { 10957c478bd9Sstevel@tonic-gate if (*name == '\\') { 10967c478bd9Sstevel@tonic-gate name++; 10977c478bd9Sstevel@tonic-gate /* XXX need to handle \nnn form. */ 10987c478bd9Sstevel@tonic-gate if (*name == '\0') 10997c478bd9Sstevel@tonic-gate break; 11007c478bd9Sstevel@tonic-gate } else if (*name == '.') { 11017c478bd9Sstevel@tonic-gate name++; 11027c478bd9Sstevel@tonic-gate break; 11037c478bd9Sstevel@tonic-gate } 11047c478bd9Sstevel@tonic-gate name++; 11057c478bd9Sstevel@tonic-gate } 11067c478bd9Sstevel@tonic-gate } 11077c478bd9Sstevel@tonic-gate return (name - oname); 11087c478bd9Sstevel@tonic-gate } 11097c478bd9Sstevel@tonic-gate 11109525b14bSRao Shoaib /*% 11117c478bd9Sstevel@tonic-gate * int 11127c478bd9Sstevel@tonic-gate * charstr(rdata, edata, buf, buflen) 11137c478bd9Sstevel@tonic-gate * Format a <character-string> into the presentation buffer. 11147c478bd9Sstevel@tonic-gate * return: 11157c478bd9Sstevel@tonic-gate * Number of rdata octets consumed 11167c478bd9Sstevel@tonic-gate * 0 for protocol format error 11177c478bd9Sstevel@tonic-gate * -1 for output buffer error 11187c478bd9Sstevel@tonic-gate * side effects: 11197c478bd9Sstevel@tonic-gate * buffer is advanced on success. 11207c478bd9Sstevel@tonic-gate */ 11217c478bd9Sstevel@tonic-gate static int 11227c478bd9Sstevel@tonic-gate charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) { 11237c478bd9Sstevel@tonic-gate const u_char *odata = rdata; 11247c478bd9Sstevel@tonic-gate size_t save_buflen = *buflen; 11257c478bd9Sstevel@tonic-gate char *save_buf = *buf; 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate if (addstr("\"", 1, buf, buflen) < 0) 11287c478bd9Sstevel@tonic-gate goto enospc; 11297c478bd9Sstevel@tonic-gate if (rdata < edata) { 11307c478bd9Sstevel@tonic-gate int n = *rdata; 11317c478bd9Sstevel@tonic-gate 11327c478bd9Sstevel@tonic-gate if (rdata + 1 + n <= edata) { 11337c478bd9Sstevel@tonic-gate rdata++; 11347c478bd9Sstevel@tonic-gate while (n-- > 0) { 11357c478bd9Sstevel@tonic-gate if (strchr("\n\"\\", *rdata) != NULL) 11367c478bd9Sstevel@tonic-gate if (addstr("\\", 1, buf, buflen) < 0) 11377c478bd9Sstevel@tonic-gate goto enospc; 11387c478bd9Sstevel@tonic-gate if (addstr((const char *)rdata, 1, 11397c478bd9Sstevel@tonic-gate buf, buflen) < 0) 11407c478bd9Sstevel@tonic-gate goto enospc; 11417c478bd9Sstevel@tonic-gate rdata++; 11427c478bd9Sstevel@tonic-gate } 11437c478bd9Sstevel@tonic-gate } 11447c478bd9Sstevel@tonic-gate } 11457c478bd9Sstevel@tonic-gate if (addstr("\"", 1, buf, buflen) < 0) 11467c478bd9Sstevel@tonic-gate goto enospc; 11477c478bd9Sstevel@tonic-gate return (rdata - odata); 11487c478bd9Sstevel@tonic-gate enospc: 11497c478bd9Sstevel@tonic-gate errno = ENOSPC; 11507c478bd9Sstevel@tonic-gate *buf = save_buf; 11517c478bd9Sstevel@tonic-gate *buflen = save_buflen; 11527c478bd9Sstevel@tonic-gate return (-1); 11537c478bd9Sstevel@tonic-gate } 11547c478bd9Sstevel@tonic-gate 11557c478bd9Sstevel@tonic-gate static int 11567c478bd9Sstevel@tonic-gate addname(const u_char *msg, size_t msglen, 11577c478bd9Sstevel@tonic-gate const u_char **pp, const char *origin, 11587c478bd9Sstevel@tonic-gate char **buf, size_t *buflen) 11597c478bd9Sstevel@tonic-gate { 11607c478bd9Sstevel@tonic-gate size_t newlen, save_buflen = *buflen; 11617c478bd9Sstevel@tonic-gate char *save_buf = *buf; 11627c478bd9Sstevel@tonic-gate int n; 11637c478bd9Sstevel@tonic-gate 11647c478bd9Sstevel@tonic-gate n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen); 11657c478bd9Sstevel@tonic-gate if (n < 0) 11669525b14bSRao Shoaib goto enospc; /*%< Guess. */ 11677c478bd9Sstevel@tonic-gate newlen = prune_origin(*buf, origin); 11687c478bd9Sstevel@tonic-gate if (**buf == '\0') { 11697c478bd9Sstevel@tonic-gate goto root; 11709525b14bSRao Shoaib } else if (newlen == 0U) { 11717c478bd9Sstevel@tonic-gate /* Use "@" instead of name. */ 11727c478bd9Sstevel@tonic-gate if (newlen + 2 > *buflen) 11737c478bd9Sstevel@tonic-gate goto enospc; /* No room for "@\0". */ 11747c478bd9Sstevel@tonic-gate (*buf)[newlen++] = '@'; 11757c478bd9Sstevel@tonic-gate (*buf)[newlen] = '\0'; 11767c478bd9Sstevel@tonic-gate } else { 11777c478bd9Sstevel@tonic-gate if (((origin == NULL || origin[0] == '\0') || 11787c478bd9Sstevel@tonic-gate (origin[0] != '.' && origin[1] != '\0' && 11797c478bd9Sstevel@tonic-gate (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') { 11807c478bd9Sstevel@tonic-gate /* No trailing dot. */ 11817c478bd9Sstevel@tonic-gate root: 11827c478bd9Sstevel@tonic-gate if (newlen + 2 > *buflen) 11837c478bd9Sstevel@tonic-gate goto enospc; /* No room for ".\0". */ 11847c478bd9Sstevel@tonic-gate (*buf)[newlen++] = '.'; 11857c478bd9Sstevel@tonic-gate (*buf)[newlen] = '\0'; 11867c478bd9Sstevel@tonic-gate } 11877c478bd9Sstevel@tonic-gate } 11887c478bd9Sstevel@tonic-gate *pp += n; 11897c478bd9Sstevel@tonic-gate addlen(newlen, buf, buflen); 11907c478bd9Sstevel@tonic-gate **buf = '\0'; 11917c478bd9Sstevel@tonic-gate return (newlen); 11927c478bd9Sstevel@tonic-gate enospc: 11937c478bd9Sstevel@tonic-gate errno = ENOSPC; 11947c478bd9Sstevel@tonic-gate *buf = save_buf; 11957c478bd9Sstevel@tonic-gate *buflen = save_buflen; 11967c478bd9Sstevel@tonic-gate return (-1); 11977c478bd9Sstevel@tonic-gate } 11987c478bd9Sstevel@tonic-gate 11997c478bd9Sstevel@tonic-gate static void 12007c478bd9Sstevel@tonic-gate addlen(size_t len, char **buf, size_t *buflen) { 12017c478bd9Sstevel@tonic-gate INSIST(len <= *buflen); 12027c478bd9Sstevel@tonic-gate *buf += len; 12037c478bd9Sstevel@tonic-gate *buflen -= len; 12047c478bd9Sstevel@tonic-gate } 12057c478bd9Sstevel@tonic-gate 12067c478bd9Sstevel@tonic-gate static int 12077c478bd9Sstevel@tonic-gate addstr(const char *src, size_t len, char **buf, size_t *buflen) { 12087c478bd9Sstevel@tonic-gate if (len >= *buflen) { 12097c478bd9Sstevel@tonic-gate errno = ENOSPC; 12107c478bd9Sstevel@tonic-gate return (-1); 12117c478bd9Sstevel@tonic-gate } 12127c478bd9Sstevel@tonic-gate memcpy(*buf, src, len); 12137c478bd9Sstevel@tonic-gate addlen(len, buf, buflen); 12147c478bd9Sstevel@tonic-gate **buf = '\0'; 12157c478bd9Sstevel@tonic-gate return (0); 12167c478bd9Sstevel@tonic-gate } 12177c478bd9Sstevel@tonic-gate 12187c478bd9Sstevel@tonic-gate static int 12197c478bd9Sstevel@tonic-gate addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) { 12207c478bd9Sstevel@tonic-gate size_t save_buflen = *buflen; 12217c478bd9Sstevel@tonic-gate char *save_buf = *buf; 12227c478bd9Sstevel@tonic-gate int t; 12237c478bd9Sstevel@tonic-gate 12247c478bd9Sstevel@tonic-gate if (spaced || len >= target - 1) { 12257c478bd9Sstevel@tonic-gate T(addstr(" ", 2, buf, buflen)); 12267c478bd9Sstevel@tonic-gate spaced = 1; 12277c478bd9Sstevel@tonic-gate } else { 12287c478bd9Sstevel@tonic-gate for (t = (target - len - 1) / 8; t >= 0; t--) 12297c478bd9Sstevel@tonic-gate if (addstr("\t", 1, buf, buflen) < 0) { 12307c478bd9Sstevel@tonic-gate *buflen = save_buflen; 12317c478bd9Sstevel@tonic-gate *buf = save_buf; 12327c478bd9Sstevel@tonic-gate return (-1); 12337c478bd9Sstevel@tonic-gate } 12347c478bd9Sstevel@tonic-gate spaced = 0; 12357c478bd9Sstevel@tonic-gate } 12367c478bd9Sstevel@tonic-gate return (spaced); 12377c478bd9Sstevel@tonic-gate } 12389525b14bSRao Shoaib 12399525b14bSRao Shoaib /*! \file */ 1240