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