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 / TOOLS / NSLOOKUP / debug.c < prev    next >
Text File  |  1994-09-23  |  10KB  |  453 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 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.  
  20. #ifndef lint
  21. static char sccsid[] = "@(#)debug.c    5.22 (Berkeley) 6/29/90";
  22. #endif /* not lint */
  23.  
  24. /*
  25.  *******************************************************************************
  26.  *
  27.  *  debug.c --
  28.  *
  29.  *    Routines to print out packets received from a name server query.
  30.  *
  31.  *      Modified version of 4.3BSD BIND res_debug.c 5.30 6/27/90
  32.  *
  33.  *******************************************************************************
  34.  */
  35.  
  36. #ifdef OSK
  37. #include <types.h>
  38. #include <in.h>
  39. #else
  40. #include <sys/types.h>
  41. #include <netinetin.h>
  42. #endif
  43. #include <stdio.h>
  44. #include <arpa/nameser.h>
  45. #include <arpa/inet.h>
  46. #include <resolv.h>
  47. #include <netdb.h>
  48. #include "res.h"
  49. #ifndef OSK
  50. extern char ctime();
  51. #endif
  52.  
  53. /*
  54.  *  Imported from res_debug.c
  55.  */
  56. extern char *_res_resultcodes[];
  57. extern char *_res_opcodes[];
  58.  
  59. /*
  60.  *  Used to highlight the start of a record when printing it.
  61.  */
  62. #define INDENT "    ->  "
  63.  
  64.  
  65.  
  66. /*
  67.  * Print the contents of a query.
  68.  * This is intended to be primarily a debugging routine.
  69.  */
  70.  
  71. Print_query(msg, eom, printHeader)
  72.     char *msg, *eom;
  73.     int printHeader;
  74. {
  75.     Fprint_query(msg, eom, printHeader,stdout);
  76. }
  77.  
  78. Fprint_query(msg, eom, printHeader,file)
  79.     char *msg, *eom;
  80.     int printHeader;
  81.     FILE *file;
  82. {
  83.     register char *cp;
  84.     register HEADER *hp;
  85.     register int n;
  86.     short class;
  87.     short type;
  88.  
  89.     /*
  90.      * Print header fields.
  91.      */
  92.     hp = (HEADER *)msg;
  93.     cp = msg + sizeof(HEADER);
  94.     if (printHeader || (_res.options & RES_DEBUG2)) {
  95.         fprintf(file,"    HEADER:\n");
  96.         fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
  97.         fprintf(file,", id = %d", ntohs(hp->id));
  98.         fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
  99.         fprintf(file,"\theader flags: ");
  100.         if (hp->qr) {
  101.             fprintf(file," response");
  102.         } else {
  103.             fprintf(file," query");
  104.         }
  105.         if (hp->aa)
  106.             fprintf(file,", auth. answer");
  107.         if (hp->tc)
  108.             fprintf(file,", truncation");
  109.         if (hp->rd)
  110.             fprintf(file,", want recursion");
  111.         if (hp->ra)
  112.             fprintf(file,", recursion avail.");
  113.         if (hp->pr)
  114.             fprintf(file,", primary");
  115.         fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount));
  116.         fprintf(file,",  answers = %d", ntohs(hp->ancount));
  117.         fprintf(file,",  authority records = %d", ntohs(hp->nscount));
  118.         fprintf(file,",  additional = %d\n\n", ntohs(hp->arcount));
  119.     }
  120.  
  121.     /*
  122.      * Print question records.
  123.      */
  124.     if (n = ntohs(hp->qdcount)) {
  125.         fprintf(file,"    QUESTIONS:\n");
  126.         while (--n >= 0) {
  127.             fprintf(file,"\t");
  128.             cp = Print_cdname(cp, msg, eom, file);
  129.             if (cp == NULL)
  130.                 return;
  131.             type = _getshort(cp);
  132.             cp += sizeof(u_short);
  133.             class = _getshort(cp);
  134.             cp += sizeof(u_short);
  135.             fprintf(file,", type = %s", p_type(type));
  136.             fprintf(file,", class = %s\n", p_class(class));
  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, INDENT);
  146.             cp = Print_rr(cp, msg, eom, 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,"    AUTHORITY RECORDS:\n");
  156.         while (--n >= 0) {
  157.             fprintf(file, INDENT);
  158.             cp = Print_rr(cp, msg, eom, 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, INDENT);
  170.             cp = Print_rr(cp, msg, eom, file);
  171.             if (cp == NULL)
  172.                 return;
  173.         }
  174.     }
  175.     fprintf(file,"\n------------\n");
  176. }
  177.  
  178.  
  179. char *
  180. Print_cdname_sub(cp, msg, eom, file, format)
  181.     char *cp, *msg, *eom;
  182.     FILE *file;
  183.     int format;
  184. {
  185.     int n;
  186.     char name[MAXDNAME];
  187.     extern char *strcpy();
  188.  
  189.     if ((n = dn_expand(msg, eom, cp, name, sizeof(name))) < 0)
  190.         return (NULL);
  191.     if (name[0] == '\0') {
  192.         (void) strcpy(name, "(root)");
  193.     }
  194.     if (format) {
  195.         fprintf(file, "%-30s", name);
  196.     } else {
  197.         fputs(name, file);
  198.     }
  199.     return (cp + n);
  200. }
  201.  
  202. char *
  203. Print_cdname(cp, msg, eom, file)
  204.     char *cp, *msg, *eom;
  205.     FILE *file;
  206. {
  207.     return(Print_cdname_sub(cp, msg, eom, file, 0));
  208. }
  209.  
  210. char *
  211. Print_cdname2(cp, msg, eom, file)
  212.     char *cp, *msg, *eom;
  213.     FILE *file;
  214. {
  215.     return(Print_cdname_sub(cp, msg, eom, file, 1));
  216. }
  217.  
  218. /*
  219.  * Print resource record fields in human readable form.
  220.  */
  221. char *
  222. Print_rr(cp, msg, eom, file)
  223.     char *cp, *msg, *eom;
  224.     FILE *file;
  225. {
  226.     int type, class, dlen, n, c;
  227.     unsigned long rrttl, ttl;
  228.     struct in_addr inaddr;
  229.     char *cp1, *cp2;
  230.     int debug;
  231.  
  232.     if ((cp = Print_cdname(cp, msg, eom, file)) == NULL) {
  233.         fprintf(file, "(name truncated?)\n");
  234.         return (NULL);            /* compression error */
  235.     }
  236.  
  237.     type = _getshort(cp);
  238.     cp += sizeof(u_short);
  239.     class = _getshort(cp);
  240.     cp += sizeof(u_short);
  241.     rrttl = _getlong(cp);
  242.     cp += sizeof(u_long);
  243.     dlen = _getshort(cp);
  244.     cp += sizeof(u_short);
  245.  
  246.     debug = _res.options & (RES_DEBUG|RES_DEBUG2);
  247.     if (debug) {
  248.         if (_res.options & RES_DEBUG2) {
  249.         fprintf(file,"\n\ttype = %s, class = %s, dlen = %d",
  250.                 p_type(type), p_class(class), dlen);
  251.         }
  252.         if (type == T_SOA) {
  253.         fprintf(file,"\n\tttl = %lu (%s)", rrttl, p_time(rrttl));
  254.         }
  255.         (void) putc('\n', file);
  256.     } 
  257.  
  258.     cp1 = cp;
  259.  
  260.     /*
  261.      * Print type specific data, if appropriate
  262.      */
  263.     switch (type) {
  264.     case T_A:
  265.         switch (class) {
  266.         case C_IN:
  267.         case C_HS:
  268.             bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  269.             if (dlen == 4) {
  270.                 fprintf(file,"\tinternet address = %s\n",
  271.                     inet_ntoa(inaddr));
  272.                 cp += dlen;
  273.             } else if (dlen == 7) {
  274.                 fprintf(file,"\tinternet address = %s",
  275.                     inet_ntoa(inaddr));
  276.                 fprintf(file,", protocol = %d", cp[4]);
  277.                 fprintf(file,", port = %d\n",
  278.                     (cp[5] << 8) + cp[6]);
  279.                 cp += dlen;
  280.             }
  281.             break;
  282.         default:
  283.             fprintf(file,"\taddress, class = %d, len = %d\n",
  284.                 class, dlen);
  285.             cp += dlen;
  286.         }
  287.         break;
  288.  
  289.     case T_CNAME:
  290.         fprintf(file,"\tcanonical name = ");
  291.         goto doname;
  292.  
  293.     case T_MG:
  294.         fprintf(file,"\tmail group member = ");
  295.         goto doname;
  296.     case T_MB:
  297.         fprintf(file,"\tmail box = ");
  298.         goto doname;
  299.     case T_MR:
  300.         fprintf(file,"\tmailbox rename = ");
  301.         goto doname;
  302.     case T_MX:
  303.         fprintf(file,"\tpreference = %u",_getshort(cp));
  304.         cp += sizeof(u_short);
  305.         fprintf(file,", mail exchanger = ");
  306.         goto doname;
  307.     case T_NS:
  308.         fprintf(file,"\tnameserver = ");
  309.         goto doname;
  310.     case T_PTR:
  311.         fprintf(file,"\tname = ");
  312. doname:
  313.         cp = Print_cdname(cp, msg, eom, file);
  314.         (void) putc('\n', file);
  315.         break;
  316.  
  317.     case T_HINFO:
  318.         if (n = *cp++) {
  319.             fprintf(file,"\tCPU = %.*s", n, cp);
  320.             cp += n;
  321.         }
  322.         if (n = *cp++) {
  323.             fprintf(file,"\tOS = %.*s\n", n, cp);
  324.             cp += n;
  325.         }
  326.         break;
  327.  
  328.     case T_SOA:
  329.         if (!debug)
  330.             (void) putc('\n', file);
  331.         fprintf(file,"\torigin = ");
  332.         cp = Print_cdname(cp, msg, eom, file);
  333.         fprintf(file,"\n\tmail addr = ");
  334.         cp = Print_cdname(cp, msg, eom, file);
  335.         fprintf(file,"\n\tserial = %lu", _getlong(cp));
  336.         cp += sizeof(u_long);
  337.         ttl = _getlong(cp);
  338.         fprintf(file,"\n\trefresh = %lu (%s)", ttl, p_time(ttl));
  339.         cp += sizeof(u_long);
  340.         ttl = _getlong(cp);
  341.         fprintf(file,"\n\tretry   = %lu (%s)", ttl, p_time(ttl));
  342.         cp += sizeof(u_long);
  343.         ttl = _getlong(cp);
  344.         fprintf(file,"\n\texpire  = %lu (%s)", ttl, p_time(ttl));
  345.         cp += sizeof(u_long);
  346.         ttl = _getlong(cp);
  347.         fprintf(file,"\n\tminimum ttl = %lu (%s)\n", ttl, p_time(ttl));
  348.         cp += sizeof(u_long);
  349.         break;
  350.  
  351.     case T_MINFO:
  352.         if (!debug)
  353.             (void) putc('\n', file);
  354.         fprintf(file,"\trequests = ");
  355.         cp = Print_cdname(cp, msg, eom, file);
  356.         fprintf(file,"\n\terrors = ");
  357.         cp = Print_cdname(cp, msg, eom, file);
  358.         (void) putc('\n', file);
  359.         break;
  360.  
  361.     case T_TXT:
  362.         (void) fputs("\ttext = \"", file);
  363.         cp2 = cp1 + dlen;
  364.         while (cp < cp2) {
  365.             if (n = (unsigned char) *cp++) {
  366.                 for (c = n; c > 0 && cp < cp2; c--)
  367.                     if (*cp == '\n') {
  368.                         (void) putc('\\', file);
  369.                         (void) putc(*cp++, file);
  370.                     } else
  371.                         (void) putc(*cp++, file);
  372.             }
  373.         }
  374.         (void) fputs("\"\n", file);
  375.           break;
  376.  
  377.     case T_UINFO:
  378.         fprintf(file,"\tuser info = %s\n", cp);
  379.         cp += dlen;
  380.         break;
  381.  
  382.     case T_UID:
  383.     case T_GID:
  384.         if (dlen == 4) {
  385.             fprintf(file,"\t%cid = %lu\n",type == T_UID ? 'u' : 'g',
  386.                 _getlong(cp));
  387.             cp += sizeof(int);
  388.         } else {
  389.             fprintf(file,"\t%cid of length %d?\n",
  390.                 type == T_UID ? 'u' : 'g', dlen);
  391.             cp += dlen;
  392.         }
  393.         break;
  394.  
  395.     case T_WKS: {
  396.         struct protoent *protoPtr;
  397.  
  398.         if (dlen < sizeof(u_long) + 1)
  399.             break;
  400.         if (!debug)
  401.             (void) putc('\n', file);
  402.         bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  403.         cp += sizeof(u_long);
  404.         if ((protoPtr = getprotobynumber(*cp)) != NULL) {
  405.             fprintf(file,"\tinet address = %s, protocol = %s\n\t",
  406.             inet_ntoa(inaddr), protoPtr->p_name);
  407.         } else {
  408.             fprintf(file,"\tinet address = %s, protocol = %d\n\t",
  409.             inet_ntoa(inaddr), *cp);
  410.         }
  411.         cp++;
  412.         n = 0;
  413.         while (cp < cp1 + dlen) {
  414.             c = *cp++;
  415.             do {
  416.                 struct servent *s;
  417.  
  418.                  if (c & 0200) {
  419.                     s = getservbyport(n, NULL);
  420.                     if (s != NULL) {
  421.                         fprintf(file,"  %s", s->s_name);
  422.                     } else {
  423.                         fprintf(file," #%d", n);
  424.                     }
  425.                 }
  426.                  c <<= 1;
  427.             } while (++n & 07);
  428.         }
  429.         putc('\n',file);
  430.         }
  431.         break;
  432.  
  433.     case T_NULL:
  434.         fprintf(file, "\tNULL (dlen %d)\n", dlen);
  435.         cp += dlen;
  436.         break;
  437.  
  438.     default:
  439.         fprintf(file,"\t??? unknown type %d ???\n", type);
  440.         cp += dlen;
  441.     }
  442.     if (_res.options & RES_DEBUG && type != T_SOA) {
  443.         fprintf(file,"\tttl = %lu (%s)\n", rrttl, p_time(rrttl));
  444.     }
  445.     if (cp != cp1 + dlen) {
  446.         fprintf(file,
  447.             "\n*** Error: record size incorrect (%d != %d)\n\n",
  448.             cp - cp1, dlen);
  449.         cp = NULL;
  450.     }
  451.     return (cp);
  452. }
  453.