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 / EXAMPLES / ch09.check_del.c < prev    next >
C/C++ Source or Header  |  1994-01-09  |  10KB  |  420 lines

  1. /*
  2. ** Program to verify subdomain delegation
  3. ** 
  4. ** Paul Albitz
  5. ** Hewlett Packard
  6. **
  7. ** usage: check_del [-v] [-F] [-o origin] -f dns_file [-o origin] \
  8. **                                                      [-f dns_file ...]
  9. **
  10. **    -v              print out successes as well as failures
  11. **              (if used twice, prints out address used and response
  12. **               packet)
  13. **    -F              fast mode - cuts down the retransmission wait time
  14. **    -o origin       same use as origin in BIND's boot file
  15. **    -f dns_file     file in RFC 1035 format
  16. **
  17. **   (The order of the arguments is important.)
  18. **
  19. **  The other source needed to make this program are db_load.c,
  20. **  db_save.c, ns.h, db.h and strcasecmp.c from the BIND source.
  21. **
  22. **  On SYSV or SYSV-derived operating systems, define SYSV at compile
  23. **  time.
  24. **
  25. */
  26.  
  27. static char rcsid[] = "@(#) $Header: main.c,v 1.8 90/04/18 10:55:31 pma Exp $";
  28.  
  29. #include <sys/types.h>
  30. #include <sys/socket.h>
  31. #include <sys/time.h>
  32. #include <netinet/in.h>
  33. #include <signal.h>
  34. #include <stdio.h>
  35. #include <errno.h>
  36. #include <signal.h>
  37. #include <syslog.h>
  38. #include <ctype.h>
  39. #include <netdb.h>
  40. #include <arpa/nameser.h>
  41. #include <resolv.h>
  42. #include "ns.h"
  43. #include "db.h"
  44.  
  45. int debug = 0;
  46. int errs = 0;
  47. int max_cache_ttl = 300;
  48. struct    netinfo *fnettab = NULL;
  49. struct    timeval tt;
  50. FILE *ddt = NULL;
  51. struct hashbuf *hashtab;    /* root hash table */
  52. struct hashbuf *fcachetab;    /* hash table of cache read from file */
  53. struct zoneinfo zone, *zones = &zone;    /* zone information */
  54. struct hostent *hp;
  55. struct state res_save;
  56. struct sockaddr_in sin;
  57. struct netinfo *nettab = NULL;
  58. struct netinfo **enettab = &nettab;
  59. char query[PACKETSZ];
  60. char response[PACKETSZ];
  61. int verbose = 0;
  62. extern int errno;
  63. char *string_resp[200];
  64. char *string_maybe[200];
  65. char *string_run[200];
  66. int noresponse = 0;
  67. int notrunning = 0;
  68. int mayberunning = 0;
  69. int goodresp = 0;
  70. int badresp = 0;
  71. int servfail = 0;
  72.  
  73. dostats()
  74. {
  75.     int j;
  76.  
  77.     printf("\n");
  78.     if(goodresp > 0)
  79.         printf("%d proper domain delegations\n", goodresp);
  80.     if(badresp > 0)
  81.         printf("%d improper domain delegations\n", badresp);
  82.     if(servfail > 0)
  83.         printf("%d SERVFAIL answers\n", servfail);
  84.     if(notrunning > 0)
  85.         printf("%d servers not running\n", notrunning);
  86.     if(noresponse > 0)
  87.         printf("%d servers not responding\n", noresponse);
  88.     if(notrunning > 0){
  89.         printf("\nServers not running:\n");
  90.         for(j = 0; j < notrunning; j++)
  91.         printf("\t%s\n", string_run[j]);
  92.     }
  93.     if(noresponse > 0){
  94.         printf("\nServers not responding:\n");
  95.         for(j = 0; j < noresponse; j++)
  96.         printf("\t%s\n", string_resp[j]);
  97.     }
  98.     exit(errs);
  99. }
  100.  
  101. usage()
  102. {
  103.     fprintf(stderr, "check_del [-v] [-F] [-o origin] -f db_file [-o origin] [-f db_file]\n");
  104.     exit(1);
  105. }
  106.  
  107. main(argc, argv)
  108. int argc;
  109. char *argv[];
  110. {
  111.     extern char *optarg;            /* for getopt */
  112.     extern int optind;              /* for getopt */
  113.     char c;                    /* for getopt */
  114.     char *origin = "";
  115.  
  116.     if(argc <=1)
  117.         usage();
  118.     /* 
  119.     ** print out a line at at time 
  120.     */
  121. #ifdef SYSV
  122.     setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
  123. #else
  124.     setlinebuf(stdout);
  125. #endif
  126.     signal(SIGINT, dostats);
  127.     res_init();
  128.     /* 
  129.     ** the name server names will be fully qualified 
  130.     */
  131.     _res.options &= ~(RES_DNSRCH|RES_DEFNAMES);
  132.     /* 
  133.     ** keep down the retransmissions 
  134.     */
  135.     _res.retry = 2;
  136.     /* 
  137.     ** send packet; wait 20 seconds; send packet wait 40 seconds 
  138.     ** (this can be tuned down on a local network)
  139.     */
  140.     _res.retrans = 20;
  141.     res_save = _res;
  142.     buildservicelist();
  143.     buildprotolist();
  144.  
  145.     while ((c = getopt(argc, argv, "Ff:o:v")) != EOF)
  146.         switch(c){
  147.             case 'F':
  148.                     _res.retrans = 5;
  149.                     res_save = _res;
  150.                     break;
  151.             case 'f':
  152.                     errs +=db_load(optarg,origin,&zone);
  153.                     break;
  154.             case 'o':
  155.                     origin = optarg;
  156.                     break;
  157.             case 'v':
  158.                     verbose++;
  159.                     break;
  160.             case '?':
  161.                     usage();
  162.                     break;
  163.         }
  164.     dostats();
  165. }
  166.  
  167. /*
  168. ** Replacement routine to check NS records
  169. ** instead of actually adding the data to
  170. ** the hash tables.
  171. */
  172. db_update(name, odp, newdp, flags, htp)
  173.     char name[];
  174.     struct databuf *odp, *newdp;
  175.     int flags;
  176.     struct hashbuf *htp;
  177. {
  178.     int i, j, n, failure;
  179.     HEADER *header;
  180.  
  181.     /* 
  182.     ** only look at NS records 
  183.     */
  184.     if(newdp->d_type == T_NS){
  185.  
  186.         /* 
  187.         ** Reset _res structure for gethostbyname
  188.         ** in case it is later modified
  189.         */
  190.         _res = res_save;
  191.         failure = 0;
  192.  
  193.         /*
  194.         ** Skip over servers that aren't running
  195.         ** or haven't responded.  
  196.         */
  197.         for(j = 0; j < noresponse; j++)
  198.             if(strcasecmp(newdp->d_data, string_resp[j]) == 0){
  199.                 if(verbose > 0)
  200.                     printf("Skipping %s\n", newdp->d_data);
  201.                 goto skip;
  202.             }
  203.         for(j = 0; j < notrunning; j++)
  204.             if(strcasecmp(newdp->d_data, string_run[j]) == 0){
  205.                 if(verbose > 0)
  206.                     printf("Skipping %s\n", newdp->d_data);
  207.                 goto skip;
  208.             }
  209.         hp = gethostbyname(newdp->d_data);
  210.         if(hp == NULL){
  211.             printf("No address for %s\n", newdp->d_data);
  212.         } else {
  213.             /* 
  214.             **try each address 
  215.             */
  216.             for(i = 0; hp->h_addr_list[i]; i++){
  217.                   memcpy((caddr_t)&sin.sin_addr, 
  218.                     hp->h_addr_list[i],
  219.                     hp->h_length);
  220.                 if(verbose > 1)
  221.                     printf("address %s\n", 
  222.                     inet_ntoa(sin.sin_addr));
  223.  
  224.                 /* 
  225.                 ** make SOA query 
  226.                 */
  227.                 n = res_mkquery(QUERY, name, C_IN, T_SOA, 
  228.                     NULL, 0, NULL, query, PACKETSZ);
  229.                 if(n < 0){
  230.                     fprintf(stderr, "res_mkquery failed\n");
  231.                     continue;
  232.                 }
  233.                 header = (HEADER *) query;
  234.  
  235.                 /* 
  236.                 ** turn off recursion desired bit so
  237.                 ** the server does not go out and
  238.                 ** find the SOA data
  239.                 */
  240.                 header->rd = 0;
  241.  
  242.                 /* 
  243.                 ** use only 1 address to get proper errno 
  244.                 ** to determine if server was or wasn't
  245.                 ** running
  246.                 */
  247.                     _res.nsaddr_list[0].sin_addr = 
  248.                             sin.sin_addr;
  249.                     _res.nscount = 1;
  250.                 errno = 0;
  251.                 n = res_send(query, n, response, PACKETSZ);
  252.  
  253.                 if(verbose > 1)
  254.                     fp_query(response,stdout);
  255.                 if(n > 0) {
  256.                         for(j = 0; j < mayberunning; j++)
  257.                             if(!strcasecmp(newdp->d_data, string_maybe[j])){
  258.                         if(verbose > 0)
  259.                             printf("\tServer %s moved off of maybe list\n",
  260.                             string_maybe[j]);
  261.                         free(string_maybe[j]);
  262.                         string_maybe[j] = NULL;
  263.                     }
  264.                     header = (HEADER *) response;
  265.                     if (header->rcode == SERVFAIL){
  266.                     servfail++;
  267.                     printf("SERVFAIL response from %s (domain %s)\n",
  268.                         newdp->d_data, name);
  269.                     /*
  270.                     ** authoritative server will have aa bit
  271.                     ** on and something in the answer section
  272.                     */
  273.                     } else if ((header->aa != 1) ||
  274.                     (ntohs(header->ancount) == 0)){
  275.                     badresp++;
  276.                     printf("Server %s is not authoritative for %s\n",
  277.                         newdp->d_data, name);
  278.                     } else {
  279.                     goodresp++;
  280.                     if(verbose > 0)
  281.                         printf("Server %s is authoritative for %s\n",
  282.                         newdp->d_data, name);
  283.                     }
  284.                     break;
  285.                 } else {
  286.                     failure = errno;
  287.                     /* 
  288.                     ** server not running, don't
  289.                     ** bother trying other addresses
  290.                     */
  291.                     if(errno == ECONNREFUSED)
  292.                     break;
  293.                 }
  294.             }
  295.             if((verbose > 0) && (failure == ECONNREFUSED)){
  296.                 printf("No name server running on %s (domain %s)\n",
  297.                         newdp->d_data, name);
  298.             } else {
  299.                 if((verbose > 0) && (failure == ETIMEDOUT))
  300.                     printf("No response from %s (domain %s)\n",
  301.                         newdp->d_data, name);
  302.             }
  303.             /* 
  304.             ** keep track of servers not running or not responding 
  305.             */
  306.             if((failure == ECONNREFUSED) && (notrunning < 200))
  307.                 string_run[notrunning++] = 
  308.                         savestr(newdp->d_data);
  309.             if((failure == ETIMEDOUT) && (mayberunning < 200)){
  310.                 int found;
  311.                 found = 0;
  312.                 for(j = 0; j < mayberunning; j++){
  313.                 if(string_maybe[j] == NULL)
  314.                     continue;
  315.                     if(!strcasecmp(newdp->d_data, string_maybe[j])){
  316.                     if(noresponse < 200){
  317.                     if(verbose > 0)
  318.                         printf("\tServer %s moved to not responding list\n",
  319.                             string_maybe[j]);
  320.                         string_resp[noresponse++] =
  321.                             string_maybe[j];
  322.                     }
  323.                     found = 1;
  324.                     break;
  325.                 }
  326.                 }
  327.                 if(found == 0){
  328.                 if(verbose > 0)
  329.                     printf("\tServer %s put on maybe list\n",
  330.                         newdp->d_data);
  331.                 string_maybe[mayberunning++] = 
  332.                         savestr(newdp->d_data);
  333.                 }
  334.             }
  335.  
  336.         }
  337.     } 
  338.     skip:
  339.     free(newdp);
  340.     return(1);
  341. }
  342.  
  343. /*
  344. ** Misc routines necessary to compile
  345. */
  346.  
  347. gettime(ttp)
  348. struct timeval *ttp;
  349. {
  350.     if (gettimeofday(ttp, (struct timezone *)0) < 0)
  351.         syslog(LOG_ERR, "gettimeofday failed: %m");
  352.     return;
  353. }
  354.  
  355. net_mask()
  356. {
  357.     return(0);
  358. }
  359.  
  360. extern char *sys_errlist[];
  361. extern int errno;
  362.  
  363. syslog(a,b,c,d,e,f)
  364. int  a;
  365. char *b, *c, *d, *e, *f;
  366. {
  367.     int percent=0;
  368.     int position=0;
  369.     char *s;
  370.     int tmperrno;
  371.     char msg[256];
  372.  
  373.     tmperrno=errno;
  374.  
  375.     /*
  376.      * Copy the string in case
  377.      * it is modified by the next
  378.      * step.
  379.      */
  380.     strcpy(msg,b);
  381.     for(s=msg; *s!=NULL; s++)
  382.         if(*s == '%'){
  383.             percent++;
  384.             if(*(s+1) == 'm'){
  385.                 *(s+1) = 's';
  386.                 position=percent;
  387.             }
  388.         }
  389.     switch(position){
  390.         case 0: fprintf(stdout,msg,c,d,e,f); break;
  391.         case 1: fprintf(stdout,msg,sys_errlist[tmperrno],c,d,e,f); break;
  392.         case 2: fprintf(stdout,msg,c,sys_errlist[tmperrno],d,e,f); break;
  393.         case 3: fprintf(stdout,msg,c,d,sys_errlist[tmperrno],e,f); break;
  394.         case 4: fprintf(stdout,msg,c,d,e,sys_errlist[tmperrno],f); break;
  395.         case 5: fprintf(stdout,msg,c,d,e,f,sys_errlist[tmperrno]); break;
  396.         default: fprintf(stdout,"percent m in position %d\n",position); break;
  397.     }
  398.     fprintf(stdout,"\n");
  399. }
  400.  
  401. openlog()
  402. {}
  403.  
  404. /*
  405. ** Fake stubs for findnetinfo and printnetinfo to satisfy the compiler
  406. */
  407.  
  408. struct netinfo *
  409. findnetinfo(addr)
  410.     struct in_addr addr;
  411. {
  412.     return((struct netinfo *) NULL);
  413. }
  414.  
  415. printnetinfo(ntp)
  416.     register struct netinfo *ntp;
  417. {
  418.     return(1);
  419. }
  420.