aboutsummaryrefslogtreecommitdiff
path: root/resolv/res_debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'resolv/res_debug.c')
-rw-r--r--resolv/res_debug.c419
1 files changed, 348 insertions, 71 deletions
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
index 62cd81c..dfb3b47 100644
--- a/resolv/res_debug.c
+++ b/resolv/res_debug.c
@@ -50,6 +50,28 @@
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
* -
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software. No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
* --Copyright--
*/
@@ -65,11 +87,14 @@ static char rcsid[] = "$Id$";
#include <arpa/inet.h>
#include <arpa/nameser.h>
-#include <stdio.h>
#include <ctype.h>
#include <netdb.h>
#include <resolv.h>
+#include <stdio.h>
+#include <time.h>
+
#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
+# include <stdlib.h>
# include <string.h>
#else
# include "../conf/portability.h"
@@ -291,6 +316,12 @@ __fp_nquery(msg, len, file)
fprintf(file, " rd");
if (hp->ra)
fprintf(file, " ra");
+ if (hp->unused)
+ fprintf(file, " UNUSED-BIT-ON");
+ if (hp->ad)
+ fprintf(file, " ad");
+ if (hp->cd)
+ fprintf(file, " cd");
}
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
@@ -404,6 +435,30 @@ __p_cdname(cp, msg, file)
return (p_cdnname(cp, msg, PACKETSZ, file));
}
+
+/* Return a fully-qualified domain name from a compressed name (with
+ length supplied). */
+
+const u_char *
+__p_fqnname(cp, msg, msglen, name, namelen)
+ const u_char *cp, *msg;
+ int msglen;
+ char *name;
+ int namelen;
+{
+ int n, newlen;
+
+ if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
+ return (NULL);
+ newlen = strlen (name);
+ if (newlen == 0 || name[newlen - 1] != '.')
+ if (newlen+1 >= namelen) /* Lack space for final dot */
+ return (NULL);
+ else
+ strcpy(name + newlen, ".");
+ return (cp + n);
+}
+
/* XXX: the rest of these functions need to become length-limited, too. (vix)
*/
@@ -413,18 +468,13 @@ __p_fqname(cp, msg, file)
FILE *file;
{
char name[MAXDNAME];
- int n;
+ const u_char *n;
- if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0)
+ n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
+ if (n == NULL)
return (NULL);
- if (name[0] == '\0') {
- putc('.', file);
- } else {
- fputs(name, file);
- if (name[strlen(name) - 1] != '.')
- putc('.', file);
- }
- return (cp + n);
+ fputs(name, file);
+ return (n);
}
/*
@@ -440,13 +490,19 @@ __p_rr(cp, msg, file)
const u_char *cp1, *cp2;
u_int32_t tmpttl, t;
int lcnt;
+ u_int16_t keyflags;
+ char rrname[MAXDNAME]; /* The fqdn of this RR */
+ char base64_key[MAX_KEY_BASE64];
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (NULL);
}
- if ((cp = p_fqname(cp, msg, file)) == NULL)
+ cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
+ if (!cp)
return (NULL); /* compression error */
+ fputs(rrname, file);
+
type = _getshort((u_char*)cp);
cp += INT16SZ;
class = _getshort((u_char*)cp);
@@ -481,7 +537,7 @@ __p_rr(cp, msg, file)
address = inet_ntoa(inaddr);
cp += INADDRSZ;
protocol = *(u_char*)cp;
- cp += sizeof(u_char);
+ cp += sizeof (u_char);
port = _getshort((u_char*)cp);
cp += INT16SZ;
fprintf(file, "\t%s\t; proto %d, port %d",
@@ -505,16 +561,16 @@ __p_rr(cp, msg, file)
case T_HINFO:
case T_ISDN:
- (void) fputs("\t\"", file);
cp2 = cp + dlen;
+ (void) fputs("\t\"", file);
if ((n = (unsigned char) *cp++) != 0) {
for (c = n; c > 0 && cp < cp2; c--) {
if (strchr("\n\"\\", *cp))
(void) putc('\\', file);
(void) putc(*cp++, file);
}
- putc('"', file);
}
+ putc('"', file);
if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
(void) fputs ("\t\"", file);
for (c = n; c > 0 && cp < cp2; c--) {
@@ -572,11 +628,24 @@ __p_rr(cp, msg, file)
return (NULL);
break;
- case T_TXT:
case T_X25:
+ cp2 = cp + dlen;
(void) fputs("\t\"", file);
+ if ((n = (unsigned char) *cp++) != 0) {
+ for (c = n; c > 0 && cp < cp2; c--) {
+ if (strchr("\n\"\\", *cp))
+ (void) putc('\\', file);
+ (void) putc(*cp++, file);
+ }
+ }
+ putc('"', file);
+ break;
+
+ case T_TXT:
+ (void) putc('\t', file);
cp2 = cp1 + dlen;
while (cp < cp2) {
+ putc('"', file);
if (n = (unsigned char) *cp++) {
for (c = n; c > 0 && cp < cp2; c--) {
if (strchr("\n\"\\", *cp))
@@ -584,8 +653,10 @@ __p_rr(cp, msg, file)
(void) putc(*cp++, file);
}
}
+ putc('"', file);
+ if (cp < cp2)
+ putc(' ', file);
}
- putc('"', file);
break;
case T_NSAP:
@@ -641,7 +712,7 @@ __p_rr(cp, msg, file)
fprintf(file, "\t%s %s ( ",
inet_ntoa(inaddr),
deproto((int) *cp));
- cp += sizeof(u_char);
+ cp += sizeof (u_char);
n = 0;
lcnt = 0;
while (cp < cp1 + dlen) {
@@ -662,6 +733,72 @@ __p_rr(cp, msg, file)
putc(')', file);
break;
+ case T_KEY:
+ putc('\t', file);
+ keyflags = _getshort(cp);
+ cp += 2;
+ fprintf(file,"0x%04x", keyflags ); /* flags */
+ fprintf(file," %u", *cp++); /* protocol */
+ fprintf(file," %u (", *cp++); /* algorithm */
+
+ n = b64_ntop(cp, (cp1 + dlen) - cp,
+ base64_key, sizeof base64_key);
+ for (c = 0; c < n; ++c) {
+ if (0 == (c & 0x3F))
+ fprintf(file, "\n\t");
+ putc(base64_key[c], file); /* public key data */
+ }
+
+ fprintf(file, " )");
+ if (n < 0)
+ fprintf(file, "\t; BAD BASE64");
+ fflush(file);
+ cp = cp1 + dlen;
+ break;
+
+ case T_SIG:
+ type = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ fprintf(file, " %s", p_type(type));
+ fprintf(file, "\t%d", *cp++); /* algorithm */
+ /* Check label value and print error if wrong. */
+ n = *cp++;
+ c = dn_count_labels (rrname);
+ if (n != c)
+ fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
+ n, c);
+ /* orig ttl */
+ n = _getlong((u_char*)cp);
+ if (n != tmpttl)
+ fprintf(file, " %u", n);
+ cp += INT32SZ;
+ /* sig expire */
+ fprintf(file, " (\n\t%s",
+ __p_secstodate(_getlong((u_char*)cp)));
+ cp += INT32SZ;
+ /* time signed */
+ fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
+ cp += INT32SZ;
+ /* sig footprint */
+ fprintf(file," %u ", _getshort((u_char*)cp));
+ cp += INT16SZ;
+ /* signer's name */
+ cp = p_fqname(cp, msg, file);
+ n = b64_ntop(cp, (cp1 + dlen) - cp,
+ base64_key, sizeof base64_key);
+ for (c = 0; c < n; c++) {
+ if (0 == (c & 0x3F))
+ fprintf (file, "\n\t");
+ putc(base64_key[c], file); /* signature */
+ }
+ /* Clean up... */
+ fprintf(file, " )");
+ if (n < 0)
+ fprintf(file, "\t; BAD BASE64");
+ fflush(file);
+ cp = cp1+dlen;
+ break;
+
#ifdef ALLOW_T_UNSPEC
case T_UNSPEC:
{
@@ -698,54 +835,151 @@ __p_rr(cp, msg, file)
}
/*
+ * Names of RR classes and qclasses. Classes and qclasses are the same, except
+ * that C_ANY is a qclass but not a class. (You can ask for records of class
+ * C_ANY, but you can't have any records of that class in the database.)
+ */
+const struct res_sym __p_class_syms[] = {
+ {C_IN, "IN"},
+ {C_CHAOS, "CHAOS"},
+ {C_HS, "HS"},
+ {C_HS, "HESIOD"},
+ {C_ANY, "ANY"},
+ {C_IN, (char *)0}
+};
+
+/*
+ * Names of RR types and qtypes. Types and qtypes are the same, except
+ * that T_ANY is a qtype but not a type. (You can ask for records of type
+ * T_ANY, but you can't have any records of that type in the database.)
+ */
+const struct res_sym __p_type_syms[] = {
+ {T_A, "A", "address"},
+ {T_NS, "NS", "name server"},
+ {T_CNAME, "CNAME", "canonical name"},
+ {T_SOA, "SOA", "start of authority"},
+ {T_MB, "MB", "mailbox"},
+ {T_MG, "MG", "mail group member"},
+ {T_MR, "MR", "mail rename"},
+ {T_NULL, "NULL", "null"},
+ {T_WKS, "WKS", "well-known service"},
+ {T_PTR, "PTR", "domain name pointer"},
+ {T_HINFO, "HINFO", "host information"},
+ {T_MINFO, "MINFO", "mailbox information"},
+ {T_MX, "MX", "mail exchanger"},
+ {T_TXT, "TXT", "text"},
+ {T_RP, "RP", "responsible person"},
+ {T_AFSDB, "AFSDB", "DCE or AFS server"},
+ {T_X25, "X25", "X25 address"},
+ {T_ISDN, "ISDN", "ISDN address"},
+ {T_RT, "RT", "router"},
+ {T_NSAP, "NSAP", "nsap address"},
+ {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
+ {T_SIG, "SIG", "signature"},
+ {T_KEY, "KEY", "key"},
+ {T_NXT, "NXT", "next valid name"},
+ {T_PX, "PX", "mapping information"},
+ {T_GPOS, "GPOS", "geographical position"},
+ {T_AAAA, "AAAA", "IPv6 address"},
+ {T_LOC, "LOC", "location"},
+ {T_AXFR, "AXFR", "zone transfer"},
+ {T_MAILB, "MAILB", "mailbox-related data"},
+ {T_MAILA, "MAILA", "mail agent"},
+ {T_UINFO, "UINFO", "user information"},
+ {T_UID, "UID", "user ID"},
+ {T_GID, "GID", "group ID"},
+#ifdef ALLOW_T_UNSPEC
+ {T_UNSPEC, "UNSPEC", "unspecified data"},
+#endif /* ALLOW_T_UNSPEC */
+ {T_ANY, "ANY", "\"any\""},
+ {0, (char *)0, (char *)0}
+};
+
+int
+__sym_ston(syms, name, success)
+ const struct res_sym *syms;
+ char *name;
+ int *success;
+{
+#ifdef _LIBC
+ /* Changed to prevent warning. --drepper@gnu */
+ for (; syms->name != 0; syms++) {
+#else
+ for (NULL; syms->name != 0; syms++) {
+#endif
+ if (strcasecmp (name, syms->name) == 0) {
+ if (success)
+ *success = 1;
+ return (syms->number);
+ }
+ }
+ if (success)
+ *success = 0;
+ return (syms->number); /* The default value. */
+}
+
+const char *
+__sym_ntos(syms, number, success)
+ const struct res_sym *syms;
+ int number;
+ int *success;
+{
+ static char unname[20];
+
+#ifdef _LIBC
+ /* Changed to prevent warning. --drepper@gnu */
+ for (; syms->name != 0; syms++) {
+#else
+ for (NULL; syms->name != 0; syms++) {
+#endif
+ if (number == syms->number) {
+ if (success)
+ *success = 1;
+ return (syms->name);
+ }
+ }
+
+ sprintf (unname, "%d", number);
+ if (success)
+ *success = 0;
+ return (unname);
+}
+
+
+const char *
+__sym_ntop(syms, number, success)
+ const struct res_sym *syms;
+ int number;
+ int *success;
+{
+ static char unname[20];
+
+#ifdef _LIBC
+ /* Changed to prevent warning. --drepper@gnu */
+ for (; syms->name != 0; syms++) {
+#else
+ for (NULL; syms->name != 0; syms++) {
+#endif
+ if (number == syms->number) {
+ if (success)
+ *success = 1;
+ return (syms->humanname);
+ }
+ }
+ sprintf(unname, "%d", number);
+ if (success)
+ *success = 0;
+ return (unname);
+}
+
+/*
* Return a string for the type
*/
const char *
__p_type(type)
int type;
{
- static char nbuf[20];
-
- switch (type) {
- case T_A: return "A";
- case T_NS: return "NS";
- case T_CNAME: return "CNAME";
- case T_SOA: return "SOA";
- case T_MB: return "MB";
- case T_MG: return "MG";
- case T_MR: return "MR";
- case T_NULL: return "NULL";
- case T_WKS: return "WKS";
- case T_PTR: return "PTR";
- case T_HINFO: return "HINFO";
- case T_MINFO: return "MINFO";
- case T_MX: return "MX";
- case T_TXT: return "TXT";
- case T_RP: return "RP";
- case T_AFSDB: return "AFSDB";
- case T_X25: return "X25";
- case T_ISDN: return "ISDN";
- case T_RT: return "RT";
- case T_NSAP: return "NSAP";
- case T_NSAP_PTR: return "NSAP_PTR";
- case T_SIG: return "SIG";
- case T_KEY: return "KEY";
- case T_PX: return "PX";
- case T_GPOS: return "GPOS";
- case T_AAAA: return "AAAA";
- case T_LOC: return "LOC";
- case T_AXFR: return "AXFR";
- case T_MAILB: return "MAILB";
- case T_MAILA: return "MAILA";
- case T_ANY: return "ANY";
- case T_UINFO: return "UINFO";
- case T_UID: return "UID";
- case T_GID: return "GID";
-#ifdef ALLOW_T_UNSPEC
- case T_UNSPEC: return "UNSPEC";
-#endif /* ALLOW_T_UNSPEC */
- default: (void)sprintf(nbuf, "%d", type); return (nbuf);
- }
+ return (__sym_ntos (__p_type_syms, type, (int *)0));
}
/*
@@ -755,14 +989,7 @@ const char *
__p_class(class)
int class;
{
- static char nbuf[20];
-
- switch (class) {
- case C_IN: return "IN";
- case C_HS: return "HS";
- case C_ANY: return "ANY";
- default: (void)sprintf(nbuf, "%d", class); return (nbuf);
- }
+ return (__sym_ntos (__p_class_syms, class, (int *)0));
}
/*
@@ -857,7 +1084,7 @@ static const char *
precsize_ntoa(prec)
u_int8_t prec;
{
- static char retbuf[sizeof("90000000.00")];
+ static char retbuf[sizeof "90000000.00"];
unsigned long val;
int mantissa, exponent;
@@ -1044,11 +1271,11 @@ loc_aton(ascii, binary)
longit = lltemp1;
latit = lltemp2;
} else { /* some kind of brokenness */
- return 0;
+ return (0);
}
break;
default: /* we didn't get one of each */
- return 0;
+ return (0);
}
/* altitude */
@@ -1224,3 +1451,53 @@ loc_ntoa(binary, ascii)
return (ascii);
}
+
+
+/* Return the number of DNS hierarchy levels in the name. */
+int
+__dn_count_labels(name)
+ char *name;
+{
+ int i, len, count;
+
+ len = strlen(name);
+
+ for(i = 0, count = 0; i < len; i++) {
+ if (name[i] == '.')
+ count++;
+ }
+
+ /* don't count initial wildcard */
+ if (name[0] == '*')
+ if (count)
+ count--;
+
+ /* don't count the null label for root. */
+ /* if terminating '.' not found, must adjust */
+ /* count to include last label */
+ if (len > 0 && name[len-1] != '.')
+ count++;
+ return (count);
+}
+
+
+/*
+ * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
+ * SIG records are required to be printed like this, by the Secure DNS RFC.
+ */
+char *
+__p_secstodate (secs)
+ unsigned long secs;
+{
+ static char output[15]; /* YYYYMMDDHHMMSS and null */
+ time_t clock = secs;
+ struct tm *time;
+
+ time = gmtime(&clock);
+ time->tm_year += 1900;
+ time->tm_mon += 1;
+ sprintf(output, "%04d%02d%02d%02d%02d%02d",
+ time->tm_year, time->tm_mon, time->tm_mday,
+ time->tm_hour, time->tm_min, time->tm_sec);
+ return (output);
+}