1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate /* 7*7c478bd9Sstevel@tonic-gate * Copyright (c) 1996-1999 by Internet Software Consortium. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 10*7c478bd9Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 11*7c478bd9Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 12*7c478bd9Sstevel@tonic-gate * 13*7c478bd9Sstevel@tonic-gate * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 14*7c478bd9Sstevel@tonic-gate * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 15*7c478bd9Sstevel@tonic-gate * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 16*7c478bd9Sstevel@tonic-gate * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 17*7c478bd9Sstevel@tonic-gate * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 18*7c478bd9Sstevel@tonic-gate * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 19*7c478bd9Sstevel@tonic-gate * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20*7c478bd9Sstevel@tonic-gate * SOFTWARE. 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate 23*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate #ifndef lint 26*7c478bd9Sstevel@tonic-gate static const char rcsid[] = "$Id: ns_print.c,v 8.26 2003/02/24 23:56:35 vixie Exp $"; 27*7c478bd9Sstevel@tonic-gate #endif 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* Import. */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #include "port_before.h" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/socket.h> 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 37*7c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 38*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #include <isc/assertions.h> 41*7c478bd9Sstevel@tonic-gate #include <isc/dst.h> 42*7c478bd9Sstevel@tonic-gate #include <errno.h> 43*7c478bd9Sstevel@tonic-gate #include <resolv.h> 44*7c478bd9Sstevel@tonic-gate #include <string.h> 45*7c478bd9Sstevel@tonic-gate #include <ctype.h> 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate #include "port_after.h" 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate #ifdef SPRINTF_CHAR 50*7c478bd9Sstevel@tonic-gate # define SPRINTF(x) strlen(sprintf/**/x) 51*7c478bd9Sstevel@tonic-gate #else 52*7c478bd9Sstevel@tonic-gate # define SPRINTF(x) ((size_t)sprintf x) 53*7c478bd9Sstevel@tonic-gate #endif 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate /* Forward. */ 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate static size_t prune_origin(const char *name, const char *origin); 58*7c478bd9Sstevel@tonic-gate static int charstr(const u_char *rdata, const u_char *edata, 59*7c478bd9Sstevel@tonic-gate char **buf, size_t *buflen); 60*7c478bd9Sstevel@tonic-gate static int addname(const u_char *msg, size_t msglen, 61*7c478bd9Sstevel@tonic-gate const u_char **p, const char *origin, 62*7c478bd9Sstevel@tonic-gate char **buf, size_t *buflen); 63*7c478bd9Sstevel@tonic-gate static void addlen(size_t len, char **buf, size_t *buflen); 64*7c478bd9Sstevel@tonic-gate static int addstr(const char *src, size_t len, 65*7c478bd9Sstevel@tonic-gate char **buf, size_t *buflen); 66*7c478bd9Sstevel@tonic-gate static int addtab(size_t len, size_t target, int spaced, 67*7c478bd9Sstevel@tonic-gate char **buf, size_t *buflen); 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate #ifdef ORIGINAL_ISC_CODE 70*7c478bd9Sstevel@tonic-gate #else 71*7c478bd9Sstevel@tonic-gate /* Proto. */ 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate u_int16_t dst_s_dns_key_id(const u_char *, const int); 74*7c478bd9Sstevel@tonic-gate #endif 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate /* Macros. */ 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate #define T(x) \ 79*7c478bd9Sstevel@tonic-gate do { \ 80*7c478bd9Sstevel@tonic-gate if ((x) < 0) \ 81*7c478bd9Sstevel@tonic-gate return (-1); \ 82*7c478bd9Sstevel@tonic-gate } while (0) 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate /* Public. */ 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate /* 87*7c478bd9Sstevel@tonic-gate * int 88*7c478bd9Sstevel@tonic-gate * ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen) 89*7c478bd9Sstevel@tonic-gate * Convert an RR to presentation format. 90*7c478bd9Sstevel@tonic-gate * return: 91*7c478bd9Sstevel@tonic-gate * Number of characters written to buf, or -1 (check errno). 92*7c478bd9Sstevel@tonic-gate */ 93*7c478bd9Sstevel@tonic-gate int 94*7c478bd9Sstevel@tonic-gate ns_sprintrr(const ns_msg *handle, const ns_rr *rr, 95*7c478bd9Sstevel@tonic-gate const char *name_ctx, const char *origin, 96*7c478bd9Sstevel@tonic-gate char *buf, size_t buflen) 97*7c478bd9Sstevel@tonic-gate { 98*7c478bd9Sstevel@tonic-gate int n; 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle), 101*7c478bd9Sstevel@tonic-gate ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr), 102*7c478bd9Sstevel@tonic-gate ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr), 103*7c478bd9Sstevel@tonic-gate name_ctx, origin, buf, buflen); 104*7c478bd9Sstevel@tonic-gate return (n); 105*7c478bd9Sstevel@tonic-gate } 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate /* 108*7c478bd9Sstevel@tonic-gate * int 109*7c478bd9Sstevel@tonic-gate * ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen, 110*7c478bd9Sstevel@tonic-gate * name_ctx, origin, buf, buflen) 111*7c478bd9Sstevel@tonic-gate * Convert the fields of an RR into presentation format. 112*7c478bd9Sstevel@tonic-gate * return: 113*7c478bd9Sstevel@tonic-gate * Number of characters written to buf, or -1 (check errno). 114*7c478bd9Sstevel@tonic-gate */ 115*7c478bd9Sstevel@tonic-gate int 116*7c478bd9Sstevel@tonic-gate ns_sprintrrf(const u_char *msg, size_t msglen, 117*7c478bd9Sstevel@tonic-gate const char *name, ns_class class, ns_type type, 118*7c478bd9Sstevel@tonic-gate u_long ttl, const u_char *rdata, size_t rdlen, 119*7c478bd9Sstevel@tonic-gate const char *name_ctx, const char *origin, 120*7c478bd9Sstevel@tonic-gate char *buf, size_t buflen) 121*7c478bd9Sstevel@tonic-gate { 122*7c478bd9Sstevel@tonic-gate const char *obuf = buf; 123*7c478bd9Sstevel@tonic-gate const u_char *edata = rdata + rdlen; 124*7c478bd9Sstevel@tonic-gate int spaced = 0; 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate const char *comment; 127*7c478bd9Sstevel@tonic-gate char tmp[100]; 128*7c478bd9Sstevel@tonic-gate int len, x; 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* 131*7c478bd9Sstevel@tonic-gate * Owner. 132*7c478bd9Sstevel@tonic-gate */ 133*7c478bd9Sstevel@tonic-gate if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) { 134*7c478bd9Sstevel@tonic-gate T(addstr("\t\t\t", 3, &buf, &buflen)); 135*7c478bd9Sstevel@tonic-gate } else { 136*7c478bd9Sstevel@tonic-gate len = prune_origin(name, origin); 137*7c478bd9Sstevel@tonic-gate if (*name == '\0') { 138*7c478bd9Sstevel@tonic-gate goto root; 139*7c478bd9Sstevel@tonic-gate } else if (len == 0) { 140*7c478bd9Sstevel@tonic-gate T(addstr("@\t\t\t", 4, &buf, &buflen)); 141*7c478bd9Sstevel@tonic-gate } else { 142*7c478bd9Sstevel@tonic-gate T(addstr(name, len, &buf, &buflen)); 143*7c478bd9Sstevel@tonic-gate /* Origin not used or not root, and no trailing dot? */ 144*7c478bd9Sstevel@tonic-gate if (((origin == NULL || origin[0] == '\0') || 145*7c478bd9Sstevel@tonic-gate (origin[0] != '.' && origin[1] != '\0' && 146*7c478bd9Sstevel@tonic-gate name[len] == '\0')) && name[len - 1] != '.') { 147*7c478bd9Sstevel@tonic-gate root: 148*7c478bd9Sstevel@tonic-gate T(addstr(".", 1, &buf, &buflen)); 149*7c478bd9Sstevel@tonic-gate len++; 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 24, spaced, &buf, &buflen)); 152*7c478bd9Sstevel@tonic-gate } 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate /* 156*7c478bd9Sstevel@tonic-gate * TTL, Class, Type. 157*7c478bd9Sstevel@tonic-gate */ 158*7c478bd9Sstevel@tonic-gate T(x = ns_format_ttl(ttl, buf, buflen)); 159*7c478bd9Sstevel@tonic-gate addlen(x, &buf, &buflen); 160*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type))); 161*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 162*7c478bd9Sstevel@tonic-gate if (rdlen == 0) 163*7c478bd9Sstevel@tonic-gate return (buf - obuf); 164*7c478bd9Sstevel@tonic-gate T(spaced = addtab(x + len, 16, spaced, &buf, &buflen)); 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate * RData. 168*7c478bd9Sstevel@tonic-gate */ 169*7c478bd9Sstevel@tonic-gate switch (type) { 170*7c478bd9Sstevel@tonic-gate case ns_t_a: 171*7c478bd9Sstevel@tonic-gate if (rdlen != NS_INADDRSZ) 172*7c478bd9Sstevel@tonic-gate goto formerr; 173*7c478bd9Sstevel@tonic-gate (void) inet_ntop(AF_INET, rdata, buf, buflen); 174*7c478bd9Sstevel@tonic-gate addlen(strlen(buf), &buf, &buflen); 175*7c478bd9Sstevel@tonic-gate break; 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate case ns_t_cname: 178*7c478bd9Sstevel@tonic-gate case ns_t_mb: 179*7c478bd9Sstevel@tonic-gate case ns_t_mg: 180*7c478bd9Sstevel@tonic-gate case ns_t_mr: 181*7c478bd9Sstevel@tonic-gate case ns_t_ns: 182*7c478bd9Sstevel@tonic-gate case ns_t_ptr: 183*7c478bd9Sstevel@tonic-gate case ns_t_dname: 184*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 185*7c478bd9Sstevel@tonic-gate break; 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate case ns_t_hinfo: 188*7c478bd9Sstevel@tonic-gate case ns_t_isdn: 189*7c478bd9Sstevel@tonic-gate /* First word. */ 190*7c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 191*7c478bd9Sstevel@tonic-gate if (len == 0) 192*7c478bd9Sstevel@tonic-gate goto formerr; 193*7c478bd9Sstevel@tonic-gate rdata += len; 194*7c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate /* Second word, optional in ISDN records. */ 198*7c478bd9Sstevel@tonic-gate if (type == ns_t_isdn && rdata == edata) 199*7c478bd9Sstevel@tonic-gate break; 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 202*7c478bd9Sstevel@tonic-gate if (len == 0) 203*7c478bd9Sstevel@tonic-gate goto formerr; 204*7c478bd9Sstevel@tonic-gate rdata += len; 205*7c478bd9Sstevel@tonic-gate break; 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate case ns_t_soa: { 208*7c478bd9Sstevel@tonic-gate u_long t; 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate /* Server name. */ 211*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 212*7c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate /* Administrator name. */ 215*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 216*7c478bd9Sstevel@tonic-gate T(addstr(" (\n", 3, &buf, &buflen)); 217*7c478bd9Sstevel@tonic-gate spaced = 0; 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate if ((edata - rdata) != 5*NS_INT32SZ) 220*7c478bd9Sstevel@tonic-gate goto formerr; 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate /* Serial number. */ 223*7c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 224*7c478bd9Sstevel@tonic-gate T(addstr("\t\t\t\t\t", 5, &buf, &buflen)); 225*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%lu", t)); 226*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 227*7c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 16, spaced, &buf, &buflen)); 228*7c478bd9Sstevel@tonic-gate T(addstr("; serial\n", 9, &buf, &buflen)); 229*7c478bd9Sstevel@tonic-gate spaced = 0; 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate /* Refresh interval. */ 232*7c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 233*7c478bd9Sstevel@tonic-gate T(addstr("\t\t\t\t\t", 5, &buf, &buflen)); 234*7c478bd9Sstevel@tonic-gate T(len = ns_format_ttl(t, buf, buflen)); 235*7c478bd9Sstevel@tonic-gate addlen(len, &buf, &buflen); 236*7c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 16, spaced, &buf, &buflen)); 237*7c478bd9Sstevel@tonic-gate T(addstr("; refresh\n", 10, &buf, &buflen)); 238*7c478bd9Sstevel@tonic-gate spaced = 0; 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate /* Retry interval. */ 241*7c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 242*7c478bd9Sstevel@tonic-gate T(addstr("\t\t\t\t\t", 5, &buf, &buflen)); 243*7c478bd9Sstevel@tonic-gate T(len = ns_format_ttl(t, buf, buflen)); 244*7c478bd9Sstevel@tonic-gate addlen(len, &buf, &buflen); 245*7c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 16, spaced, &buf, &buflen)); 246*7c478bd9Sstevel@tonic-gate T(addstr("; retry\n", 8, &buf, &buflen)); 247*7c478bd9Sstevel@tonic-gate spaced = 0; 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate /* Expiry. */ 250*7c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 251*7c478bd9Sstevel@tonic-gate T(addstr("\t\t\t\t\t", 5, &buf, &buflen)); 252*7c478bd9Sstevel@tonic-gate T(len = ns_format_ttl(t, buf, buflen)); 253*7c478bd9Sstevel@tonic-gate addlen(len, &buf, &buflen); 254*7c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 16, spaced, &buf, &buflen)); 255*7c478bd9Sstevel@tonic-gate T(addstr("; expiry\n", 9, &buf, &buflen)); 256*7c478bd9Sstevel@tonic-gate spaced = 0; 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate /* Minimum TTL. */ 259*7c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 260*7c478bd9Sstevel@tonic-gate T(addstr("\t\t\t\t\t", 5, &buf, &buflen)); 261*7c478bd9Sstevel@tonic-gate T(len = ns_format_ttl(t, buf, buflen)); 262*7c478bd9Sstevel@tonic-gate addlen(len, &buf, &buflen); 263*7c478bd9Sstevel@tonic-gate T(addstr(" )", 2, &buf, &buflen)); 264*7c478bd9Sstevel@tonic-gate T(spaced = addtab(len, 16, spaced, &buf, &buflen)); 265*7c478bd9Sstevel@tonic-gate T(addstr("; minimum\n", 10, &buf, &buflen)); 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate break; 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate case ns_t_mx: 271*7c478bd9Sstevel@tonic-gate case ns_t_afsdb: 272*7c478bd9Sstevel@tonic-gate case ns_t_rt: { 273*7c478bd9Sstevel@tonic-gate u_int t; 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate if (rdlen < NS_INT16SZ) 276*7c478bd9Sstevel@tonic-gate goto formerr; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate /* Priority. */ 279*7c478bd9Sstevel@tonic-gate t = ns_get16(rdata); 280*7c478bd9Sstevel@tonic-gate rdata += NS_INT16SZ; 281*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%u ", t)); 282*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate /* Target. */ 285*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate break; 288*7c478bd9Sstevel@tonic-gate } 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate case ns_t_px: { 291*7c478bd9Sstevel@tonic-gate u_int t; 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate if (rdlen < NS_INT16SZ) 294*7c478bd9Sstevel@tonic-gate goto formerr; 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate /* Priority. */ 297*7c478bd9Sstevel@tonic-gate t = ns_get16(rdata); 298*7c478bd9Sstevel@tonic-gate rdata += NS_INT16SZ; 299*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%u ", t)); 300*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate /* Name1. */ 303*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 304*7c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate /* Name2. */ 307*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate break; 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate case ns_t_x25: 313*7c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 314*7c478bd9Sstevel@tonic-gate if (len == 0) 315*7c478bd9Sstevel@tonic-gate goto formerr; 316*7c478bd9Sstevel@tonic-gate rdata += len; 317*7c478bd9Sstevel@tonic-gate break; 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate case ns_t_txt: 320*7c478bd9Sstevel@tonic-gate while (rdata < edata) { 321*7c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 322*7c478bd9Sstevel@tonic-gate if (len == 0) 323*7c478bd9Sstevel@tonic-gate goto formerr; 324*7c478bd9Sstevel@tonic-gate rdata += len; 325*7c478bd9Sstevel@tonic-gate if (rdata < edata) 326*7c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate break; 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate case ns_t_nsap: { 331*7c478bd9Sstevel@tonic-gate char t[2+255*3]; 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate (void) inet_nsap_ntoa(rdlen, rdata, t); 334*7c478bd9Sstevel@tonic-gate T(addstr(t, strlen(t), &buf, &buflen)); 335*7c478bd9Sstevel@tonic-gate break; 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate case ns_t_aaaa: 339*7c478bd9Sstevel@tonic-gate if (rdlen != NS_IN6ADDRSZ) 340*7c478bd9Sstevel@tonic-gate goto formerr; 341*7c478bd9Sstevel@tonic-gate (void) inet_ntop(AF_INET6, rdata, buf, buflen); 342*7c478bd9Sstevel@tonic-gate addlen(strlen(buf), &buf, &buflen); 343*7c478bd9Sstevel@tonic-gate break; 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate case ns_t_loc: { 346*7c478bd9Sstevel@tonic-gate char t[255]; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate /* XXX protocol format checking? */ 349*7c478bd9Sstevel@tonic-gate (void) loc_ntoa(rdata, t); 350*7c478bd9Sstevel@tonic-gate T(addstr(t, strlen(t), &buf, &buflen)); 351*7c478bd9Sstevel@tonic-gate break; 352*7c478bd9Sstevel@tonic-gate } 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate case ns_t_naptr: { 355*7c478bd9Sstevel@tonic-gate u_int order, preference; 356*7c478bd9Sstevel@tonic-gate char t[50]; 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate if (rdlen < 2*NS_INT16SZ) 359*7c478bd9Sstevel@tonic-gate goto formerr; 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate /* Order, Precedence. */ 362*7c478bd9Sstevel@tonic-gate order = ns_get16(rdata); rdata += NS_INT16SZ; 363*7c478bd9Sstevel@tonic-gate preference = ns_get16(rdata); rdata += NS_INT16SZ; 364*7c478bd9Sstevel@tonic-gate len = SPRINTF((t, "%u %u ", order, preference)); 365*7c478bd9Sstevel@tonic-gate T(addstr(t, len, &buf, &buflen)); 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate /* Flags. */ 368*7c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 369*7c478bd9Sstevel@tonic-gate if (len == 0) 370*7c478bd9Sstevel@tonic-gate goto formerr; 371*7c478bd9Sstevel@tonic-gate rdata += len; 372*7c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 373*7c478bd9Sstevel@tonic-gate 374*7c478bd9Sstevel@tonic-gate /* Service. */ 375*7c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 376*7c478bd9Sstevel@tonic-gate if (len == 0) 377*7c478bd9Sstevel@tonic-gate goto formerr; 378*7c478bd9Sstevel@tonic-gate rdata += len; 379*7c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate /* Regexp. */ 382*7c478bd9Sstevel@tonic-gate T(len = charstr(rdata, edata, &buf, &buflen)); 383*7c478bd9Sstevel@tonic-gate if (len < 0) 384*7c478bd9Sstevel@tonic-gate return (-1); 385*7c478bd9Sstevel@tonic-gate if (len == 0) 386*7c478bd9Sstevel@tonic-gate goto formerr; 387*7c478bd9Sstevel@tonic-gate rdata += len; 388*7c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate /* Server. */ 391*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 392*7c478bd9Sstevel@tonic-gate break; 393*7c478bd9Sstevel@tonic-gate } 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate case ns_t_srv: { 396*7c478bd9Sstevel@tonic-gate u_int priority, weight, port; 397*7c478bd9Sstevel@tonic-gate char t[50]; 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate if (rdlen < NS_INT16SZ*3) 400*7c478bd9Sstevel@tonic-gate goto formerr; 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate /* Priority, Weight, Port. */ 403*7c478bd9Sstevel@tonic-gate priority = ns_get16(rdata); rdata += NS_INT16SZ; 404*7c478bd9Sstevel@tonic-gate weight = ns_get16(rdata); rdata += NS_INT16SZ; 405*7c478bd9Sstevel@tonic-gate port = ns_get16(rdata); rdata += NS_INT16SZ; 406*7c478bd9Sstevel@tonic-gate len = SPRINTF((t, "%u %u %u ", priority, weight, port)); 407*7c478bd9Sstevel@tonic-gate T(addstr(t, len, &buf, &buflen)); 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate /* Server. */ 410*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 411*7c478bd9Sstevel@tonic-gate break; 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate case ns_t_minfo: 415*7c478bd9Sstevel@tonic-gate case ns_t_rp: 416*7c478bd9Sstevel@tonic-gate /* Name1. */ 417*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 418*7c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 419*7c478bd9Sstevel@tonic-gate 420*7c478bd9Sstevel@tonic-gate /* Name2. */ 421*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate break; 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate case ns_t_wks: { 426*7c478bd9Sstevel@tonic-gate int n, lcnt; 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate if (rdlen < NS_INT32SZ + 1) 429*7c478bd9Sstevel@tonic-gate goto formerr; 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate /* Address. */ 432*7c478bd9Sstevel@tonic-gate (void) inet_ntop(AF_INET, rdata, buf, buflen); 433*7c478bd9Sstevel@tonic-gate addlen(strlen(buf), &buf, &buflen); 434*7c478bd9Sstevel@tonic-gate rdata += NS_INADDRSZ; 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate /* Protocol. */ 437*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, " %u ( ", *rdata)); 438*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 439*7c478bd9Sstevel@tonic-gate rdata += NS_INT8SZ; 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate /* Bit map. */ 442*7c478bd9Sstevel@tonic-gate n = 0; 443*7c478bd9Sstevel@tonic-gate lcnt = 0; 444*7c478bd9Sstevel@tonic-gate while (rdata < edata) { 445*7c478bd9Sstevel@tonic-gate u_int c = *rdata++; 446*7c478bd9Sstevel@tonic-gate do { 447*7c478bd9Sstevel@tonic-gate if (c & 0200) { 448*7c478bd9Sstevel@tonic-gate if (lcnt == 0) { 449*7c478bd9Sstevel@tonic-gate T(addstr("\n\t\t\t\t", 5, 450*7c478bd9Sstevel@tonic-gate &buf, &buflen)); 451*7c478bd9Sstevel@tonic-gate lcnt = 10; 452*7c478bd9Sstevel@tonic-gate spaced = 0; 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%d ", n)); 455*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 456*7c478bd9Sstevel@tonic-gate lcnt--; 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate c <<= 1; 459*7c478bd9Sstevel@tonic-gate } while (++n & 07); 460*7c478bd9Sstevel@tonic-gate } 461*7c478bd9Sstevel@tonic-gate T(addstr(")", 1, &buf, &buflen)); 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate break; 464*7c478bd9Sstevel@tonic-gate } 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate case ns_t_key: { 467*7c478bd9Sstevel@tonic-gate char base64_key[NS_MD5RSA_MAX_BASE64]; 468*7c478bd9Sstevel@tonic-gate u_int keyflags, protocol, algorithm, key_id; 469*7c478bd9Sstevel@tonic-gate const char *leader; 470*7c478bd9Sstevel@tonic-gate int n; 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ) 473*7c478bd9Sstevel@tonic-gate goto formerr; 474*7c478bd9Sstevel@tonic-gate 475*7c478bd9Sstevel@tonic-gate /* Key flags, Protocol, Algorithm. */ 476*7c478bd9Sstevel@tonic-gate key_id = dst_s_dns_key_id(rdata, edata-rdata); 477*7c478bd9Sstevel@tonic-gate keyflags = ns_get16(rdata); rdata += NS_INT16SZ; 478*7c478bd9Sstevel@tonic-gate protocol = *rdata++; 479*7c478bd9Sstevel@tonic-gate algorithm = *rdata++; 480*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "0x%04x %u %u", 481*7c478bd9Sstevel@tonic-gate keyflags, protocol, algorithm)); 482*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate /* Public key data. */ 485*7c478bd9Sstevel@tonic-gate len = b64_ntop(rdata, edata - rdata, 486*7c478bd9Sstevel@tonic-gate base64_key, sizeof base64_key); 487*7c478bd9Sstevel@tonic-gate if (len < 0) 488*7c478bd9Sstevel@tonic-gate goto formerr; 489*7c478bd9Sstevel@tonic-gate if (len > 15) { 490*7c478bd9Sstevel@tonic-gate T(addstr(" (", 2, &buf, &buflen)); 491*7c478bd9Sstevel@tonic-gate leader = "\n\t\t"; 492*7c478bd9Sstevel@tonic-gate spaced = 0; 493*7c478bd9Sstevel@tonic-gate } else 494*7c478bd9Sstevel@tonic-gate leader = " "; 495*7c478bd9Sstevel@tonic-gate for (n = 0; n < len; n += 48) { 496*7c478bd9Sstevel@tonic-gate T(addstr(leader, strlen(leader), &buf, &buflen)); 497*7c478bd9Sstevel@tonic-gate T(addstr(base64_key + n, MIN(len - n, 48), 498*7c478bd9Sstevel@tonic-gate &buf, &buflen)); 499*7c478bd9Sstevel@tonic-gate } 500*7c478bd9Sstevel@tonic-gate if (len > 15) 501*7c478bd9Sstevel@tonic-gate T(addstr(" )", 2, &buf, &buflen)); 502*7c478bd9Sstevel@tonic-gate n = SPRINTF((tmp, " ; key_tag= %u", key_id)); 503*7c478bd9Sstevel@tonic-gate T(addstr(tmp, n, &buf, &buflen)); 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate break; 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate case ns_t_sig: { 509*7c478bd9Sstevel@tonic-gate char base64_key[NS_MD5RSA_MAX_BASE64]; 510*7c478bd9Sstevel@tonic-gate u_int type, algorithm, labels, footprint; 511*7c478bd9Sstevel@tonic-gate const char *leader; 512*7c478bd9Sstevel@tonic-gate u_long t; 513*7c478bd9Sstevel@tonic-gate int n; 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate if (rdlen < 22) 516*7c478bd9Sstevel@tonic-gate goto formerr; 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate /* Type covered, Algorithm, Label count, Original TTL. */ 519*7c478bd9Sstevel@tonic-gate type = ns_get16(rdata); rdata += NS_INT16SZ; 520*7c478bd9Sstevel@tonic-gate algorithm = *rdata++; 521*7c478bd9Sstevel@tonic-gate labels = *rdata++; 522*7c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 523*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%s %d %d %lu ", 524*7c478bd9Sstevel@tonic-gate p_type(type), algorithm, labels, t)); 525*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 526*7c478bd9Sstevel@tonic-gate if (labels > (u_int)dn_count_labels(name)) 527*7c478bd9Sstevel@tonic-gate goto formerr; 528*7c478bd9Sstevel@tonic-gate 529*7c478bd9Sstevel@tonic-gate /* Signature expiry. */ 530*7c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 531*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%s ", p_secstodate(t))); 532*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate /* Time signed. */ 535*7c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 536*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%s ", p_secstodate(t))); 537*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate /* Signature Footprint. */ 540*7c478bd9Sstevel@tonic-gate footprint = ns_get16(rdata); rdata += NS_INT16SZ; 541*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%u ", footprint)); 542*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate /* Signer's name. */ 545*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate /* Signature. */ 548*7c478bd9Sstevel@tonic-gate len = b64_ntop(rdata, edata - rdata, 549*7c478bd9Sstevel@tonic-gate base64_key, sizeof base64_key); 550*7c478bd9Sstevel@tonic-gate if (len > 15) { 551*7c478bd9Sstevel@tonic-gate T(addstr(" (", 2, &buf, &buflen)); 552*7c478bd9Sstevel@tonic-gate leader = "\n\t\t"; 553*7c478bd9Sstevel@tonic-gate spaced = 0; 554*7c478bd9Sstevel@tonic-gate } else 555*7c478bd9Sstevel@tonic-gate leader = " "; 556*7c478bd9Sstevel@tonic-gate if (len < 0) 557*7c478bd9Sstevel@tonic-gate goto formerr; 558*7c478bd9Sstevel@tonic-gate for (n = 0; n < len; n += 48) { 559*7c478bd9Sstevel@tonic-gate T(addstr(leader, strlen(leader), &buf, &buflen)); 560*7c478bd9Sstevel@tonic-gate T(addstr(base64_key + n, MIN(len - n, 48), 561*7c478bd9Sstevel@tonic-gate &buf, &buflen)); 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate if (len > 15) 564*7c478bd9Sstevel@tonic-gate T(addstr(" )", 2, &buf, &buflen)); 565*7c478bd9Sstevel@tonic-gate break; 566*7c478bd9Sstevel@tonic-gate } 567*7c478bd9Sstevel@tonic-gate 568*7c478bd9Sstevel@tonic-gate case ns_t_nxt: { 569*7c478bd9Sstevel@tonic-gate int n, c; 570*7c478bd9Sstevel@tonic-gate 571*7c478bd9Sstevel@tonic-gate /* Next domain name. */ 572*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 573*7c478bd9Sstevel@tonic-gate 574*7c478bd9Sstevel@tonic-gate /* Type bit map. */ 575*7c478bd9Sstevel@tonic-gate n = edata - rdata; 576*7c478bd9Sstevel@tonic-gate for (c = 0; c < n*8; c++) 577*7c478bd9Sstevel@tonic-gate if (NS_NXT_BIT_ISSET(c, rdata)) { 578*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, " %s", p_type(c))); 579*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate break; 582*7c478bd9Sstevel@tonic-gate } 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate case ns_t_cert: { 585*7c478bd9Sstevel@tonic-gate u_int c_type, key_tag, alg; 586*7c478bd9Sstevel@tonic-gate int n; 587*7c478bd9Sstevel@tonic-gate unsigned int siz; 588*7c478bd9Sstevel@tonic-gate char base64_cert[8192], tmp[40]; 589*7c478bd9Sstevel@tonic-gate const char *leader; 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate c_type = ns_get16(rdata); rdata += NS_INT16SZ; 592*7c478bd9Sstevel@tonic-gate key_tag = ns_get16(rdata); rdata += NS_INT16SZ; 593*7c478bd9Sstevel@tonic-gate alg = (u_int) *rdata++; 594*7c478bd9Sstevel@tonic-gate 595*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%d %d %d ", c_type, key_tag, alg)); 596*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 597*7c478bd9Sstevel@tonic-gate siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */ 598*7c478bd9Sstevel@tonic-gate if (siz > sizeof(base64_cert) * 3/4) { 599*7c478bd9Sstevel@tonic-gate const char *str = "record too long to print"; 600*7c478bd9Sstevel@tonic-gate T(addstr(str, strlen(str), &buf, &buflen)); 601*7c478bd9Sstevel@tonic-gate } 602*7c478bd9Sstevel@tonic-gate else { 603*7c478bd9Sstevel@tonic-gate len = b64_ntop(rdata, edata-rdata, base64_cert, siz); 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate if (len < 0) 606*7c478bd9Sstevel@tonic-gate goto formerr; 607*7c478bd9Sstevel@tonic-gate else if (len > 15) { 608*7c478bd9Sstevel@tonic-gate T(addstr(" (", 2, &buf, &buflen)); 609*7c478bd9Sstevel@tonic-gate leader = "\n\t\t"; 610*7c478bd9Sstevel@tonic-gate spaced = 0; 611*7c478bd9Sstevel@tonic-gate } 612*7c478bd9Sstevel@tonic-gate else 613*7c478bd9Sstevel@tonic-gate leader = " "; 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate for (n = 0; n < len; n += 48) { 616*7c478bd9Sstevel@tonic-gate T(addstr(leader, strlen(leader), 617*7c478bd9Sstevel@tonic-gate &buf, &buflen)); 618*7c478bd9Sstevel@tonic-gate T(addstr(base64_cert + n, MIN(len - n, 48), 619*7c478bd9Sstevel@tonic-gate &buf, &buflen)); 620*7c478bd9Sstevel@tonic-gate } 621*7c478bd9Sstevel@tonic-gate if (len > 15) 622*7c478bd9Sstevel@tonic-gate T(addstr(" )", 2, &buf, &buflen)); 623*7c478bd9Sstevel@tonic-gate } 624*7c478bd9Sstevel@tonic-gate break; 625*7c478bd9Sstevel@tonic-gate } 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate case ns_t_tkey: { 628*7c478bd9Sstevel@tonic-gate /* KJD - need to complete this */ 629*7c478bd9Sstevel@tonic-gate u_long t; 630*7c478bd9Sstevel@tonic-gate int mode, err, keysize; 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate /* Algorithm name. */ 633*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 634*7c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 635*7c478bd9Sstevel@tonic-gate 636*7c478bd9Sstevel@tonic-gate /* Inception. */ 637*7c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 638*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%s ", p_secstodate(t))); 639*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 640*7c478bd9Sstevel@tonic-gate 641*7c478bd9Sstevel@tonic-gate /* Experation. */ 642*7c478bd9Sstevel@tonic-gate t = ns_get32(rdata); rdata += NS_INT32SZ; 643*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%s ", p_secstodate(t))); 644*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 645*7c478bd9Sstevel@tonic-gate 646*7c478bd9Sstevel@tonic-gate /* Mode , Error, Key Size. */ 647*7c478bd9Sstevel@tonic-gate /* Priority, Weight, Port. */ 648*7c478bd9Sstevel@tonic-gate mode = ns_get16(rdata); rdata += NS_INT16SZ; 649*7c478bd9Sstevel@tonic-gate err = ns_get16(rdata); rdata += NS_INT16SZ; 650*7c478bd9Sstevel@tonic-gate keysize = ns_get16(rdata); rdata += NS_INT16SZ; 651*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%u %u %u ", mode, err, keysize)); 652*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 653*7c478bd9Sstevel@tonic-gate 654*7c478bd9Sstevel@tonic-gate /* need to dump key, print otherdata length & other data */ 655*7c478bd9Sstevel@tonic-gate break; 656*7c478bd9Sstevel@tonic-gate } 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate case ns_t_tsig: { 659*7c478bd9Sstevel@tonic-gate /* BEW - need to complete this */ 660*7c478bd9Sstevel@tonic-gate int n; 661*7c478bd9Sstevel@tonic-gate 662*7c478bd9Sstevel@tonic-gate T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen)); 663*7c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 664*7c478bd9Sstevel@tonic-gate rdata += 8; /* time */ 665*7c478bd9Sstevel@tonic-gate n = ns_get16(rdata); rdata += INT16SZ; 666*7c478bd9Sstevel@tonic-gate rdata += n; /* sig */ 667*7c478bd9Sstevel@tonic-gate n = ns_get16(rdata); rdata += INT16SZ; /* original id */ 668*7c478bd9Sstevel@tonic-gate sprintf(buf, "%d", ns_get16(rdata)); 669*7c478bd9Sstevel@tonic-gate rdata += INT16SZ; 670*7c478bd9Sstevel@tonic-gate addlen(strlen(buf), &buf, &buflen); 671*7c478bd9Sstevel@tonic-gate break; 672*7c478bd9Sstevel@tonic-gate } 673*7c478bd9Sstevel@tonic-gate 674*7c478bd9Sstevel@tonic-gate case ns_t_a6: { 675*7c478bd9Sstevel@tonic-gate struct in6_addr a; 676*7c478bd9Sstevel@tonic-gate int pbyte, pbit; 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate /* prefix length */ 679*7c478bd9Sstevel@tonic-gate if (rdlen == 0) goto formerr; 680*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%d ", *rdata)); 681*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 682*7c478bd9Sstevel@tonic-gate pbit = *rdata; 683*7c478bd9Sstevel@tonic-gate if (pbit > 128) goto formerr; 684*7c478bd9Sstevel@tonic-gate pbyte = (pbit & ~7) / 8; 685*7c478bd9Sstevel@tonic-gate rdata++; 686*7c478bd9Sstevel@tonic-gate 687*7c478bd9Sstevel@tonic-gate /* address suffix: provided only when prefix len != 128 */ 688*7c478bd9Sstevel@tonic-gate if (pbit < 128) { 689*7c478bd9Sstevel@tonic-gate if (rdata + pbyte >= edata) goto formerr; 690*7c478bd9Sstevel@tonic-gate memset(&a, 0, sizeof(a)); 691*7c478bd9Sstevel@tonic-gate memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte); 692*7c478bd9Sstevel@tonic-gate (void) inet_ntop(AF_INET6, &a, buf, buflen); 693*7c478bd9Sstevel@tonic-gate addlen(strlen(buf), &buf, &buflen); 694*7c478bd9Sstevel@tonic-gate rdata += sizeof(a) - pbyte; 695*7c478bd9Sstevel@tonic-gate } 696*7c478bd9Sstevel@tonic-gate 697*7c478bd9Sstevel@tonic-gate /* prefix name: provided only when prefix len > 0 */ 698*7c478bd9Sstevel@tonic-gate if (pbit == 0) 699*7c478bd9Sstevel@tonic-gate break; 700*7c478bd9Sstevel@tonic-gate if (rdata >= edata) goto formerr; 701*7c478bd9Sstevel@tonic-gate T(addstr(" ", 1, &buf, &buflen)); 702*7c478bd9Sstevel@tonic-gate T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 703*7c478bd9Sstevel@tonic-gate 704*7c478bd9Sstevel@tonic-gate break; 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate case ns_t_opt: { 708*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "%u bytes", class)); 709*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 710*7c478bd9Sstevel@tonic-gate break; 711*7c478bd9Sstevel@tonic-gate } 712*7c478bd9Sstevel@tonic-gate 713*7c478bd9Sstevel@tonic-gate default: 714*7c478bd9Sstevel@tonic-gate comment = "unknown RR type"; 715*7c478bd9Sstevel@tonic-gate goto hexify; 716*7c478bd9Sstevel@tonic-gate } 717*7c478bd9Sstevel@tonic-gate return (buf - obuf); 718*7c478bd9Sstevel@tonic-gate formerr: 719*7c478bd9Sstevel@tonic-gate comment = "RR format error"; 720*7c478bd9Sstevel@tonic-gate hexify: { 721*7c478bd9Sstevel@tonic-gate int n, m; 722*7c478bd9Sstevel@tonic-gate char *p; 723*7c478bd9Sstevel@tonic-gate 724*7c478bd9Sstevel@tonic-gate len = SPRINTF((tmp, "\\# %u (\t; %s", edata - rdata, comment)); 725*7c478bd9Sstevel@tonic-gate T(addstr(tmp, len, &buf, &buflen)); 726*7c478bd9Sstevel@tonic-gate while (rdata < edata) { 727*7c478bd9Sstevel@tonic-gate p = tmp; 728*7c478bd9Sstevel@tonic-gate p += SPRINTF((p, "\n\t")); 729*7c478bd9Sstevel@tonic-gate spaced = 0; 730*7c478bd9Sstevel@tonic-gate n = MIN(16, edata - rdata); 731*7c478bd9Sstevel@tonic-gate for (m = 0; m < n; m++) 732*7c478bd9Sstevel@tonic-gate p += SPRINTF((p, "%02x ", rdata[m])); 733*7c478bd9Sstevel@tonic-gate T(addstr(tmp, p - tmp, &buf, &buflen)); 734*7c478bd9Sstevel@tonic-gate if (n < 16) { 735*7c478bd9Sstevel@tonic-gate T(addstr(")", 1, &buf, &buflen)); 736*7c478bd9Sstevel@tonic-gate T(addtab(p - tmp + 1, 48, spaced, &buf, &buflen)); 737*7c478bd9Sstevel@tonic-gate } 738*7c478bd9Sstevel@tonic-gate p = tmp; 739*7c478bd9Sstevel@tonic-gate p += SPRINTF((p, "; ")); 740*7c478bd9Sstevel@tonic-gate for (m = 0; m < n; m++) 741*7c478bd9Sstevel@tonic-gate *p++ = (isascii(rdata[m]) && isprint(rdata[m])) 742*7c478bd9Sstevel@tonic-gate ? rdata[m] 743*7c478bd9Sstevel@tonic-gate : '.'; 744*7c478bd9Sstevel@tonic-gate T(addstr(tmp, p - tmp, &buf, &buflen)); 745*7c478bd9Sstevel@tonic-gate rdata += n; 746*7c478bd9Sstevel@tonic-gate } 747*7c478bd9Sstevel@tonic-gate return (buf - obuf); 748*7c478bd9Sstevel@tonic-gate } 749*7c478bd9Sstevel@tonic-gate } 750*7c478bd9Sstevel@tonic-gate 751*7c478bd9Sstevel@tonic-gate /* Private. */ 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate /* 754*7c478bd9Sstevel@tonic-gate * size_t 755*7c478bd9Sstevel@tonic-gate * prune_origin(name, origin) 756*7c478bd9Sstevel@tonic-gate * Find out if the name is at or under the current origin. 757*7c478bd9Sstevel@tonic-gate * return: 758*7c478bd9Sstevel@tonic-gate * Number of characters in name before start of origin, 759*7c478bd9Sstevel@tonic-gate * or length of name if origin does not match. 760*7c478bd9Sstevel@tonic-gate * notes: 761*7c478bd9Sstevel@tonic-gate * This function should share code with samedomain(). 762*7c478bd9Sstevel@tonic-gate */ 763*7c478bd9Sstevel@tonic-gate static size_t 764*7c478bd9Sstevel@tonic-gate prune_origin(const char *name, const char *origin) { 765*7c478bd9Sstevel@tonic-gate const char *oname = name; 766*7c478bd9Sstevel@tonic-gate 767*7c478bd9Sstevel@tonic-gate while (*name != '\0') { 768*7c478bd9Sstevel@tonic-gate if (origin != NULL && ns_samename(name, origin) == 1) 769*7c478bd9Sstevel@tonic-gate return (name - oname - (name > oname)); 770*7c478bd9Sstevel@tonic-gate while (*name != '\0') { 771*7c478bd9Sstevel@tonic-gate if (*name == '\\') { 772*7c478bd9Sstevel@tonic-gate name++; 773*7c478bd9Sstevel@tonic-gate /* XXX need to handle \nnn form. */ 774*7c478bd9Sstevel@tonic-gate if (*name == '\0') 775*7c478bd9Sstevel@tonic-gate break; 776*7c478bd9Sstevel@tonic-gate } else if (*name == '.') { 777*7c478bd9Sstevel@tonic-gate name++; 778*7c478bd9Sstevel@tonic-gate break; 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate name++; 781*7c478bd9Sstevel@tonic-gate } 782*7c478bd9Sstevel@tonic-gate } 783*7c478bd9Sstevel@tonic-gate return (name - oname); 784*7c478bd9Sstevel@tonic-gate } 785*7c478bd9Sstevel@tonic-gate 786*7c478bd9Sstevel@tonic-gate /* 787*7c478bd9Sstevel@tonic-gate * int 788*7c478bd9Sstevel@tonic-gate * charstr(rdata, edata, buf, buflen) 789*7c478bd9Sstevel@tonic-gate * Format a <character-string> into the presentation buffer. 790*7c478bd9Sstevel@tonic-gate * return: 791*7c478bd9Sstevel@tonic-gate * Number of rdata octets consumed 792*7c478bd9Sstevel@tonic-gate * 0 for protocol format error 793*7c478bd9Sstevel@tonic-gate * -1 for output buffer error 794*7c478bd9Sstevel@tonic-gate * side effects: 795*7c478bd9Sstevel@tonic-gate * buffer is advanced on success. 796*7c478bd9Sstevel@tonic-gate */ 797*7c478bd9Sstevel@tonic-gate static int 798*7c478bd9Sstevel@tonic-gate charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) { 799*7c478bd9Sstevel@tonic-gate const u_char *odata = rdata; 800*7c478bd9Sstevel@tonic-gate size_t save_buflen = *buflen; 801*7c478bd9Sstevel@tonic-gate char *save_buf = *buf; 802*7c478bd9Sstevel@tonic-gate 803*7c478bd9Sstevel@tonic-gate if (addstr("\"", 1, buf, buflen) < 0) 804*7c478bd9Sstevel@tonic-gate goto enospc; 805*7c478bd9Sstevel@tonic-gate if (rdata < edata) { 806*7c478bd9Sstevel@tonic-gate int n = *rdata; 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate if (rdata + 1 + n <= edata) { 809*7c478bd9Sstevel@tonic-gate rdata++; 810*7c478bd9Sstevel@tonic-gate while (n-- > 0) { 811*7c478bd9Sstevel@tonic-gate if (strchr("\n\"\\", *rdata) != NULL) 812*7c478bd9Sstevel@tonic-gate if (addstr("\\", 1, buf, buflen) < 0) 813*7c478bd9Sstevel@tonic-gate goto enospc; 814*7c478bd9Sstevel@tonic-gate if (addstr((const char *)rdata, 1, 815*7c478bd9Sstevel@tonic-gate buf, buflen) < 0) 816*7c478bd9Sstevel@tonic-gate goto enospc; 817*7c478bd9Sstevel@tonic-gate rdata++; 818*7c478bd9Sstevel@tonic-gate } 819*7c478bd9Sstevel@tonic-gate } 820*7c478bd9Sstevel@tonic-gate } 821*7c478bd9Sstevel@tonic-gate if (addstr("\"", 1, buf, buflen) < 0) 822*7c478bd9Sstevel@tonic-gate goto enospc; 823*7c478bd9Sstevel@tonic-gate return (rdata - odata); 824*7c478bd9Sstevel@tonic-gate enospc: 825*7c478bd9Sstevel@tonic-gate errno = ENOSPC; 826*7c478bd9Sstevel@tonic-gate *buf = save_buf; 827*7c478bd9Sstevel@tonic-gate *buflen = save_buflen; 828*7c478bd9Sstevel@tonic-gate return (-1); 829*7c478bd9Sstevel@tonic-gate } 830*7c478bd9Sstevel@tonic-gate 831*7c478bd9Sstevel@tonic-gate static int 832*7c478bd9Sstevel@tonic-gate addname(const u_char *msg, size_t msglen, 833*7c478bd9Sstevel@tonic-gate const u_char **pp, const char *origin, 834*7c478bd9Sstevel@tonic-gate char **buf, size_t *buflen) 835*7c478bd9Sstevel@tonic-gate { 836*7c478bd9Sstevel@tonic-gate size_t newlen, save_buflen = *buflen; 837*7c478bd9Sstevel@tonic-gate char *save_buf = *buf; 838*7c478bd9Sstevel@tonic-gate int n; 839*7c478bd9Sstevel@tonic-gate 840*7c478bd9Sstevel@tonic-gate n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen); 841*7c478bd9Sstevel@tonic-gate if (n < 0) 842*7c478bd9Sstevel@tonic-gate goto enospc; /* Guess. */ 843*7c478bd9Sstevel@tonic-gate newlen = prune_origin(*buf, origin); 844*7c478bd9Sstevel@tonic-gate if (**buf == '\0') { 845*7c478bd9Sstevel@tonic-gate goto root; 846*7c478bd9Sstevel@tonic-gate } else if (newlen == 0) { 847*7c478bd9Sstevel@tonic-gate /* Use "@" instead of name. */ 848*7c478bd9Sstevel@tonic-gate if (newlen + 2 > *buflen) 849*7c478bd9Sstevel@tonic-gate goto enospc; /* No room for "@\0". */ 850*7c478bd9Sstevel@tonic-gate (*buf)[newlen++] = '@'; 851*7c478bd9Sstevel@tonic-gate (*buf)[newlen] = '\0'; 852*7c478bd9Sstevel@tonic-gate } else { 853*7c478bd9Sstevel@tonic-gate if (((origin == NULL || origin[0] == '\0') || 854*7c478bd9Sstevel@tonic-gate (origin[0] != '.' && origin[1] != '\0' && 855*7c478bd9Sstevel@tonic-gate (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') { 856*7c478bd9Sstevel@tonic-gate /* No trailing dot. */ 857*7c478bd9Sstevel@tonic-gate root: 858*7c478bd9Sstevel@tonic-gate if (newlen + 2 > *buflen) 859*7c478bd9Sstevel@tonic-gate goto enospc; /* No room for ".\0". */ 860*7c478bd9Sstevel@tonic-gate (*buf)[newlen++] = '.'; 861*7c478bd9Sstevel@tonic-gate (*buf)[newlen] = '\0'; 862*7c478bd9Sstevel@tonic-gate } 863*7c478bd9Sstevel@tonic-gate } 864*7c478bd9Sstevel@tonic-gate *pp += n; 865*7c478bd9Sstevel@tonic-gate addlen(newlen, buf, buflen); 866*7c478bd9Sstevel@tonic-gate **buf = '\0'; 867*7c478bd9Sstevel@tonic-gate return (newlen); 868*7c478bd9Sstevel@tonic-gate enospc: 869*7c478bd9Sstevel@tonic-gate errno = ENOSPC; 870*7c478bd9Sstevel@tonic-gate *buf = save_buf; 871*7c478bd9Sstevel@tonic-gate *buflen = save_buflen; 872*7c478bd9Sstevel@tonic-gate return (-1); 873*7c478bd9Sstevel@tonic-gate } 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate static void 876*7c478bd9Sstevel@tonic-gate addlen(size_t len, char **buf, size_t *buflen) { 877*7c478bd9Sstevel@tonic-gate INSIST(len <= *buflen); 878*7c478bd9Sstevel@tonic-gate *buf += len; 879*7c478bd9Sstevel@tonic-gate *buflen -= len; 880*7c478bd9Sstevel@tonic-gate } 881*7c478bd9Sstevel@tonic-gate 882*7c478bd9Sstevel@tonic-gate static int 883*7c478bd9Sstevel@tonic-gate addstr(const char *src, size_t len, char **buf, size_t *buflen) { 884*7c478bd9Sstevel@tonic-gate if (len >= *buflen) { 885*7c478bd9Sstevel@tonic-gate errno = ENOSPC; 886*7c478bd9Sstevel@tonic-gate return (-1); 887*7c478bd9Sstevel@tonic-gate } 888*7c478bd9Sstevel@tonic-gate memcpy(*buf, src, len); 889*7c478bd9Sstevel@tonic-gate addlen(len, buf, buflen); 890*7c478bd9Sstevel@tonic-gate **buf = '\0'; 891*7c478bd9Sstevel@tonic-gate return (0); 892*7c478bd9Sstevel@tonic-gate } 893*7c478bd9Sstevel@tonic-gate 894*7c478bd9Sstevel@tonic-gate static int 895*7c478bd9Sstevel@tonic-gate addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) { 896*7c478bd9Sstevel@tonic-gate size_t save_buflen = *buflen; 897*7c478bd9Sstevel@tonic-gate char *save_buf = *buf; 898*7c478bd9Sstevel@tonic-gate int t; 899*7c478bd9Sstevel@tonic-gate 900*7c478bd9Sstevel@tonic-gate if (spaced || len >= target - 1) { 901*7c478bd9Sstevel@tonic-gate T(addstr(" ", 2, buf, buflen)); 902*7c478bd9Sstevel@tonic-gate spaced = 1; 903*7c478bd9Sstevel@tonic-gate } else { 904*7c478bd9Sstevel@tonic-gate for (t = (target - len - 1) / 8; t >= 0; t--) 905*7c478bd9Sstevel@tonic-gate if (addstr("\t", 1, buf, buflen) < 0) { 906*7c478bd9Sstevel@tonic-gate *buflen = save_buflen; 907*7c478bd9Sstevel@tonic-gate *buf = save_buf; 908*7c478bd9Sstevel@tonic-gate return (-1); 909*7c478bd9Sstevel@tonic-gate } 910*7c478bd9Sstevel@tonic-gate spaced = 0; 911*7c478bd9Sstevel@tonic-gate } 912*7c478bd9Sstevel@tonic-gate return (spaced); 913*7c478bd9Sstevel@tonic-gate } 914