]>
git.saurik.com Git - apple/libinfo.git/blob - dns.subproj/res_debug.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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
22 * @APPLE_LICENSE_HEADER_END@
25 * ++Copyright++ 1985, 1990, 1993
27 * Copyright (c) 1985, 1990, 1993
28 * The Regents of the University of California. All rights reserved.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
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.
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
58 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
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.
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
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 */
84 #include <sys/param.h>
85 #include <netinet/in.h>
86 #include <arpa/inet.h>
91 #include "nameser8_compat.h"
92 #include "resolv8_compat.h"
94 #if defined(BSD) && (BSD >= 199103)
97 # include "portability.h"
100 #if defined(USE_OPTIONS_H)
101 # include "options.h"
104 const char *_res_opcodes
[] = {
108 "CQUERYU", /* experimental */
109 "NOTIFY", /* experimental */
123 const char *_res_resultcodes
[] = {
142 /* XXX: we should use getservbyport() instead. */
147 static char nbuf
[20];
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
);
200 /* XXX: we should use getprotobynumber() instead. */
205 static char nbuf
[20];
208 case 1: return "icmp";
209 case 2: return "igmp";
210 case 3: return "ggp";
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
);
224 static const u_char
*
225 do_rrset(msg
, len
, cp
, cnt
, pflag
, file
, hs
)
227 const u_char
*cp
, *msg
;
235 * Print answer records.
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
);
243 if ((!_res
.pfcode
) || sflag
) {
244 cp
= p_rr(cp
, msg
, file
);
247 cp
+= __dn_skipname(cp
, cp
+ MAXCDNAME
);
251 dlen
= _getshort((u_char
*)cp
);
255 if ((cp
- msg
) > len
)
258 if ((!_res
.pfcode
) ||
259 ((sflag
) && (_res
.pfcode
& RES_PRF_HEAD1
)))
269 __fp_query(msg
, stdout
);
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.
285 * Print the current options.
286 * This is intended to be primarily a debugging routine.
289 __fp_resstat(statp
, file
)
290 struct __res_state
*statp
;
293 register u_long mask
;
295 fprintf(file
, ";; res options:");
298 for (mask
= 1; mask
!= 0; mask
<<= 1)
299 if (statp
->options
& mask
)
300 fprintf(file
, " %s", p_option(mask
));
305 * Print the contents of a query.
306 * This is intended to be primarily a debugging routine.
309 __fp_nquery(msg
, len
, file
)
314 register const u_char
*cp
, *endMark
;
315 register const HEADER
*hp
;
318 if ((_res
.options
& RES_INIT
) == 0 && res_init() == -1)
321 #define TruncTest(x) if (x >= endMark) goto trunc
322 #define ErrorTest(x) if (x == NULL) goto error
325 * Print header fields.
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
],
338 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEAD2
)) {
339 fprintf(file
, "; flags:");
341 fprintf(file
, " qr");
343 fprintf(file
, " aa");
345 fprintf(file
, " tc");
347 fprintf(file
, " rd");
349 fprintf(file
, " ra");
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
));
357 if ((!_res
.pfcode
) || (_res
.pfcode
&
358 (RES_PRF_HEADX
| RES_PRF_HEAD2
| RES_PRF_HEAD1
))) {
362 * Print question records.
364 if ((n
= ntohs(hp
->qdcount
))) {
365 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
366 fprintf(file
, ";; QUESTIONS:\n");
368 fprintf(file
, ";;\t");
370 cp
= p_cdnname(cp
, msg
, len
, file
);
373 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
374 fprintf(file
, ", type = %s",
375 __p_type(_getshort((u_char
*)cp
)));
378 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
379 fprintf(file
, ", class = %s\n",
380 __p_class(_getshort((u_char
*)cp
)));
386 * Print authoritative answer records
389 cp
= do_rrset(msg
, len
, cp
, hp
->ancount
, RES_PRF_ANS
, file
,
394 * print name server records
397 cp
= do_rrset(msg
, len
, cp
, hp
->nscount
, RES_PRF_AUTH
, file
,
398 ";; AUTHORITY RECORDS:\n");
403 * print additional records
405 cp
= do_rrset(msg
, len
, cp
, hp
->arcount
, RES_PRF_ADD
, file
,
406 ";; ADDITIONAL RECORDS:\n");
410 fprintf(file
, "\n;; ...truncated\n");
413 fprintf(file
, "\n;; ...malformed\n");
417 __fp_query(msg
, file
)
421 fp_nquery(msg
, PACKETSZ
, file
);
425 __p_cdnname(cp
, msg
, len
, file
)
426 const u_char
*cp
, *msg
;
433 if ((n
= dn_expand(msg
, msg
+ len
, cp
, name
, sizeof name
)) < 0)
443 __p_cdname(cp
, msg
, file
)
444 const u_char
*cp
, *msg
;
447 return (p_cdnname(cp
, msg
, PACKETSZ
, file
));
450 /* XXX: the rest of these functions need to become length-limited, too. (vix)
454 __p_fqname(cp
, msg
, file
)
455 const u_char
*cp
, *msg
;
461 if ((n
= dn_expand(msg
, cp
+ MAXCDNAME
, cp
, name
, sizeof name
)) < 0)
463 if (name
[0] == '\0') {
467 if (name
[strlen(name
) - 1] != '.')
474 * Print resource record fields in human readable form.
477 __p_rr(cp
, msg
, file
)
478 const u_char
*cp
, *msg
;
481 int type
, class, n
, c
;
483 struct in_addr inaddr
;
484 const u_char
*cp1
, *cp2
;
488 if ((_res
.options
& RES_INIT
) == 0 && res_init() == -1) {
489 h_errno
= NETDB_INTERNAL
;
492 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
493 return (NULL
); /* compression error */
494 type
= _getshort((u_char
*)cp
);
496 class = _getshort((u_char
*)cp
);
498 tmpttl
= _getlong((u_char
*)cp
);
500 dlen
= _getshort((u_char
*)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
));
509 * Print type specific data, if appropriate
516 bcopy(cp
, (char *)&inaddr
, INADDRSZ
);
518 fprintf(file
, "\t%s", inet_ntoa(inaddr
));
520 } else if (dlen
== 7) {
525 address
= inet_ntoa(inaddr
);
527 protocol
= *(u_char
*)cp
;
528 cp
+= sizeof(u_char
);
529 port
= _getshort((u_char
*)cp
);
531 fprintf(file
, "\t%s\t; proto %d, port %d",
532 address
, protocol
, port
);
546 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
554 fprintf(file
, "\t%.*s", n
, cp
);
557 if ((cp
< cp2
) && (n
= *cp
++)) {
558 fprintf(file
, "\t%.*s", n
, cp
);
560 } else if (type
== T_HINFO
)
561 fprintf(file
, "\n;; *** Warning *** OS-type missing");
566 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
569 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
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
));
591 fprintf(file
, "\t%d ", _getshort((u_char
*)cp
));
593 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
598 fprintf(file
, "\t%d ", _getshort((u_char
*)cp
));
600 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
603 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
609 (void) fputs("\t\"", file
);
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
);
618 (void) putc(*cp
++, file
);
625 (void) fprintf(file
, "\t%s", inet_nsap_ntoa(dlen
, cp
, NULL
));
632 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
635 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
641 fputs((char *)cp
, file
);
648 fprintf(file
, "\t%u", _getlong((u_char
*)cp
));
654 if (dlen
< INT32SZ
+ 1)
656 bcopy(cp
, (char *)&inaddr
, INADDRSZ
);
658 fprintf(file
, "\t%s %s ( ",
661 cp
+= sizeof(u_char
);
664 while (cp
< cp1
+ dlen
) {
669 fputs("\n\t\t\t", file
);
672 fputs(dewks(n
), file
);
682 #ifdef ALLOW_T_UNSPEC
689 if (dlen
< NumBytes
) NumBytes
= dlen
;
690 fprintf(file
, "\tFirst %d bytes of hex data:",
692 for (i
= 0, DataPtr
= cp
; i
< NumBytes
; i
++, DataPtr
++)
693 fprintf(file
, " %x", *DataPtr
);
697 #endif /* ALLOW_T_UNSPEC */
700 fprintf(file
, "\t?%d?", type
);
704 fprintf(file
, "\t; dlen=%d, ttl %s\n", dlen
, __p_time(tmpttl
));
708 if (cp
- cp1
!= dlen
) {
710 fprintf(file
, ";; packet size error (found %ld, dlen was %d)\n", cp
- cp1
, dlen
);
712 fprintf(file
, ";; packet size error (found %d, dlen was %d)\n", cp
- cp1
, dlen
);
720 * Return a string for the type
726 static char nbuf
[20];
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
);
771 * Return a mnemonic for class
777 static char nbuf
[20];
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
);
788 * Return a mnemonic for an option
794 static char nbuf
[40];
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
);
815 * Return a mnemonic for a time to live
821 static char nbuf
[40];
822 int secs
, mins
, hours
, days
;
826 strcpy(nbuf
, "0 secs");
839 #define PLURALIZE(x) x, (x == 1) ? "" : "s"
842 (void)sprintf(p
, "%d day%s", PLURALIZE(days
));
848 (void)sprintf(p
, "%d hour%s", PLURALIZE(hours
));
854 (void)sprintf(p
, "%d min%s", PLURALIZE(mins
));
857 if (secs
|| ! (days
|| hours
|| mins
)) {
858 if (days
|| hours
|| mins
)
860 (void)sprintf(p
, "%d sec%s", PLURALIZE(secs
));