1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18: #if !defined(_LIBC) && !defined(lint)
19: static const char rcsid[] = "$BINDId: ns_print.c,v 8.18 2000/02/29 05:48:12 vixie Exp $";
20: #endif
21:
22:
23:
24: #include <sys/types.h>
25: #include <sys/socket.h>
26:
27: #include <netinet/in.h>
28: #include <arpa/nameser.h>
29: #include <arpa/inet.h>
30:
31: #include <assert.h>
32: #include <errno.h>
33: #include <resolv.h>
34: #include <string.h>
35: #include <ctype.h>
36:
37: #ifdef SPRINTF_CHAR
38: # define SPRINTF(x) strlen(sprintfx)
39: #else
40: # define SPRINTF(x) ((size_t)sprintf x)
41: #endif
42:
43:
44:
45: static size_t prune_origin(const char *name, const char *origin);
46: static int charstr(const u_char *rdata, const u_char *edata,
47: char **buf, size_t *buflen);
48: static int addname(const u_char *msg, size_t msglen,
49: const u_char **p, const char *origin,
50: char **buf, size_t *buflen);
51: static void addlen(size_t len, char **buf, size_t *buflen);
52: static int addstr(const char *src, size_t len,
53: char **buf, size_t *buflen);
54: static int addtab(size_t len, size_t target, int spaced,
55: char **buf, size_t *buflen);
56:
57:
58:
59: #ifndef _LIBC
60: u_int16_t dst_s_dns_key_id(const u_char *, const int);
61: #endif
62:
63:
64:
65: #define T(x) \
66: do { \
67: if ((x) < 0) \
68: return (-1); \
69: } while (0)
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80: int
81: ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
82: const char *name_ctx, const char *origin,
83: char *buf, size_t buflen)
84: {
85: int n;
86:
87: n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
88: ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
89: ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
90: name_ctx, origin, buf, buflen);
91: return (n);
92: }
93:
94:
95:
96:
97:
98:
99:
100:
101:
102: int
103: ns_sprintrrf(const u_char *msg, size_t msglen,
104: const char *name, ns_class class, ns_type type,
105: u_long ttl, const u_char *rdata, size_t rdlen,
106: const char *name_ctx, const char *origin,
107: char *buf, size_t buflen)
108: {
109: const char *obuf = buf;
110: const u_char *edata = rdata + rdlen;
111: int spaced = 0;
112:
113: const char *comment;
114: char tmp[100];
115: char errbuf[40];
116: int len, x;
117:
118:
119:
120:
121: if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) {
122: T(addstr("\t\t\t", 3, &buf, &buflen));
123: } else {
124: len = prune_origin(name, origin);
125: if (len == 0) {
126: T(addstr("@\t\t\t", 4, &buf, &buflen));
127: } else {
128: T(addstr(name, len, &buf, &buflen));
129:
130: if (((origin == NULL || origin[0] == '\0') ||
131: (origin[0] != '.' && origin[1] != '\0' &&
132: name[len] == '\0')) && name[len - 1] != '.') {
133: T(addstr(".", 1, &buf, &buflen));
134: len++;
135: }
136: T(spaced = addtab(len, 24, spaced, &buf, &buflen));
137: }
138: }
139:
140:
141:
142:
143: T(x = ns_format_ttl(ttl, buf, buflen));
144: addlen(x, &buf, &buflen);
145: len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
146: T(addstr(tmp, len, &buf, &buflen));
147: T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
148:
149:
150:
151:
152: switch (type) {
153: case ns_t_a:
154: if (rdlen != NS_INADDRSZ)
155: goto formerr;
156: (void) inet_ntop(AF_INET, rdata, buf, buflen);
157: addlen(strlen(buf), &buf, &buflen);
158: break;
159:
160: case ns_t_cname:
161: case ns_t_mb:
162: case ns_t_mg:
163: case ns_t_mr:
164: case ns_t_ns:
165: case ns_t_ptr:
166: T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
167: break;
168:
169: case ns_t_hinfo:
170: case ns_t_isdn:
171:
172: T(len = charstr(rdata, edata, &buf, &buflen));
173: if (len == 0)
174: goto formerr;
175: rdata += len;
176: T(addstr(" ", 1, &buf, &buflen));
177:
178:
179:
180: if (type == ns_t_isdn && rdata == edata)
181: break;
182:
183: T(len = charstr(rdata, edata, &buf, &buflen));
184: if (len == 0)
185: goto formerr;
186: rdata += len;
187: break;
188:
189: case ns_t_soa: {
190: u_long t;
191:
192:
193: T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
194: T(addstr(" ", 1, &buf, &buflen));
195:
196:
197: T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
198: T(addstr(" (\n", 3, &buf, &buflen));
199: spaced = 0;
200:
201: if ((edata - rdata) != 5*NS_INT32SZ)
202: goto formerr;
203:
204:
205: t = ns_get32(rdata); rdata += NS_INT32SZ;
206: T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
207: len = SPRINTF((tmp, "%lu", t));
208: T(addstr(tmp, len, &buf, &buflen));
209: T(spaced = addtab(len, 16, spaced, &buf, &buflen));
210: T(addstr("; serial\n", 9, &buf, &buflen));
211: spaced = 0;
212:
213:
214: t = ns_get32(rdata); rdata += NS_INT32SZ;
215: T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
216: T(len = ns_format_ttl(t, buf, buflen));
217: addlen(len, &buf, &buflen);
218: T(spaced = addtab(len, 16, spaced, &buf, &buflen));
219: T(addstr("; refresh\n", 10, &buf, &buflen));
220: spaced = 0;
221:
222:
223: t = ns_get32(rdata); rdata += NS_INT32SZ;
224: T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
225: T(len = ns_format_ttl(t, buf, buflen));
226: addlen(len, &buf, &buflen);
227: T(spaced = addtab(len, 16, spaced, &buf, &buflen));
228: T(addstr("; retry\n", 8, &buf, &buflen));
229: spaced = 0;
230:
231:
232: t = ns_get32(rdata); rdata += NS_INT32SZ;
233: T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
234: T(len = ns_format_ttl(t, buf, buflen));
235: addlen(len, &buf, &buflen);
236: T(spaced = addtab(len, 16, spaced, &buf, &buflen));
237: T(addstr("; expiry\n", 9, &buf, &buflen));
238: spaced = 0;
239:
240:
241: t = ns_get32(rdata); rdata += NS_INT32SZ;
242: T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
243: T(len = ns_format_ttl(t, buf, buflen));
244: addlen(len, &buf, &buflen);
245: T(addstr(" )", 2, &buf, &buflen));
246: T(spaced = addtab(len, 16, spaced, &buf, &buflen));
247: T(addstr("; minimum\n", 10, &buf, &buflen));
248:
249: break;
250: }
251:
252: case ns_t_mx:
253: case ns_t_afsdb:
254: case ns_t_rt: {
255: u_int t;
256:
257: if (rdlen < NS_INT16SZ)
258: goto formerr;
259:
260:
261: t = ns_get16(rdata);
262: rdata += NS_INT16SZ;
263: len = SPRINTF((tmp, "%u ", t));
264: T(addstr(tmp, len, &buf, &buflen));
265:
266:
267: T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
268:
269: break;
270: }
271:
272: case ns_t_px: {
273: u_int t;
274:
275: if (rdlen < NS_INT16SZ)
276: goto formerr;
277:
278:
279: t = ns_get16(rdata);
280: rdata += NS_INT16SZ;
281: len = SPRINTF((tmp, "%u ", t));
282: T(addstr(tmp, len, &buf, &buflen));
283:
284:
285: T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
286: T(addstr(" ", 1, &buf, &buflen));
287:
288:
289: T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
290:
291: break;
292: }
293:
294: case ns_t_x25:
295: T(len = charstr(rdata, edata, &buf, &buflen));
296: if (len == 0)
297: goto formerr;
298: rdata += len;
299: break;
300:
301: case ns_t_txt:
302: while (rdata < edata) {
303: T(len = charstr(rdata, edata, &buf, &buflen));
304: if (len == 0)
305: goto formerr;
306: rdata += len;
307: if (rdata < edata)
308: T(addstr(" ", 1, &buf, &buflen));
309: }
310: break;
311:
312: case ns_t_nsap: {
313:
314:
315: char t[255*2 + 128 + 2];
316:
317: (void) inet_nsap_ntoa(rdlen, rdata, t);
318: T(addstr(t, strlen(t), &buf, &buflen));
319: break;
320: }
321:
322: case ns_t_aaaa:
323: if (rdlen != NS_IN6ADDRSZ)
324: goto formerr;
325: (void) inet_ntop(AF_INET6, rdata, buf, buflen);
326: addlen(strlen(buf), &buf, &buflen);
327: break;
328:
329: case ns_t_loc: {
330: char t[255];
331:
332:
333: (void) loc_ntoa(rdata, t);
334: T(addstr(t, strlen(t), &buf, &buflen));
335: break;
336: }
337:
338: case ns_t_naptr: {
339: u_int order, preference;
340: char t[50];
341:
342: if (rdlen < 2*NS_INT16SZ)
343: goto formerr;
344:
345:
346: order = ns_get16(rdata); rdata += NS_INT16SZ;
347: preference = ns_get16(rdata); rdata += NS_INT16SZ;
348: len = SPRINTF((t, "%u %u ", order, preference));
349: T(addstr(t, len, &buf, &buflen));
350:
351:
352: T(len = charstr(rdata, edata, &buf, &buflen));
353: if (len == 0)
354: goto formerr;
355: rdata += len;
356: T(addstr(" ", 1, &buf, &buflen));
357:
358:
359: T(len = charstr(rdata, edata, &buf, &buflen));
360: if (len == 0)
361: goto formerr;
362: rdata += len;
363: T(addstr(" ", 1, &buf, &buflen));
364:
365:
366: T(len = charstr(rdata, edata, &buf, &buflen));
367: if (len < 0)
368: return (-1);
369: if (len == 0)
370: goto formerr;
371: rdata += len;
372: T(addstr(" ", 1, &buf, &buflen));
373:
374:
375: T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
376: break;
377: }
378:
379: case ns_t_srv: {
380: u_int priority, weight, port;
381: char t[50];
382:
383: if (rdlen < NS_INT16SZ*3)
384: goto formerr;
385:
386:
387: priority = ns_get16(rdata); rdata += NS_INT16SZ;
388: weight = ns_get16(rdata); rdata += NS_INT16SZ;
389: port = ns_get16(rdata); rdata += NS_INT16SZ;
390: len = SPRINTF((t, "%u %u %u ", priority, weight, port));
391: T(addstr(t, len, &buf, &buflen));
392:
393:
394: T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
395: break;
396: }
397:
398: case ns_t_minfo:
399: case ns_t_rp:
400:
401: T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
402: T(addstr(" ", 1, &buf, &buflen));
403:
404:
405: T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
406:
407: break;
408:
409: case ns_t_wks: {
410: int n, lcnt;
411:
412: if (rdlen < NS_INT32SZ + 1)
413: goto formerr;
414:
415:
416: (void) inet_ntop(AF_INET, rdata, buf, buflen);
417: addlen(strlen(buf), &buf, &buflen);
418: rdata += NS_INADDRSZ;
419:
420:
421: len = SPRINTF((tmp, " %u ( ", *rdata));
422: T(addstr(tmp, len, &buf, &buflen));
423: rdata += NS_INT8SZ;
424:
425:
426: n = 0;
427: lcnt = 0;
428: while (rdata < edata) {
429: u_int c = *rdata++;
430: do {
431: if (c & 0200) {
432: if (lcnt == 0) {
433: T(addstr("\n\t\t\t\t", 5,
434: &buf, &buflen));
435: lcnt = 10;
436: spaced = 0;
437: }
438: len = SPRINTF((tmp, "%d ", n));
439: T(addstr(tmp, len, &buf, &buflen));
440: lcnt--;
441: }
442: c <<= 1;
443: } while (++n & 07);
444: }
445: T(addstr(")", 1, &buf, &buflen));
446:
447: break;
448: }
449:
450: case ns_t_key: {
451: #ifndef _LIBC
452: char base64_key[NS_MD5RSA_MAX_BASE64];
453: u_int keyflags, protocol, algorithm, key_id;
454: const char *leader;
455: int n;
456:
457: if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
458: goto formerr;
459:
460:
461: key_id = dst_s_dns_key_id(rdata, edata-rdata);
462: keyflags = ns_get16(rdata); rdata += NS_INT16SZ;
463: protocol = *rdata++;
464: algorithm = *rdata++;
465: len = SPRINTF((tmp, "0x%04x %u %u",
466: keyflags, protocol, algorithm));
467: T(addstr(tmp, len, &buf, &buflen));
468:
469:
470: len = b64_ntop(rdata, edata - rdata,
471: base64_key, sizeof base64_key);
472: if (len < 0)
473: goto formerr;
474: if (len > 15) {
475: T(addstr(" (", 2, &buf, &buflen));
476: leader = "\n\t\t";
477: spaced = 0;
478: } else
479: leader = " ";
480: for (n = 0; n < len; n += 48) {
481: T(addstr(leader, strlen(leader), &buf, &buflen));
482: T(addstr(base64_key + n, MIN(len - n, 48),
483: &buf, &buflen));
484: }
485: if (len > 15)
486: T(addstr(" )", 2, &buf, &buflen));
487: n = SPRINTF((tmp, " ; key_tag= %u", key_id));
488: T(addstr(tmp, n, &buf, &buflen));
489: #endif
490:
491: break;
492: }
493:
494: case ns_t_sig: {
495: #ifndef _LIBC
496: char base64_key[NS_MD5RSA_MAX_BASE64];
497: u_int type, algorithm, labels, footprint;
498: const char *leader;
499: u_long t;
500: int n;
501:
502: if (rdlen < 22)
503: goto formerr;
504:
505:
506: type = ns_get16(rdata); rdata += NS_INT16SZ;
507: algorithm = *rdata++;
508: labels = *rdata++;
509: t = ns_get32(rdata); rdata += NS_INT32SZ;
510: len = SPRINTF((tmp, "%s %d %d %lu ",
511: p_type(type), algorithm, labels, t));
512: T(addstr(tmp, len, &buf, &buflen));
513: if (labels > (u_int)dn_count_labels(name))
514: goto formerr;
515:
516:
517: t = ns_get32(rdata); rdata += NS_INT32SZ;
518: len = SPRINTF((tmp, "%s ", p_secstodate(t)));
519: T(addstr(tmp, len, &buf, &buflen));
520:
521:
522: t = ns_get32(rdata); rdata += NS_INT32SZ;
523: