Good morning all first I would like to thank all the monks who have put up with me this week in my quest for knowldge I know I have some silly questions at times, but I promise it is just in the quest to better understand the wonders of perl. Anyway on to my battle I have been working with various DNS mods to parse over 30,000 zone files i have on my DNS system to get the data into a mySQL DB for managment and I thought I had this one whipped, but I have come across an issue that for the life of me I can't figure out and come to you all for help.
After some playing and hacking of the mods I have decided that my best fit will be Net::DNS::ZoneFile for this task, now the issue I have is that I want to only parse certain zone files for certain data ( A CNAME MX NS PTR ) now for the most part I have my other scripts working the only two I have trouble with are the scripts for forward records ( A ) and reverse ( PTR ). The mod understands the standards in Bind for RR types and has added functionality for the special $GENERATE and $INCLUDE. The issue I run into with the code below is that when I parse for forward and reverse data with my test to m/^A/ or m/PTR/ is that once the file is loaded and the parse begins once the read finds a line with the $GENERATE on it the script hangs and doesn't know what to do. I have done testing to see what the mod is doing and calls to to build the record {type} and that produces A NS CNAME MX PTR but doesn't match the $GENERATE, so the issue I have is how do I test for that and then build that data so I may insert into my DB. In the Net::DNS::ZoneFile ZoneFile.pm the sub _parse seems to build the data on the fly ( please see the sub for this ) so I know that the test for {type} wont work here and I am at my wits end as how to make this work for both standard records and the special $GENERATE if anyone could please help me out as I am loosing much hair over this one.
Below is my code so far.
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
use FileHandle;
use Data::Dumper;
use Net::DNS::ZoneFile;
use DBI;
my $dbh = DBI->connect(
"DBI:mysql:database=dns;host=localhost",
"root", "test",
{'RaiseError' => 1}
);
my $sth = $dbh->prepare(
"INSERT INTO a (hname,zone,host) VALUES (?,?,?)"
);
my $base = "/chroot/named/master/net";
find(\&wanted, $base);
$dbh->disconnect();
exit;
sub wanted {
return unless ( -f "$File::Find::name" and $File::Find::name !~ m!
+ /in-addr/! );
my $index = 1;
my $root = shift;
my $zone = new FileHandle "$File::Find::name", "r";
my @name = split('/',$File::Find::name);
my $out = join('.', reverse(@name[4..$#name]));
my $rrset = Net::DNS::ZoneFile->readfh($zone, $root);
for(@$rrset) {
print "This is our file to be parsed $out\n";
print "Working on line: ", $index++, ".\n";
print "$_->{type}\n";
print "$_->rdatastr\n" if $_->{type} =~ m/^A/;
print "$_->{name},",$_->rdatastr, "\n" if $_->{type} =~ m/^A/;
print STDOUT Data::Dumper->Dump([$_->rrset]) . "\n";
if($_->{type} =~ m/^A/) {
print "Working on line: ", $index++, ".\n";
$sth->execute( $_->{name}, $out, $_->rdatastr) or die $dbh->
+errstr;
}
}
}
And here is the section from the ZoneFile.pm for the $GENERATE handling.
elsif ($text =~ # $GENERATE
s/
\A\$GENERATE \s+
(\d+) \s* - \s* (\d+) \s+
(|\*|\@|\.|([-\w\$\d]+(\.[-\w\$\d]+)*\.?)) \s+
((IN|HESIOD|CHAOS) \s+)?
(\w+) \s+
([-\w\$\d]+((\.[-\w\$\d]+)*)?\.) \s*$
//mxi)
{
return undef if $2 < $1;
my $rr_template = join(' ', $3, $7 || 'IN', $8, $9);
for my $i (reverse $1 .. $2) {
my $rr = $rr_template . "\n";
$rr =~ s/\$/$i/g;
substr($text, 0, 0) = $rr;
}
}
SUNADMN
USE PERL