home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / ISP / bind.4.8.3.lzh / BIND483 / RES / res_debug.c < prev    next >
Text File  |  1994-09-23  |  11KB  |  505 lines

  1. /*-
  2.  * Copyright (c) 1985, 1990 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted provided
  6.  * that: (1) source distributions retain this entire copyright notice and
  7.  * comment, and (2) distributions including binaries display the following
  8.  * acknowledgement:  ``This product includes software developed by the
  9.  * University of California, Berkeley and its contributors'' in the
  10.  * documentation or other materials provided with the distribution and in
  11.  * all advertising materials mentioning features or use of this software.
  12.  * Neither the name of the University nor the names of its contributors may
  13.  * be used to endorse or promote products derived from this software without
  14.  * specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  16.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  17.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  *
  19.  *    @(#)res_debug.c    5.30 (Berkeley) 6/27/90
  20.  */
  21.  
  22. #if defined(LIBC_SCCS) && !defined(lint)
  23. static char sccsid[] = "@(#)res_debug.c    5.30 (Berkeley) 6/27/90";
  24. #endif /* LIBC_SCCS and not lint */
  25.  
  26. #ifdef OSK
  27. #include <types.h>
  28. #include <in.h>
  29. #include <stdio.h>
  30. #include <nameser.h>
  31. #else
  32. #include <sys/types.h>
  33. #include <netinet/in.h>
  34. #include <stdio.h>
  35. #include <arpa/nameser.h>
  36. #endif
  37.  
  38. extern char *p_cdname(), *p_rr(), *p_type(), *p_class(), *p_time();
  39. extern char *inet_ntoa();
  40.  
  41. char *_res_opcodes[] = {
  42.     "QUERY",
  43.     "IQUERY",
  44.     "CQUERYM",
  45.     "CQUERYU",
  46.     "4",
  47.     "5",
  48.     "6",
  49.     "7",
  50.     "8",
  51.     "UPDATEA",
  52.     "UPDATED",
  53.     "UPDATEDA",
  54.     "UPDATEM",
  55.     "UPDATEMA",
  56.     "ZONEINIT",
  57.     "ZONEREF",
  58. };
  59.  
  60. char *_res_resultcodes[] = {
  61.     "NOERROR",
  62.     "FORMERR",
  63.     "SERVFAIL",
  64.     "NXDOMAIN",
  65.     "NOTIMP",
  66.     "REFUSED",
  67.     "6",
  68.     "7",
  69.     "8",
  70.     "9",
  71.     "10",
  72.     "11",
  73.     "12",
  74.     "13",
  75.     "14",
  76.     "NOCHANGE",
  77. };
  78.  
  79. p_query(msg)
  80.     char *msg;
  81. {
  82.     fp_query(msg,stdout);
  83. }
  84.  
  85. /*
  86.  * Print the contents of a query.
  87.  * This is intended to be primarily a debugging routine.
  88.  */
  89. fp_query(msg,file)
  90.     char *msg;
  91.     FILE *file;
  92. {
  93.     register char *cp;
  94.     register HEADER *hp;
  95.     register int n;
  96.  
  97.     /*
  98.      * Print header fields.
  99.      */
  100.     hp = (HEADER *)msg;
  101.     cp = msg + sizeof(HEADER);
  102.     fprintf(file,"HEADER:\n");
  103.     fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
  104.     fprintf(file,", id = %d", ntohs(hp->id));
  105.     fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
  106.     fprintf(file,"\theader flags: ");
  107.     if (hp->qr)
  108.         fprintf(file," qr");
  109.     if (hp->aa)
  110.         fprintf(file," aa");
  111.     if (hp->tc)
  112.         fprintf(file," tc");
  113.     if (hp->rd)
  114.         fprintf(file," rd");
  115.     if (hp->ra)
  116.         fprintf(file," ra");
  117.     if (hp->pr)
  118.         fprintf(file," pr");
  119.     fprintf(file,"\n\tqdcount = %d", ntohs(hp->qdcount));
  120.     fprintf(file,", ancount = %d", ntohs(hp->ancount));
  121.     fprintf(file,", nscount = %d", ntohs(hp->nscount));
  122.     fprintf(file,", arcount = %d\n\n", ntohs(hp->arcount));
  123.     /*
  124.      * Print question records.
  125.      */
  126.     if (n = ntohs(hp->qdcount)) {
  127.         fprintf(file,"QUESTIONS:\n");
  128.         while (--n >= 0) {
  129.             fprintf(file,"\t");
  130.             cp = p_cdname(cp, msg, file);
  131.             if (cp == NULL)
  132.                 return;
  133.             fprintf(file,", type = %s", p_type(_getshort(cp)));
  134.             cp += sizeof(u_short);
  135.             fprintf(file,", class = %s\n\n", p_class(_getshort(cp)));
  136.             cp += sizeof(u_short);
  137.         }
  138.     }
  139.     /*
  140.      * Print authoritative answer records
  141.      */
  142.     if (n = ntohs(hp->ancount)) {
  143.         fprintf(file,"ANSWERS:\n");
  144.         while (--n >= 0) {
  145.             fprintf(file,"\t");
  146.             cp = p_rr(cp, msg, file);
  147.             if (cp == NULL)
  148.                 return;
  149.         }
  150.     }
  151.     /*
  152.      * print name server records
  153.      */
  154.     if (n = ntohs(hp->nscount)) {
  155.         fprintf(file,"NAME SERVERS:\n");
  156.         while (--n >= 0) {
  157.             fprintf(file,"\t");
  158.             cp = p_rr(cp, msg, file);
  159.             if (cp == NULL)
  160.                 return;
  161.         }
  162.     }
  163.     /*
  164.      * print additional records
  165.      */
  166.     if (n = ntohs(hp->arcount)) {
  167.         fprintf(file,"ADDITIONAL RECORDS:\n");
  168.         while (--n >= 0) {
  169.             fprintf(file,"\t");
  170.             cp = p_rr(cp, msg, file);
  171.             if (cp == NULL)
  172.                 return;
  173.         }
  174.     }
  175. }
  176.  
  177. char *
  178. p_cdname(cp, msg, file)
  179.     char *cp, *msg;
  180.     FILE *file;
  181. {
  182.     char name[MAXDNAME];
  183.     int n;
  184.  
  185.     if ((n = dn_expand(msg, msg + 512, cp, name, sizeof(name))) < 0)
  186.         return (NULL);
  187.     if (name[0] == '\0') {
  188.         name[0] = '.';
  189.         name[1] = '\0';
  190.     }
  191.     fputs(name, file);
  192.     return (cp + n);
  193. }
  194.  
  195. /*
  196.  * Print resource record fields in human readable form.
  197.  */
  198. char *
  199. p_rr(cp, msg, file)
  200.     char *cp, *msg;
  201.     FILE *file;
  202. {
  203.     int type, class, dlen, n, c;
  204.     struct in_addr inaddr;
  205.     char *cp1, *cp2;
  206.  
  207.     if ((cp = p_cdname(cp, msg, file)) == NULL)
  208.         return (NULL);            /* compression error */
  209.     fprintf(file,"\n\ttype = %s", p_type(type = _getshort(cp)));
  210.     cp += sizeof(u_short);
  211.     fprintf(file,", class = %s", p_class(class = _getshort(cp)));
  212.     cp += sizeof(u_short);
  213.     fprintf(file,", ttl = %s", p_time(_getlong(cp)));
  214.     cp += sizeof(u_long);
  215.     fprintf(file,", dlen = %d\n", dlen = _getshort(cp));
  216.     cp += sizeof(u_short);
  217.     cp1 = cp;
  218.     /*
  219.      * Print type specific data, if appropriate
  220.      */
  221.     switch (type) {
  222.     case T_A:
  223.         switch (class) {
  224.         case C_IN:
  225.         case C_HS:
  226.             bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  227.             if (dlen == 4) {
  228.                 fprintf(file,"\tinternet address = %s\n",
  229.                     inet_ntoa(inaddr));
  230.                 cp += dlen;
  231.             } else if (dlen == 7) {
  232.                 fprintf(file,"\tinternet address = %s",
  233.                     inet_ntoa(inaddr));
  234.                 fprintf(file,", protocol = %d", cp[4]);
  235.                 fprintf(file,", port = %d\n",
  236.                     (cp[5] << 8) + cp[6]);
  237.                 cp += dlen;
  238.             }
  239.             break;
  240.         default:
  241.             cp += dlen;
  242.         }
  243.         break;
  244.     case T_CNAME:
  245.     case T_MB:
  246.     case T_MG:
  247.     case T_MR:
  248.     case T_NS:
  249.     case T_PTR:
  250.         fprintf(file,"\tdomain name = ");
  251.         cp = p_cdname(cp, msg, file);
  252.         fprintf(file,"\n");
  253.         break;
  254.  
  255.     case T_HINFO:
  256.         if (n = *cp++) {
  257.             fprintf(file,"\tCPU=%.*s\n", n, cp);
  258.             cp += n;
  259.         }
  260.         if (n = *cp++) {
  261.             fprintf(file,"\tOS=%.*s\n", n, cp);
  262.             cp += n;
  263.         }
  264.         break;
  265.  
  266.     case T_SOA:
  267.         fprintf(file,"\torigin = ");
  268.         cp = p_cdname(cp, msg, file);
  269.         fprintf(file,"\n\tmail addr = ");
  270.         cp = p_cdname(cp, msg, file);
  271.         fprintf(file,"\n\tserial = %ld", _getlong(cp));
  272.         cp += sizeof(u_long);
  273.         fprintf(file,"\n\trefresh = %s", p_time(_getlong(cp)));
  274.         cp += sizeof(u_long);
  275.         fprintf(file,"\n\tretry = %s", p_time(_getlong(cp)));
  276.         cp += sizeof(u_long);
  277.         fprintf(file,"\n\texpire = %s", p_time(_getlong(cp)));
  278.         cp += sizeof(u_long);
  279.         fprintf(file,"\n\tmin = %s\n", p_time(_getlong(cp)));
  280.         cp += sizeof(u_long);
  281.         break;
  282.  
  283.     case T_MX:
  284.         fprintf(file,"\tpreference = %ld,",_getshort(cp));
  285.         cp += sizeof(u_short);
  286.         fprintf(file," name = ");
  287.         cp = p_cdname(cp, msg, file);
  288.         break;
  289.  
  290.       case T_TXT:
  291.         (void) fputs("\t\"", file);
  292.         cp2 = cp1 + dlen;
  293.         while (cp < cp2) {
  294.             if (n = (unsigned char) *cp++) {
  295.                 for (c = n; c > 0 && cp < cp2; c--)
  296.                     if (*cp == '\n') {
  297.                         (void) putc('\\', file);
  298.                         (void) putc(*cp++, file);
  299.                     } else
  300.                         (void) putc(*cp++, file);
  301.             }
  302.         }
  303.         (void) fputs("\"\n", file);
  304.           break;
  305.  
  306.     case T_MINFO:
  307.         fprintf(file,"\trequests = ");
  308.         cp = p_cdname(cp, msg, file);
  309.         fprintf(file,"\n\terrors = ");
  310.         cp = p_cdname(cp, msg, file);
  311.         break;
  312.  
  313.     case T_UINFO:
  314.         fprintf(file,"\t%s\n", cp);
  315.         cp += dlen;
  316.         break;
  317.  
  318.     case T_UID:
  319.     case T_GID:
  320.         if (dlen == 4) {
  321.             fprintf(file,"\t%ld\n", _getlong(cp));
  322.             cp += sizeof(int);
  323.         }
  324.         break;
  325.  
  326.     case T_WKS:
  327.         if (dlen < sizeof(u_long) + 1)
  328.             break;
  329.         bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  330.         cp += sizeof(u_long);
  331.         fprintf(file,"\tinternet address = %s, protocol = %d\n\t",
  332.             inet_ntoa(inaddr), *cp++);
  333.         n = 0;
  334.         while (cp < cp1 + dlen) {
  335.             c = *cp++;
  336.             do {
  337.                  if (c & 0200)
  338.                     fprintf(file," %d", n);
  339.                  c <<= 1;
  340.             } while (++n & 07);
  341.         }
  342.         putc('\n',file);
  343.         break;
  344.  
  345. #ifdef ALLOW_T_UNSPEC
  346.     case T_UNSPEC:
  347.         {
  348.             int NumBytes = 8;
  349.             char *DataPtr;
  350.             int i;
  351.  
  352.             if (dlen < NumBytes) NumBytes = dlen;
  353.             fprintf(file, "\tFirst %d bytes of hex data:",
  354.                 NumBytes);
  355.             for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
  356.                 fprintf(file, " %x", *DataPtr);
  357.             fputs("\n", file);
  358.             cp += dlen;
  359.         }
  360.         break;
  361. #endif /* ALLOW_T_UNSPEC */
  362.  
  363.     default:
  364.         fprintf(file,"\t???\n");
  365.         cp += dlen;
  366.     }
  367.     if (cp != cp1 + dlen) {
  368.         fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen);
  369.         cp = NULL;
  370.     }
  371.     fprintf(file,"\n");
  372.     return (cp);
  373. }
  374.  
  375. static    char nbuf[40];
  376.  
  377. /*
  378.  * Return a string for the type
  379.  */
  380. char *
  381. p_type(type)
  382.     int type;
  383. {
  384.     switch (type) {
  385.     case T_A:
  386.         return("A");
  387.     case T_NS:        /* authoritative server */
  388.         return("NS");
  389.     case T_CNAME:        /* canonical name */
  390.         return("CNAME");
  391.     case T_SOA:        /* start of authority zone */
  392.         return("SOA");
  393.     case T_MB:        /* mailbox domain name */
  394.         return("MB");
  395.     case T_MG:        /* mail group member */
  396.         return("MG");
  397.     case T_MR:        /* mail rename name */
  398.         return("MR");
  399.     case T_NULL:        /* null resource record */
  400.         return("NULL");
  401.     case T_WKS:        /* well known service */
  402.         return("WKS");
  403.     case T_PTR:        /* domain name pointer */
  404.         return("PTR");
  405.     case T_HINFO:        /* host information */
  406.         return("HINFO");
  407.     case T_MINFO:        /* mailbox information */
  408.         return("MINFO");
  409.     case T_MX:        /* mail routing info */
  410.         return("MX");
  411.     case T_TXT:        /* text */
  412.         return("TXT");
  413.     case T_AXFR:        /* zone transfer */
  414.         return("AXFR");
  415.     case T_MAILB:        /* mail box */
  416.         return("MAILB");
  417.     case T_MAILA:        /* mail address */
  418.         return("MAILA");
  419.     case T_ANY:        /* matches any type */
  420.         return("ANY");
  421.     case T_UINFO:
  422.         return("UINFO");
  423.     case T_UID:
  424.         return("UID");
  425.     case T_GID:
  426.         return("GID");
  427. #ifdef ALLOW_T_UNSPEC
  428.     case T_UNSPEC:
  429.         return("UNSPEC");
  430. #endif /* ALLOW_T_UNSPEC */
  431.     default:
  432.         (void)sprintf(nbuf, "%d", type);
  433.         return(nbuf);
  434.     }
  435. }
  436.  
  437. /*
  438.  * Return a mnemonic for class
  439.  */
  440. char *
  441. p_class(class)
  442.     int class;
  443. {
  444.  
  445.     switch (class) {
  446.     case C_IN:        /* internet class */
  447.         return("IN");
  448.     case C_HS:        /* hesiod class */
  449.         return("HS");
  450.     case C_ANY:        /* matches any class */
  451.         return("ANY");
  452.     default:
  453.         (void)sprintf(nbuf, "%d", class);
  454.         return(nbuf);
  455.     }
  456. }
  457.  
  458. /*
  459.  * Return a mnemonic for a time to live
  460.  */
  461. char *
  462. p_time(value)
  463.     u_long value;
  464. {
  465.     int secs, mins, hours;
  466.     register char *p;
  467.  
  468.     if (value == 0) {
  469.         strcpy(nbuf, "0 secs");
  470.         return(nbuf);
  471.     }
  472.  
  473.     secs = value % 60;
  474.     value /= 60;
  475.     mins = value % 60;
  476.     value /= 60;
  477.     hours = value % 24;
  478.     value /= 24;
  479.  
  480. #define    PLURALIZE(x)    x, (x == 1) ? "" : "s"
  481.     p = nbuf;
  482.     if (value) {
  483.         (void)sprintf(p, "%d day%s", PLURALIZE(value));
  484.         while (*++p);
  485.     }
  486.     if (hours) {
  487.         if (value)
  488.             *p++ = ' ';
  489.         (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
  490.         while (*++p);
  491.     }
  492.     if (mins) {
  493.         if (value || hours)
  494.             *p++ = ' ';
  495.         (void)sprintf(p, "%d min%s", PLURALIZE(mins));
  496.         while (*++p);
  497.     }
  498.     if (secs || ! (value || hours || mins)) {
  499.         if (value || hours || mins)
  500.             *p++ = ' ';
  501.         (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
  502.     }
  503.     return(nbuf);
  504. }
  505.