Libinfo-324.1.tar.gz
[apple/libinfo.git] / dns.subproj / res_debug.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * ++Copyright++ 1985, 1990, 1993
26 * -
27 * Copyright (c) 1985, 1990, 1993
28 * The Regents of the University of California. All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the University of
41 * California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 * may be used to endorse or promote products derived from this software
44 * without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 * -
58 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
59 *
60 * Permission to use, copy, modify, and distribute this software for any
61 * purpose with or without fee is hereby granted, provided that the above
62 * copyright notice and this permission notice appear in all copies, and that
63 * the name of Digital Equipment Corporation not be used in advertising or
64 * publicity pertaining to distribution of the document or software without
65 * specific, written prior permission.
66 *
67 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
68 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
69 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
70 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
71 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
72 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
73 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
74 * SOFTWARE.
75 * -
76 * --Copyright--
77 */
78
79 #if defined(LIBC_SCCS) && !defined(lint)
80 static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
81 static char rcsid[] = "$Id: res_debug.c,v 1.5 2004/06/11 23:16:00 majka Exp $";
82 #endif /* LIBC_SCCS and not lint */
83
84 #include <sys/param.h>
85 #include <netinet/in.h>
86 #include <arpa/inet.h>
87
88 #include <stdio.h>
89 #include <netdb.h>
90
91 #include "nameser8_compat.h"
92 #include "resolv8_compat.h"
93
94 #if defined(BSD) && (BSD >= 199103)
95 # include <string.h>
96 #else
97 # include "portability.h"
98 #endif
99
100 #if defined(USE_OPTIONS_H)
101 # include "options.h"
102 #endif
103
104 const char *_res_opcodes[] = {
105 "QUERY",
106 "IQUERY",
107 "CQUERYM",
108 "CQUERYU", /* experimental */
109 "NOTIFY", /* experimental */
110 "5",
111 "6",
112 "7",
113 "8",
114 "UPDATEA",
115 "UPDATED",
116 "UPDATEDA",
117 "UPDATEM",
118 "UPDATEMA",
119 "ZONEINIT",
120 "ZONEREF",
121 };
122
123 const char *_res_resultcodes[] = {
124 "NOERROR",
125 "FORMERR",
126 "SERVFAIL",
127 "NXDOMAIN",
128 "NOTIMP",
129 "REFUSED",
130 "6",
131 "7",
132 "8",
133 "9",
134 "10",
135 "11",
136 "12",
137 "13",
138 "14",
139 "NOCHANGE",
140 };
141
142 /* XXX: we should use getservbyport() instead. */
143 static const char *
144 dewks(wks)
145 int wks;
146 {
147 static char nbuf[20];
148
149 switch (wks) {
150 case 5: return "rje";
151 case 7: return "echo";
152 case 9: return "discard";
153 case 11: return "systat";
154 case 13: return "daytime";
155 case 15: return "netstat";
156 case 17: return "qotd";
157 case 19: return "chargen";
158 case 20: return "ftp-data";
159 case 21: return "ftp";
160 case 23: return "telnet";
161 case 25: return "smtp";
162 case 37: return "time";
163 case 39: return "rlp";
164 case 42: return "name";
165 case 43: return "whois";
166 case 53: return "domain";
167 case 57: return "apts";
168 case 59: return "apfs";
169 case 67: return "bootps";
170 case 68: return "bootpc";
171 case 69: return "tftp";
172 case 77: return "rje";
173 case 79: return "finger";
174 case 87: return "link";
175 case 95: return "supdup";
176 case 100: return "newacct";
177 case 101: return "hostnames";
178 case 102: return "iso-tsap";
179 case 103: return "x400";
180 case 104: return "x400-snd";
181 case 105: return "csnet-ns";
182 case 109: return "pop-2";
183 case 111: return "sunrpc";
184 case 113: return "auth";
185 case 115: return "sftp";
186 case 117: return "uucp-path";
187 case 119: return "nntp";
188 case 121: return "erpc";
189 case 123: return "ntp";
190 case 133: return "statsrv";
191 case 136: return "profile";
192 case 144: return "NeWS";
193 case 161: return "snmp";
194 case 162: return "snmp-trap";
195 case 170: return "print-srv";
196 default: (void) sprintf(nbuf, "%d", wks); return (nbuf);
197 }
198 }
199
200 /* XXX: we should use getprotobynumber() instead. */
201 static const char *
202 deproto(protonum)
203 int protonum;
204 {
205 static char nbuf[20];
206
207 switch (protonum) {
208 case 1: return "icmp";
209 case 2: return "igmp";
210 case 3: return "ggp";
211 case 5: return "st";
212 case 6: return "tcp";
213 case 7: return "ucl";
214 case 8: return "egp";
215 case 9: return "igp";
216 case 11: return "nvp-II";
217 case 12: return "pup";
218 case 16: return "chaos";
219 case 17: return "udp";
220 default: (void) sprintf(nbuf, "%d", protonum); return (nbuf);
221 }
222 }
223
224 static const u_char *
225 do_rrset(msg, len, cp, cnt, pflag, file, hs)
226 int cnt, pflag, len;
227 const u_char *cp, *msg;
228 const char *hs;
229 FILE *file;
230 {
231 int n;
232 int sflag;
233
234 /*
235 * Print answer records.
236 */
237 sflag = (_res.pfcode & pflag);
238 if ((n = ntohs(cnt))) {
239 if ((!_res.pfcode) ||
240 ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
241 fprintf(file, "%s", hs);
242 while (--n >= 0) {
243 if ((!_res.pfcode) || sflag) {
244 cp = p_rr(cp, msg, file);
245 } else {
246 unsigned int dlen;
247 cp += __dn_skipname(cp, cp + MAXCDNAME);
248 cp += INT16SZ;
249 cp += INT16SZ;
250 cp += INT32SZ;
251 dlen = _getshort((u_char*)cp);
252 cp += INT16SZ;
253 cp += dlen;
254 }
255 if ((cp - msg) > len)
256 return (NULL);
257 }
258 if ((!_res.pfcode) ||
259 ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
260 putc('\n', file);
261 }
262 return (cp);
263 }
264
265 void
266 __p_query(msg)
267 const u_char *msg;
268 {
269 __fp_query(msg, stdout);
270 }
271
272 #ifdef ultrix
273 /* ultrix 4.0's packaging has some icky packaging. alias for it here.
274 * there is more junk of this kind over in res_comp.c.
275 */
276 void
277 p_query(msg)
278 const u_char *msg;
279 {
280 __p_query(msg);
281 }
282 #endif
283
284 /*
285 * Print the current options.
286 * This is intended to be primarily a debugging routine.
287 */
288 void
289 __fp_resstat(statp, file)
290 struct __res_state *statp;
291 FILE *file;
292 {
293 register u_long mask;
294
295 fprintf(file, ";; res options:");
296 if (!statp)
297 statp = &_res;
298 for (mask = 1; mask != 0; mask <<= 1)
299 if (statp->options & mask)
300 fprintf(file, " %s", p_option(mask));
301 putc('\n', file);
302 }
303
304 /*
305 * Print the contents of a query.
306 * This is intended to be primarily a debugging routine.
307 */
308 void
309 __fp_nquery(msg, len, file)
310 const u_char *msg;
311 int len;
312 FILE *file;
313 {
314 register const u_char *cp, *endMark;
315 register const HEADER *hp;
316 register int n;
317
318 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
319 return;
320
321 #define TruncTest(x) if (x >= endMark) goto trunc
322 #define ErrorTest(x) if (x == NULL) goto error
323
324 /*
325 * Print header fields.
326 */
327 hp = (HEADER *)msg;
328 cp = msg + HFIXEDSZ;
329 endMark = cp + len;
330 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
331 fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
332 _res_opcodes[hp->opcode],
333 _res_resultcodes[hp->rcode],
334 ntohs(hp->id));
335 putc('\n', file);
336 }
337 putc(';', file);
338 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
339 fprintf(file, "; flags:");
340 if (hp->qr)
341 fprintf(file, " qr");
342 if (hp->aa)
343 fprintf(file, " aa");
344 if (hp->tc)
345 fprintf(file, " tc");
346 if (hp->rd)
347 fprintf(file, " rd");
348 if (hp->ra)
349 fprintf(file, " ra");
350 }
351 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
352 fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
353 fprintf(file, ", Ans: %d", ntohs(hp->ancount));
354 fprintf(file, ", Auth: %d", ntohs(hp->nscount));
355 fprintf(file, ", Addit: %d", ntohs(hp->arcount));
356 }
357 if ((!_res.pfcode) || (_res.pfcode &
358 (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
359 putc('\n',file);
360 }
361 /*
362 * Print question records.
363 */
364 if ((n = ntohs(hp->qdcount))) {
365 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
366 fprintf(file, ";; QUESTIONS:\n");
367 while (--n >= 0) {
368 fprintf(file, ";;\t");
369 TruncTest(cp);
370 cp = p_cdnname(cp, msg, len, file);
371 ErrorTest(cp);
372 TruncTest(cp);
373 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
374 fprintf(file, ", type = %s",
375 __p_type(_getshort((u_char*)cp)));
376 cp += INT16SZ;
377 TruncTest(cp);
378 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
379 fprintf(file, ", class = %s\n",
380 __p_class(_getshort((u_char*)cp)));
381 cp += INT16SZ;
382 putc('\n', file);
383 }
384 }
385 /*
386 * Print authoritative answer records
387 */
388 TruncTest(cp);
389 cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
390 ";; ANSWERS:\n");
391 ErrorTest(cp);
392
393 /*
394 * print name server records
395 */
396 TruncTest(cp);
397 cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
398 ";; AUTHORITY RECORDS:\n");
399 ErrorTest(cp);
400
401 TruncTest(cp);
402 /*
403 * print additional records
404 */
405 cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
406 ";; ADDITIONAL RECORDS:\n");
407 ErrorTest(cp);
408 return;
409 trunc:
410 fprintf(file, "\n;; ...truncated\n");
411 return;
412 error:
413 fprintf(file, "\n;; ...malformed\n");
414 }
415
416 void
417 __fp_query(msg, file)
418 const u_char *msg;
419 FILE *file;
420 {
421 fp_nquery(msg, PACKETSZ, file);
422 }
423
424 const u_char *
425 __p_cdnname(cp, msg, len, file)
426 const u_char *cp, *msg;
427 int len;
428 FILE *file;
429 {
430 char name[MAXDNAME];
431 int n;
432
433 if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
434 return (NULL);
435 if (name[0] == '\0')
436 putc('.', file);
437 else
438 fputs(name, file);
439 return (cp + n);
440 }
441
442 const u_char *
443 __p_cdname(cp, msg, file)
444 const u_char *cp, *msg;
445 FILE *file;
446 {
447 return (p_cdnname(cp, msg, PACKETSZ, file));
448 }
449
450 /* XXX: the rest of these functions need to become length-limited, too. (vix)
451 */
452
453 const u_char *
454 __p_fqname(cp, msg, file)
455 const u_char *cp, *msg;
456 FILE *file;
457 {
458 char name[MAXDNAME];
459 int n;
460
461 if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0)
462 return (NULL);
463 if (name[0] == '\0') {
464 putc('.', file);
465 } else {
466 fputs(name, file);
467 if (name[strlen(name) - 1] != '.')
468 putc('.', file);
469 }
470 return (cp + n);
471 }
472
473 /*
474 * Print resource record fields in human readable form.
475 */
476 const u_char *
477 __p_rr(cp, msg, file)
478 const u_char *cp, *msg;
479 FILE *file;
480 {
481 int type, class, n, c;
482 int dlen;
483 struct in_addr inaddr;
484 const u_char *cp1, *cp2;
485 u_int32_t tmpttl, t;
486 int lcnt;
487
488 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
489 h_errno = NETDB_INTERNAL;
490 return (NULL);
491 }
492 if ((cp = p_fqname(cp, msg, file)) == NULL)
493 return (NULL); /* compression error */
494 type = _getshort((u_char*)cp);
495 cp += INT16SZ;
496 class = _getshort((u_char*)cp);
497 cp += INT16SZ;
498 tmpttl = _getlong((u_char*)cp);
499 cp += INT32SZ;
500 dlen = _getshort((u_char*)cp);
501 cp += INT16SZ;
502 cp1 = cp;
503 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
504 fprintf(file, "\t%lu", (u_long)tmpttl);
505 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
506 fprintf(file, "\t%s", __p_class(class));
507 fprintf(file, "\t%s", __p_type(type));
508 /*
509 * Print type specific data, if appropriate
510 */
511 switch (type) {
512 case T_A:
513 switch (class) {
514 case C_IN:
515 case C_HS:
516 bcopy(cp, (char *)&inaddr, INADDRSZ);
517 if (dlen == 4) {
518 fprintf(file, "\t%s", inet_ntoa(inaddr));
519 cp += dlen;
520 } else if (dlen == 7) {
521 char *address;
522 u_char protocol;
523 u_short port;
524
525 address = inet_ntoa(inaddr);
526 cp += INADDRSZ;
527 protocol = *(u_char*)cp;
528 cp += sizeof(u_char);
529 port = _getshort((u_char*)cp);
530 cp += INT16SZ;
531 fprintf(file, "\t%s\t; proto %d, port %d",
532 address, protocol, port);
533 }
534 break;
535 default:
536 cp += dlen;
537 }
538 break;
539 case T_CNAME:
540 case T_MB:
541 case T_MG:
542 case T_MR:
543 case T_NS:
544 case T_PTR:
545 putc('\t', file);
546 if ((cp = p_fqname(cp, msg, file)) == NULL)
547 return (NULL);
548 break;
549
550 case T_HINFO:
551 case T_ISDN:
552 cp2 = cp + dlen;
553 if ((n = *cp++)) {
554 fprintf(file, "\t%.*s", n, cp);
555 cp += n;
556 }
557 if ((cp < cp2) && (n = *cp++)) {
558 fprintf(file, "\t%.*s", n, cp);
559 cp += n;
560 } else if (type == T_HINFO)
561 fprintf(file, "\n;; *** Warning *** OS-type missing");
562 break;
563
564 case T_SOA:
565 putc('\t', file);
566 if ((cp = p_fqname(cp, msg, file)) == NULL)
567 return (NULL);
568 putc(' ', file);
569 if ((cp = p_fqname(cp, msg, file)) == NULL)
570 return (NULL);
571 fputs(" (\n", file);
572 t = _getlong((u_char*)cp); cp += INT32SZ;
573 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
574 t = _getlong((u_char*)cp); cp += INT32SZ;
575 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
576 (u_long)t, __p_time(t));
577 t = _getlong((u_char*)cp); cp += INT32SZ;
578 fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
579 (u_long)t, __p_time(t));
580 t = _getlong((u_char*)cp); cp += INT32SZ;
581 fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
582 (u_long)t, __p_time(t));
583 t = _getlong((u_char*)cp); cp += INT32SZ;
584 fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
585 (u_long)t, __p_time(t));
586 break;
587
588 case T_MX:
589 case T_AFSDB:
590 case T_RT:
591 fprintf(file, "\t%d ", _getshort((u_char*)cp));
592 cp += INT16SZ;
593 if ((cp = p_fqname(cp, msg, file)) == NULL)
594 return (NULL);
595 break;
596
597 case T_PX:
598 fprintf(file, "\t%d ", _getshort((u_char*)cp));
599 cp += INT16SZ;
600 if ((cp = p_fqname(cp, msg, file)) == NULL)
601 return (NULL);
602 putc(' ', file);
603 if ((cp = p_fqname(cp, msg, file)) == NULL)
604 return (NULL);
605 break;
606
607 case T_TXT:
608 case T_X25:
609 (void) fputs("\t\"", file);
610 cp2 = cp1 + dlen;
611 while (cp < cp2) {
612 if ((n = (unsigned char) *cp++)) {
613 for (c = n; c > 0 && cp < cp2; c--)
614 if ((*cp == '\n') || (*cp == '"')) {
615 (void) putc('\\', file);
616 (void) putc(*cp++, file);
617 } else
618 (void) putc(*cp++, file);
619 }
620 }
621 putc('"', file);
622 break;
623
624 case T_NSAP:
625 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
626 cp += dlen;
627 break;
628
629 case T_MINFO:
630 case T_RP:
631 putc('\t', file);
632 if ((cp = p_fqname(cp, msg, file)) == NULL)
633 return (NULL);
634 putc(' ', file);
635 if ((cp = p_fqname(cp, msg, file)) == NULL)
636 return (NULL);
637 break;
638
639 case T_UINFO:
640 putc('\t', file);
641 fputs((char *)cp, file);
642 cp += dlen;
643 break;
644
645 case T_UID:
646 case T_GID:
647 if (dlen == 4) {
648 fprintf(file, "\t%u", _getlong((u_char*)cp));
649 cp += INT32SZ;
650 }
651 break;
652
653 case T_WKS:
654 if (dlen < INT32SZ + 1)
655 break;
656 bcopy(cp, (char *)&inaddr, INADDRSZ);
657 cp += INT32SZ;
658 fprintf(file, "\t%s %s ( ",
659 inet_ntoa(inaddr),
660 deproto((int) *cp));
661 cp += sizeof(u_char);
662 n = 0;
663 lcnt = 0;
664 while (cp < cp1 + dlen) {
665 c = *cp++;
666 do {
667 if (c & 0200) {
668 if (lcnt == 0) {
669 fputs("\n\t\t\t", file);
670 lcnt = 5;
671 }
672 fputs(dewks(n), file);
673 putc(' ', file);
674 lcnt--;
675 }
676 c <<= 1;
677 } while (++n & 07);
678 }
679 putc(')', file);
680 break;
681
682 #ifdef ALLOW_T_UNSPEC
683 case T_UNSPEC:
684 {
685 int NumBytes = 8;
686 u_char *DataPtr;
687 int i;
688
689 if (dlen < NumBytes) NumBytes = dlen;
690 fprintf(file, "\tFirst %d bytes of hex data:",
691 NumBytes);
692 for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
693 fprintf(file, " %x", *DataPtr);
694 cp += dlen;
695 }
696 break;
697 #endif /* ALLOW_T_UNSPEC */
698
699 default:
700 fprintf(file, "\t?%d?", type);
701 cp += dlen;
702 }
703 #if 0
704 fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
705 #else
706 putc('\n', file);
707 #endif
708 if (cp - cp1 != dlen) {
709 #ifdef __LP64__
710 fprintf(file, ";; packet size error (found %ld, dlen was %d)\n", cp - cp1, dlen);
711 #else
712 fprintf(file, ";; packet size error (found %d, dlen was %d)\n", cp - cp1, dlen);
713 #endif
714 cp = NULL;
715 }
716 return (cp);
717 }
718
719 /*
720 * Return a string for the type
721 */
722 const char *
723 __p_type(type)
724 int type;
725 {
726 static char nbuf[20];
727
728 switch (type) {
729 case T_A: return "A";
730 case T_NS: return "NS";
731 case T_CNAME: return "CNAME";
732 case T_SOA: return "SOA";
733 case T_MB: return "MB";
734 case T_MG: return "MG";
735 case T_MR: return "MR";
736 case T_NULL: return "NULL";
737 case T_WKS: return "WKS";
738 case T_PTR: return "PTR";
739 case T_HINFO: return "HINFO";
740 case T_MINFO: return "MINFO";
741 case T_MX: return "MX";
742 case T_TXT: return "TXT";
743 case T_RP: return "RP";
744 case T_AFSDB: return "AFSDB";
745 case T_X25: return "X25";
746 case T_ISDN: return "ISDN";
747 case T_RT: return "RT";
748 case T_NSAP: return "NSAP";
749 case T_NSAP_PTR: return "NSAP_PTR";
750 case T_SIG: return "SIG";
751 case T_KEY: return "KEY";
752 case T_PX: return "PX";
753 case T_GPOS: return "GPOS";
754 case T_AAAA: return "AAAA";
755 case T_LOC: return "LOC";
756 case T_AXFR: return "AXFR";
757 case T_MAILB: return "MAILB";
758 case T_MAILA: return "MAILA";
759 case T_ANY: return "ANY";
760 case T_UINFO: return "UINFO";
761 case T_UID: return "UID";
762 case T_GID: return "GID";
763 #ifdef ALLOW_T_UNSPEC
764 case T_UNSPEC: return "UNSPEC";
765 #endif /* ALLOW_T_UNSPEC */
766 default: (void)sprintf(nbuf, "%d", type); return (nbuf);
767 }
768 }
769
770 /*
771 * Return a mnemonic for class
772 */
773 const char *
774 __p_class(class)
775 int class;
776 {
777 static char nbuf[20];
778
779 switch (class) {
780 case C_IN: return "IN";
781 case C_HS: return "HS";
782 case C_ANY: return "ANY";
783 default: (void)sprintf(nbuf, "%d", class); return (nbuf);
784 }
785 }
786
787 /*
788 * Return a mnemonic for an option
789 */
790 const char *
791 __p_option(option)
792 u_long option;
793 {
794 static char nbuf[40];
795
796 switch (option) {
797 case RES_INIT: return "init";
798 case RES_DEBUG: return "debug";
799 case RES_AAONLY: return "aaonly(unimpl)";
800 case RES_USEVC: return "usevc";
801 case RES_PRIMARY: return "primry(unimpl)";
802 case RES_IGNTC: return "igntc";
803 case RES_RECURSE: return "recurs";
804 case RES_DEFNAMES: return "defnam";
805 case RES_STAYOPEN: return "styopn";
806 case RES_DNSRCH: return "dnsrch";
807 case RES_INSECURE1: return "insecure1";
808 case RES_INSECURE2: return "insecure2";
809 default: sprintf(nbuf, "?0x%lx?", (u_long)option);
810 return (nbuf);
811 }
812 }
813
814 /*
815 * Return a mnemonic for a time to live
816 */
817 char *
818 __p_time(value)
819 u_int32_t value;
820 {
821 static char nbuf[40];
822 int secs, mins, hours, days;
823 register char *p;
824
825 if (value == 0) {
826 strcpy(nbuf, "0 secs");
827 return (nbuf);
828 }
829
830 secs = value % 60;
831 value /= 60;
832 mins = value % 60;
833 value /= 60;
834 hours = value % 24;
835 value /= 24;
836 days = value;
837 value = 0;
838
839 #define PLURALIZE(x) x, (x == 1) ? "" : "s"
840 p = nbuf;
841 if (days) {
842 (void)sprintf(p, "%d day%s", PLURALIZE(days));
843 while (*++p);
844 }
845 if (hours) {
846 if (days)
847 *p++ = ' ';
848 (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
849 while (*++p);
850 }
851 if (mins) {
852 if (days || hours)
853 *p++ = ' ';
854 (void)sprintf(p, "%d min%s", PLURALIZE(mins));
855 while (*++p);
856 }
857 if (secs || ! (days || hours || mins)) {
858 if (days || hours || mins)
859 *p++ = ' ';
860 (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
861 }
862 return (nbuf);
863 }