2 * ++Copyright++ 1985, 1990, 1993
4 * Copyright (c) 1985, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
37 * Permission to use, copy, modify, and distribute this software for any
38 * purpose with or without fee is hereby granted, provided that the above
39 * copyright notice and this permission notice appear in all copies, and that
40 * the name of Digital Equipment Corporation not be used in advertising or
41 * publicity pertaining to distribution of the document or software without
42 * specific, written prior permission.
44 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
45 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
46 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
47 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
48 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
49 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
50 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * Portions Copyright (c) 1995 by International Business Machines, Inc.
55 * International Business Machines, Inc. (hereinafter called IBM) grants
56 * permission under its copyrights to use, copy, modify, and distribute this
57 * Software with or without fee, provided that the above copyright notice and
58 * all paragraphs of this notice appear in all copies, and that the name of IBM
59 * not be used in connection with the marketing of any product incorporating
60 * the Software or modifications thereof, without specific, written prior
63 * To the extent it has a right to do so, IBM grants an immunity from suit
64 * under its patents, if any, for the use, sale or manufacture of products to
65 * the extent that such products are used for performing Domain Name System
66 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
67 * granted for any product per se or for any other function of any product.
69 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
70 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
71 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
72 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
73 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
74 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
78 #if defined(LIBC_SCCS) && !defined(lint)
79 static char sccsid
[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
80 static char rcsid
[] = "$Id$";
81 #endif /* LIBC_SCCS and not lint */
83 #include <sys/param.h>
84 #include <sys/types.h>
85 #include <sys/socket.h>
86 #include <netinet/in.h>
87 #include <arpa/inet.h>
88 #include <arpa/nameser.h>
96 #if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
100 # include "../conf/portability.h"
103 #if defined(USE_OPTIONS_H)
104 # include "../conf/options.h"
107 extern const char *_res_opcodes
[];
108 extern const char *_res_resultcodes
[];
110 /* XXX: we should use getservbyport() instead. */
115 static char nbuf
[20];
118 case 5: return "rje";
119 case 7: return "echo";
120 case 9: return "discard";
121 case 11: return "systat";
122 case 13: return "daytime";
123 case 15: return "netstat";
124 case 17: return "qotd";
125 case 19: return "chargen";
126 case 20: return "ftp-data";
127 case 21: return "ftp";
128 case 23: return "telnet";
129 case 25: return "smtp";
130 case 37: return "time";
131 case 39: return "rlp";
132 case 42: return "name";
133 case 43: return "whois";
134 case 53: return "domain";
135 case 57: return "apts";
136 case 59: return "apfs";
137 case 67: return "bootps";
138 case 68: return "bootpc";
139 case 69: return "tftp";
140 case 77: return "rje";
141 case 79: return "finger";
142 case 87: return "link";
143 case 95: return "supdup";
144 case 100: return "newacct";
145 case 101: return "hostnames";
146 case 102: return "iso-tsap";
147 case 103: return "x400";
148 case 104: return "x400-snd";
149 case 105: return "csnet-ns";
150 case 109: return "pop-2";
151 case 111: return "sunrpc";
152 case 113: return "auth";
153 case 115: return "sftp";
154 case 117: return "uucp-path";
155 case 119: return "nntp";
156 case 121: return "erpc";
157 case 123: return "ntp";
158 case 133: return "statsrv";
159 case 136: return "profile";
160 case 144: return "NeWS";
161 case 161: return "snmp";
162 case 162: return "snmp-trap";
163 case 170: return "print-srv";
164 default: (void) sprintf(nbuf
, "%d", wks
); return (nbuf
);
168 /* XXX: we should use getprotobynumber() instead. */
173 static char nbuf
[20];
176 case 1: return "icmp";
177 case 2: return "igmp";
178 case 3: return "ggp";
180 case 6: return "tcp";
181 case 7: return "ucl";
182 case 8: return "egp";
183 case 9: return "igp";
184 case 11: return "nvp-II";
185 case 12: return "pup";
186 case 16: return "chaos";
187 case 17: return "udp";
188 default: (void) sprintf(nbuf
, "%d", protonum
); return (nbuf
);
192 static const u_char
*
193 do_rrset(msg
, len
, cp
, cnt
, pflag
, file
, hs
)
195 const u_char
*cp
, *msg
;
203 * Print answer records.
205 sflag
= (_res
.pfcode
& pflag
);
206 if ((n
= ntohs(cnt
))) {
207 if ((!_res
.pfcode
) ||
208 ((sflag
) && (_res
.pfcode
& RES_PRF_HEAD1
)))
211 if ((!_res
.pfcode
) || sflag
) {
212 cp
= p_rr(cp
, msg
, file
);
215 cp
+= __dn_skipname(cp
, cp
+ MAXCDNAME
);
219 dlen
= _getshort((u_char
*)cp
);
223 if ((cp
- msg
) > len
)
226 if ((!_res
.pfcode
) ||
227 ((sflag
) && (_res
.pfcode
& RES_PRF_HEAD1
)))
237 __fp_query(msg
, stdout
);
242 /* ultrix 4.0's packaging has some icky packaging. alias for it here.
243 * there is more junk of this kind over in res_comp.c.
254 * Print the current options.
255 * This is intended to be primarily a debugging routine.
258 __fp_resstat(statp
, file
)
259 struct __res_state
*statp
;
262 register u_long mask
;
264 fprintf(file
, ";; res options:");
267 for (mask
= 1; mask
!= 0; mask
<<= 1)
268 if (statp
->options
& mask
)
269 fprintf(file
, " %s", p_option(mask
));
274 * Print the contents of a query.
275 * This is intended to be primarily a debugging routine.
278 __fp_nquery(msg
, len
, file
)
283 register const u_char
*cp
, *endMark
;
284 register const HEADER
*hp
;
287 if ((_res
.options
& RES_INIT
) == 0 && res_init() == -1)
290 #define TruncTest(x) if (x > endMark) goto trunc
291 #define ErrorTest(x) if (x == NULL) goto error
294 * Print header fields.
299 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEADX
) || hp
->rcode
) {
300 fprintf(file
, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
301 _res_opcodes
[hp
->opcode
],
302 _res_resultcodes
[hp
->rcode
],
306 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEADX
))
308 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEAD2
)) {
309 fprintf(file
, "; flags:");
311 fprintf(file
, " qr");
313 fprintf(file
, " aa");
315 fprintf(file
, " tc");
317 fprintf(file
, " rd");
319 fprintf(file
, " ra");
321 fprintf(file
, " UNUSED-BIT-ON");
323 fprintf(file
, " ad");
325 fprintf(file
, " cd");
327 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEAD1
)) {
328 fprintf(file
, "; Ques: %d", ntohs(hp
->qdcount
));
329 fprintf(file
, ", Ans: %d", ntohs(hp
->ancount
));
330 fprintf(file
, ", Auth: %d", ntohs(hp
->nscount
));
331 fprintf(file
, ", Addit: %d", ntohs(hp
->arcount
));
333 if ((!_res
.pfcode
) || (_res
.pfcode
&
334 (RES_PRF_HEADX
| RES_PRF_HEAD2
| RES_PRF_HEAD1
))) {
338 * Print question records.
340 if ((n
= ntohs(hp
->qdcount
))) {
341 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
342 fprintf(file
, ";; QUESTIONS:\n");
344 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
345 fprintf(file
, ";;\t");
347 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
348 cp
= p_cdnname(cp
, msg
, len
, file
);
353 if ((n
= dn_expand(msg
, msg
+len
, cp
, name
,
361 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
362 fprintf(file
, ", type = %s",
363 __p_type(_getshort((u_char
*)cp
)));
366 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
367 fprintf(file
, ", class = %s\n",
368 __p_class(_getshort((u_char
*)cp
)));
370 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
375 * Print authoritative answer records
378 cp
= do_rrset(msg
, len
, cp
, hp
->ancount
, RES_PRF_ANS
, file
,
383 * print name server records
386 cp
= do_rrset(msg
, len
, cp
, hp
->nscount
, RES_PRF_AUTH
, file
,
387 ";; AUTHORITY RECORDS:\n");
392 * print additional records
394 cp
= do_rrset(msg
, len
, cp
, hp
->arcount
, RES_PRF_ADD
, file
,
395 ";; ADDITIONAL RECORDS:\n");
399 fprintf(file
, "\n;; ...truncated\n");
402 fprintf(file
, "\n;; ...malformed\n");
406 __fp_query(msg
, file
)
410 fp_nquery(msg
, PACKETSZ
, file
);
414 __p_cdnname(cp
, msg
, len
, file
)
415 const u_char
*cp
, *msg
;
422 if ((n
= dn_expand(msg
, msg
+ len
, cp
, name
, sizeof name
)) < 0)
432 __p_cdname(cp
, msg
, file
)
433 const u_char
*cp
, *msg
;
436 return (p_cdnname(cp
, msg
, PACKETSZ
, file
));
440 /* Return a fully-qualified domain name from a compressed name (with
444 __p_fqnname(cp
, msg
, msglen
, name
, namelen
)
445 const u_char
*cp
, *msg
;
452 if ((n
= dn_expand(msg
, cp
+ msglen
, cp
, name
, namelen
)) < 0)
454 newlen
= strlen (name
);
455 if (newlen
== 0 || name
[newlen
- 1] != '.') {
456 if (newlen
+1 >= namelen
) /* Lack space for final dot */
459 strcpy(name
+ newlen
, ".");
464 /* XXX: the rest of these functions need to become length-limited, too. (vix)
468 __p_fqname(cp
, msg
, file
)
469 const u_char
*cp
, *msg
;
475 n
= __p_fqnname(cp
, msg
, MAXCDNAME
, name
, sizeof name
);
483 * Print resource record fields in human readable form.
486 __p_rr(cp
, msg
, file
)
487 const u_char
*cp
, *msg
;
490 int type
, class, dlen
, n
, c
;
491 struct in_addr inaddr
;
492 const u_char
*cp1
, *cp2
;
496 char rrname
[MAXDNAME
]; /* The fqdn of this RR */
497 char base64_key
[MAX_KEY_BASE64
];
499 if ((_res
.options
& RES_INIT
) == 0 && res_init() == -1) {
500 __set_h_errno (NETDB_INTERNAL
);
503 cp
= __p_fqnname(cp
, msg
, MAXCDNAME
, rrname
, sizeof rrname
);
505 return (NULL
); /* compression error */
508 type
= _getshort((u_char
*)cp
);
510 class = _getshort((u_char
*)cp
);
512 tmpttl
= _getlong((u_char
*)cp
);
514 dlen
= _getshort((u_char
*)cp
);
517 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_TTLID
))
518 fprintf(file
, "\t%lu", (u_long
)tmpttl
);
519 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_CLASS
))
520 fprintf(file
, "\t%s", __p_class(class));
521 fprintf(file
, "\t%s", __p_type(type
));
523 * Print type specific data, if appropriate
530 bcopy(cp
, (char *)&inaddr
, INADDRSZ
);
532 fprintf(file
, "\t%s", inet_ntoa(inaddr
));
534 } else if (dlen
== 7) {
539 address
= inet_ntoa(inaddr
);
541 protocol
= *(u_char
*)cp
;
542 cp
+= sizeof (u_char
);
543 port
= _getshort((u_char
*)cp
);
545 fprintf(file
, "\t%s\t; proto %d, port %d",
546 address
, protocol
, port
);
560 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
567 (void) fputs("\t\"", file
);
568 if ((n
= (unsigned char) *cp
++) != 0) {
569 for (c
= n
; c
> 0 && cp
< cp2
; c
--) {
570 if (strchr("\n\"\\", *cp
))
571 (void) putc('\\', file
);
572 (void) putc(*cp
++, file
);
576 if (cp
< cp2
&& (n
= (unsigned char) *cp
++) != 0) {
577 (void) fputs ("\t\"", file
);
578 for (c
= n
; c
> 0 && cp
< cp2
; c
--) {
579 if (strchr("\n\"\\", *cp
))
580 (void) putc('\\', file
);
581 (void) putc(*cp
++, file
);
584 } else if (type
== T_HINFO
) {
585 (void) fputs("\"?\"", file
);
586 fprintf(file
, "\n;; *** Warning *** OS-type missing");
592 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
595 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
598 t
= _getlong((u_char
*)cp
); cp
+= INT32SZ
;
599 fprintf(file
, "\t\t\t%lu\t; serial\n", (u_long
)t
);
600 t
= _getlong((u_char
*)cp
); cp
+= INT32SZ
;
601 fprintf(file
, "\t\t\t%lu\t; refresh (%s)\n",
602 (u_long
)t
, __p_time(t
));
603 t
= _getlong((u_char
*)cp
); cp
+= INT32SZ
;
604 fprintf(file
, "\t\t\t%lu\t; retry (%s)\n",
605 (u_long
)t
, __p_time(t
));
606 t
= _getlong((u_char
*)cp
); cp
+= INT32SZ
;
607 fprintf(file
, "\t\t\t%lu\t; expire (%s)\n",
608 (u_long
)t
, __p_time(t
));
609 t
= _getlong((u_char
*)cp
); cp
+= INT32SZ
;
610 fprintf(file
, "\t\t\t%lu )\t; minimum (%s)",
611 (u_long
)t
, __p_time(t
));
617 fprintf(file
, "\t%d ", _getshort((u_char
*)cp
));
619 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
624 fprintf(file
, "\t%d ", _getshort((u_char
*)cp
));
626 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
629 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
635 (void) fputs("\t\"", file
);
636 if ((n
= (unsigned char) *cp
++) != 0) {
637 for (c
= n
; c
> 0 && cp
< cp2
; c
--) {
638 if (strchr("\n\"\\", *cp
))
639 (void) putc('\\', file
);
640 (void) putc(*cp
++, file
);
647 (void) putc('\t', file
);
651 if ((n
= (unsigned char) *cp
++)) {
652 for (c
= n
; c
> 0 && cp
< cp2
; c
--) {
653 if (strchr("\n\"\\", *cp
))
654 (void) putc('\\', file
);
655 (void) putc(*cp
++, file
);
665 (void) fprintf(file
, "\t%s", inet_nsap_ntoa(dlen
, cp
, NULL
));
670 char t
[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
672 fprintf(file
, "\t%s", inet_ntop(AF_INET6
, cp
, t
, sizeof t
));
680 (void) fprintf(file
, "\t%s", loc_ntoa(cp
, t
));
686 u_int order
, preference
;
688 order
= _getshort(cp
); cp
+= INT16SZ
;
689 preference
= _getshort(cp
); cp
+= INT16SZ
;
690 fprintf(file
, "\t%u %u ",order
, preference
);
693 fprintf(file
,"\"%.*s\" ", (int)n
, cp
);
697 fprintf(file
,"\"%.*s\" ", (int)n
, cp
);
701 fprintf(file
,"\"%.*s\" ", (int)n
, cp
);
703 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
709 u_int priority
, weight
, port
;
711 priority
= _getshort(cp
); cp
+= INT16SZ
;
712 weight
= _getshort(cp
); cp
+= INT16SZ
;
713 port
= _getshort(cp
); cp
+= INT16SZ
;
714 fprintf(file
, "\t%u %u %u ", priority
, weight
, port
);
715 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
723 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
726 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
732 fputs((char *)cp
, file
);
739 fprintf(file
, "\t%u", _getlong((u_char
*)cp
));
745 if (dlen
< INT32SZ
+ 1)
747 bcopy(cp
, (char *)&inaddr
, INADDRSZ
);
749 fprintf(file
, "\t%s %s ( ",
752 cp
+= sizeof (u_char
);
755 while (cp
< cp1
+ dlen
) {
760 fputs("\n\t\t\t", file
);
763 fputs(dewks(n
), file
);
775 keyflags
= _getshort(cp
);
777 fprintf(file
,"0x%04x", keyflags
); /* flags */
778 fprintf(file
," %u", *cp
++); /* protocol */
779 fprintf(file
," %u (", *cp
++); /* algorithm */
781 n
= b64_ntop(cp
, (cp1
+ dlen
) - cp
,
782 base64_key
, sizeof base64_key
);
783 for (c
= 0; c
< n
; ++c
) {
785 fprintf(file
, "\n\t");
786 putc(base64_key
[c
], file
); /* public key data */
791 fprintf(file
, "\t; BAD BASE64");
797 type
= _getshort((u_char
*)cp
);
799 fprintf(file
, " %s", p_type(type
));
800 fprintf(file
, "\t%d", *cp
++); /* algorithm */
801 /* Check label value and print error if wrong. */
803 c
= dn_count_labels (rrname
);
805 fprintf(file
, "\t; LABELS WRONG (%d should be %d)\n\t",
808 n
= _getlong((u_char
*)cp
);
809 if ((u_int32_t
) n
!= tmpttl
)
810 fprintf(file
, " %u", n
);
813 fprintf(file
, " (\n\t%s",
814 __p_secstodate(_getlong((u_char
*)cp
)));
817 fprintf(file
, " %s", __p_secstodate(_getlong((u_char
*)cp
)));
820 fprintf(file
," %u ", _getshort((u_char
*)cp
));
823 cp
= p_fqname(cp
, msg
, file
);
824 n
= b64_ntop(cp
, (cp1
+ dlen
) - cp
,
825 base64_key
, sizeof base64_key
);
826 for (c
= 0; c
< n
; c
++) {
828 fprintf (file
, "\n\t");
829 putc(base64_key
[c
], file
); /* signature */
834 fprintf(file
, "\t; BAD BASE64");
839 #ifdef ALLOW_T_UNSPEC
846 if (dlen
< NumBytes
) NumBytes
= dlen
;
847 fprintf(file
, "\tFirst %d bytes of hex data:",
849 for (i
= 0, DataPtr
= cp
; i
< NumBytes
; i
++, DataPtr
++)
850 fprintf(file
, " %x", *DataPtr
);
854 #endif /* ALLOW_T_UNSPEC */
857 fprintf(file
, "\t?%d?", type
);
861 fprintf(file
, "\t; dlen=%d, ttl %s\n", dlen
, __p_time(tmpttl
));
865 if (cp
- cp1
!= dlen
) {
867 ";; packet size error (found %lu, dlen was %d)\n",
868 (unsigned long) (cp
- cp1
), dlen
);
875 * Names of RR classes and qclasses. Classes and qclasses are the same, except
876 * that C_ANY is a qclass but not a class. (You can ask for records of class
877 * C_ANY, but you can't have any records of that class in the database.)
879 const struct res_sym __p_class_syms
[] = {
889 * Names of RR types and qtypes. Types and qtypes are the same, except
890 * that T_ANY is a qtype but not a type. (You can ask for records of type
891 * T_ANY, but you can't have any records of that type in the database.)
893 const struct res_sym __p_type_syms
[] = {
894 {T_A
, "A", "address"},
895 {T_NS
, "NS", "name server"},
896 {T_MD
, "MD", "mail destination (deprecated)"},
897 {T_MF
, "MF", "mail forwarder (deprecated)"},
898 {T_CNAME
, "CNAME", "canonical name"},
899 {T_SOA
, "SOA", "start of authority"},
900 {T_MB
, "MB", "mailbox"},
901 {T_MG
, "MG", "mail group member"},
902 {T_MR
, "MR", "mail rename"},
903 {T_NULL
, "NULL", "null"},
904 {T_WKS
, "WKS", "well-known service (deprecated)"},
905 {T_PTR
, "PTR", "domain name pointer"},
906 {T_HINFO
, "HINFO", "host information"},
907 {T_MINFO
, "MINFO", "mailbox information"},
908 {T_MX
, "MX", "mail exchanger"},
909 {T_TXT
, "TXT", "text"},
910 {T_RP
, "RP", "responsible person"},
911 {T_AFSDB
, "AFSDB", "DCE or AFS server"},
912 {T_X25
, "X25", "X25 address"},
913 {T_ISDN
, "ISDN", "ISDN address"},
914 {T_RT
, "RT", "router"},
915 {T_NSAP
, "NSAP", "nsap address"},
916 {T_NSAP_PTR
, "NSAP_PTR", "domain name pointer"},
917 {T_SIG
, "SIG", "signature"},
918 {T_KEY
, "KEY", "key"},
919 {T_PX
, "PX", "mapping information"},
920 {T_GPOS
, "GPOS", "geographical position (withdrawn)"},
921 {T_AAAA
, "AAAA", "IPv6 address"},
922 {T_LOC
, "LOC", "location"},
923 {T_NXT
, "NXT", "next valid name (unimplemented)"},
924 {T_EID
, "EID", "endpoint identifier (unimplemented)"},
925 {T_NIMLOC
, "NIMLOC", "NIMROD locator (unimplemented)"},
926 {T_SRV
, "SRV", "server selection"},
927 {T_ATMA
, "ATMA", "ATM address (unimplemented)"},
928 {T_IXFR
, "IXFR", "incremental zone transfer"},
929 {T_AXFR
, "AXFR", "zone transfer"},
930 {T_MAILB
, "MAILB", "mailbox-related data (deprecated)"},
931 {T_MAILA
, "MAILA", "mail agent (deprecated)"},
932 {T_UINFO
, "UINFO", "user information (nonstandard)"},
933 {T_UID
, "UID", "user ID (nonstandard)"},
934 {T_GID
, "GID", "group ID (nonstandard)"},
935 {T_NAPTR
, "NAPTR", "URN Naming Authority"},
936 #ifdef ALLOW_T_UNSPEC
937 {T_UNSPEC
, "UNSPEC", "unspecified data (nonstandard)"},
938 #endif /* ALLOW_T_UNSPEC */
939 {T_ANY
, "ANY", "\"any\""},
944 __sym_ston(syms
, name
, success
)
945 const struct res_sym
*syms
;
950 /* Changed to prevent warning. --drepper@gnu */
951 for (; syms
->name
!= 0; syms
++) {
953 for (NULL
; syms
->name
!= 0; syms
++) {
955 if (strcasecmp (name
, syms
->name
) == 0) {
958 return (syms
->number
);
963 return (syms
->number
); /* The default value. */
967 __sym_ntos(syms
, number
, success
)
968 const struct res_sym
*syms
;
972 static char unname
[20];
975 /* Changed to prevent warning. --drepper@gnu */
976 for (; syms
->name
!= 0; syms
++) {
978 for (NULL
; syms
->name
!= 0; syms
++) {
980 if (number
== syms
->number
) {
987 sprintf (unname
, "%d", number
);
995 __sym_ntop(syms
, number
, success
)
996 const struct res_sym
*syms
;
1000 static char unname
[20];
1003 /* Changed to prevent warning. --drepper@gnu */
1004 for (; syms
->name
!= 0; syms
++) {
1006 for (NULL
; syms
->name
!= 0; syms
++) {
1008 if (number
== syms
->number
) {
1011 return (syms
->humanname
);
1014 sprintf(unname
, "%d", number
);
1021 * Return a string for the type
1027 return (__sym_ntos (__p_type_syms
, type
, (int *)0));
1031 * Return a mnemonic for class
1037 return (__sym_ntos (__p_class_syms
, class, (int *)0));
1041 * Return a mnemonic for an option
1047 static char nbuf
[40];
1050 case RES_INIT
: return "init";
1051 case RES_DEBUG
: return "debug";
1052 case RES_AAONLY
: return "aaonly(unimpl)";
1053 case RES_USEVC
: return "usevc";
1054 case RES_PRIMARY
: return "primry(unimpl)";
1055 case RES_IGNTC
: return "igntc";
1056 case RES_RECURSE
: return "recurs";
1057 case RES_DEFNAMES
: return "defnam";
1058 case RES_STAYOPEN
: return "styopn";
1059 case RES_DNSRCH
: return "dnsrch";
1060 case RES_INSECURE1
: return "insecure1";
1061 case RES_INSECURE2
: return "insecure2";
1062 default: sprintf(nbuf
, "?0x%lx?", (u_long
)option
);
1068 * Return a mnemonic for a time to live
1074 static char nbuf
[60];
1075 int secs
, mins
, hours
, days
;
1079 strcpy(nbuf
, "0 secs");
1092 #define PLURALIZE(x) x, (x == 1) ? "" : "s"
1095 (void)sprintf(p
, "%d day%s", PLURALIZE(days
));
1101 (void)sprintf(p
, "%d hour%s", PLURALIZE(hours
));
1107 (void)sprintf(p
, "%d min%s", PLURALIZE(mins
));
1110 if (secs
|| ! (days
|| hours
|| mins
)) {
1111 if (days
|| hours
|| mins
)
1113 (void)sprintf(p
, "%d sec%s", PLURALIZE(secs
));
1119 * routines to convert between on-the-wire RR format and zone file format.
1120 * Does not contain conversion to/from decimal degrees; divide or multiply
1121 * by 60*60*1000 for that.
1124 static unsigned int poweroften
[10] = {1, 10, 100, 1000, 10000, 100000,
1125 1000000,10000000,100000000,1000000000};
1127 /* takes an XeY precision/size value, returns a string representation. */
1132 static char retbuf
[sizeof "90000000.00"];
1134 int mantissa
, exponent
;
1136 mantissa
= (int)((prec
>> 4) & 0x0f) % 10;
1137 exponent
= (int)((prec
>> 0) & 0x0f) % 10;
1139 val
= mantissa
* poweroften
[exponent
];
1141 (void) sprintf(retbuf
, "%ld.%.2ld", val
/100, val
%100);
1145 /* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
1147 precsize_aton(strptr
)
1150 u_int8_t retval
= 0;
1156 while (isdigit(*cp
)) {
1158 mantissa
= *cp
- '0';
1168 mantissa
= *cp
- '0';
1175 mantissa
= *cp
- '0';
1189 retval
= (mantissa
<< 4) | exponent
;
1194 /* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
1196 latlon2ul(latlonstrptr
,which
)
1197 char **latlonstrptr
;
1202 int deg
= 0, min
= 0, secs
= 0, secsfrac
= 0;
1206 while (isdigit(*cp
))
1207 deg
= deg
* 10 + (*cp
++ - '0');
1209 while (isspace(*cp
))
1212 if (!(isdigit(*cp
)))
1215 while (isdigit(*cp
))
1216 min
= min
* 10 + (*cp
++ - '0');
1218 while (isspace(*cp
))
1221 if (!(isdigit(*cp
)))
1224 while (isdigit(*cp
))
1225 secs
= secs
* 10 + (*cp
++ - '0');
1227 if (*cp
== '.') { /* decimal seconds */
1230 secsfrac
= (*cp
++ - '0') * 100;
1232 secsfrac
+= (*cp
++ - '0') * 10;
1234 secsfrac
+= (*cp
++ - '0');
1240 while (!isspace(*cp
)) /* if any trailing garbage */
1243 while (isspace(*cp
))
1250 retval
= ((unsigned)1<<31)
1251 + (((((deg
* 60) + min
) * 60) + secs
) * 1000)
1256 retval
= ((unsigned)1<<31)
1257 - (((((deg
* 60) + min
) * 60) + secs
) * 1000)
1261 retval
= 0; /* invalid value -- indicates error */
1268 *which
= 1; /* latitude */
1272 *which
= 2; /* longitude */
1275 *which
= 0; /* error */
1279 cp
++; /* skip the hemisphere */
1281 while (!isspace(*cp
)) /* if any trailing garbage */
1284 while (isspace(*cp
)) /* move to next field */
1292 /* converts a zone file representation in a string to an RDATA on-the-wire
1293 * representation. */
1295 loc_aton(ascii
, binary
)
1299 const char *cp
, *maxcp
;
1302 u_int32_t latit
= 0, longit
= 0, alt
= 0;
1303 u_int32_t lltemp1
= 0, lltemp2
= 0;
1304 int altmeters
= 0, altfrac
= 0, altsign
= 1;
1305 u_int8_t hp
= 0x16; /* default = 1e6 cm = 10000.00m = 10km */
1306 u_int8_t vp
= 0x13; /* default = 1e3 cm = 10.00m */
1307 u_int8_t siz
= 0x12; /* default = 1e2 cm = 1.00m */
1308 int which1
= 0, which2
= 0;
1311 maxcp
= cp
+ strlen(ascii
);
1313 lltemp1
= latlon2ul(&cp
, &which1
);
1315 lltemp2
= latlon2ul(&cp
, &which2
);
1317 switch (which1
+ which2
) {
1318 case 3: /* 1 + 2, the only valid combination */
1319 if ((which1
== 1) && (which2
== 2)) { /* normal case */
1322 } else if ((which1
== 2) && (which2
== 1)) { /* reversed */
1325 } else { /* some kind of brokenness */
1329 default: /* we didn't get one of each */
1342 while (isdigit(*cp
))
1343 altmeters
= altmeters
* 10 + (*cp
++ - '0');
1345 if (*cp
== '.') { /* decimal meters */
1348 altfrac
= (*cp
++ - '0') * 10;
1350 altfrac
+= (*cp
++ - '0');
1355 alt
= (10000000 + (altsign
* (altmeters
* 100 + altfrac
)));
1357 while (!isspace(*cp
) && (cp
< maxcp
)) /* if trailing garbage or m */
1360 while (isspace(*cp
) && (cp
< maxcp
))
1366 siz
= precsize_aton(&cp
);
1368 while (!isspace(*cp
) && (cp
< maxcp
)) /* if trailing garbage or m */
1371 while (isspace(*cp
) && (cp
< maxcp
))
1377 hp
= precsize_aton(&cp
);
1379 while (!isspace(*cp
) && (cp
< maxcp
)) /* if trailing garbage or m */
1382 while (isspace(*cp
) && (cp
< maxcp
))
1388 vp
= precsize_aton(&cp
);
1393 *bcp
++ = (u_int8_t
) 0; /* version byte */
1398 PUTLONG(longit
,bcp
);
1401 return (16); /* size of RR in octets */
1404 /* takes an on-the-wire LOC RR and formats it in a human readable format. */
1406 loc_ntoa(binary
, ascii
)
1407 const u_char
*binary
;
1410 static char *error
= "?";
1411 register const u_char
*cp
= binary
;
1413 int latdeg
, latmin
, latsec
, latsecfrac
;
1414 int longdeg
, longmin
, longsec
, longsecfrac
;
1415 char northsouth
, eastwest
;
1416 int altmeters
, altfrac
, altsign
;
1418 const int referencealt
= 100000 * 100;
1420 int32_t latval
, longval
, altval
;
1422 u_int8_t sizeval
, hpval
, vpval
, versionval
;
1424 char *sizestr
, *hpstr
, *vpstr
;
1429 sprintf(ascii
, "; error: unknown LOC RR version");
1439 latval
= (templ
- ((unsigned)1<<31));
1442 longval
= (templ
- ((unsigned)1<<31));
1445 if (templ
< (u_int32_t
) referencealt
) { /* below WGS 84 spheroid */
1446 altval
= referencealt
- templ
;
1449 altval
= templ
- referencealt
;
1459 latsecfrac
= latval
% 1000;
1460 latval
= latval
/ 1000;
1461 latsec
= latval
% 60;
1462 latval
= latval
/ 60;
1463 latmin
= latval
% 60;
1464 latval
= latval
/ 60;
1473 longsecfrac
= longval
% 1000;
1474 longval
= longval
/ 1000;
1475 longsec
= longval
% 60;
1476 longval
= longval
/ 60;
1477 longmin
= longval
% 60;
1478 longval
= longval
/ 60;
1481 altfrac
= altval
% 100;
1482 altmeters
= (altval
/ 100) * altsign
;
1484 if ((sizestr
= strdup(precsize_ntoa(sizeval
))) == NULL
)
1486 if ((hpstr
= strdup(precsize_ntoa(hpval
))) == NULL
)
1488 if ((vpstr
= strdup(precsize_ntoa(vpval
))) == NULL
)
1492 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
1493 latdeg
, latmin
, latsec
, latsecfrac
, northsouth
,
1494 longdeg
, longmin
, longsec
, longsecfrac
, eastwest
,
1495 altmeters
, altfrac
, sizestr
, hpstr
, vpstr
);
1497 if (sizestr
!= error
)
1508 /* Return the number of DNS hierarchy levels in the name. */
1510 __dn_count_labels(name
)
1517 for(i
= 0, count
= 0; i
< len
; i
++) {
1522 /* don't count initial wildcard */
1527 /* don't count the null label for root. */
1528 /* if terminating '.' not found, must adjust */
1529 /* count to include last label */
1530 if (len
> 0 && name
[len
-1] != '.')
1537 * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
1538 * SIG records are required to be printed like this, by the Secure DNS RFC.
1541 __p_secstodate (secs
)
1544 static char output
[15]; /* YYYYMMDDHHMMSS and null */
1545 time_t clock
= secs
;
1548 __gmtime_r(&clock
, &time
);
1549 time
.tm_year
+= 1900;
1551 sprintf(output
, "%04d%02d%02d%02d%02d%02d",
1552 time
.tm_year
, time
.tm_mon
, time
.tm_mday
,
1553 time
.tm_hour
, time
.tm_min
, time
.tm_sec
);