home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / dns / ddt2.0 / cmd / soac < prev    next >
Encoding:
Text File  |  1993-05-31  |  7.3 KB  |  349 lines

  1. #! /usr/local/bin/perl
  2. #
  3. #  soac - DNS authority records (SOA) checker
  4. #
  5. #  invoke as:
  6. #    soac [-l msglevel]
  7. #
  8. #  Copyright (C) 1992, 1993 PUUG - Grupo Portugues de Utilizadores
  9. #                   do Sistema UNIX
  10. #             1992, 1993 FCCN - Fundacao para o Desenvolvimento dos Meios 
  11. #                        Nacionais de Calculo Cientifico     
  12. #
  13. #  Authors: Jorge Frazao de Oliveira <frazao@puug.pt>
  14. #        Artur Romao <artur@dns.pt>
  15. #
  16. #  This file is part of the DDT package, Version 2.0.
  17. #
  18. #  Permission to use, copy, modify, and distribute this software and its 
  19. #  documentation for any purpose and without any fee is hereby granted, 
  20. #  provided that the above copyright notice appear in all copies.  Neither 
  21. #  PUUG nor FCCN make any representations about the suitability of this
  22. #  software for any purpose.  It is provided "as is" without express or 
  23. #  implied warranty.
  24.  
  25.  
  26. # =()<push(@INC, "@<LIBDIR>@");>()=
  27. push(@INC, "/usr/local/lib/ddt/cmd");
  28.  
  29. require "ddt.pl";
  30.  
  31. # Default values for SOA timers.
  32. $TopLevel{"Refresh"} = 86400;    # 24h
  33. $TopLevel{"Retry"}   = 7200;    #  2h
  34. $TopLevel{"Expire"}  = 2592000;    # 30d
  35. $TopLevel{"TTL"}     = 345600;    #  4d
  36. $Other{"Refresh"}    = 28800;    #  8h
  37. $Other{"Retry"}      = 7200;    #  2h
  38. $Other{"Expire"}     = 604800;    #  7h
  39. $Other{"TTL"}        = 86400;    #  1d
  40.  
  41. $diffTopLevel{"Refresh"} = 0;
  42. $diffTopLevel{"Retry"}   = 0;
  43. $diffTopLevel{"Expire"}  = 0;
  44. $diffTopLevel{"TTL"}     = 0;
  45.  
  46. $diffOther{"Refresh"}    = 0;
  47. $diffOther{"Retry"}      = 0;
  48. $diffOther{"Expire"}     = 0;
  49. $diffOther{"TTL"}        = 0;
  50.  
  51. $Timeout = 1;
  52.  
  53. # =()<&read_config("@<SOACONFIG>@");>()=
  54. &read_config("/usr/local/lib/ddt/cmd/SOA-timers");
  55.  
  56.  
  57. while (<STDIN>) {
  58.     next if /^;/;            # ignore commented lines
  59.  
  60.         chop;                           # strip record separator
  61.     @Field = split(/\s+/, $_);    # break the input line
  62.  
  63.     if (/^\$ORIGIN/) {
  64.         $Origin = $Field[2];    # set to a different origin
  65.     
  66.         next;
  67.     }
  68.  
  69.         if (/^[*\.\-0-9A-Za-z]+/) { 
  70.         $LineName = 1;
  71.  
  72.         $Name = &make_name($Field[1], $Origin);
  73.     }
  74.  
  75.         if (/\tIN\tSOA\t/) {
  76.             $saveLine = $_;
  77.  
  78.             &show_zone($Zone);
  79.  
  80.             undef %NS;
  81.  
  82.             $Zone = $Name;
  83.  
  84.             if ($saveLine =~ /\(\s*$/) {
  85.                 chop ($_ = <STDIN>);
  86.             }         
  87.             else {
  88.                 $_ = $saveLine;
  89.             }
  90.  
  91.             # get the timers for this zone
  92.             $_ =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+).*\)$/;
  93.  
  94.                    $SerialNo   = $1;
  95.                    $Refresh    = $2;
  96.                    $Retry      = $3;
  97.                    $Expire     = $4;
  98.             $DefaultTTL = $5;
  99.     }
  100.     elsif (/\tIN\tNS\t/) {
  101.         if ($Name eq $Zone) {
  102.             $NS{$Field[$#Field]} = 1;
  103.         }
  104.     }
  105. }
  106.  
  107. &show_zone($Zone);
  108.  
  109. exit 0;
  110.  
  111.  
  112. sub read_config {
  113.         local($file) = @_;
  114.     local($value);
  115.  
  116.         if(open(CONFIG, $file)) { 
  117.             while (<CONFIG>) {
  118.             next if !/\s*(\d+)/;
  119.  
  120.             $value = $1;
  121.  
  122.             $_ = &toupper($_);
  123.  
  124.             if (/^T_REFRESH/) {
  125.                     $TopLevel{"Refresh"} = $value;
  126.             }
  127.             elsif (/^T_RETRY/) {
  128.                     $TopLevel{"Retry"} = $value;
  129.             }
  130.             elsif (/^T_EXPIRE/) {
  131.                     $TopLevel{"Expire"} = $value;
  132.             }
  133.             elsif (/^T_TTL/) {
  134.                     $TopLevel{"TTL"} = $value;
  135.             }
  136.             elsif (/^REFRESH/) {
  137.                     $Other{"Refresh"} = $value;
  138.             }
  139.             elsif (/^RETRY/) {
  140.                     $Other{"Retry"} = $value;
  141.             }
  142.             elsif (/^EXPIRE/) {
  143.                     $Other{"Expire"} = $value;
  144.             }
  145.             elsif (/^TTL/) {
  146.                     $Other{"TTL"} = $value;
  147.             }
  148.             elsif (/^DIFFT_REFRESH/) {
  149.                     $diffTopLevel{"Refresh"} = $value;
  150.             }
  151.             elsif (/^DIFFT_RETRY/) {
  152.                     $diffTopLevel{"Retry"} = $value;
  153.             }
  154.             elsif (/^DIFFT_EXPIRE/) {
  155.                     $diffTopLevel{"Expire"} = $value;
  156.             }
  157.             elsif (/^DIFFT_TTL/) {
  158.                     $diffTopLevel{"TTL"} = $value;
  159.             }
  160.             elsif (/^DIFFREFRESH/) {
  161.                     $diffOther{"Refresh"} = $value;
  162.             }
  163.             elsif (/^DIFFRETRY/) {
  164.                     $diffOther{"Retry"} = $value;
  165.             }
  166.             elsif (/^DIFFEXPIRE/) {
  167.                     $diffOther{"Expire"} = $value;
  168.             }
  169.             elsif (/^DIFFTTL/) {
  170.                     $diffOther{"TTL"} = $value;
  171.             }
  172.             elsif (/^TIMEOUT/) {
  173.                     $Timeout = $value;
  174.             }
  175.         }
  176.  
  177.             delete $opened{$file} && close($file);
  178.         }
  179.     else {
  180.         warn "Can't open $file: $!\n"; 
  181.     }
  182. }
  183.  
  184.  
  185. #
  186. # the absolute value of a number
  187. #
  188. sub abs {
  189.         local($value) = @_;
  190.  
  191.     return $value < 0 ? -$value : $value;
  192. }
  193.  
  194.  
  195. #
  196. # check each of the timers for their convenience, according to the values read
  197. # from $ConfigFile (or the default ones, listed at the begining of this file
  198. #
  199. sub check_SOA {
  200.     local($zone) = @_;
  201.         local(@Msg, $msg, $fmt);
  202.     local($rref, $dref, $rret, $dret, $rexp, $dexp, $rttl, $dttl);
  203.  
  204.         if ($Level >= 3) {
  205.         if ($zone =~ tr/\./\./ == 1) {    # top level domain 
  206.             $rref = $TopLevel{"Refresh"};
  207.             $dref = $diffTopLevel{"Refresh"};
  208.             
  209.             $rret = $TopLevel{"Retry"};
  210.             $dret = $diffTopLevel{"Retry"};
  211.  
  212.             $rexp = $TopLevel{"Expire"};
  213.             $dexp = $diffTopLevel{"Expire"};
  214.  
  215.             $rttl = $TopLevel{"TTL"};
  216.             $dttl = $diffTopLevel{"TTL"};
  217.         }
  218.         else {                # non-top level domain
  219.             $rref = $Other{"Refresh"};
  220.             $dref = $diffOther{"Refresh"};
  221.     
  222.             $rret = $Other{"Retry"};
  223.             $dret = $diffOther{"Retry"};
  224.  
  225.             $rexp = $Other{"Expire"};
  226.             $dexp = $diffOther{"Expire"};
  227.  
  228.             $rttl = $Other{"TTL"};
  229.             $dttl = $diffOther{"TTL"};
  230.         }
  231.  
  232.         $fmt = "%s%-12s %8d [recommended value: %8d]";
  233.  
  234.             if (&abs($Refresh - $rref) gt $dref) {
  235.               push(@Msg, 
  236.                  sprintf($fmt, $Lpad[3], "Refresh", $Refresh, $rref));
  237.             }
  238.  
  239.             if (&abs($Retry - $rret) gt $dret) {
  240.             push(@Msg,
  241.                              sprintf($fmt, $Lpad[3], "Retry", $Retry, $rret));
  242.             }
  243.  
  244.             if (&abs($Expire - $rexp) gt $dexp) {
  245.             push(@Msg,
  246.                    sprintf($fmt, $Lpad[3], "Expire", $Expire, $rexp));
  247.             }
  248.  
  249.             if (&abs($DefaultTTL - $rttl) gt $dttl) {
  250.             push(@Msg, 
  251.                    sprintf($fmt, $Lpad[3], "Default TTL", $DefaultTTL, $rttl));
  252.         }
  253.  
  254.         if ($#Msg) {
  255.                 print "  SOA Record";
  256.             foreach $msg ($[ .. $#Msg) {
  257.                 print shift(@Msg);
  258.             }
  259.  
  260.             print "";
  261.         }
  262.     }
  263. }
  264.  
  265.  
  266. #
  267. # call dig to see the SOA record for this zone, according to $server
  268. #
  269. sub dig {
  270.     local($server, $zone) = @_;
  271.         local($exists, $auth);
  272.  
  273.     chop $server if $server =~ /[.][0-9]*[.]$/;    # cut trailing dot
  274.                             # from IP address 
  275.  
  276. # =()<    $dig = "@<DIG>@";>()=
  277.     $dig = "/usr/local/bin/dig";
  278.  
  279.         open(DIG, "$dig @$server $zone SOA +pfset=0x2220 +norec +time=$Timeout 2>&1 |");
  280.  
  281.     while(<DIG>) {
  282.         chop;
  283.  
  284.         $exists = 1;    # dig said something...
  285.  
  286.         if (/^;; flags:.*\baa\b/) {
  287.             $auth = 1;    # authoritative answer
  288.         }
  289.  
  290.         if (/^; Bad server/ && $Level >= 1) {
  291.                 return sprintf("%s%-20s [Bad server]", 
  292.                        $Lpad[1], $server);
  293.         }
  294.  
  295.         if (/Connection (.*)/ &&  $Level >= 4) {
  296.             return sprintf("%s%-20s [Connection %s]",
  297.                        $Lpad[4], $server, $1);
  298.         }
  299.  
  300.         if (/(\d+)\s*;serial$/ && $SerialNo != $1 && $Level >= 3) {
  301.             return sprintf("%s%-20s [Serial number mismatch (cached:%d, current:%d)]",
  302.                        $Lpad[3], $server, $SerialNo, $1);
  303.         }
  304.     }
  305.  
  306.     if ((!$exists || !$auth) && $Level >= 1) {
  307.         return sprintf("%s%-20s [Non-authoritative answer]",
  308.                    $LPad[1], $server);
  309.     }
  310. }
  311.  
  312.  
  313. sub check_NS {
  314.     local($zone) = @_;
  315.         local($ns, @Msg, $msg);
  316.  
  317.     if ($#NS == 1 && $Level >= 1) {    # this is dangerous
  318.         push(@Msg, "$Lpad[1]$zone has only one name server\n");
  319.     }
  320.  
  321.         foreach $ns (keys %NS) {        # check each of the name
  322.         if ($msg = &dig($ns, $zone)) {    # servers for authority 
  323.             push(@Msg, $msg);    # information
  324.         }
  325.         }
  326.  
  327.     if ($#Msg) {
  328.         print "  Name Servers";
  329.  
  330.         foreach $msg ($[ .. $#Msg) {
  331.             print shift(@Msg);
  332.         }
  333.  
  334.         print "";
  335.         }
  336. }
  337.  
  338.  
  339. sub show_zone {
  340.     local($zone) = @_;
  341.  
  342.     if ($zone ne "") {
  343.             print "\n ###", &toupper($zone), "###\n";
  344.  
  345.             &check_SOA($zone);
  346.             &check_NS($zone);
  347.     }
  348. }
  349.