* Copyright (c) 1985, 1990 Regents of the University of California.
* %sccs.include.redist.c%
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies, and that
* the name of Digital Equipment Corporation not be used in advertising or
* publicity pertaining to distribution of the document or software without
* specific, written prior permission.
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)res_debug.c 5.37 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <arpa/nameser.h>
char *__p_class(), *__p_time(), *__p_type();
char *p_cdname(), *p_fqname(), *p_rr();
static char *p_option
__P((u_int32_t
));
char *_res_resultcodes
[] = {
case 9: return("discard");
case 11: return("systat");
case 13: return("daytime");
case 15: return("netstat");
case 19: return("chargen");
case 20: return("ftp-data");
case 23: return("telnet");
case 43: return("whois");
case 53: return("domain");
case 67: return("bootps");
case 68: return("bootpc");
case 79: return("finger");
case 95: return("supdup");
case 100: return("newacct");
case 101: return("hostnames");
case 102: return("iso-tsap");
case 103: return("x400");
case 104: return("x400-snd");
case 105: return("csnet-ns");
case 109: return("pop-2");
case 111: return("sunrpc");
case 113: return("auth");
case 115: return("sftp");
case 117: return("uucp-path");
case 119: return("nntp");
case 121: return("erpc");
case 133: return("statsrv");
case 136: return("profile");
case 144: return("NeWS");
case 161: return("snmp");
case 162: return("snmp-trap");
case 170: return("print-srv");
default: (void) sprintf(retbuf
, "%d", wks
); return(retbuf
);
case 11: return("nvp-II");
case 16: return("chaos");
default: (void) sprintf(retbuf
, "%d", protonum
); return(retbuf
);
do_rrset(msg
, cp
, cnt
, pflag
, file
, hs
)
sflag
= (_res
.pfcode
& pflag
);
if ((!_res
.pfcode
) || ((sflag
) && (_res
.pfcode
& RES_PRF_HEAD1
)))
cp
= p_rr(cp
, msg
, file
);
if ((!_res
.pfcode
) || ((sflag
) && (_res
.pfcode
& RES_PRF_HEAD1
)))
* Print the current options.
* This is intended to be primarily a debugging routine.
__fp_resstat(statp
, file
)
struct __res_state
*statp
;
fprintf(file
, ";; res options:");
for (bit
= 0; bit
< 32; bit
++) { /* XXX 32 - bad assumption! */
if (statp
->options
& (1<<bit
))
fprintf(file
, " %s", p_option(1<<bit
));
* Print the contents of a query.
* This is intended to be primarily a debugging routine.
cp
= msg
+ sizeof(HEADER
);
if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEADX
) || hp
->rcode
) {
fprintf(file
,";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
_res_opcodes
[hp
->opcode
],
_res_resultcodes
[hp
->rcode
],
if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEAD2
)) {
fprintf(file
,"; flags:");
if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEAD1
)) {
fprintf(file
,"; Ques: %d", ntohs(hp
->qdcount
));
fprintf(file
,", Ans: %d", ntohs(hp
->ancount
));
fprintf(file
,", Auth: %d", ntohs(hp
->nscount
));
fprintf(file
,", Addit: %d\n", ntohs(hp
->arcount
));
if (_res
.pfcode
& (RES_PRF_HEADX
| RES_PRF_HEAD2
| RES_PRF_HEAD1
)) {
* Print question records.
if (n
= ntohs(hp
->qdcount
)) {
if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
fprintf(file
,";; QUESTIONS:\n");
cp
= p_cdname(cp
, msg
, file
);
if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
fprintf(file
, ", type = %s",
__p_type(_getshort(cp
)));
if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
fprintf(file
, ", class = %s\n\n",
__p_class(_getshort(cp
)));
* Print authoritative answer records
cp
= do_rrset(msg
, cp
, hp
->ancount
, RES_PRF_ANS
, file
,
* print name server records
cp
= do_rrset(msg
, cp
, hp
->nscount
, RES_PRF_AUTH
, file
,
";; AUTHORITY RECORDS:\n");
* print additional records
cp
= do_rrset(msg
, cp
, hp
->arcount
, RES_PRF_ADD
, file
,
";; ADDITIONAL RECORDS:\n");
if ((n
= dn_expand((u_char
*)msg
, (u_char
*)msg
+ MAXCDNAME
,
(u_char
*)cp
, (u_char
*)name
, sizeof(name
))) < 0)
if ((n
= dn_expand((u_char
*)msg
, (u_char
*)msg
+ MAXCDNAME
,
(u_char
*)cp
, (u_char
*)name
, sizeof(name
))) < 0)
if (name
[strlen(name
) - 1] != '.')
* Print resource record fields in human readable form.
int type
, class, dlen
, n
, c
;
if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
return (NULL
); /* compression error */
if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_TTLID
))
fprintf(file
, "\t%lu", tmpttl
);
if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_CLASS
))
fprintf(file
, "\t%s", __p_class(class));
fprintf(file
, "\t%s", __p_type(type
));
* Print type specific data, if appropriate
bcopy(cp
, (char *)&inaddr
, sizeof(inaddr
));
fprintf(file
,"\t%s", inet_ntoa(inaddr
));
address
= inet_ntoa(inaddr
);
fprintf(file
, "\t%s\t; proto %d, port %d",
address
, protocol
, port
);
cp
= p_fqname(cp
, msg
, file
);
fprintf(file
,"\t%.*s", n
, cp
);
fprintf(file
,"\t%.*s", n
, cp
);
cp
= p_fqname(cp
, msg
, file
); /* origin */
cp
= p_fqname(cp
, msg
, file
); /* mail addr */
t
= _getlong(cp
); cp
+= sizeof(u_int32_t
);
fprintf(file
,"\t\t\t%lu\t; serial\n", t
);
t
= _getlong(cp
); cp
+= sizeof(u_int32_t
);
fprintf(file
,"\t\t\t%lu\t; refresh (%s)\n", t
, __p_time(t
));
t
= _getlong(cp
); cp
+= sizeof(u_int32_t
);
fprintf(file
,"\t\t\t%lu\t; retry (%s)\n", t
, __p_time(t
));
t
= _getlong(cp
); cp
+= sizeof(u_int32_t
);
fprintf(file
,"\t\t\t%lu\t; expire (%s)\n", t
, __p_time(t
));
t
= _getlong(cp
); cp
+= sizeof(u_int32_t
);
fprintf(file
,"\t\t\t%lu )\t; minimum (%s)", t
, __p_time(t
));
fprintf(file
,"\t%d ", _getshort(cp
));
cp
= p_fqname(cp
, msg
, file
);
(void) fputs("\t\"", file
);
if (n
= (unsigned char) *cp
++) {
for (c
= n
; c
> 0 && cp
< cp2
; c
--)
(void) putc(*cp
++, file
);
(void) putc(*cp
++, file
);
cp
= p_fqname(cp
, msg
, file
);
cp
= p_fqname(cp
, msg
, file
);
fprintf(file
,"\t%u", _getlong(cp
));
if (dlen
< sizeof(u_int32_t
) + 1)
bcopy(cp
, (char *)&inaddr
, sizeof(inaddr
));
fprintf(file
, "\t%s %s ( ",
while (cp
< cp1
+ dlen
) {
if (dlen
< NumBytes
) NumBytes
= dlen
;
fprintf(file
, "\tFirst %d bytes of hex data:",
for (i
= 0, DataPtr
= cp
; i
< NumBytes
; i
++, DataPtr
++)
fprintf(file
, " %x", *DataPtr
);
#endif /* ALLOW_T_UNSPEC */
fprintf(file
,"\t?%d?", type
);
fprintf(file
, "\t; dlen=%d, ttl %s\n", dlen
, __p_time(tmpttl
));
fprintf(file
,";; packet size error (found %d, dlen was %d)\n",
* Return a string for the type
case T_NS
: /* authoritative server */
case T_CNAME
: /* canonical name */
case T_SOA
: /* start of authority zone */
case T_MB
: /* mailbox domain name */
case T_MG
: /* mail group member */
case T_MR
: /* mail rename name */
case T_NULL
: /* null resource record */
case T_WKS
: /* well known service */
case T_PTR
: /* domain name pointer */
case T_HINFO
: /* host information */
case T_MINFO
: /* mailbox information */
case T_MX
: /* mail routing info */
case T_RP
: /* responsible person */
case T_AXFR
: /* zone transfer */
case T_MAILB
: /* mail box */
case T_MAILA
: /* mail address */
case T_ANY
: /* matches any type */
#endif /* ALLOW_T_UNSPEC */
(void)sprintf(nbuf
, "%d", type
);
* Return a mnemonic for class
case C_IN
: /* internet class */
case C_HS
: /* hesiod class */
case C_ANY
: /* matches any class */
(void)sprintf(nbuf
, "%d", class);
* Return a mnemonic for an option
case RES_INIT
: return "init";
case RES_DEBUG
: return "debug";
case RES_AAONLY
: return "aaonly";
case RES_USEVC
: return "usevc";
case RES_PRIMARY
: return "primry";
case RES_IGNTC
: return "igntc";
case RES_RECURSE
: return "recurs";
case RES_DEFNAMES
: return "defnam";
case RES_STAYOPEN
: return "styopn";
case RES_DNSRCH
: return "dnsrch";
default: sprintf(nbuf
, "?0x%x?", option
); return nbuf
;
* Return a mnemonic for a time to live
int secs
, mins
, hours
, days
;
#define PLURALIZE(x) x, (x == 1) ? "" : "s"
(void)sprintf(p
, "%d day%s", PLURALIZE(days
));
(void)sprintf(p
, "%d hour%s", PLURALIZE(hours
));
(void)sprintf(p
, "%d min%s", PLURALIZE(mins
));
if (secs
|| ! (days
|| hours
|| mins
)) {
if (days
|| hours
|| mins
)
(void)sprintf(p
, "%d sec%s", PLURALIZE(secs
));