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, ".");
463 /* XXX: the rest of these functions need to become length-limited, too. (vix)
467 __p_fqname(cp, msg, file)
468 const u_char *cp, *msg;
474 n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
482 * Print resource record fields in human readable form.
485 __p_rr(cp, msg, file)
486 const u_char *cp, *msg;
489 int type, class, dlen, n, c;
490 struct in_addr inaddr;
491 const u_char *cp1, *cp2;
495 char rrname[MAXDNAME]; /* The fqdn of this RR */
496 char base64_key[MAX_KEY_BASE64];
498 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
499 __set_h_errno (NETDB_INTERNAL);
502 cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
504 return (NULL); /* compression error */
507 type = _getshort((u_char*)cp);
509 class = _getshort((u_char*)cp);
511 tmpttl = _getlong((u_char*)cp);
513 dlen = _getshort((u_char*)cp);
516 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
517 fprintf(file, "\t%lu", (u_long)tmpttl);
518 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
519 fprintf(file, "\t%s", __p_class(class));
520 fprintf(file, "\t%s", __p_type(type));
522 * Print type specific data, if appropriate
529 bcopy(cp, (char *)&inaddr, INADDRSZ);
531 fprintf(file, "\t%s", inet_ntoa(inaddr));
533 } else if (dlen == 7) {
538 address = inet_ntoa(inaddr);
540 protocol = *(u_char*)cp;
541 cp += sizeof (u_char);
542 port = _getshort((u_char*)cp);
544 fprintf(file, "\t%s\t; proto %d, port %d",
545 address, protocol, port);
559 if ((cp = p_fqname(cp, msg, file)) == NULL)
566 (void) fputs("\t\"", file);
567 if ((n = (unsigned char) *cp++) != 0) {
568 for (c = n; c > 0 && cp < cp2; c--) {
569 if (strchr("\n\"\\", *cp))
570 (void) putc('\\', file);
571 (void) putc(*cp++, file);
575 if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
576 (void) fputs ("\t\"", file);
577 for (c = n; c > 0 && cp < cp2; c--) {
578 if (strchr("\n\"\\", *cp))
579 (void) putc('\\', file);
580 (void) putc(*cp++, file);
583 } else if (type == T_HINFO) {
584 (void) fputs("\"?\"", file);
585 fprintf(file, "\n;; *** Warning *** OS-type missing");
591 if ((cp = p_fqname(cp, msg, file)) == NULL)
594 if ((cp = p_fqname(cp, msg, file)) == NULL)
597 t = _getlong((u_char*)cp); cp += INT32SZ;
598 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
599 t = _getlong((u_char*)cp); cp += INT32SZ;
600 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
601 (u_long)t, __p_time(t));
602 t = _getlong((u_char*)cp); cp += INT32SZ;
603 fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
604 (u_long)t, __p_time(t));
605 t = _getlong((u_char*)cp); cp += INT32SZ;
606 fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
607 (u_long)t, __p_time(t));
608 t = _getlong((u_char*)cp); cp += INT32SZ;
609 fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
610 (u_long)t, __p_time(t));
616 fprintf(file, "\t%d ", _getshort((u_char*)cp));
618 if ((cp = p_fqname(cp, msg, file)) == NULL)
623 fprintf(file, "\t%d ", _getshort((u_char*)cp));
625 if ((cp = p_fqname(cp, msg, file)) == NULL)
628 if ((cp = p_fqname(cp, msg, file)) == NULL)
634 (void) fputs("\t\"", file);
635 if ((n = (unsigned char) *cp++) != 0) {
636 for (c = n; c > 0 && cp < cp2; c--) {
637 if (strchr("\n\"\\", *cp))
638 (void) putc('\\', file);
639 (void) putc(*cp++, file);
646 (void) putc('\t', file);
650 if (n = (unsigned char) *cp++) {
651 for (c = n; c > 0 && cp < cp2; c--) {
652 if (strchr("\n\"\\", *cp))
653 (void) putc('\\', file);
654 (void) putc(*cp++, file);
664 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
669 char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
671 fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));
679 (void) fprintf(file, "\t%s", loc_ntoa(cp, t));
685 u_int priority, weight, port;
687 priority = _getshort(cp); cp += INT16SZ;
688 weight = _getshort(cp); cp += INT16SZ;
689 port = _getshort(cp); cp += INT16SZ;
690 fprintf(file, "\t%u %u %u ", priority, weight, port);
691 if ((cp = p_fqname(cp, msg, file)) == NULL)
699 if ((cp = p_fqname(cp, msg, file)) == NULL)
702 if ((cp = p_fqname(cp, msg, file)) == NULL)
708 fputs((char *)cp, file);
715 fprintf(file, "\t%u", _getlong((u_char*)cp));
721 if (dlen < INT32SZ + 1)
723 bcopy(cp, (char *)&inaddr, INADDRSZ);
725 fprintf(file, "\t%s %s ( ",
728 cp += sizeof (u_char);
731 while (cp < cp1 + dlen) {
736 fputs("\n\t\t\t", file);
739 fputs(dewks(n), file);
751 keyflags = _getshort(cp);
753 fprintf(file,"0x%04x", keyflags ); /* flags */
754 fprintf(file," %u", *cp++); /* protocol */
755 fprintf(file," %u (", *cp++); /* algorithm */
757 n = b64_ntop(cp, (cp1 + dlen) - cp,
758 base64_key, sizeof base64_key);
759 for (c = 0; c < n; ++c) {
761 fprintf(file, "\n\t");
762 putc(base64_key[c], file); /* public key data */
767 fprintf(file, "\t; BAD BASE64");
773 type = _getshort((u_char*)cp);
775 fprintf(file, " %s", p_type(type));
776 fprintf(file, "\t%d", *cp++); /* algorithm */
777 /* Check label value and print error if wrong. */
779 c = dn_count_labels (rrname);
781 fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
784 n = _getlong((u_char*)cp);
786 fprintf(file, " %u", n);
789 fprintf(file, " (\n\t%s",
790 __p_secstodate(_getlong((u_char*)cp)));
793 fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
796 fprintf(file," %u ", _getshort((u_char*)cp));
799 cp = p_fqname(cp, msg, file);
800 n = b64_ntop(cp, (cp1 + dlen) - cp,
801 base64_key, sizeof base64_key);
802 for (c = 0; c < n; c++) {
804 fprintf (file, "\n\t");
805 putc(base64_key[c], file); /* signature */
810 fprintf(file, "\t; BAD BASE64");
815 #ifdef ALLOW_T_UNSPEC
822 if (dlen < NumBytes) NumBytes = dlen;
823 fprintf(file, "\tFirst %d bytes of hex data:",
825 for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
826 fprintf(file, " %x", *DataPtr);
830 #endif /* ALLOW_T_UNSPEC */
833 fprintf(file, "\t?%d?", type);
837 fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
841 if (cp - cp1 != dlen) {
843 ";; packet size error (found %lu, dlen was %d)\n",
844 (unsigned long) (cp - cp1), dlen);
851 * Names of RR classes and qclasses. Classes and qclasses are the same, except
852 * that C_ANY is a qclass but not a class. (You can ask for records of class
853 * C_ANY, but you can't have any records of that class in the database.)
855 const struct res_sym __p_class_syms[] = {
865 * Names of RR types and qtypes. Types and qtypes are the same, except
866 * that T_ANY is a qtype but not a type. (You can ask for records of type
867 * T_ANY, but you can't have any records of that type in the database.)
869 const struct res_sym __p_type_syms[] = {
870 {T_A, "A", "address"},
871 {T_NS, "NS", "name server"},
872 {T_MD, "MD", "mail destination (deprecated)"},
873 {T_MF, "MF", "mail forwarder (deprecated)"},
874 {T_CNAME, "CNAME", "canonical name"},
875 {T_SOA, "SOA", "start of authority"},
876 {T_MB, "MB", "mailbox"},
877 {T_MG, "MG", "mail group member"},
878 {T_MR, "MR", "mail rename"},
879 {T_NULL, "NULL", "null"},
880 {T_WKS, "WKS", "well-known service (deprecated)"},
881 {T_PTR, "PTR", "domain name pointer"},
882 {T_HINFO, "HINFO", "host information"},
883 {T_MINFO, "MINFO", "mailbox information"},
884 {T_MX, "MX", "mail exchanger"},
885 {T_TXT, "TXT", "text"},
886 {T_RP, "RP", "responsible person"},
887 {T_AFSDB, "AFSDB", "DCE or AFS server"},
888 {T_X25, "X25", "X25 address"},
889 {T_ISDN, "ISDN", "ISDN address"},
890 {T_RT, "RT", "router"},
891 {T_NSAP, "NSAP", "nsap address"},
892 {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
893 {T_SIG, "SIG", "signature"},
894 {T_KEY, "KEY", "key"},
895 {T_PX, "PX", "mapping information"},
896 {T_GPOS, "GPOS", "geographical position (withdrawn)"},
897 {T_AAAA, "AAAA", "IPv6 address"},
898 {T_LOC, "LOC", "location"},
899 {T_NXT, "NXT", "next valid name (unimplemented)"},
900 {T_EID, "EID", "endpoint identifier (unimplemented)"},
901 {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"},
902 {T_SRV, "SRV", "server selection"},
903 {T_ATMA, "ATMA", "ATM address (unimplemented)"},
904 {T_IXFR, "IXFR", "incremental zone transfer"},
905 {T_AXFR, "AXFR", "zone transfer"},
906 {T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
907 {T_MAILA, "MAILA", "mail agent (deprecated)"},
908 {T_UINFO, "UINFO", "user information (nonstandard)"},
909 {T_UID, "UID", "user ID (nonstandard)"},
910 {T_GID, "GID", "group ID (nonstandard)"},
911 #ifdef ALLOW_T_UNSPEC
912 {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"},
913 #endif /* ALLOW_T_UNSPEC */
914 {T_ANY, "ANY", "\"any\""},
919 __sym_ston(syms, name, success)
920 const struct res_sym *syms;
925 /* Changed to prevent warning. --drepper@gnu */
926 for (; syms->name != 0; syms++) {
928 for (NULL; syms->name != 0; syms++) {
930 if (strcasecmp (name, syms->name) == 0) {
933 return (syms->number);
938 return (syms->number); /* The default value. */
942 __sym_ntos(syms, number, success)
943 const struct res_sym *syms;
947 static char unname[20];
950 /* Changed to prevent warning. --drepper@gnu */
951 for (; syms->name != 0; syms++) {
953 for (NULL; syms->name != 0; syms++) {
955 if (number == syms->number) {
962 sprintf (unname, "%d", number);
970 __sym_ntop(syms, number, success)
971 const struct res_sym *syms;
975 static char unname[20];
978 /* Changed to prevent warning. --drepper@gnu */
979 for (; syms->name != 0; syms++) {
981 for (NULL; syms->name != 0; syms++) {
983 if (number == syms->number) {
986 return (syms->humanname);
989 sprintf(unname, "%d", number);
996 * Return a string for the type
1002 return (__sym_ntos (__p_type_syms, type, (int *)0));
1006 * Return a mnemonic for class
1012 return (__sym_ntos (__p_class_syms, class, (int *)0));
1016 * Return a mnemonic for an option
1022 static char nbuf[40];
1025 case RES_INIT: return "init";
1026 case RES_DEBUG: return "debug";
1027 case RES_AAONLY: return "aaonly(unimpl)";
1028 case RES_USEVC: return "usevc";
1029 case RES_PRIMARY: return "primry(unimpl)";
1030 case RES_IGNTC: return "igntc";
1031 case RES_RECURSE: return "recurs";
1032 case RES_DEFNAMES: return "defnam";
1033 case RES_STAYOPEN: return "styopn";
1034 case RES_DNSRCH: return "dnsrch";
1035 case RES_INSECURE1: return "insecure1";
1036 case RES_INSECURE2: return "insecure2";
1037 default: sprintf(nbuf, "?0x%lx?", (u_long)option);
1043 * Return a mnemonic for a time to live
1049 static char nbuf[60];
1050 int secs, mins, hours, days;
1054 strcpy(nbuf, "0 secs");
1067 #define PLURALIZE(x) x, (x == 1) ? "" : "s"
1070 (void)sprintf(p, "%d day%s", PLURALIZE(days));
1076 (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
1082 (void)sprintf(p, "%d min%s", PLURALIZE(mins));
1085 if (secs || ! (days || hours || mins)) {
1086 if (days || hours || mins)
1088 (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
1094 * routines to convert between on-the-wire RR format and zone file format.
1095 * Does not contain conversion to/from decimal degrees; divide or multiply
1096 * by 60*60*1000 for that.
1099 static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1100 1000000,10000000,100000000,1000000000};
1102 /* takes an XeY precision/size value, returns a string representation. */
1107 static char retbuf[sizeof "90000000.00"];
1109 int mantissa, exponent;
1111 mantissa = (int)((prec >> 4) & 0x0f) % 10;
1112 exponent = (int)((prec >> 0) & 0x0f) % 10;
1114 val = mantissa * poweroften[exponent];
1116 (void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);
1120 /* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
1122 precsize_aton(strptr)
1125 unsigned int mval = 0, cmval = 0;
1126 u_int8_t retval = 0;
1128 register int exponent;
1129 register int mantissa;
1133 while (isdigit(*cp))
1134 mval = mval * 10 + (*cp++ - '0');
1136 if (*cp == '.') { /* centimeters */
1139 cmval = (*cp++ - '0') * 10;
1141 cmval += (*cp++ - '0');
1145 cmval = (mval * 100) + cmval;
1147 for (exponent = 0; exponent < 9; exponent++)
1148 if (cmval < poweroften[exponent+1])
1151 mantissa = cmval / poweroften[exponent];
1155 retval = (mantissa << 4) | exponent;
1162 /* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
1164 latlon2ul(latlonstrptr,which)
1165 char **latlonstrptr;
1170 int deg = 0, min = 0, secs = 0, secsfrac = 0;
1174 while (isdigit(*cp))
1175 deg = deg * 10 + (*cp++ - '0');
1177 while (isspace(*cp))
1180 if (!(isdigit(*cp)))
1183 while (isdigit(*cp))
1184 min = min * 10 + (*cp++ - '0');
1186 while (isspace(*cp))
1189 if (!(isdigit(*cp)))
1192 while (isdigit(*cp))
1193 secs = secs * 10 + (*cp++ - '0');
1195 if (*cp == '.') { /* decimal seconds */
1198 secsfrac = (*cp++ - '0') * 100;
1200 secsfrac += (*cp++ - '0') * 10;
1202 secsfrac += (*cp++ - '0');
1208 while (!isspace(*cp)) /* if any trailing garbage */
1211 while (isspace(*cp))
1218 retval = ((unsigned)1<<31)
1219 + (((((deg * 60) + min) * 60) + secs) * 1000)
1224 retval = ((unsigned)1<<31)
1225 - (((((deg * 60) + min) * 60) + secs) * 1000)
1229 retval = 0; /* invalid value -- indicates error */
1236 *which = 1; /* latitude */
1240 *which = 2; /* longitude */
1243 *which = 0; /* error */
1247 cp++; /* skip the hemisphere */
1249 while (!isspace(*cp)) /* if any trailing garbage */
1252 while (isspace(*cp)) /* move to next field */
1260 /* converts a zone file representation in a string to an RDATA on-the-wire
1261 * representation. */
1263 loc_aton(ascii, binary)
1267 const char *cp, *maxcp;
1270 u_int32_t latit = 0, longit = 0, alt = 0;
1271 u_int32_t lltemp1 = 0, lltemp2 = 0;
1272 int altmeters = 0, altfrac = 0, altsign = 1;
1273 u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
1274 u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
1275 u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
1276 int which1 = 0, which2 = 0;
1279 maxcp = cp + strlen(ascii);
1281 lltemp1 = latlon2ul(&cp, &which1);
1283 lltemp2 = latlon2ul(&cp, &which2);
1285 switch (which1 + which2) {
1286 case 3: /* 1 + 2, the only valid combination */
1287 if ((which1 == 1) && (which2 == 2)) { /* normal case */
1290 } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
1293 } else { /* some kind of brokenness */
1297 default: /* we didn't get one of each */
1310 while (isdigit(*cp))
1311 altmeters = altmeters * 10 + (*cp++ - '0');
1313 if (*cp == '.') { /* decimal meters */
1316 altfrac = (*cp++ - '0') * 10;
1318 altfrac += (*cp++ - '0');
1323 alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
1325 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1328 while (isspace(*cp) && (cp < maxcp))
1334 siz = precsize_aton(&cp);
1336 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1339 while (isspace(*cp) && (cp < maxcp))
1345 hp = precsize_aton(&cp);
1347 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1350 while (isspace(*cp) && (cp < maxcp))
1356 vp = precsize_aton(&cp);
1361 *bcp++ = (u_int8_t) 0; /* version byte */
1366 PUTLONG(longit,bcp);
1369 return (16); /* size of RR in octets */
1372 /* takes an on-the-wire LOC RR and formats it in a human readable format. */
1374 loc_ntoa(binary, ascii)
1375 const u_char *binary;
1378 static char *error = "?";
1379 register const u_char *cp = binary;
1381 int latdeg, latmin, latsec, latsecfrac;
1382 int longdeg, longmin, longsec, longsecfrac;
1383 char northsouth, eastwest;
1384 int altmeters, altfrac, altsign;
1386 const int referencealt = 100000 * 100;
1388 int32_t latval, longval, altval;
1390 u_int8_t sizeval, hpval, vpval, versionval;
1392 char *sizestr, *hpstr, *vpstr;
1397 sprintf(ascii, "; error: unknown LOC RR version");
1407 latval = (templ - ((unsigned)1<<31));
1410 longval = (templ - ((unsigned)1<<31));
1413 if (templ < referencealt) { /* below WGS 84 spheroid */
1414 altval = referencealt - templ;
1417 altval = templ - referencealt;
1427 latsecfrac = latval % 1000;
1428 latval = latval / 1000;
1429 latsec = latval % 60;
1430 latval = latval / 60;
1431 latmin = latval % 60;
1432 latval = latval / 60;
1441 longsecfrac = longval % 1000;
1442 longval = longval / 1000;
1443 longsec = longval % 60;
1444 longval = longval / 60;
1445 longmin = longval % 60;
1446 longval = longval / 60;
1449 altfrac = altval % 100;
1450 altmeters = (altval / 100) * altsign;
1452 if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
1454 if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
1456 if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
1460 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
1461 latdeg, latmin, latsec, latsecfrac, northsouth,
1462 longdeg, longmin, longsec, longsecfrac, eastwest,
1463 altmeters, altfrac, sizestr, hpstr, vpstr);
1465 if (sizestr != error)
1476 /* Return the number of DNS hierarchy levels in the name. */
1478 __dn_count_labels(name)
1485 for(i = 0, count = 0; i < len; i++) {
1490 /* don't count initial wildcard */
1495 /* don't count the null label for root. */
1496 /* if terminating '.' not found, must adjust */
1497 /* count to include last label */
1498 if (len > 0 && name[len-1] != '.')
1505 * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
1506 * SIG records are required to be printed like this, by the Secure DNS RFC.
1509 __p_secstodate (secs)
1512 static char output[15]; /* YYYYMMDDHHMMSS and null */
1513 time_t clock = secs;
1516 __gmtime_r(&clock, &time);
1517 time.tm_year += 1900;
1519 sprintf(output, "%04d%02d%02d%02d%02d%02d",
1520 time.tm_year, time.tm_mon, time.tm_mday,
1521 time.tm_hour, time.tm_min, time.tm_sec);