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