home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / named / tools / nslookup / debug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-24  |  11.0 KB  |  463 lines

  1. /*
  2.  * Copyright (c) 1985,1989 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)debug.c    5.26 (Berkeley) 3/21/91";
  36. #endif /* not lint */
  37.  
  38. /*
  39.  *******************************************************************************
  40.  *
  41.  *  debug.c --
  42.  *
  43.  *    Routines to print out packets received from a name server query.
  44.  *
  45.  *      Modified version of 4.3BSD BIND res_debug.c 5.30 6/27/90
  46.  *
  47.  *******************************************************************************
  48.  */
  49.  
  50. #include <sys/param.h>
  51. #include <netinet/in.h>
  52. #include <arpa/nameser.h>
  53. #include <arpa/inet.h>
  54. #include <resolv.h>
  55. #include <netdb.h>
  56. #include <stdio.h>
  57. #include "res.h"
  58.  
  59. extern char ctime();
  60.  
  61. /*
  62.  *  Imported from res_debug.c
  63.  */
  64. extern char *_res_resultcodes[];
  65. extern char *_res_opcodes[];
  66.  
  67. /*
  68.  *  Used to highlight the start of a record when printing it.
  69.  */
  70. #define INDENT "    ->  "
  71.  
  72.  
  73.  
  74. /*
  75.  * Print the contents of a query.
  76.  * This is intended to be primarily a debugging routine.
  77.  */
  78.  
  79. Print_query(msg, eom, printHeader)
  80.     char *msg, *eom;
  81.     int printHeader;
  82. {
  83.     Fprint_query(msg, eom, printHeader,stdout);
  84. }
  85.  
  86. Fprint_query(msg, eom, printHeader,file)
  87.     char *msg, *eom;
  88.     int printHeader;
  89.     FILE *file;
  90. {
  91.     register char *cp;
  92.     register HEADER *hp;
  93.     register int n;
  94.     short class;
  95.     short type;
  96.  
  97.     /*
  98.      * Print header fields.
  99.      */
  100.     hp = (HEADER *)msg;
  101.     cp = msg + sizeof(HEADER);
  102.     if (printHeader || (_res.options & RES_DEBUG2)) {
  103.         fprintf(file,"    HEADER:\n");
  104.         fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
  105.         fprintf(file,", id = %d", ntohs(hp->id));
  106.         fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
  107.         fprintf(file,"\theader flags: ");
  108.         if (hp->qr) {
  109.             fprintf(file," response");
  110.         } else {
  111.             fprintf(file," query");
  112.         }
  113.         if (hp->aa)
  114.             fprintf(file,", auth. answer");
  115.         if (hp->tc)
  116.             fprintf(file,", truncation");
  117.         if (hp->rd)
  118.             fprintf(file,", want recursion");
  119.         if (hp->ra)
  120.             fprintf(file,", recursion avail.");
  121.         if (hp->pr)
  122.             fprintf(file,", primary");
  123.         fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount));
  124.         fprintf(file,",  answers = %d", ntohs(hp->ancount));
  125.         fprintf(file,",  authority records = %d", ntohs(hp->nscount));
  126.         fprintf(file,",  additional = %d\n\n", ntohs(hp->arcount));
  127.     }
  128.  
  129.     /*
  130.      * Print question records.
  131.      */
  132.     if (n = ntohs(hp->qdcount)) {
  133.         fprintf(file,"    QUESTIONS:\n");
  134.         while (--n >= 0) {
  135.             fprintf(file,"\t");
  136.             cp = Print_cdname(cp, msg, eom, file);
  137.             if (cp == NULL)
  138.                 return;
  139.             type = _getshort(cp);
  140.             cp += sizeof(u_short);
  141.             class = _getshort(cp);
  142.             cp += sizeof(u_short);
  143.             fprintf(file,", type = %s", p_type(type));
  144.             fprintf(file,", class = %s\n", p_class(class));
  145.         }
  146.     }
  147.     /*
  148.      * Print authoritative answer records
  149.      */
  150.     if (n = ntohs(hp->ancount)) {
  151.         fprintf(file,"    ANSWERS:\n");
  152.         while (--n >= 0) {
  153.             fprintf(file, INDENT);
  154.             cp = Print_rr(cp, msg, eom, file);
  155.             if (cp == NULL)
  156.                 return;
  157.         }
  158.     }
  159.     /*
  160.      * print name server records
  161.      */
  162.     if (n = ntohs(hp->nscount)) {
  163.         fprintf(file,"    AUTHORITY RECORDS:\n");
  164.         while (--n >= 0) {
  165.             fprintf(file, INDENT);
  166.             cp = Print_rr(cp, msg, eom, file);
  167.             if (cp == NULL)
  168.                 return;
  169.         }
  170.     }
  171.     /*
  172.      * print additional records
  173.      */
  174.     if (n = ntohs(hp->arcount)) {
  175.         fprintf(file,"    ADDITIONAL RECORDS:\n");
  176.         while (--n >= 0) {
  177.             fprintf(file, INDENT);
  178.             cp = Print_rr(cp, msg, eom, file);
  179.             if (cp == NULL)
  180.                 return;
  181.         }
  182.     }
  183.     fprintf(file,"\n------------\n");
  184. }
  185.  
  186.  
  187. char *
  188. Print_cdname_sub(cp, msg, eom, file, format)
  189.     u_char *cp, *msg, *eom;
  190.     FILE *file;
  191.     int format;
  192. {
  193.     int n;
  194.     u_char name[MAXDNAME];
  195.     extern char *strcpy();
  196.  
  197.     if ((n = dn_expand(msg, eom, cp, name, sizeof(name))) < 0)
  198.         return (NULL);
  199.     if (name[0] == '\0') {
  200.         (void) strcpy(name, "(root)");
  201.     }
  202.     if (format) {
  203.         fprintf(file, "%-30s", name);
  204.     } else {
  205.         fputs((char *)name, file);
  206.     }
  207.     return ((char *)cp + n);
  208. }
  209.  
  210. char *
  211. Print_cdname(cp, msg, eom, file)
  212.     char *cp, *msg, *eom;
  213.     FILE *file;
  214. {
  215.     return(Print_cdname_sub(cp, msg, eom, file, 0));
  216. }
  217.  
  218. char *
  219. Print_cdname2(cp, msg, eom, file)
  220.     char *cp, *msg, *eom;
  221.     FILE *file;
  222. {
  223.     return(Print_cdname_sub(cp, msg, eom, file, 1));
  224. }
  225.  
  226. /*
  227.  * Print resource record fields in human readable form.
  228.  */
  229. char *
  230. Print_rr(cp, msg, eom, file)
  231.     char *cp, *msg, *eom;
  232.     FILE *file;
  233. {
  234.     int type, class, dlen, n, c;
  235.     unsigned long rrttl, ttl;
  236.     struct in_addr inaddr;
  237.     char *cp1, *cp2;
  238.     int debug;
  239.  
  240.     if ((cp = Print_cdname(cp, msg, eom, file)) == NULL) {
  241.         fprintf(file, "(name truncated?)\n");
  242.         return (NULL);            /* compression error */
  243.     }
  244.  
  245.     type = _getshort(cp);
  246.     cp += sizeof(u_short);
  247.     class = _getshort(cp);
  248.     cp += sizeof(u_short);
  249.     rrttl = _getlong(cp);
  250.     cp += sizeof(u_long);
  251.     dlen = _getshort(cp);
  252.     cp += sizeof(u_short);
  253.  
  254.     debug = _res.options & (RES_DEBUG|RES_DEBUG2);
  255.     if (debug) {
  256.         if (_res.options & RES_DEBUG2) {
  257.         fprintf(file,"\n\ttype = %s, class = %s, dlen = %d",
  258.                 p_type(type), p_class(class), dlen);
  259.         }
  260.         if (type == T_SOA) {
  261.         fprintf(file,"\n\tttl = %lu (%s)", rrttl, p_time(rrttl));
  262.         }
  263.         (void) putc('\n', file);
  264.     } 
  265.  
  266.     cp1 = cp;
  267.  
  268.     /*
  269.      * Print type specific data, if appropriate
  270.      */
  271.     switch (type) {
  272.     case T_A:
  273.         switch (class) {
  274.         case C_IN:
  275.         case C_HS:
  276.             bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  277.             if (dlen == 4) {
  278.                 fprintf(file,"\tinternet address = %s\n",
  279.                     inet_ntoa(inaddr));
  280.                 cp += dlen;
  281.             } else if (dlen == 7) {
  282.                 fprintf(file,"\tinternet address = %s",
  283.                     inet_ntoa(inaddr));
  284.                 fprintf(file,", protocol = %d", cp[4]);
  285.                 fprintf(file,", port = %d\n",
  286.                     (cp[5] << 8) + cp[6]);
  287.                 cp += dlen;
  288.             }
  289.             break;
  290.         default:
  291.             fprintf(file,"\taddress, class = %d, len = %d\n",
  292.                 class, dlen);
  293.             cp += dlen;
  294.         }
  295.         break;
  296.  
  297.     case T_CNAME:
  298.         fprintf(file,"\tcanonical name = ");
  299.         goto doname;
  300.  
  301.     case T_MG:
  302.         fprintf(file,"\tmail group member = ");
  303.         goto doname;
  304.     case T_MB:
  305.         fprintf(file,"\tmail box = ");
  306.         goto doname;
  307.     case T_MR:
  308.         fprintf(file,"\tmailbox rename = ");
  309.         goto doname;
  310.     case T_MX:
  311.         fprintf(file,"\tpreference = %u",_getshort(cp));
  312.         cp += sizeof(u_short);
  313.         fprintf(file,", mail exchanger = ");
  314.         goto doname;
  315.     case T_NS:
  316.         fprintf(file,"\tnameserver = ");
  317.         goto doname;
  318.     case T_PTR:
  319.         fprintf(file,"\tname = ");
  320. doname:
  321.         cp = Print_cdname(cp, msg, eom, file);
  322.         (void) putc('\n', file);
  323.         break;
  324.  
  325.     case T_HINFO:
  326.         if (n = *cp++) {
  327.             fprintf(file,"\tCPU = %.*s", n, cp);
  328.             cp += n;
  329.         }
  330.         if (n = *cp++) {
  331.             fprintf(file,"\tOS = %.*s\n", n, cp);
  332.             cp += n;
  333.         }
  334.         break;
  335.  
  336.     case T_SOA:
  337.         if (!debug)
  338.             (void) putc('\n', file);
  339.         fprintf(file,"\torigin = ");
  340.         cp = Print_cdname(cp, msg, eom, file);
  341.         fprintf(file,"\n\tmail addr = ");
  342.         cp = Print_cdname(cp, msg, eom, file);
  343.         fprintf(file,"\n\tserial = %lu", _getlong(cp));
  344.         cp += sizeof(u_long);
  345.         ttl = _getlong(cp);
  346.         fprintf(file,"\n\trefresh = %lu (%s)", ttl, p_time(ttl));
  347.         cp += sizeof(u_long);
  348.         ttl = _getlong(cp);
  349.         fprintf(file,"\n\tretry   = %lu (%s)", ttl, p_time(ttl));
  350.         cp += sizeof(u_long);
  351.         ttl = _getlong(cp);
  352.         fprintf(file,"\n\texpire  = %lu (%s)", ttl, p_time(ttl));
  353.         cp += sizeof(u_long);
  354.         ttl = _getlong(cp);
  355.         fprintf(file,
  356.             "\n\tminimum ttl = %lu (%s)\n", ttl, p_time(ttl));
  357.         cp += sizeof(u_long);
  358.         break;
  359.  
  360.     case T_MINFO:
  361.         if (!debug)
  362.             (void) putc('\n', file);
  363.         fprintf(file,"\trequests = ");
  364.         cp = Print_cdname(cp, msg, eom, file);
  365.         fprintf(file,"\n\terrors = ");
  366.         cp = Print_cdname(cp, msg, eom, file);
  367.         (void) putc('\n', file);
  368.         break;
  369.  
  370.     case T_TXT:
  371.         (void) fputs("\ttext = \"", file);
  372.         cp2 = cp1 + dlen;
  373.         while (cp < cp2) {
  374.             if (n = (unsigned char) *cp++) {
  375.                 for (c = n; c > 0 && cp < cp2; c--)
  376.                     if (*cp == '\n') {
  377.                         (void) putc('\\', file);
  378.                         (void) putc(*cp++, file);
  379.                     } else
  380.                         (void) putc(*cp++, file);
  381.             }
  382.         }
  383.         (void) fputs("\"\n", file);
  384.           break;
  385.  
  386.     case T_UINFO:
  387.         fprintf(file,"\tuser info = %s\n", cp);
  388.         cp += dlen;
  389.         break;
  390.  
  391.     case T_UID:
  392.     case T_GID:
  393.         if (dlen == 4) {
  394.             fprintf(file,"\t%cid = %lu\n",type == T_UID ? 'u' : 'g',
  395.                 _getlong(cp));
  396.             cp += sizeof(int);
  397.         } else {
  398.             fprintf(file,"\t%cid of length %d?\n",
  399.                 type == T_UID ? 'u' : 'g', dlen);
  400.             cp += dlen;
  401.         }
  402.         break;
  403.  
  404.     case T_WKS: {
  405.         struct protoent *protoPtr;
  406.  
  407.         if (dlen < sizeof(u_long) + 1)
  408.             break;
  409.         if (!debug)
  410.             (void) putc('\n', file);
  411.         bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  412.         cp += sizeof(u_long);
  413.         if ((protoPtr = getprotobynumber(*cp)) != NULL) {
  414.             fprintf(file,"\tinet address = %s, protocol = %s\n\t",
  415.             inet_ntoa(inaddr), protoPtr->p_name);
  416.         } else {
  417.             fprintf(file,"\tinet address = %s, protocol = %d\n\t",
  418.             inet_ntoa(inaddr), *cp);
  419.         }
  420.         cp++;
  421.         n = 0;
  422.         while (cp < cp1 + dlen) {
  423.             c = *cp++;
  424.             do {
  425.                 struct servent *s;
  426.  
  427.                  if (c & 0200) {
  428.                     s = getservbyport((int)htons(n),
  429.                         protoPtr ? protoPtr->p_name : NULL);
  430.                     if (s != NULL) {
  431.                         fprintf(file,"  %s", s->s_name);
  432.                     } else {
  433.                         fprintf(file," #%d", n);
  434.                     }
  435.                 }
  436.                  c <<= 1;
  437.             } while (++n & 07);
  438.         }
  439.         putc('\n',file);
  440.         }
  441.         break;
  442.  
  443.     case T_NULL:
  444.         fprintf(file, "\tNULL (dlen %d)\n", dlen);
  445.         cp += dlen;
  446.         break;
  447.  
  448.     default:
  449.         fprintf(file,"\t??? unknown type %d ???\n", type);
  450.         cp += dlen;
  451.     }
  452.     if (_res.options & RES_DEBUG && type != T_SOA) {
  453.         fprintf(file,"\tttl = %lu (%s)\n", rrttl, p_time(rrttl));
  454.     }
  455.     if (cp != cp1 + dlen) {
  456.         fprintf(file,
  457.             "\n*** Error: record size incorrect (%d != %d)\n\n",
  458.             cp - cp1, dlen);
  459.         cp = NULL;
  460.     }
  461.     return (cp);
  462. }
  463.