Initial import
This commit is contained in:
commit
d06a79e353
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/BAK/*
|
459
analyze_dns_datafile.pl
Executable file
459
analyze_dns_datafile.pl
Executable file
@ -0,0 +1,459 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
|
||||
use Symbol qw(gensym);
|
||||
use Getopt::Std;
|
||||
use IO::File;
|
||||
use File::Basename;
|
||||
use Cwd;
|
||||
|
||||
use vars qw/$opt_a $opt_b $opt_d $opt_e $opt_h $opt_m $opt_o $opt_q/;
|
||||
|
||||
|
||||
my $zonefile_suffixi_default = "file";
|
||||
my $outfile_default = "data_dns";
|
||||
|
||||
my $out_data_file = "nsdata.txt";
|
||||
|
||||
## - hashes to store the records at all, but also
|
||||
## - domains, maildomains and the defined hosts
|
||||
## -
|
||||
my %doms = ();
|
||||
my %maildoms = ();
|
||||
my %hosts = () ;
|
||||
my %records = () ;
|
||||
|
||||
|
||||
## - filehandle
|
||||
## -
|
||||
my $fh = new IO::File ;
|
||||
|
||||
|
||||
getopts('ab:d:e:hmo:q') || &usage();
|
||||
&usage if defined $opt_h ;
|
||||
|
||||
my $i;
|
||||
if (! defined $opt_q) {
|
||||
print "\n command invoked: $0";
|
||||
foreach $i (@ARGV) {
|
||||
print " $i";
|
||||
}
|
||||
print "\n\n";
|
||||
}
|
||||
|
||||
my $backup = defined($opt_b) ? $opt_b : 1;
|
||||
if ( $backup != 1 && $backup != 0 ) {
|
||||
print "\n wrong value for flag -b : $opt_b";
|
||||
&usage;
|
||||
}
|
||||
|
||||
|
||||
exit ( &main(@ARGV) );
|
||||
|
||||
sub main {
|
||||
|
||||
my $infile = shift || return usage();
|
||||
|
||||
|
||||
-f $infile or die "$infile: $!";
|
||||
|
||||
my $base_infile = basename($infile);
|
||||
|
||||
|
||||
my ($line, $filename);
|
||||
my ( @lines, @data_file_lines, @single_file_lines );
|
||||
my ( @domains, @maildomains, @hostlist, @records );
|
||||
|
||||
my ( $extension, $outdir, $outfile, $multiple_files, $add_files );
|
||||
|
||||
## - look at the programm parameters
|
||||
## -
|
||||
$extension = defined($opt_e) ? $opt_e : $zonefile_suffixi_default;
|
||||
$outdir = defined($opt_d) ? $opt_d : "./";
|
||||
|
||||
|
||||
## - like to work with the realpath
|
||||
## -
|
||||
$outdir = Cwd::abs_path($outdir);
|
||||
## $outdir =~ s#^(.*)/$#$1#;
|
||||
|
||||
|
||||
$outfile = defined($opt_o) ? $opt_o : $outfile_default;
|
||||
$outfile = $outdir . "/" . $outfile;
|
||||
$multiple_files = defined($opt_m) ? 1 : 0;
|
||||
$add_files = defined($opt_a) ? 1 : 0;
|
||||
|
||||
## - Datei einlesen
|
||||
## -
|
||||
if ( $fh->open($infile) ) {
|
||||
flock( $fh, LOCK_SH );
|
||||
chomp (@lines = <$fh>);
|
||||
flock( $fh, LOCK_UN );
|
||||
$fh->close();
|
||||
} else {
|
||||
die "can't open $! for read";
|
||||
}
|
||||
|
||||
|
||||
## oder so..
|
||||
## -
|
||||
## open( $fh ,$infile ) or die "can't open $! for read" ;
|
||||
## flock( $fh, LOCK_SH );
|
||||
## @lines = <$fh>;
|
||||
## flock( $fh, LOCK_UN );
|
||||
## close ( $fh );
|
||||
|
||||
## - sichere original file
|
||||
## -
|
||||
&write_file($outdir . "/" . $base_infile,@lines);
|
||||
|
||||
## - first we push into hashes, so we can sort
|
||||
## - afterwords
|
||||
## -
|
||||
|
||||
foreach (@lines) {
|
||||
|
||||
## chomp ;
|
||||
|
||||
## - ignore emty lines
|
||||
## -
|
||||
next if /^\s*$/o ;
|
||||
|
||||
## - ignore comments
|
||||
## -
|
||||
next if /^#/o ;
|
||||
|
||||
$records{$_} = 1 ;
|
||||
if ( /^([\.|\&|Z])([^:]*)(.*)$/o ) {
|
||||
$doms{$2} = 1 ;
|
||||
}
|
||||
|
||||
## - maildomain ?
|
||||
## -
|
||||
if ( /^(\@)([^:]*)(.*)/o) {
|
||||
$maildoms{$2} = 1;
|
||||
}
|
||||
|
||||
## - host definition ?
|
||||
## -
|
||||
if ( /^(\+)([^:]*)(.*)/o) {
|
||||
$hosts{$2} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
## - Now sort and put into the considered arrays
|
||||
## -
|
||||
@domains = sort ( keys %doms ) ;
|
||||
@maildomains = sort ( keys %maildoms ) ;
|
||||
@hostlist = sort ( keys %hosts ) ;
|
||||
@records = sort ( sort_records keys %records);
|
||||
|
||||
|
||||
|
||||
## - schreibe domainliste, maildomainliste, hostliste, records
|
||||
## -
|
||||
if ( $add_files ) {
|
||||
&write_file($outdir . "/domains.lst",@domains);
|
||||
&write_file($outdir . "/maildomains.lst",@maildomains);
|
||||
&write_file($outdir . "/hostlist.lst",@hostlist);
|
||||
&write_file($outdir . "/records.lst",@records);
|
||||
}
|
||||
|
||||
my $_domain ="";
|
||||
my $_type;
|
||||
my $_filename = 0;
|
||||
foreach ( @records ) {
|
||||
|
||||
/(.)([^:]+).*/o ;
|
||||
if ( $_domain eq get_domain($2) ) {
|
||||
if ( $_type ne $1 ) {
|
||||
if ( $multiple_files ) {
|
||||
push ( @single_file_lines, get_record_comment($1) );
|
||||
} else {
|
||||
push ( @data_file_lines, get_record_comment($1) );
|
||||
}
|
||||
}
|
||||
if ( $multiple_files ) {
|
||||
push ( @single_file_lines, $_ );
|
||||
} else {
|
||||
push ( @data_file_lines, $_ );
|
||||
}
|
||||
} else {
|
||||
&write_file($filename,@single_file_lines) if ($filename);
|
||||
@single_file_lines = ();
|
||||
$_type = "";
|
||||
$_domain = get_domain($2);
|
||||
|
||||
if ( $multiple_files ) {
|
||||
$filename = $outdir . "/" . $_domain . ".file";
|
||||
push ( @single_file_lines, "## - domain: $_domain");
|
||||
push ( @single_file_lines, "## - ");
|
||||
push ( @single_file_lines, get_record_comment($1) );
|
||||
push ( @single_file_lines, $_ );
|
||||
} else {
|
||||
push ( @data_file_lines, "\n" );
|
||||
push ( @data_file_lines, "## - domain: $_domain");
|
||||
push ( @data_file_lines, "## - ");
|
||||
push ( @data_file_lines, get_record_comment($1) );
|
||||
push ( @data_file_lines, $_ );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
$_type = $1;
|
||||
|
||||
}
|
||||
|
||||
if ( $multiple_files ) {
|
||||
## - letztes file muss noch geschrieben werdem
|
||||
## -
|
||||
&write_file($filename, @single_file_lines);
|
||||
} else {
|
||||
## - schreibe alles in ein file
|
||||
## -
|
||||
&write_file($outfile, @data_file_lines);
|
||||
}
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
sub get_domain {
|
||||
|
||||
my $record = shift ;
|
||||
|
||||
if ( $doms{$record} ) {
|
||||
return $record ;
|
||||
} else {
|
||||
while ( $record =~ /([^\.]*).(.*)/o ) {
|
||||
if ( $doms{$2} ) {
|
||||
return $2;
|
||||
}
|
||||
$record = $2;
|
||||
}
|
||||
}
|
||||
|
||||
return 1 ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub get_record_comment {
|
||||
my $directive_type = shift;
|
||||
my $comment;
|
||||
|
||||
SWITCH : {
|
||||
|
||||
$1 eq "Z" and $comment = "## - SOA" , last SWITCH;
|
||||
$1 eq "." and $comment = "## - SOA, NS, A" , last SWITCH;
|
||||
$1 eq "&" and $comment = "## - NS, A" , last SWITCH;
|
||||
$1 eq "@" and $comment = "## - MX, A" , last SWITCH;
|
||||
$1 eq "=" and $comment = "## - A, PTR" , last SWITCH;
|
||||
$1 eq "+" and $comment = "## - A" , last SWITCH;
|
||||
$1 eq "C" and $comment = "## - CNAME" , last SWITCH;
|
||||
$1 eq "^" and $comment = "## - PTR" , last SWITCH;
|
||||
$1 eq "'" and $comment = "## - TEXT" , last SWITCH;
|
||||
$1 eq "3" and $comment = "## - AAAA" , last SWITCH;
|
||||
$1 eq "6" and $comment = "## - AAAA, PTR" , last SWITCH;
|
||||
$comment = "## - unknown record";
|
||||
}
|
||||
return $comment;
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Datei schreiben
|
||||
#
|
||||
sub write_file {
|
||||
|
||||
my $outfile = shift ;
|
||||
my @lines = @_ ;
|
||||
|
||||
backup($outfile) if ( -f $outfile );
|
||||
|
||||
if (! defined $opt_q) {
|
||||
print "\twrite $outfile ..\n";
|
||||
}
|
||||
|
||||
$fh = new IO::File "> $outfile";
|
||||
if (defined $fh) {
|
||||
foreach (@lines) {
|
||||
print $fh $_ . "\n" ;
|
||||
}
|
||||
$fh->close();
|
||||
}
|
||||
|
||||
## - oder auch so..
|
||||
## -
|
||||
## open ( $fh , "> $outfile") or die "can't open $! for write" ;
|
||||
## print $fh @lines ;
|
||||
## close ($fh);
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# - backup
|
||||
#
|
||||
sub backup {
|
||||
|
||||
my $filename = shift ;
|
||||
|
||||
# Sicherungskopie erstellen
|
||||
#
|
||||
if ($backup) {
|
||||
OUTER: for ( my $i = 0 ; $i < 10 ; $i++ ) {
|
||||
for ( my $j = 0 ; $j < 10 ; $j++ ) {
|
||||
my $backupfile = $filename . ".$i$j" ;
|
||||
if ( -f $backupfile
|
||||
|| -d $backupfile
|
||||
|| -l $backupfile
|
||||
|| -p $backupfile
|
||||
|| -c $backupfile
|
||||
|| -b $backupfile
|
||||
|| -S $backupfile ) {
|
||||
next ;
|
||||
} else {
|
||||
my $retval = system( "cp -f $filename $backupfile") ;
|
||||
if ($retval != 0) {
|
||||
die "can't store backupfile $backupfile"
|
||||
}
|
||||
if (! defined $opt_q) {
|
||||
print "\n\tbackupfile stored in $backupfile\n";
|
||||
}
|
||||
last OUTER ;
|
||||
}
|
||||
}
|
||||
} # ende OUTER : for ( ...
|
||||
} # ende if
|
||||
} # end backup()
|
||||
|
||||
sub sort_records {
|
||||
|
||||
my ( $rval1, $rval2, $domain_a, $domain_b, $directive_a, $directive_b );
|
||||
|
||||
|
||||
$a =~ /(.)([^:]+).*/;
|
||||
|
||||
## - get directive
|
||||
## -
|
||||
SWITCH : {
|
||||
|
||||
$1 eq "Z" and $directive_a = 10 , last SWITCH;
|
||||
$1 eq "." and $directive_a = 20 , last SWITCH;
|
||||
$1 eq "&" and $directive_a = 30 , last SWITCH;
|
||||
$1 eq "@" and $directive_a = 40 , last SWITCH;
|
||||
$1 eq "=" and $directive_a = 50 , last SWITCH;
|
||||
$1 eq "+" and $directive_a = 60 , last SWITCH;
|
||||
$1 eq "C" and $directive_a = 70 , last SWITCH;
|
||||
$1 eq "^" and $directive_a = 80 , last SWITCH;
|
||||
$1 eq "'" and $directive_a = 90 , last SWITCH;
|
||||
$1 eq "3" and $directive_a = 100, last SWITCH;
|
||||
$1 eq "6" and $directive_a = 110, last SWITCH;
|
||||
$directive_a = 999;
|
||||
}
|
||||
|
||||
## - get domain..
|
||||
## -
|
||||
$domain_a = get_domain($2);
|
||||
|
||||
$b =~ /(.)([^:]+).*/;
|
||||
|
||||
## - get directive
|
||||
## -
|
||||
SWITCH : {
|
||||
|
||||
$1 eq "Z" and $directive_b = 10 , last SWITCH;
|
||||
$1 eq "." and $directive_b = 20 , last SWITCH;
|
||||
$1 eq "&" and $directive_b = 30 , last SWITCH;
|
||||
$1 eq "@" and $directive_b = 40 , last SWITCH;
|
||||
$1 eq "=" and $directive_b = 50 , last SWITCH;
|
||||
$1 eq "+" and $directive_b = 60 , last SWITCH;
|
||||
$1 eq "C" and $directive_b = 70 , last SWITCH;
|
||||
$1 eq "^" and $directive_b = 80 , last SWITCH;
|
||||
$1 eq "'" and $directive_b = 90 , last SWITCH;
|
||||
$1 eq "3" and $directive_b = 100, last SWITCH;
|
||||
$1 eq "6" and $directive_b = 110, last SWITCH;
|
||||
$directive_b = 999;
|
||||
}
|
||||
|
||||
## - get domain..
|
||||
## -
|
||||
$domain_b = get_domain($2);
|
||||
|
||||
$rval1 = $domain_a cmp $domain_b ;
|
||||
|
||||
|
||||
if ( $rval1 == 0 ) {
|
||||
$rval2 = $directive_a <=> $directive_b;
|
||||
if ( $rval2 == 0 ) {
|
||||
return $a cmp $b;
|
||||
} else {
|
||||
return $rval2;
|
||||
}
|
||||
} else {
|
||||
return $rval1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#
|
||||
# - usage
|
||||
#
|
||||
sub usage {
|
||||
my $file = basename($0);
|
||||
$file =~ s#.*/([^/]+)$#$1# ;
|
||||
|
||||
print <<ENDE;
|
||||
|
||||
Usage: $file [OPTIONS] <tinydns-data-file>
|
||||
|
||||
This script concatinates all zonefiles with a certain fileextension
|
||||
of a given directory.
|
||||
|
||||
This script takes all directives from a given djb tinydns-data-file,
|
||||
sorts them and put the sortet list back into one data-file or, if
|
||||
option "m" is set into one file for each domain, named by the concerning
|
||||
domain.
|
||||
|
||||
A copy of the (original) inputfile will be written out in <outdir>.
|
||||
|
||||
|
||||
Control Options:
|
||||
|
||||
-a The following addition files be written:
|
||||
<outdir>/domains.lst.......: alphabetical list of domains
|
||||
<outdir>/maildomains.lst...: alphabetical list of domains
|
||||
with MX entry
|
||||
<outdir>/hostlist.lst......: alphabetical list of all
|
||||
hostentries (A - Record)
|
||||
<outdir>/records.lst.......: all records sorted by domain but
|
||||
without any comment or emty line
|
||||
|
||||
-b <0|1> a value of "1" means: befor writing a file backup existing one;
|
||||
dont backup if "0". default value is "1"
|
||||
|
||||
-d <outdir> directory where the outfile(s) are written. defaults to
|
||||
working directory
|
||||
|
||||
-e <ext> write data-files with extension <ext>. defaults to
|
||||
"$zonefile_suffixi_default". only affected if option -m is set
|
||||
|
||||
-h prints this helpcontents
|
||||
|
||||
-m write one file for each domain
|
||||
|
||||
-o <outfile> name of outputfile. defaults to "$outfile_default". only
|
||||
affect if not -m is set
|
||||
|
||||
-q silent output
|
||||
|
||||
|
||||
ENDE
|
||||
|
||||
exit 1 ;
|
||||
}
|
169
concatenate_dns_datafiles.pl
Executable file
169
concatenate_dns_datafiles.pl
Executable file
@ -0,0 +1,169 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
|
||||
use Symbol;
|
||||
use Getopt::Std;
|
||||
use Cwd;
|
||||
use vars qw/$opt_e $opt_h $opt_o $opt_q $opt_r $opt_R $opt_X/;
|
||||
|
||||
|
||||
my $zonefile_suffixi_default = "file";
|
||||
my $outfile_default = "data_dns";
|
||||
|
||||
my ( @lines );
|
||||
my ( $extension, $dirdepth, $recursiv, $excl_dir, $outfile );
|
||||
|
||||
my $i ;
|
||||
|
||||
getopts('e:ho:qrR:X:') || &usage();
|
||||
&usage if defined $opt_h ;
|
||||
|
||||
|
||||
if (! defined $opt_q) {
|
||||
print "\n command invoked: $0";
|
||||
foreach $i (@ARGV) {
|
||||
print " $i";
|
||||
}
|
||||
print "\n\n";
|
||||
}
|
||||
|
||||
exit ( &main(@ARGV) );
|
||||
|
||||
## - main method
|
||||
##
|
||||
sub main {
|
||||
|
||||
my $rootdir = shift || return usage();
|
||||
$rootdir =~ s#/$## ;
|
||||
|
||||
## - like to work with the realpath
|
||||
## -
|
||||
$rootdir = Cwd::abs_path($rootdir);
|
||||
|
||||
## - look at the programm parameters
|
||||
## -
|
||||
$extension = defined($opt_e) ? $opt_e : $zonefile_suffixi_default;
|
||||
$outfile = defined($opt_o) ? $opt_o : $outfile_default;
|
||||
$dirdepth = defined($opt_R) ? $opt_R : -1;
|
||||
if ($dirdepth > 0 ) {
|
||||
$recursiv = 1 ;
|
||||
} else {
|
||||
$recursiv = defined($opt_r) ? 1 : 0;
|
||||
}
|
||||
$excl_dir = defined($opt_X) ? $opt_X : "";
|
||||
|
||||
&traverse_dir($rootdir,0);
|
||||
|
||||
&write_file("data_dns",@lines);
|
||||
exit (0)
|
||||
|
||||
}
|
||||
|
||||
## - traverse_dir
|
||||
## -
|
||||
sub traverse_dir {
|
||||
|
||||
my $dir = shift ;
|
||||
my $dircount = shift ;
|
||||
|
||||
my $dirh = gensym ;
|
||||
my $filename ;
|
||||
my @dir ;
|
||||
|
||||
opendir($dirh , $dir) || die "can't open $dir";
|
||||
@dir=readdir($dirh);
|
||||
@dir = sort(@dir);
|
||||
closedir($dirh);
|
||||
#while ( defined ( $filename = readdir($dirh) ) ) {
|
||||
foreach ( @dir ) {
|
||||
$filename = $_;
|
||||
|
||||
next if $filename eq "." || $filename eq ".." ;
|
||||
## - no system files
|
||||
next if ( $filename =~ /^\./ ) ;
|
||||
my $pathname = $dir . "/" . $filename ;
|
||||
next if -l $pathname ;
|
||||
next if ( -d $pathname && $filename eq $excl_dir ) ;
|
||||
if ( -d $pathname && $recursiv
|
||||
&& ($dirdepth == -1 || $dircount < $dirdepth)
|
||||
) {
|
||||
&traverse_dir($pathname, ($dircount + 1 )) ;
|
||||
next ;
|
||||
}
|
||||
next if not -T $pathname ;
|
||||
next unless -f $pathname;
|
||||
if ($extension ne "") {
|
||||
next if not ( $pathname =~ /$extension$/ ) ;
|
||||
}
|
||||
|
||||
open (CFG, $pathname ) or die "open file $pathname: $!\n";
|
||||
while ( <CFG> ) {
|
||||
push(@lines , $_);
|
||||
}
|
||||
close CFG;
|
||||
push (@lines, "\n\n");
|
||||
}
|
||||
|
||||
## - write out concatinated file
|
||||
## -
|
||||
&write_file($outfile, @lines);
|
||||
|
||||
return 0;
|
||||
} # ende traverse_dir
|
||||
|
||||
|
||||
|
||||
# Datei schreiben
|
||||
#
|
||||
sub write_file {
|
||||
|
||||
my $outfile = shift ;
|
||||
my @lines = @_ ;
|
||||
|
||||
open ( FH , "> $outfile") or die "can't open $! for write" ;
|
||||
print FH @lines ;
|
||||
close (FH);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# - usage
|
||||
#
|
||||
sub usage {
|
||||
my $file = $0;
|
||||
$file =~ s#.*/([^/]+)$#$1# ;
|
||||
|
||||
print <<ENDE;
|
||||
|
||||
Usage: $file [OPTIONS] <zone-file-directory>
|
||||
|
||||
This script concatinates all zonefiles with a certain fileextension
|
||||
of a given directory.
|
||||
|
||||
|
||||
Control Options:
|
||||
|
||||
-e <ext> concatinate files with extension ext
|
||||
defaults to "$zonefile_suffixi_default"
|
||||
|
||||
-h prints this helpcontents
|
||||
|
||||
-o <outfile> name of outputfile. defaults to "$outfile_default" in the
|
||||
working directory
|
||||
|
||||
-q silent output
|
||||
|
||||
-r recursivly
|
||||
|
||||
-R NUM concatinate files recursivly with directorydepth = "NUM"
|
||||
|
||||
|
||||
-X dir excluding replacing directories named dir
|
||||
|
||||
ENDE
|
||||
|
||||
exit 1 ;
|
||||
}
|
||||
|
687
convert_tinydns_to_bind.pl
Executable file
687
convert_tinydns_to_bind.pl
Executable file
@ -0,0 +1,687 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
|
||||
use Symbol qw(gensym);
|
||||
use Getopt::Std;
|
||||
use IO::File;
|
||||
use File::Basename;
|
||||
use Cwd;
|
||||
|
||||
use vars qw/$opt_a $opt_b $opt_d $opt_e $opt_h $opt_m $opt_o $opt_q/;
|
||||
|
||||
|
||||
my $zonefile_suffix_default = "zone";
|
||||
my $outfile_default = "data_dns";
|
||||
|
||||
my $out_data_file = "nsdata.txt";
|
||||
|
||||
## - hashes to store the records at all, but also
|
||||
## - domains, maildomains and the defined hosts
|
||||
## -
|
||||
my %doms = ();
|
||||
my %maildoms = ();
|
||||
my %hosts = () ;
|
||||
my %records = () ;
|
||||
|
||||
|
||||
## - filehandle
|
||||
## -
|
||||
my $fh = new IO::File ;
|
||||
|
||||
|
||||
getopts('ab:d:e:hmo:q') || &usage();
|
||||
&usage if defined $opt_h ;
|
||||
|
||||
my $i;
|
||||
if (! defined $opt_q) {
|
||||
print "\n command invoked: $0";
|
||||
foreach $i (@ARGV) {
|
||||
print " $i";
|
||||
}
|
||||
print "\n\n";
|
||||
}
|
||||
|
||||
my $backup = defined($opt_b) ? $opt_b : 1;
|
||||
if ( $backup != 1 && $backup != 0 ) {
|
||||
print "\n wrong value for flag -b : $opt_b";
|
||||
&usage;
|
||||
}
|
||||
|
||||
|
||||
exit ( &main(@ARGV) );
|
||||
|
||||
sub main {
|
||||
|
||||
my $infile = shift || return usage();
|
||||
|
||||
|
||||
-f $infile or die "$infile: $!";
|
||||
|
||||
my $base_infile = basename($infile);
|
||||
|
||||
|
||||
my ( $line, $filename, $bind_filename);
|
||||
my ( @lines, @data_file_lines, @single_file_lines);
|
||||
my ( @domains, @maildomains, @hostlist, @records );
|
||||
|
||||
my ( $bind_filename, $bind_named_conf_local_master_filename, $bind_named_conf_local_slave_filename );
|
||||
my ( @bind_file_lines , @bind_named_conf_local_master_lines, @bind_named_conf_local_slave_lines);
|
||||
|
||||
my ( $extension, $outdir, $outfile, $multiple_files, $add_files );
|
||||
|
||||
## - look at the programm parameters
|
||||
## -
|
||||
$extension = defined($opt_e) ? $opt_e : $zonefile_suffix_default;
|
||||
$outdir = defined($opt_d) ? $opt_d : "./";
|
||||
|
||||
## - exit if $outdir does not exist
|
||||
## -
|
||||
-d $outdir or die "$outdir: $!";
|
||||
|
||||
## - craete $outdir/bind if mot exists
|
||||
## -
|
||||
-d "$outdir/bind" or mkdir("$outdir/bind", 0755);
|
||||
|
||||
-d "$outdir/bind/conf" or mkdir("$outdir/bind/conf", 0755);
|
||||
$bind_named_conf_local_master_filename = "$outdir/bind/conf/named.conf.local.master";
|
||||
$bind_named_conf_local_slave_filename = "$outdir/bind/conf/named.conf.local.slave";
|
||||
|
||||
|
||||
## - like to work with the realpath
|
||||
## -
|
||||
$outdir = Cwd::abs_path($outdir);
|
||||
## $outdir =~ s#^(.*)/$#$1#;
|
||||
|
||||
|
||||
$outfile = defined($opt_o) ? $opt_o : $outfile_default;
|
||||
$outfile = $outdir . "/" . $outfile;
|
||||
$multiple_files = defined($opt_m) ? 1 : 0;
|
||||
$add_files = defined($opt_a) ? 1 : 0;
|
||||
|
||||
## - Datei einlesen
|
||||
## -
|
||||
if ( $fh->open($infile) ) {
|
||||
flock( $fh, LOCK_SH );
|
||||
chomp (@lines = <$fh>);
|
||||
flock( $fh, LOCK_UN );
|
||||
$fh->close();
|
||||
} else {
|
||||
die "can't open $! for read";
|
||||
}
|
||||
|
||||
|
||||
## oder so..
|
||||
## -
|
||||
## open( $fh ,$infile ) or die "can't open $! for read" ;
|
||||
## flock( $fh, LOCK_SH );
|
||||
## @lines = <$fh>;
|
||||
## flock( $fh, LOCK_UN );
|
||||
## close ( $fh );
|
||||
|
||||
## - sichere original file
|
||||
## -
|
||||
&write_file($outdir . "/" . $base_infile,@lines);
|
||||
|
||||
## - first we push into hashes, so we can sort
|
||||
## - afterwords
|
||||
## -
|
||||
|
||||
foreach (@lines) {
|
||||
|
||||
## chomp ;
|
||||
|
||||
## - ignore emty lines
|
||||
## -
|
||||
next if /^\s*$/o ;
|
||||
|
||||
## - ignore comments
|
||||
## -
|
||||
next if /^#/o ;
|
||||
|
||||
$records{$_} = 1 ;
|
||||
if ( /^([\.|\&|Z])([^:]+)(.*)$/o ) {
|
||||
$doms{$2} = 1 ;
|
||||
}
|
||||
|
||||
## - maildomain ?
|
||||
## -
|
||||
if ( /^(\@)([^:]+)(.*)/o) {
|
||||
$maildoms{$2} = 1;
|
||||
}
|
||||
|
||||
## - host definition ?
|
||||
## -
|
||||
if ( /^(\+)([^:]+)(.*)/o) {
|
||||
$hosts{$2} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
## - Now sort and put into the considered arrays
|
||||
## -
|
||||
@domains = sort ( keys %doms ) ;
|
||||
#@domains = keys %doms ;
|
||||
@maildomains = sort ( keys %maildoms ) ;
|
||||
@hostlist = sort ( keys %hosts ) ;
|
||||
@records = sort ( sort_records keys %records);
|
||||
|
||||
|
||||
|
||||
## - schreibe domainliste, maildomainliste, hostliste, records
|
||||
## -
|
||||
if ( $add_files ) {
|
||||
&write_file($outdir . "/domains.lst",@domains);
|
||||
&write_file($outdir . "/maildomains.lst",@maildomains);
|
||||
&write_file($outdir . "/hostlist.lst",@hostlist);
|
||||
&write_file($outdir . "/records.lst",@records);
|
||||
}
|
||||
|
||||
my $_domain ="";
|
||||
my $_hostname;
|
||||
my ( $_ipv6_tynidns, $_ipv6_bind, @_ipv6 ) ;
|
||||
my $_ipv4 ;
|
||||
my ( $_mx_host , $_mx_prio );
|
||||
my $_nameserver ;
|
||||
my $_type;
|
||||
#my $_filename = 0;
|
||||
|
||||
my $_blank_hostname ;
|
||||
my $_no_blank_hostname = 20 ;
|
||||
|
||||
my $_blank_soa_comment;
|
||||
my $_no_blank_soa_comment = 12;
|
||||
|
||||
foreach ( @records ) {
|
||||
|
||||
/(.)([^:]+).*/o ;
|
||||
if ( $_domain eq get_domain($2) ) {
|
||||
if ( $_type ne $1 ) {
|
||||
if ( $multiple_files ) {
|
||||
push ( @single_file_lines, get_record_comment($1) );
|
||||
} else {
|
||||
push ( @data_file_lines, get_record_comment($1) );
|
||||
}
|
||||
|
||||
push (@bind_file_lines, get_record_comment_bind($1) );
|
||||
}
|
||||
if ( $multiple_files ) {
|
||||
push ( @single_file_lines, $_ );
|
||||
} else {
|
||||
push ( @data_file_lines, $_ );
|
||||
}
|
||||
|
||||
if ( "$1" eq "&" ) {
|
||||
/&([^:]+):([^:]*):([^:]+):([^:]+).*/o ;
|
||||
$_blank_hostname = "";
|
||||
$_hostname = $1;
|
||||
$_nameserver = $3 ;
|
||||
$_hostname =~ s/\.?$_domain// ;
|
||||
if ( "$_hostname" eq "" ) {
|
||||
for ( my $i=0; $i < ($_no_blank_hostname - 1) ; $i++ ) {
|
||||
$_blank_hostname = $_blank_hostname . " ";
|
||||
}
|
||||
push (@bind_file_lines, "\@${_blank_hostname}IN NS ${_nameserver}.");
|
||||
} else {
|
||||
if ( length($_hostname) < $_no_blank_hostname ) {
|
||||
for ( my $i=0; $i < ($_no_blank_hostname - length($_hostname)) ; $i++ ) {
|
||||
$_blank_hostname = $_blank_hostname . " ";
|
||||
}
|
||||
} else {
|
||||
$_blank_hostname = " " ;
|
||||
}
|
||||
push (@bind_file_lines, "$_hostname${_blank_hostname}IN NS ${_nameserver}.");
|
||||
}
|
||||
|
||||
} elsif ( "$1" eq "\@" ) {
|
||||
/\@([^:]+):([^:]*):([^:]+):([^:]+):([^:]+).*/o ;
|
||||
$_blank_hostname = "";
|
||||
$_hostname = $1;
|
||||
$_mx_host = $3;
|
||||
$_mx_prio = $4;
|
||||
$_hostname =~ s/\.?$_domain// ;
|
||||
if ( "$_hostname" eq "" ) {
|
||||
for ( my $i=0; $i < ($_no_blank_hostname - 1) ; $i++ ) {
|
||||
$_blank_hostname = $_blank_hostname . " ";
|
||||
}
|
||||
push (@bind_file_lines, "\@${_blank_hostname}IN MX $_mx_prio $_mx_host.");
|
||||
} else {
|
||||
if ( length($_hostname) < $_no_blank_hostname ) {
|
||||
for ( my $i=0; $i < ($_no_blank_hostname - length($_hostname)) ; $i++ ) {
|
||||
$_blank_hostname = $_blank_hostname . " ";
|
||||
}
|
||||
} else {
|
||||
$_blank_hostname = " " ;
|
||||
}
|
||||
push (@bind_file_lines, "${_hostname}${_blank_hostname}IN MX $_mx_prio $_mx_host.");
|
||||
}
|
||||
} elsif ( "$1" eq "+" ) {
|
||||
/\+([^:]+):([^:]+):([^:]+).*/o ;
|
||||
$_blank_hostname = "";
|
||||
if ( "$1" eq "$_domain" ) {
|
||||
for ( my $i=0; $i < ($_no_blank_hostname - 1) ; $i++ ) {
|
||||
$_blank_hostname = $_blank_hostname . " ";
|
||||
}
|
||||
push (@bind_file_lines, "\@${_blank_hostname}IN A $2");
|
||||
} else {
|
||||
$_hostname = $1;
|
||||
$_ipv4 = $2 ;
|
||||
$_hostname =~ s/\.$_domain// ;
|
||||
|
||||
if ( length($_hostname) < $_no_blank_hostname ) {
|
||||
for ( my $i=0; $i < ($_no_blank_hostname - length($_hostname)) ; $i++ ) {
|
||||
$_blank_hostname = $_blank_hostname . " ";
|
||||
}
|
||||
} else {
|
||||
$_blank_hostname = " " ;
|
||||
}
|
||||
push (@bind_file_lines, "${_hostname}${_blank_hostname}IN A $_ipv4");
|
||||
}
|
||||
} elsif ( "$1" eq "3" ) {
|
||||
/\ ?3([^:]+):([^:]+):([^:]+).*/o ;
|
||||
$_blank_hostname = "";
|
||||
$_hostname = $1 ;
|
||||
$_ipv6_tynidns = $2;
|
||||
$_ipv6_bind = "";
|
||||
for(my $i=0; $i<31; $i = $i +4) {
|
||||
$_ipv6_bind = $_ipv6_bind . substr($_ipv6_tynidns,$i,4);
|
||||
if ( $i < 28 ) {
|
||||
$_ipv6_bind = $_ipv6_bind .":" ;
|
||||
}
|
||||
}
|
||||
if ( "$1" eq "$_domain" ) {
|
||||
$_ipv6_bind =~ s/:0{1,3}/:/g ;
|
||||
$_ipv6_bind = reverse($_ipv6_bind);
|
||||
$_ipv6_bind =~ s/:0:(0:)+/::/ ;
|
||||
$_ipv6_bind = reverse($_ipv6_bind);
|
||||
|
||||
for ( my $i=0; $i < ($_no_blank_hostname - 1) ; $i++ ) {
|
||||
$_blank_hostname = $_blank_hostname . " ";
|
||||
}
|
||||
|
||||
push (@bind_file_lines, "\@${_blank_hostname}IN AAAA $_ipv6_bind");
|
||||
} else {
|
||||
$_hostname =~ s/\.$_domain// ;
|
||||
$_ipv6_bind =~ s/:0{1,3}/:/g ;
|
||||
$_ipv6_bind = reverse($_ipv6_bind);
|
||||
$_ipv6_bind =~ s/:0:(0:)+/::/ ;
|
||||
$_ipv6_bind = reverse($_ipv6_bind);
|
||||
|
||||
if ( length($_hostname) < $_no_blank_hostname ) {
|
||||
for ( my $i=0; $i < ($_no_blank_hostname - length($_hostname)) ; $i++ ) {
|
||||
$_blank_hostname = $_blank_hostname . " ";
|
||||
}
|
||||
} else {
|
||||
$_blank_hostname = " " ;
|
||||
}
|
||||
|
||||
push (@bind_file_lines, "${_hostname}${_blank_hostname}IN AAAA $_ipv6_bind");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
&write_file($filename,@single_file_lines) if ($filename);
|
||||
@single_file_lines = ();
|
||||
$_type = "";
|
||||
$_domain = get_domain($2);
|
||||
|
||||
if ( $multiple_files ) {
|
||||
$filename = $outdir . "/" . $_domain . ".file";
|
||||
push ( @single_file_lines, "## - domain: $_domain");
|
||||
push ( @single_file_lines, "## - ");
|
||||
push ( @single_file_lines, get_record_comment($1) );
|
||||
push ( @single_file_lines, $_ );
|
||||
} else {
|
||||
push ( @data_file_lines, "\n" );
|
||||
push ( @data_file_lines, "## - domain: $_domain");
|
||||
push ( @data_file_lines, "## - ");
|
||||
push ( @data_file_lines, get_record_comment($1) );
|
||||
push ( @data_file_lines, $_ );
|
||||
}
|
||||
|
||||
&write_file($bind_filename, @bind_file_lines) if ($bind_filename);;
|
||||
@bind_file_lines =();
|
||||
$bind_filename = $outdir . "/bind/" . $_domain . ".zone";
|
||||
push (@bind_file_lines, "; - domain: $_domain");
|
||||
push (@bind_file_lines, "; -");
|
||||
push (@bind_file_lines, "\$TTL 43200");
|
||||
|
||||
$_blank_hostname = "" ;
|
||||
for ( my $i=0; $i < $_no_blank_hostname ; $i++ ) {
|
||||
$_blank_hostname = $_blank_hostname . " ";
|
||||
}
|
||||
|
||||
if ( "$1" eq "Z" ) {
|
||||
/Z([^:]+):([^:]+):([^:]+):([^:]+):([^:]+):([^:]+):([^:]+):([^:]+).*/o ;
|
||||
push (@bind_file_lines, "\@ $8 IN SOA $2. $3 (");
|
||||
|
||||
$_blank_soa_comment = "" ;
|
||||
for ( my $i=0; $i < ($_no_blank_soa_comment - length($4)) ; $i++ ) {
|
||||
$_blank_soa_comment= $_blank_soa_comment . " ";
|
||||
}
|
||||
push (@bind_file_lines, "${_blank_hostname}$4$_blank_soa_comment; serial");
|
||||
|
||||
$_blank_soa_comment = "" ;
|
||||
for ( my $i=0; $i < ($_no_blank_soa_comment - length($5)) ; $i++ ) {
|
||||
$_blank_soa_comment= $_blank_soa_comment . " ";
|
||||
}
|
||||
push (@bind_file_lines, "${_blank_hostname}$5$_blank_soa_comment; refresh");
|
||||
|
||||
$_blank_soa_comment = "" ;
|
||||
for ( my $i=0; $i < ($_no_blank_soa_comment - length($6)) ; $i++ ) {
|
||||
$_blank_soa_comment= $_blank_soa_comment . " ";
|
||||
}
|
||||
push (@bind_file_lines, "${_blank_hostname}$6$_blank_soa_comment; retry");
|
||||
|
||||
$_blank_soa_comment = "" ;
|
||||
for ( my $i=0; $i < ($_no_blank_soa_comment - length($7)) ; $i++ ) {
|
||||
$_blank_soa_comment= $_blank_soa_comment . " ";
|
||||
}
|
||||
push (@bind_file_lines, "${_blank_hostname}$7$_blank_soa_comment; expire");
|
||||
|
||||
$_blank_soa_comment = "" ;
|
||||
for ( my $i=0; $i < ($_no_blank_soa_comment - length($8)) ; $i++ ) {
|
||||
$_blank_soa_comment= $_blank_soa_comment . " ";
|
||||
}
|
||||
push (@bind_file_lines, "${_blank_hostname}$8$_blank_soa_comment; minimum");
|
||||
|
||||
push (@bind_file_lines, ")");
|
||||
}
|
||||
|
||||
push (@bind_named_conf_local_master_lines, "");
|
||||
push (@bind_named_conf_local_master_lines, "zone \"$_domain\" {");
|
||||
push (@bind_named_conf_local_master_lines, " type master;");
|
||||
push (@bind_named_conf_local_master_lines, " file \"/etc/bind/master/$_domain.zone\";");
|
||||
push (@bind_named_conf_local_master_lines, "};");
|
||||
|
||||
|
||||
push (@bind_named_conf_local_slave_lines, "");
|
||||
push (@bind_named_conf_local_slave_lines, "zone \"$_domain\" {");
|
||||
push (@bind_named_conf_local_slave_lines, " type slave;");
|
||||
push (@bind_named_conf_local_slave_lines, " file \"/etc/bind/slave/$_domain.zone\";");
|
||||
push (@bind_named_conf_local_slave_lines, " //allow-query { any; };");
|
||||
push (@bind_named_conf_local_slave_lines, " //allow-transfer {none;};");
|
||||
push (@bind_named_conf_local_slave_lines, " masters {");
|
||||
push (@bind_named_conf_local_slave_lines, " 83.223.90.92;");
|
||||
push (@bind_named_conf_local_slave_lines, " };");
|
||||
push (@bind_named_conf_local_slave_lines, "};");
|
||||
|
||||
|
||||
}
|
||||
$_type = $1;
|
||||
|
||||
}
|
||||
|
||||
if ( $multiple_files ) {
|
||||
## - letztes file muss noch geschrieben werdem
|
||||
## -
|
||||
&write_file($filename, @single_file_lines);
|
||||
} else {
|
||||
## - schreibe alles in ein file
|
||||
## -
|
||||
&write_file($outfile, @data_file_lines);
|
||||
}
|
||||
|
||||
&write_file($bind_filename, @bind_file_lines);
|
||||
|
||||
&write_file($bind_named_conf_local_master_filename, @bind_named_conf_local_master_lines);
|
||||
&write_file($bind_named_conf_local_slave_filename, @bind_named_conf_local_slave_lines);
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
sub get_domain {
|
||||
|
||||
my $record = shift ;
|
||||
|
||||
if ( $doms{$record} ) {
|
||||
return $record ;
|
||||
} else {
|
||||
while ( $record =~ /([^\.]*).(.*)/o ) {
|
||||
if ( $doms{$2} ) {
|
||||
return $2;
|
||||
}
|
||||
$record = $2;
|
||||
}
|
||||
}
|
||||
|
||||
return 1 ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub get_record_comment {
|
||||
my $directive_type = shift;
|
||||
my $comment;
|
||||
|
||||
SWITCH : {
|
||||
|
||||
$1 eq "Z" and $comment = "## - SOA" , last SWITCH;
|
||||
$1 eq "." and $comment = "## - SOA, NS, A" , last SWITCH;
|
||||
$1 eq "&" and $comment = "## - NS, A" , last SWITCH;
|
||||
$1 eq "@" and $comment = "## - MX, A" , last SWITCH;
|
||||
$1 eq "=" and $comment = "## - A, PTR" , last SWITCH;
|
||||
$1 eq "+" and $comment = "## - A" , last SWITCH;
|
||||
$1 eq "C" and $comment = "## - CNAME" , last SWITCH;
|
||||
$1 eq "^" and $comment = "## - PTR" , last SWITCH;
|
||||
$1 eq "'" and $comment = "## - TEXT" , last SWITCH;
|
||||
$1 eq "3" and $comment = "## - AAAA" , last SWITCH;
|
||||
$1 eq "6" and $comment = "## - AAAA, PTR" , last SWITCH;
|
||||
$comment = "## - unknown record";
|
||||
}
|
||||
return $comment;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub get_record_comment_bind {
|
||||
my $directive_type = shift;
|
||||
my $comment;
|
||||
|
||||
SWITCH : {
|
||||
|
||||
$1 eq "&" and $comment = "\n;\n; NS Records\n;\n" , last SWITCH;
|
||||
$1 eq "@" and $comment = "\n;\n; MX Records\n;\n" , last SWITCH;
|
||||
$1 eq "+" and $comment = "\n;\n; IPv4 Hostaddresses\n;\n" , last SWITCH;
|
||||
$1 eq "C" and $comment = "\n;\n; CNAME Records\n;\n" , last SWITCH;
|
||||
$1 eq "3" and $comment = "\n;\n; IPv6 Hostaddresses\n;\n" , last SWITCH;
|
||||
$comment = "\n;\n; unknown record\n;\n";
|
||||
}
|
||||
return $comment;
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Datei schreiben
|
||||
#
|
||||
sub write_file {
|
||||
|
||||
my $outfile = shift ;
|
||||
my @lines = @_ ;
|
||||
|
||||
backup($outfile) if ( -f $outfile );
|
||||
|
||||
if (! defined $opt_q) {
|
||||
print "\twrite $outfile ..\n";
|
||||
}
|
||||
|
||||
$fh = new IO::File "> $outfile";
|
||||
if (defined $fh) {
|
||||
foreach (@lines) {
|
||||
print $fh $_ . "\n" ;
|
||||
}
|
||||
$fh->close();
|
||||
}
|
||||
|
||||
## - oder auch so..
|
||||
## -
|
||||
## open ( $fh , "> $outfile") or die "can't open $! for write" ;
|
||||
## print $fh @lines ;
|
||||
## close ($fh);
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# - backup
|
||||
#
|
||||
sub backup {
|
||||
|
||||
my $filename = shift ;
|
||||
|
||||
# Sicherungskopie erstellen
|
||||
#
|
||||
if ($backup) {
|
||||
OUTER: for ( my $i = 0 ; $i < 10 ; $i++ ) {
|
||||
for ( my $j = 0 ; $j < 10 ; $j++ ) {
|
||||
my $backupfile = $filename . ".$i$j" ;
|
||||
if ( -f $backupfile
|
||||
|| -d $backupfile
|
||||
|| -l $backupfile
|
||||
|| -p $backupfile
|
||||
|| -c $backupfile
|
||||
|| -b $backupfile
|
||||
|| -S $backupfile ) {
|
||||
next ;
|
||||
} else {
|
||||
my $retval = system( "cp -f $filename $backupfile") ;
|
||||
if ($retval != 0) {
|
||||
die "can't store backupfile $backupfile"
|
||||
}
|
||||
if (! defined $opt_q) {
|
||||
print "\n\tbackupfile stored in $backupfile\n";
|
||||
}
|
||||
last OUTER ;
|
||||
}
|
||||
}
|
||||
} # ende OUTER : for ( ...
|
||||
} # ende if
|
||||
} # end backup()
|
||||
|
||||
sub sort_records {
|
||||
|
||||
my ( $rval1, $rval2, $domain_a, $domain_b, $directive_a, $directive_b );
|
||||
|
||||
|
||||
$a =~ /(.)([^:]+).*/;
|
||||
|
||||
## - get directive
|
||||
## -
|
||||
SWITCH : {
|
||||
|
||||
$1 eq "Z" and $directive_a = 10 , last SWITCH;
|
||||
$1 eq "." and $directive_a = 20 , last SWITCH;
|
||||
$1 eq "&" and $directive_a = 30 , last SWITCH;
|
||||
$1 eq "@" and $directive_a = 40 , last SWITCH;
|
||||
$1 eq "=" and $directive_a = 50 , last SWITCH;
|
||||
$1 eq "+" and $directive_a = 60 , last SWITCH;
|
||||
$1 eq "C" and $directive_a = 70 , last SWITCH;
|
||||
$1 eq "^" and $directive_a = 80 , last SWITCH;
|
||||
$1 eq "'" and $directive_a = 90 , last SWITCH;
|
||||
$1 eq "3" and $directive_a = 100, last SWITCH;
|
||||
$1 eq "6" and $directive_a = 110, last SWITCH;
|
||||
$directive_a = 999;
|
||||
}
|
||||
|
||||
## - get domain..
|
||||
## -
|
||||
$domain_a = get_domain($2);
|
||||
|
||||
$b =~ /(.)([^:]+).*/;
|
||||
|
||||
## - get directive
|
||||
## -
|
||||
SWITCH : {
|
||||
|
||||
$1 eq "Z" and $directive_b = 10 , last SWITCH;
|
||||
$1 eq "." and $directive_b = 20 , last SWITCH;
|
||||
$1 eq "&" and $directive_b = 30 , last SWITCH;
|
||||
$1 eq "@" and $directive_b = 40 , last SWITCH;
|
||||
$1 eq "=" and $directive_b = 50 , last SWITCH;
|
||||
$1 eq "+" and $directive_b = 60 , last SWITCH;
|
||||
$1 eq "C" and $directive_b = 70 , last SWITCH;
|
||||
$1 eq "^" and $directive_b = 80 , last SWITCH;
|
||||
$1 eq "'" and $directive_b = 90 , last SWITCH;
|
||||
$1 eq "3" and $directive_b = 100, last SWITCH;
|
||||
$1 eq "6" and $directive_b = 110, last SWITCH;
|
||||
$directive_b = 999;
|
||||
}
|
||||
|
||||
## - get domain..
|
||||
## -
|
||||
$domain_b = get_domain($2);
|
||||
|
||||
$rval1 = $domain_a cmp $domain_b ;
|
||||
|
||||
|
||||
if ( $rval1 == 0 ) {
|
||||
$rval2 = $directive_a <=> $directive_b;
|
||||
if ( $rval2 == 0 ) {
|
||||
return $a cmp $b;
|
||||
} else {
|
||||
return $rval2;
|
||||
}
|
||||
} else {
|
||||
return $rval1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#
|
||||
# - usage
|
||||
#
|
||||
sub usage {
|
||||
my $file = basename($0);
|
||||
$file =~ s#.*/([^/]+)$#$1# ;
|
||||
|
||||
print <<ENDE;
|
||||
|
||||
Usage: $file [OPTIONS] <tinydns-data-file>
|
||||
|
||||
This script concatinates all zonefiles with a certain fileextension
|
||||
of a given directory.
|
||||
|
||||
This script takes all directives from a given djb tinydns-data-file,
|
||||
sorts them and put the sortet list back into one data-file or, if
|
||||
option "m" is set into one file for each domain, named by the concerning
|
||||
domain.
|
||||
|
||||
A copy of the (original) inputfile will be written out in <outdir>.
|
||||
|
||||
|
||||
Control Options:
|
||||
|
||||
-a The following addition files be written:
|
||||
<outdir>/domains.lst.......: alphabetical list of domains
|
||||
<outdir>/maildomains.lst...: alphabetical list of domains
|
||||
with MX entry
|
||||
<outdir>/hostlist.lst......: alphabetical list of all
|
||||
hostentries (A - Record)
|
||||
<outdir>/records.lst.......: all records sorted by domain but
|
||||
without any comment or emty line
|
||||
|
||||
-b <0|1> a value of "1" means: befor writing a file backup existing one;
|
||||
dont backup if "0". default value is "1"
|
||||
|
||||
-d <outdir> directory where the outfile(s) are written. defaults to
|
||||
working directory
|
||||
|
||||
-e <ext> write data-files with extension <ext>. defaults to
|
||||
"$zonefile_suffix_default". only affected if option -m is set
|
||||
|
||||
-h prints this helpcontents
|
||||
|
||||
-m write one file for each domain
|
||||
|
||||
-o <outfile> name of outputfile. defaults to "$outfile_default". only
|
||||
affect if not -m is set
|
||||
|
||||
-q silent output
|
||||
|
||||
|
||||
ENDE
|
||||
|
||||
exit 1 ;
|
||||
}
|
119
dnscache-log
Executable file
119
dnscache-log
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/perl -p
|
||||
|
||||
# usage: tail -f /service/dnscache/log/main/current | tai64nlocal | dnscache-log
|
||||
# use tail -F instead of tail -f if your tail supports it (linux, freebsd, etc)
|
||||
|
||||
$| = 1;
|
||||
|
||||
# strip off the year and the extra tai64 stuff.
|
||||
#s/^\d{4}-(\d\d-\d\d) (\d\d:\d\d:\d\d).(\d*)/$1 $2/;
|
||||
|
||||
## - changed by ckubu (strip off only tai64 stuff
|
||||
s/^(\d{4}-\d\d-\d\d) (\d\d:\d\d:\d\d).(\d*)/$1 $2/;
|
||||
|
||||
# convert addresses in hex to dotted decimal notation.
|
||||
# ugly fix (fn 2003 01 06)
|
||||
if (!m/ stats \d+ \d+ \d+ \d+/) {
|
||||
s/\b([a-f0-9]{8})\b/join(".", unpack("C*", pack("H8", $1)))/eg;
|
||||
## - added by ckubu (ipv6-logfile, but only print ipv4 address))
|
||||
s/[a-f0-9]{24}([a-f0-9]{8})/join(".", unpack("C*", pack("H8", $1)))/eg;
|
||||
}
|
||||
|
||||
# strip out length from sent messages.
|
||||
# sent slot-id length
|
||||
s/sent (\d+) \d+/sent $1/;
|
||||
|
||||
|
||||
### clean up some messages
|
||||
|
||||
# tx gluelessness qtype thing domain where.
|
||||
s/tx (\d+) (\d+) (\S+) (\S+) (.*)/"tx $1 " . queryType($2) . " $3 $4 $5"/e;
|
||||
|
||||
# nodata server ttl qtype thing.
|
||||
s/nodata (\S+) (\d+) (\d+) (\S+)/"nodata $1 " . queryType($2) . " $3 $4"/e;
|
||||
|
||||
# cached qtype info.
|
||||
s/cached (\d+)/"cached " . queryType($1)/e;
|
||||
|
||||
# convert stuff like 127.0.0.2:0422:05be 1 to something more descriptive.
|
||||
# query slot-id host:port qid qtype thing
|
||||
s/\b([\d.]+):(\w+):(\w+) (\d+) ([-.\w]+)/printQueryLine($1, $2, $3, $4, $5)/e;
|
||||
|
||||
# convert rr messages.
|
||||
s/rr (\S+) (\d+) (\S+) (\S+) (\S+)/printRRLine($1, $2, $3, $4, $5)/e;
|
||||
|
||||
### subs
|
||||
|
||||
sub printQueryLine {
|
||||
my ($host, $port, $query_id, $query_type, $query) = @_;
|
||||
|
||||
# pad hostname
|
||||
|
||||
my $ret = "$host:";
|
||||
$ret .= hex($port);
|
||||
$ret .= ":" . hex($query_id);
|
||||
$ret .= " " . queryType($query_type) . " $query";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub printRRLine {
|
||||
my ($host, $ttl, $query_type, $thing, $data) = @_;
|
||||
|
||||
my $ret = "rr ";
|
||||
#$ret .= "$host " . padd(6, $ttl) . " ";
|
||||
|
||||
## - ckubu add: TTL=
|
||||
$ret .= "$host TTL=" . padd(6, $ttl) . " ";
|
||||
|
||||
$ret .= queryType($query_type) . " $thing ";
|
||||
if ($query_type == 16) { # it's a txt record
|
||||
# the first byte is the length. we skip it.
|
||||
$data = substr($data, 2);
|
||||
$ret .= "\"" . unpack("A*", pack("H*", $data)) . "\"";
|
||||
} else {
|
||||
$ret .= "$data";
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
sub queryType {
|
||||
my ($type) = shift;
|
||||
|
||||
my $ret = "";
|
||||
|
||||
# i only list the ones that are in dnscache's dns.h.
|
||||
SWITCH: {
|
||||
($type == 1) && do { $ret = "a"; last SWITCH; };
|
||||
($type == 2) && do { $ret = "ns"; last SWITCH; };
|
||||
($type == 5) && do { $ret = "cname"; last SWITCH; };
|
||||
($type == 6) && do { $ret = "soa"; last SWITCH; };
|
||||
($type == 12) && do { $ret = "ptr"; last SWITCH; };
|
||||
($type == 13) && do { $ret = "hinfo"; last SWITCH; };
|
||||
($type == 15) && do { $ret = "mx"; last SWITCH; };
|
||||
($type == 16) && do { $ret = "txt"; last SWITCH; };
|
||||
($type == 17) && do { $ret = "rp"; last SWITCH; };
|
||||
($type == 24) && do { $ret = "sig"; last SWITCH; };
|
||||
($type == 25) && do { $ret = "key"; last SWITCH; };
|
||||
($type == 28) && do { $ret = "aaaa"; last SWITCH; };
|
||||
($type == 252) && do { $ret = "axfr"; last SWITCH; };
|
||||
($type == 255) && do { $ret = "any"; last SWITCH; };
|
||||
do { $ret .= "$type "; last SWITCH; };
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
# there has to be a better way
|
||||
sub pads {
|
||||
my ($amount, $item) = @_;
|
||||
|
||||
return sprintf "%" . $amount . "s", $item;
|
||||
}
|
||||
|
||||
sub padd {
|
||||
my ($amount, $item) = @_;
|
||||
|
||||
return sprintf "%0" . $amount . "d", $item;
|
||||
}
|
||||
|
270
parse_djbdns_log
Executable file
270
parse_djbdns_log
Executable file
@ -0,0 +1,270 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
"""parse_djbdns_log
|
||||
|
||||
Reads log files from tinydns and/or dnscache and prints them out in
|
||||
human-readable form. Logs can be supplied on stdin, or listed on
|
||||
the command line:
|
||||
|
||||
cat @*.s | parse_djbdns_log
|
||||
parse_djbdns_log @*.s
|
||||
tail -f current | parse_djbdns_log
|
||||
|
||||
Pipes each log file through tai64nlocal, which must be on your path.
|
||||
|
||||
Requirements:
|
||||
* tai64nlocal on the path
|
||||
* Python 2.2 or greater
|
||||
|
||||
Acknowledgments:
|
||||
|
||||
* The log format descriptions by Rob Mayoff were invaluable:
|
||||
http://dqd.com/~mayoff/notes/djbdns/tinydns-log.html
|
||||
http://dqd.com/~mayoff/notes/djbdns/dnscache-log.html
|
||||
|
||||
* Faried Nawaz's dnscache log parser was the original inspiration:
|
||||
http://www.hungry.com/~fn/dnscache-log.pl.txt
|
||||
|
||||
Written by Greg Ward <gward@python.net> 2001/12/13.
|
||||
|
||||
Modified to handle IPv6 addresses (as logged by djbdns with the patch at
|
||||
http://www.fefe.de/dns/), 2003/05/03-04, prodded and tested by Jakob
|
||||
Hirsch <jh@plonk.de>.
|
||||
|
||||
Modified to handle dnscache's AXFR request log lines by Malte Tancred
|
||||
(http://tancred.com/malte.html), 2005/12/20.
|
||||
"""
|
||||
|
||||
__revision__ = "$Id: parse_djbdns_log,v 1.4 2005/12/20 13:39:36 greg Exp $"
|
||||
|
||||
import sys, re
|
||||
from popen2 import popen2
|
||||
from time import strftime, gmtime
|
||||
from struct import pack
|
||||
|
||||
# common components of line-matching regexes
|
||||
timestamp_pat = r'[\d-]+ [\d:\.]+' # output of tai64nlocal
|
||||
hex4_pat = r'[0-9a-f]{4}'
|
||||
ip_pat = r'[0-9a-f]{8,32}' # IPv4 or IPv6 addresses in hex
|
||||
|
||||
# discriminate between dnscache and tinydns log lines
|
||||
tinydns_log_re = re.compile(
|
||||
r'(%s) (%s):(%s):(%s) ([\+\-IC/]) (%s) (.*)'
|
||||
% (timestamp_pat, ip_pat, hex4_pat, hex4_pat, hex4_pat))
|
||||
dnscache_log_re = re.compile(r'(%s) (\w+)(.*)' % timestamp_pat)
|
||||
|
||||
query_type = {
|
||||
1: "a",
|
||||
2: "ns",
|
||||
5: "cname",
|
||||
6: "soa",
|
||||
12: "ptr",
|
||||
13: "hinfo",
|
||||
15: "mx",
|
||||
16: "txt",
|
||||
17: "rp",
|
||||
24: "sig",
|
||||
25: "key",
|
||||
28: "aaaa",
|
||||
38: "a6",
|
||||
252: "axfr",
|
||||
255: "any",
|
||||
}
|
||||
|
||||
# for tinydns only
|
||||
query_drop_reason = {
|
||||
"-": "no authority",
|
||||
"I": "invalid query",
|
||||
"C": "invalid class",
|
||||
}
|
||||
|
||||
|
||||
def warn (filename, msg):
|
||||
sys.stderr.write("warning: %s: %s\n" % (filename, msg))
|
||||
|
||||
def convert_ip (ip):
|
||||
"""Convert a hex string representing an IP address to conventional
|
||||
human-readable form, ie. dotted-quad decimal for IPv4, and
|
||||
8 colon-separated hex shorts for IPv6.
|
||||
"""
|
||||
if len(ip) == 8:
|
||||
# IPv4, eg. "7f000001" -> "127.0.0.1"
|
||||
return "%d.%d.%d.%d" % tuple(map(ord, pack(">L", long(ip, 16))))
|
||||
elif len(ip) == 32:
|
||||
# IPv6 is actually simpler -- it's just a string-slicing operation,
|
||||
# eg. "00000000000000000000ffff7f000001" ->
|
||||
# "0000:0000:0000:0000:0000:ffff:7f00:0001"
|
||||
return ":".join([ip[(4*i) : (4*i+4)] for i in range(8)])
|
||||
|
||||
|
||||
def _cvt_ip (match):
|
||||
return convert_ip(match.group(1))
|
||||
|
||||
def _cvt_port (match):
|
||||
return ":" + str(int(match.group(1), 16))
|
||||
|
||||
def decode_client (words, i):
|
||||
chunks = words[i].split(":")
|
||||
if len(chunks) == 2: # ip:port
|
||||
words[i] = "%s:%d" % (convert_ip(chunks[0]), int(chunks[1], 16))
|
||||
elif len(chunks) == 3:
|
||||
words[i] = "%s:%d (id %d)" % (convert_ip(chunks[0]),
|
||||
int(chunks[1], 16),
|
||||
int(chunks[2], 16))
|
||||
|
||||
def decode_ip (words, i):
|
||||
words[i] = convert_ip(words[i])
|
||||
|
||||
def decode_ttl (words, i):
|
||||
words[i] = "TTL=%s" % words[i]
|
||||
|
||||
def decode_serial (words, i):
|
||||
serial = int(words[i])
|
||||
words[i] = "#%d" % serial
|
||||
|
||||
def decode_type (words, i):
|
||||
qt = words[i]
|
||||
words[i] = query_type.get(int(qt), qt)
|
||||
|
||||
def handle_dnscache_log (line, match):
|
||||
(timestamp, event, data) = match.groups()
|
||||
|
||||
words = data.split()
|
||||
if event == "cached":
|
||||
if words[0] not in ("cname", "ns", "nxdomain"):
|
||||
decode_type(words, 0)
|
||||
|
||||
elif event == "drop":
|
||||
decode_serial(words, 0)
|
||||
|
||||
elif event == "lame":
|
||||
decode_ip(words, 0)
|
||||
|
||||
elif event == "nodata":
|
||||
decode_ip(words, 0)
|
||||
decode_ttl(words, 1)
|
||||
decode_type(words, 2)
|
||||
|
||||
elif event == "nxdomain":
|
||||
decode_ip(words, 0)
|
||||
decode_ttl(words, 1)
|
||||
|
||||
elif event == "query":
|
||||
decode_serial(words, 0)
|
||||
decode_client(words, 1)
|
||||
decode_type(words, 2)
|
||||
|
||||
elif event == "rr":
|
||||
decode_ip(words, 0)
|
||||
decode_ttl(words, 1)
|
||||
if words[2] not in ("cname", "mx", "ns", "ptr", "soa"):
|
||||
decode_type(words, 2)
|
||||
if words[2] == "a": # decode answer to an A query
|
||||
decode_ip(words, 4)
|
||||
if words[2] == "txt": # text record
|
||||
response = words[4]
|
||||
if response.endswith("..."):
|
||||
ellipsis = "..."
|
||||
response = response[0:-3]
|
||||
else:
|
||||
ellipsis = ""
|
||||
length = int(response[0:2], 16)
|
||||
chars = []
|
||||
for i in range(1, len(response)/2):
|
||||
chars.append(chr(int(response[2*i : (2*i)+2], 16)))
|
||||
words[4] = "%d:\"%s%s\"" % (length, "".join(chars), ellipsis)
|
||||
|
||||
elif event == "sent":
|
||||
decode_serial(words, 0)
|
||||
|
||||
elif event == "stats":
|
||||
words[0] = "count=%s" % words[0]
|
||||
words[1] = "motion=%s" % words[1]
|
||||
words[2] = "udp-active=%s" % words[2]
|
||||
words[3] = "tcp-active=%s" % words[3]
|
||||
|
||||
elif event == "tx":
|
||||
words[0] = "g=%s" % words[0]
|
||||
decode_type(words, 1)
|
||||
# words[2] = name
|
||||
# words[3] = control (domain for which these servers are believed
|
||||
# to be authoritative)
|
||||
for i in range(4, len(words)):
|
||||
decode_ip(words, i)
|
||||
|
||||
elif event in ("tcpopen", "tcpclose"):
|
||||
decode_client(words, 0)
|
||||
|
||||
print timestamp, event, " ".join(words)
|
||||
|
||||
|
||||
def handle_tinydns_log (line, match):
|
||||
(timestamp, ip, port, id, code, type, name) = match.groups()
|
||||
ip = convert_ip(ip)
|
||||
port = int(port, 16)
|
||||
id = int(id, 16)
|
||||
type = int(type, 16) # "001c" -> 28
|
||||
type = query_type.get(type, type) # 28 -> "aaaa"
|
||||
|
||||
print timestamp,
|
||||
|
||||
if code == "+":
|
||||
print ("sent response to %s:%s (id %s): %s %s"
|
||||
% (ip, port, id, type, name))
|
||||
elif code in ("-", "I", "C"):
|
||||
reason = query_drop_reason[code]
|
||||
print ("dropped query (%s) from %s:%s (id %s): %s %s"
|
||||
% (reason, ip, port, id, type, name))
|
||||
elif code == "/":
|
||||
print ("dropped query (couldn't parse) from %s:%s"
|
||||
% (ip, port))
|
||||
else:
|
||||
print ("%s from %s:%s (id %s): %s %s"
|
||||
% (code, ip, port, id, type, name))
|
||||
|
||||
|
||||
def parse_logfile (file, filename):
|
||||
# Open pipe to tai64nlocal: we will write lines of our input (the
|
||||
# raw log file) to it, and read log lines with readable timestamps
|
||||
# from it.
|
||||
(tai_stdout, tai_stdin) = popen2("tai64nlocal", 0)
|
||||
|
||||
for line in file:
|
||||
tai_stdin.write(line)
|
||||
line = tai_stdout.readline()
|
||||
|
||||
match = tinydns_log_re.match(line)
|
||||
if match:
|
||||
handle_tinydns_log(line, match)
|
||||
continue
|
||||
|
||||
match = dnscache_log_re.match(line)
|
||||
if match:
|
||||
handle_dnscache_log(line, match)
|
||||
continue
|
||||
|
||||
sys.stdout.write(line)
|
||||
|
||||
# parse_logfile ()
|
||||
|
||||
|
||||
def main ():
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
for filename in sys.argv[1:]:
|
||||
if filename == "-":
|
||||
parse_logfile(sys.stdin, "(stdin)")
|
||||
else:
|
||||
file = open(filename)
|
||||
parse_logfile(file, filename)
|
||||
file.close()
|
||||
else:
|
||||
parse_logfile(sys.stdin, "(stdin)")
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
sys.exit("interrupted")
|
3
tail_djb_dnscache.sh
Executable file
3
tail_djb_dnscache.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
multitail -e /service/dnscache/log/main/current | tai64nlocal | /root/scripts/dnscache-log
|
3
tail_djbtinydns.sh
Executable file
3
tail_djbtinydns.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
multitail -e /service/tinydns/log/main/current | tai64nlocal | /root/scripts/tinydns-log_ckubu.pl
|
3
tail_djbtinydns6.sh
Executable file
3
tail_djbtinydns6.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
multitail -e /service/tinydns6/log/main/current | tai64nlocal | /root/scripts/tinydns6-log_ckubu.pl
|
8
tail_qmail-send.sh
Executable file
8
tail_qmail-send.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
#multitail -e /var/log/qmail/send/current | tai64n2tai | gawk '{$1=substr(strftime("%c",$1),0,23);print}'
|
||||
multitail -e /var/log/qmail/send/current | tai64nlocal | gawk '{$2=substr($2,1,8);print}'
|
||||
#multitail /var/log/qmail/send/current | tai64nlocal | gawk '{$2=substr($2,1,8);print}'
|
||||
#tail -f /var/log/qmail/send/current | tai64nlocal | gawk '{$2=substr($2,1,8);print}'
|
||||
|
||||
exit 0
|
8
tail_qmail-smtpd.sh
Executable file
8
tail_qmail-smtpd.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
#multitail -e /var/log/qmail/smtpd/current | tai64n2tai | gawk '{$1=substr(strftime("%c",$1),0,23);print}'
|
||||
multitail -e /var/log/qmail/smtpd/current | tai64nlocal | gawk '{$2=substr($2,1,8);print}'
|
||||
#multitail /var/log/qmail/smtpd/current | tai64nlocal | gawk '{$2=substr($2,1,8);print}'
|
||||
#tail -f /var/log/qmail/smtpd/current | tai64nlocal | gawk '{$2=substr($2,1,8);print}'
|
||||
|
||||
exit 0
|
139
tinydns-log_ckubu.pl
Executable file
139
tinydns-log_ckubu.pl
Executable file
@ -0,0 +1,139 @@
|
||||
#!/usr/bin/perl -p
|
||||
|
||||
use Sys::Hostname;
|
||||
$myhost = hostname;
|
||||
#$myhost =~ s/^([^.]+).*/$1/ ;
|
||||
|
||||
# tinydns log formatting utility
|
||||
# based on Faried Nawaz's logfile formatter for dnscache
|
||||
# by Kenji Rikitake <kenji.rikitake@acm.org> 29-JUL-2000
|
||||
# please put this on dnscache.com ftp site.
|
||||
|
||||
# convert addresses in hex to dotted decimal notation.
|
||||
## - wthout ipv6 patch
|
||||
## -
|
||||
#s/\b([a-f0-9]{8})\b/join(".", unpack("C*", pack("H8", $1)))/eg;
|
||||
|
||||
## - within ipv6
|
||||
## -
|
||||
s/[a-f0-9]{24}([a-f0-9]{8})/join(".", unpack("C*", pack("H8", $1)))/eg;
|
||||
|
||||
### clean up some messages
|
||||
# convert stuff like 127.0.0.2:0422:05be to something more descriptive.
|
||||
# query tai64n host:port:qid flag qtype thing
|
||||
# keep tai64n header as is - use tai64nlocal to convert it to TAI
|
||||
|
||||
|
||||
#s/^(@[a-f0-9]+) \b([\d.]+):(\w+):(\w+) ([\+\-\I\/]) \b([a-f0-9]+) \b([-.\w]+)/$1." ".printQueryLine($2,$3,$4,$5,$6,$7)/e;
|
||||
#s/^(@[a-f0-9]+) \b([\d.]+):(\w+):(\w+) ([\+\-CIX\/]?)\s?\b([a-f0-9]+) \b([-.\w]+)/$1." ".printQueryLine($2,$3,$4,$5,$6,$7)/e;
|
||||
|
||||
|
||||
## - if original logfile will be parsed
|
||||
## -
|
||||
#s/^(@[a-f0-9]+) \b([\d.]+):(\w+):(\w+) ([\+\-CIX\/]?)\s?\b([a-f0-9]+) ([-.\w]+)/$1." ".printQueryLine($2,$3,$4,$5,$6,$7)/e;
|
||||
|
||||
## - if logfile is tai65nlocal konverted
|
||||
## -
|
||||
#s/^([^\.]+).([0-9]+) \b([\d.]+):(\w+):(\w+) ([\+\-\ICX\/]?)\s?\b([a-f0-9]+) ([-.\w]+)/$1." ".printQueryLine($3,$4,$5,$6,$7,$8)/e;
|
||||
|
||||
## - additional print (short) hostname
|
||||
## -
|
||||
s/^([^\.]+).([0-9]+) \b([\d.]+):(\w+):(\w+) ([\+\-\ICX\/]?)\s?\b([a-f0-9]+) ([-.\w]+)/"[$myhost] ".$1." ".printQueryLine($3,$4,$5,$6,$7,$8)/e;
|
||||
|
||||
|
||||
|
||||
### subs
|
||||
|
||||
sub printQueryLine {
|
||||
my ($host, $port, $query_id, $flag, $query_type, $query) = @_;
|
||||
|
||||
# pad hostname
|
||||
|
||||
#my $ret = "$host:";
|
||||
#$ret .= hex($port);
|
||||
#$ret .= ":" . hex($query_id);
|
||||
#$ret .= " " . $flag;
|
||||
my $ret = queryHandle($host, hex($port), hex($query_id), $flag);
|
||||
$ret .= " " . queryType(hex($query_type)) . " $query";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
## -sub queryType {
|
||||
## - my ($type) = shift;
|
||||
## -
|
||||
## - my $ret = "";
|
||||
## -
|
||||
## - # i only list the ones that are in dnscache's dns.h.
|
||||
## - SWITCH: {
|
||||
## - ($type == 1) && do { $ret = "A"; last SWITCH; };
|
||||
## - ($type == 2) && do { $ret = "NS"; last SWITCH; };
|
||||
## - ($type == 5) && do { $ret = "CNAME"; last SWITCH; };
|
||||
## - ($type == 6) && do { $ret = "SOA"; last SWITCH; };
|
||||
## - ($type == 11) && do { $ret = "WKS"; last SWITCH; };
|
||||
## - ($type == 12) && do { $ret = "PTR"; last SWITCH; };
|
||||
## - ($type == 13) && do { $ret = "HINFO"; last SWITCH; };
|
||||
## - ($type == 14) && do { $ret = "MINFo"; last SWITCH; };
|
||||
## - ($type == 15) && do { $ret = "MX"; last SWITCH; };
|
||||
## - ($type == 16) && do { $ret = "TXT"; last SWITCH; };
|
||||
## - ($type == 17) && do { $ret = "RP"; last SWITCH; };
|
||||
## - ($type == 18) && do { $ret = "AFSDB"; last SWITCH; };
|
||||
## - ($type == 20) && do { $ret = "ISDN"; last SWITCH; };
|
||||
## - ($type == 21) && do { $ret = "RT"; last SWITCH; };
|
||||
## - ($type == 22) && do { $ret = "NSAP"; last SWITCH; };
|
||||
## - ($type == 23) && do { $ret = "NSAP-PTR"; last SWITCH; };
|
||||
## - ($type == 24) && do { $ret = "SIG"; last SWITCH; };
|
||||
## - ($type == 25) && do { $ret = "KEY"; last SWITCH; };
|
||||
## - ($type == 26) && do { $ret = "PX"; last SWITCH; };
|
||||
## - ($type == 28) && do { $ret = "AAAA"; last SWITCH; };
|
||||
## - ($type == 29) && do { $ret = "LOC"; last SWITCH; };
|
||||
## - ($type == 30) && do { $ret = "NXT"; last SWITCH; };
|
||||
## - ($type == 33) && do { $ret = "SRV"; last SWITCH; };
|
||||
## - ($type == 35) && do { $ret = "NAPTR"; last SWITCH; };
|
||||
## - ($type == 36) && do { $ret = "KX"; last SWITCH; };
|
||||
## - ($type == 37) && do { $ret = "CERT"; last SWITCH; };
|
||||
## - ($type == 38) && do { $ret = "A6"; last SWITCH; };
|
||||
## - ($type == 42) && do { $ret = "APL"; last SWITCH; };
|
||||
## - ($type == 249) && do { $ret = "TKEY"; last SWITCH; };
|
||||
## - ($type == 250) && do { $ret = "TSIG"; last SWITCH; };
|
||||
## - ($type == 251) && do { $ret = "IXFR"; last SWITCH; };
|
||||
## - ($type == 252) && do { $ret = "AXFR"; last SWITCH; };
|
||||
## - ($type == 255) && do { $ret = "ANY"; last SWITCH; };
|
||||
## - do { $ret .= "$type "; last SWITCH; };
|
||||
## - }
|
||||
## - return $ret;
|
||||
## -}
|
||||
|
||||
# DNS query type codes from the following RFCs:
|
||||
# 1035,1183,1348,1876,1995,2065,2163,2230,2535,2538,2845,2874,2915,2930,3123
|
||||
%QTYPE = (
|
||||
1, "A", 2, "NS", 5, "CNAME", 6, "SOA", 11, "WKS", 12, "PTR",
|
||||
13, "HINFO", 14, "MINFO", 15, "MX", 16, "TXT", 17, "RP",
|
||||
18, "AFSDB", 20, "ISDN", 21, "RT", 22, "NSAP", 23, "NSAP-PTR",
|
||||
24, "SIG", 25, "KEY", 26, "PX", 28, "AAAA", 29, "LOC", 30, "NXT",
|
||||
33, "SRV", 35, "NAPTR", 36, "KX", 37, "CERT", 38, "A6", 42, "APL",
|
||||
249, "TKEY", 250, "TSIG", 251, "IXFR", 252, "AXFR", 255, "ANY"
|
||||
);
|
||||
|
||||
sub queryType {
|
||||
my ($type) = shift;
|
||||
return $QTYPE{$type} || $type;
|
||||
}
|
||||
|
||||
sub queryHandle {
|
||||
my ($q_host, $q_port, $q_id, $q_flag) = @_;
|
||||
|
||||
my $ret = "";
|
||||
|
||||
# i only list the ones that are in dnscache's dns.h.
|
||||
SWITCH: {
|
||||
($q_flag =~ m/\+/) && do { $ret = "sent response to $q_host:$q_port (id $q_id): "; last SWITCH; };
|
||||
($q_flag =~ m/-/) && do { $ret = "dropped query (no authority) from $q_host:$q_port (id $q_id): "; last SWITCH; };
|
||||
($q_flag =~ m#/#) && do { $ret = "dropped query (couldn't parse) from $q_host:$q_port (id $q_id): "; last SWITCH; };
|
||||
($q_flag =~ m#I#) && do { $ret = "[WARN] sent RCODE of 4 (NOTIMP) to $q_host:$q_port (id $q_id): "; last SWITCH; };
|
||||
($q_flag =~ m#C#) && do { $ret = "[WARN] sent RCODE of 1 (FORMERR) to $q_host:$q_port (id $q_id): "; last SWITCH; };
|
||||
do { $ret .= "[??] $q_host:$q_port (id $q_id): $q_flag "; last SWITCH; };
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
144
tinydns6-log_ckubu.pl
Executable file
144
tinydns6-log_ckubu.pl
Executable file
@ -0,0 +1,144 @@
|
||||
#!/usr/bin/perl -p
|
||||
|
||||
use Sys::Hostname;
|
||||
$myhost = hostname;
|
||||
#$myhost =~ s/^([^.]+).*/$1/ ;
|
||||
|
||||
# tinydns log formatting utility
|
||||
# based on Faried Nawaz's logfile formatter for dnscache
|
||||
# by Kenji Rikitake <kenji.rikitake@acm.org> 29-JUL-2000
|
||||
# please put this on dnscache.com ftp site.
|
||||
|
||||
# convert addresses in hex to dotted decimal notation.
|
||||
## - wthout ipv6 patch
|
||||
## -
|
||||
#s/\b([a-f0-9]{8})\b/join(".", unpack("C*", pack("H8", $1)))/eg;
|
||||
|
||||
## - within ipv6
|
||||
## -
|
||||
#s/[a-f0-9]{24}([a-f0-9]{8})/join(".", unpack("C*", pack("H8", $1)))/eg;
|
||||
|
||||
|
||||
### clean up some messages
|
||||
# convert stuff like 127.0.0.2:0422:05be to something more descriptive.
|
||||
# query tai64n host:port:qid flag qtype thing
|
||||
# keep tai64n header as is - use tai64nlocal to convert it to TAI
|
||||
|
||||
|
||||
#s/^(@[a-f0-9]+) \b([\d.]+):(\w+):(\w+) ([\+\-\I\/]) \b([a-f0-9]+) \b([-.\w]+)/$1." ".printQueryLine($2,$3,$4,$5,$6,$7)/e;
|
||||
#s/^(@[a-f0-9]+) \b([\d.]+):(\w+):(\w+) ([\+\-CIX\/]?)\s?\b([a-f0-9]+) \b([-.\w]+)/$1." ".printQueryLine($2,$3,$4,$5,$6,$7)/e;
|
||||
|
||||
|
||||
## - if original logfile will be parsed
|
||||
## -
|
||||
#s/^(@[a-f0-9]+) \b([\d.]+):(\w+):(\w+) ([\+\-CIX\/]?)\s?\b([a-f0-9]+) ([-.\w]+)/$1." ".printQueryLine($2,$3,$4,$5,$6,$7)/e;
|
||||
|
||||
## - if logfile is tai65nlocal konverted
|
||||
## -
|
||||
#s/^([^\.]+).([0-9]+) \b([\d.]+):(\w+):(\w+) ([\+\-\ICX\/]?)\s?\b([a-f0-9]+) ([-.\w]+)/$1." ".printQueryLine($3,$4,$5,$6,$7,$8)/e;
|
||||
|
||||
## - additional print (short) hostname
|
||||
## -
|
||||
s/^([^\.]+).([0-9]+) \b([\w.]+):(\w+):(\w+) ([\+\-\ICX\/]?)\s?\b([a-f0-9]+) ([-.\w]+)/"[$myhost] ".$1." ".printQueryLine($3,$4,$5,$6,$7,$8)/e;
|
||||
|
||||
## - ipv6 embedded ipv4-addresses
|
||||
## -
|
||||
#s/00000000000000000000ffff//;
|
||||
s/([a-f0-9]{4})([a-f0-9]{4})/$1:$2:/g;
|
||||
|
||||
|
||||
### subs
|
||||
|
||||
sub printQueryLine {
|
||||
my ($host, $port, $query_id, $flag, $query_type, $query) = @_;
|
||||
|
||||
# pad hostname
|
||||
|
||||
#my $ret = "$host:";
|
||||
#$ret .= hex($port);
|
||||
#$ret .= ":" . hex($query_id);
|
||||
#$ret .= " " . $flag;
|
||||
my $ret = queryHandle($host, hex($port), hex($query_id), $flag);
|
||||
$ret .= " " . queryType(hex($query_type)) . " $query";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
## -sub queryType {
|
||||
## - my ($type) = shift;
|
||||
## -
|
||||
## - my $ret = "";
|
||||
## -
|
||||
## - # i only list the ones that are in dnscache's dns.h.
|
||||
## - SWITCH: {
|
||||
## - ($type == 1) && do { $ret = "A"; last SWITCH; };
|
||||
## - ($type == 2) && do { $ret = "NS"; last SWITCH; };
|
||||
## - ($type == 5) && do { $ret = "CNAME"; last SWITCH; };
|
||||
## - ($type == 6) && do { $ret = "SOA"; last SWITCH; };
|
||||
## - ($type == 11) && do { $ret = "WKS"; last SWITCH; };
|
||||
## - ($type == 12) && do { $ret = "PTR"; last SWITCH; };
|
||||
## - ($type == 13) && do { $ret = "HINFO"; last SWITCH; };
|
||||
## - ($type == 14) && do { $ret = "MINFo"; last SWITCH; };
|
||||
## - ($type == 15) && do { $ret = "MX"; last SWITCH; };
|
||||
## - ($type == 16) && do { $ret = "TXT"; last SWITCH; };
|
||||
## - ($type == 17) && do { $ret = "RP"; last SWITCH; };
|
||||
## - ($type == 18) && do { $ret = "AFSDB"; last SWITCH; };
|
||||
## - ($type == 20) && do { $ret = "ISDN"; last SWITCH; };
|
||||
## - ($type == 21) && do { $ret = "RT"; last SWITCH; };
|
||||
## - ($type == 22) && do { $ret = "NSAP"; last SWITCH; };
|
||||
## - ($type == 23) && do { $ret = "NSAP-PTR"; last SWITCH; };
|
||||
## - ($type == 24) && do { $ret = "SIG"; last SWITCH; };
|
||||
## - ($type == 25) && do { $ret = "KEY"; last SWITCH; };
|
||||
## - ($type == 26) && do { $ret = "PX"; last SWITCH; };
|
||||
## - ($type == 28) && do { $ret = "AAAA"; last SWITCH; };
|
||||
## - ($type == 29) && do { $ret = "LOC"; last SWITCH; };
|
||||
## - ($type == 30) && do { $ret = "NXT"; last SWITCH; };
|
||||
## - ($type == 33) && do { $ret = "SRV"; last SWITCH; };
|
||||
## - ($type == 35) && do { $ret = "NAPTR"; last SWITCH; };
|
||||
## - ($type == 36) && do { $ret = "KX"; last SWITCH; };
|
||||
## - ($type == 37) && do { $ret = "CERT"; last SWITCH; };
|
||||
## - ($type == 38) && do { $ret = "A6"; last SWITCH; };
|
||||
## - ($type == 42) && do { $ret = "APL"; last SWITCH; };
|
||||
## - ($type == 249) && do { $ret = "TKEY"; last SWITCH; };
|
||||
## - ($type == 250) && do { $ret = "TSIG"; last SWITCH; };
|
||||
## - ($type == 251) && do { $ret = "IXFR"; last SWITCH; };
|
||||
## - ($type == 252) && do { $ret = "AXFR"; last SWITCH; };
|
||||
## - ($type == 255) && do { $ret = "ANY"; last SWITCH; };
|
||||
## - do { $ret .= "$type "; last SWITCH; };
|
||||
## - }
|
||||
## - return $ret;
|
||||
## -}
|
||||
|
||||
# DNS query type codes from the following RFCs:
|
||||
# 1035,1183,1348,1876,1995,2065,2163,2230,2535,2538,2845,2874,2915,2930,3123
|
||||
%QTYPE = (
|
||||
1, "A", 2, "NS", 5, "CNAME", 6, "SOA", 11, "WKS", 12, "PTR",
|
||||
13, "HINFO", 14, "MINFO", 15, "MX", 16, "TXT", 17, "RP",
|
||||
18, "AFSDB", 20, "ISDN", 21, "RT", 22, "NSAP", 23, "NSAP-PTR",
|
||||
24, "SIG", 25, "KEY", 26, "PX", 28, "AAAA", 29, "LOC", 30, "NXT",
|
||||
33, "SRV", 35, "NAPTR", 36, "KX", 37, "CERT", 38, "A6", 42, "APL",
|
||||
249, "TKEY", 250, "TSIG", 251, "IXFR", 252, "AXFR", 255, "ANY"
|
||||
);
|
||||
|
||||
sub queryType {
|
||||
my ($type) = shift;
|
||||
return $QTYPE{$type} || $type;
|
||||
}
|
||||
|
||||
sub queryHandle {
|
||||
my ($q_host, $q_port, $q_id, $q_flag) = @_;
|
||||
|
||||
my $ret = "";
|
||||
|
||||
# i only list the ones that are in dnscache's dns.h.
|
||||
SWITCH: {
|
||||
($q_flag =~ m/\+/) && do { $ret = "sent response to $q_host:$q_port (id $q_id): "; last SWITCH; };
|
||||
($q_flag =~ m/-/) && do { $ret = "dropped query (no authority) from $q_host:$q_port (id $q_id): "; last SWITCH; };
|
||||
($q_flag =~ m#/#) && do { $ret = "dropped query (couldn't parse) from $q_host:$q_port (id $q_id): "; last SWITCH; };
|
||||
($q_flag =~ m#I#) && do { $ret = "[WARN] sent RCODE of 4 (NOTIMP) to $q_host:$q_port (id $q_id): "; last SWITCH; };
|
||||
($q_flag =~ m#C#) && do { $ret = "[WARN] sent RCODE of 1 (FORMERR) to $q_host:$q_port (id $q_id): "; last SWITCH; };
|
||||
do { $ret .= "[??] $q_host:$q_port (id $q_id): $q_flag "; last SWITCH; };
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
31
update6_djbdns_roots.sh
Executable file
31
update6_djbdns_roots.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
ipv6=false
|
||||
[ -n "`which dnsip6`" ] && ipv6=true
|
||||
|
||||
if [ -f /etc/dnsroots.global ] ; then
|
||||
if [ ! -f /etc/dnsroots.global.ORIG ] ; then
|
||||
cp /etc/dnsroots.global /etc/dnsroots.global.ORIG
|
||||
fi
|
||||
fi
|
||||
|
||||
root_servers=`dnsqr ns . | awk '/answer:/ { print $5; }' | sort`
|
||||
|
||||
> /etc/dnsroots.global
|
||||
|
||||
for server in $root_servers ; do
|
||||
echo "`dnsip $server`" >> /etc/dnsroots.global
|
||||
if $ipv6 ; then
|
||||
ip6=`dnsqr aaaa $server | awk '/answer:/ { print $5; }'`
|
||||
if [ -n "$ip6" ] ; then
|
||||
echo "$ip6" >> /etc/dnsroots.global
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
cp /etc/dnsroots.global /service/dnscache/root/servers/@
|
||||
cp /etc/dnsroots.global /service/dnscache6/root/servers/@
|
||||
svc -du /service/dnscache
|
||||
svc -du /service/dnscache6
|
14
update_djbdns_roots.sh
Executable file
14
update_djbdns_roots.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
if [ -f /etc/dnsroots.global ] ; then
|
||||
if [ ! -f /etc/dnsroots.global.ORIG ] ; then
|
||||
cp /etc/dnsroots.global /etc/dnsroots.global.ORIG
|
||||
fi
|
||||
fi
|
||||
|
||||
dnsip `dnsqr ns . | awk '/answer:/ { print $5; }' |sort` > /etc/dnsroots.global
|
||||
cp /etc/dnsroots.global /service/dnscache/root/servers/@
|
||||
svc -du /service/dnscache
|
||||
|
59
update_ipv4_adress_space.sh
Executable file
59
update_ipv4_adress_space.sh
Executable file
@ -0,0 +1,59 @@
|
||||
#!/bin/sh
|
||||
|
||||
update_url="http://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.txt"
|
||||
|
||||
base_dnscache_dir=/opt/dnscache
|
||||
dnscache_ip_dir=${base_dnscache_dir}/root/ip
|
||||
|
||||
if [ ! -d $base_dnscache_dir -o ! -d $dnscache_ip_dir ]; then
|
||||
echo
|
||||
echo "[ ERROR ]: Installtion directory for dnscache not found"
|
||||
echo " exiting now.."
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
tmp_file="/tmp/ipv4_addresss_space.$$.lst"
|
||||
|
||||
wget $update_url -O $tmp_file > /dev/null 2>&1
|
||||
|
||||
if [ $? -gt 0 ];then
|
||||
echo
|
||||
echo "[ ERROR ]: cannot fetch $update_url "
|
||||
echo " exiting now.."
|
||||
echo
|
||||
rm -f $tmp_file
|
||||
exit 2
|
||||
fi
|
||||
|
||||
adress_spaces=`grep -e " \(ALLOCATED\)$\|\(LEGACY\)$" $tmp_file | awk '{print$1}' | cut -d "/" -f 1 | sed -e's/^0*\(.*\)$/\1/'`
|
||||
|
||||
if [ -z "$adress_spaces" ] ; then
|
||||
echo
|
||||
echo "[ ERROR ]: No adress space data found $update_url "
|
||||
echo " exiting now.."
|
||||
echo
|
||||
rm -f $tmp_file
|
||||
exit 3
|
||||
fi
|
||||
|
||||
## - delete old entries..
|
||||
## -
|
||||
rm -rf $dnscache_ip_dir/*
|
||||
|
||||
cd $dnscache_ip_dir
|
||||
|
||||
for i in $adress_spaces; do
|
||||
touch ${i}
|
||||
done
|
||||
|
||||
## - send the servive a HUP signal
|
||||
## -
|
||||
svc -h $base_dnscache_dir
|
||||
|
||||
rm -f $tmp_file
|
||||
|
||||
exit 0
|
Loading…
Reference in New Issue
Block a user