⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dnswalk

📁 早期freebsd实现
💻
字号:
#!/usr/local/bin/perl# dnswalk    Walk through a DNS tree, pulling out zone data and# dumping it in a directory tree## $Id: dnswalk,v 1.4 1993/07/18 00:46:05 barr Exp $## check data collected for legality using standard resolver## invoke as dnswalk domain > logfile# Options:#    -r    Recursively descend subdomains of domain#    -f    Force a zone transfer, ignore existing axfr file#    -a    turn on warning of duplicate A records.#    -d    Debugging#    -m    Check only if the domain has been modified.  (Useful only if#        dnswalk has been run previously.)#    -F    Enable "facist" checking.  (See README)#    -l    Check lame delegationsrequire "getopts.pl";do Getopts(":rfcadmFl");$basedir = ".";($domain = $ARGV[0]) =~ tr/A-Z/a-z/;if ($domain !~ /\.$/) {    die "Usage: dnswalk domain\ndomain MUST end with a '.'\n";}mkdir($basedir,0777);&dowalk($domain);exit;sub dowalk {    local (@subdoms);    local (@sortdoms);    local ($domain)=$_[0];    $modified=0;#    ($file,@subdoms)=&doaxfr($domain);  /* perl bug */    @subdoms=&doaxfr($domain);    $file=shift(@subdoms);    if (!($opt_m && !$modified)) {        &checkfile($file,$domain);    }    else {        print STDERR "skipping...\n";    }    @sortdoms = sort byhostname @subdoms;    local ($subdom);    if ($opt_r) {        foreach $subdom (@sortdoms) {            &dowalk($subdom);        }    }}# try to get a zone transfer, trying each listed authoratative server if# if fails.sub doaxfr {    local ($domain)=@_[0];    local (%subdoms)=();    local ($serial);    local ($foundsoa)=0;    # attempt to make up for dig's poor                 # error handling    ($path=&host2path($domain)) =~ tr/A-Z/a-z/;    local(@servers) = &getauthservers($domain);    print "warning: $domain has only one authoratative nameserver\n" if (scalar(@servers) == 1);    if ((-f "$basedir/$path/axfr") && (!$main'opt_f)) {        open(DIG,"<$basedir/$path/axfr");        while (<DIG>) {            chop;            if (/(\d+)\s*; ?serial/) {                $serial=$1;            }            if (/(\S+)\s*\d+\s+NS/) {                $1 =~ tr/A-Z/a-z/;                if ((!&equal($1,$domain)) && ( !$subdoms{$1})) {                    $subdoms{$1}=1;                }            }        }        # if there's no serial number in file, assume it is corrupt        if ($serial) {            foreach $server (@servers) {                $authserno=&getserno($domain,$server);                last if ($authserno);            }            if ($authserno <= $serial) {                print STDERR "Using existing zone transfer info for $domain\n";                return ("$basedir/$path/axfr", keys %subdoms);            }        }    }    &mkdirpath($path);    SERVER:    foreach $server (@servers) {        $SIG{'INT'}="nop;";        print STDERR "Getting zone transfer of $domain from $server...";        open(DIG,"dig axfr $domain \@$server 2>/dev/null |");        open(DIGOUT,">$basedir/$path/axfr");	@subdoms=undef;        while (<DIG>) {            if (/(\S+)\s*\d+\s+NS/) {                $1 =~ tr/A-Z/a-z/;                if ((!&equal($1,$domain)) && ( !$subdoms{$1})) {                    $subdoms{$1}=1;                }            }            elsif (/\S+\s*\d+\s+SOA/) {                $foundsoa=1;            }            print DIGOUT $_;        }        if ($? || !$foundsoa) {            print STDERR "failed.\n";            close(DIGOUT);            next SERVER;        }        print STDERR "done.\n";        close(DIGOUT);        close(DIG);        last SERVER;    } # foreach #    $SIG{'INT'}=undef;    if ($? || !$foundsoa) {        print STDERR "All zone transfer attempts of $domain failed\n";        unlink("$basedir/$path/axfr");        return undef;    }    $modified=1;    return ("$basedir/$path/axfr", keys %subdoms);}# returns "edu/psu/pop" given "pop.psu.edu"sub host2path {    join('/',reverse(split(/\./,$_[0])));}# makes sure all directories exist in "foo/bar/baz"sub mkdirpath {    local (@path)=split(/\//,$_[0]);    local ($dir)=$basedir;    foreach $p (@path) {        mkdir(($dir .= "/".$p), 0777);    }}sub getserno {    local ($serno)="";    $SIG{'INT'}="nop;";    open(DIG,"dig soa $_[0] \@$_[1] 2>/dev/null|");    while (<DIG>) {        if (/(\d+)\s*; ?serial/) {             $serno=$1;        }    }    close(DIG);    $SIG{'INT'}=undef;    return $serno;}sub getauthservers {    local ($domain)=$_[0];    open(DIG,"dig +noau ns $_[0] 2>/dev/null|");    local(@servers);    while (<DIG>) {        chop;        if (/\S+\s*\d+\s+NS\s+(\S+)/) {            push(@servers,$1);        }    }    close(DIG);    return @servers;}# open result of zone tranfer and check lots of nasty things# here's where the fun beginssub checkfile {    open(FILE,"<$_[0]");    print "Checking $domain\n";    local (%glues)=();	# look for duplicate glue (A) records    local ($name, $aliases, $addrtype, $length, @addrs);    local ($prio,$mx);    local ($soa,$contact);    local ($lastns);	# last NS record we saw    local (@keys);	# temp variable    $soa=undef;    while (<FILE>) {        chop;        if (/^;/) {            if (/(.*[Ee][Rr][Rr][Oo][Rr].*)/) {                # print any dig errors                print $1 ."\n";                next;            }        }        next if /^$/;	# skip blanks        split(/\t/);        # 0=key 2=rrtype 3=value (4=value if 2=MX)        next if ($_[0] =~ /;/);        if ($_[0] =~ /[^-A-Za-z0-9._]/) {	    # I know, underscores aren't kosher but ....            print " $_[0]: invalid character(s) in name\n";        }        if ($_[2] eq "SOA") {            print STDERR 's' if $opt_d;	    if (! $soa) {  # aviod duplicate SOA's.  Argh.               ($soa,$contact) = $_[3] =~ /(\S+)\s+(\S+)/;               print "SOA=$soa	contact=$contact\n";	    }        } elsif ($_[2] eq "PTR") {            print STDERR 'p' if $opt_d;            if (scalar((@keys=split(/\./,$_[0]))) == 6 ) {                # check if forward name exists, but only if reverse is                # a full IP addr                # skip ".0" networks                if ($keys[0] ne "0") {                    if (!(($name, $aliases, $addrtype, $length, @addrs)=gethostbyname($_[3])) && $!) {                        print " gethostbyname($_[3]): $!\n";                    }                    else {                        if (!$name) {                            print " $_[0] PTR $_[3]: unknown host\n";                        }                        elsif (!&equal(($name.'.'),$_[3])) {                            print " $_[0] PTR $_[3]: CNAME (to $name)\n";                        }                            elsif (!&matchaddrlist($_[0])) {                            print " $_[0] PTR $_[3]: A record not found\n";                        }                    }                }            }        } elsif (($_[2] eq "A") ) {            print STDERR 'a' if $opt_d;# check to see that a reverse PTR record exists            if (!(($name,$aliases,$addrtype,$length,@addrs)=gethostbyaddr(pack('C4', split(/\./,$_[3])),2)) && $!) {                print " gethostbyaddr($_[3]): $!\n";            }            else {                if (!$name) {                    print " $_[0] A $_[3]: no PTR record\n";                }                elsif ($opt_F && !&equal($name.".",$_[0])) {                    print " $_[0] A $_[3]: points to $name\n" if ((split(/\./,$name,1))[0] ne "localhost");                }                if ($main'opt_a) {                    # keep list in %glues, report any duplicates                    if ($glues{$_[3]} eq "") {                        $glues{$_[3]}=$_[0];                    }                    elsif (($glues{$_[3]} eq $_[0]) && (!&equal($lastns,$domain))) {                            print " $_[0]: possible duplicate A record (glue of $lastns?)\n";                    }                }            }        } elsif ($_[2] eq "NS") {            $lastns=$_[0];            print STDERR 'n' if $opt_d;            # check to see if object of NS is real            &checklamer($_[0],$_[3]) if ($main'opt_l);            if (!(($name, $aliases, $addrtype, $length, @addrs)=gethostbyname($_[3])) && $!) {                print " gethostbyname($_[3]): $!\n";            }            else {                if (!$name) {                    print " $_[0] NS $_[3]: unknown host\n";                } elsif (!&equal(($name.'.'),$_[3])) {                    print " $_[0] NS $_[3]: CNAME (to $name)\n";                }            }        } elsif ($_[2] eq "MX") {            print STDERR 'm' if $opt_d;            # check to see if object of mx is real            ($prio,$mx)=split(/ /,$_[3]);            if (!(($name, $aliases, $addrtype, $length, @addrs)=gethostbyname($mx)) && $!) {                print " gethostbyname($mx): $!\n";            }            else {                if (!$name) {                    print " $_[0] MX $_[3]: unknown host\n";                }                elsif (!&equal(($name.'.'),$mx)) {                    print " $_[0] MX $_[3]: CNAME (to $name)\n";                }            }        } elsif ($_[2] eq "CNAME") {            print STDERR 'c' if $opt_d;            if (!(($name, $aliases, $addrtype, $length, @addrs)=gethostbyname($_[3])) && $!) {                print " gethostbyname($_[3]): $!\n";            }            else {                if (!$name) {                    print " $_[0] CNAME $_[3]: unknown host\n";                } elsif (!&equal(($name.'.'),$_[3])) {                    print " $_[0] CNAME $_[3]: CNAME (to $name)\n";                }            }        }    }    print STDERR "\n" if $opt_d;    close(FILE);}sub equal {    # Do case-insensitive string comparisons    local ($one)= $_[0];    local ($two)= $_[1];    $one =~ tr/A-Z/a-z/;    $two =~ tr/A-Z/a-z/;    return ($one eq $two);}sub matchaddrlist {    local($match)=pack('C4', reverse(split(/\./,$_[0],4)));    local($found)=0;    foreach $i (@addrs) {        $found=1 if ($i eq $match);    }    return $found;}# there's a better way to do this, it just hasn't evolved from# my brain to this program yet.sub byhostname {    @c = reverse(split(/\./,$a));    @d = reverse(split(/\./,$b));    for ($i=0;$i<=(($#c > $#d) ? $#c : $#d) ;$i++) {        next if $c[$i] eq $d[$i];        return -1 if $c[$i] eq "";        return  1 if $d[$i] eq "";        if ($c[$i] eq int($c[$i])) {            # numeric            return $c[$i] <=> $d[$i];        }        else {            # string            return $c[$i] cmp $d[$i];        }    }    return 0;}sub checklamer {    local ($isauth)=0;    local ($error)=0;    # must check twice, since first query may be authoratative    # trap stderr here and print if non-empty    open(DIG,"dig soa +noaa $_[0] \@$_[1] 2>&1 1>/dev/null |");    while (<DIG>) {        print " $_[0] NS $_[1]: nameserver error (lame?):\n" if !$error;	print;	$error=1;    }    close(DIG);    return if $error;    open(DIG,"dig soa +noaa $_[0] \@$_[1] 2>/dev/null|");    while (<DIG>) {        if (/;; flags.*aa.*;/) {             $isauth=1;        }    }    if (!$isauth) {        print " $_[0] NS $_[1]: lame NS delegation\n";    }    close(DIG);    return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -