Created by
Andrey Chesnakov
last modified
| <?xml version="1.0" encoding="UTF-8"?>
<mgrdata>
<plugin>
<name>IPv6 PTR mod</name>
<lang>perl</lang>
<require>Net-IP</require>
<manager>ipmgr</manager>
<contact>andrey@ruweb.net</contact>
</plugin>
<handler name="ipv6ptr.pl" type="cgi">
<event before="yes" name="ip.edit"/>
<event before="yes" name="ip.delete"/>
<event before="yes" name="net.addr.edit"/>
<event before="yes" name="net.addr.delete"/>
<!--event after="yes" final="yes" name="net.addr.delete.one"/-->
</handler>
</mgrdata>
|
| #!/usr/bin/perl
use strict;
use Net::IP;
print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc/>\n";
my $nameddir="/var/named/domains";
my $type="PTR";
my ($func,$ip,$net,$name,$domain,$zone,$count,$pattern,$mod,@lines);
-d $nameddir or exit;
if ($ENV{PARAM_func} eq "net.addr.edit" and $ENV{PARAM_sok}){
$func='edit';
$ip=$ENV{PARAM_name};
$net=$ENV{PARAM_plid};
$name=$ENV{PARAM_domain};
uc($ENV{PARAM_note}) eq 'NS' and $type='NS';
} elsif ($ENV{PARAM_func} eq "net.addr.delete") {
$func='delete';
$ip=(split /,/,$ENV{PARAM_elid})[0];
$net=$ENV{PARAM_plid};
} elsif ($ENV{PARAM_func} eq "ip.edit" or $ENV{PARAM_func} eq "ip.delete") {
$func=(split '\.', $ENV{PARAM_func})[-1];
$ip=$ENV{PARAM_ip};
$name=$ENV{PARAM_name};
$domain=Net::IP->new($ip)->reverse_ip;
my $len;
while (<"$nameddir/*.ip6.arpa">) {
s|$nameddir/||;
$domain =~ /$_\.$/ and $len=length and $len>$count and $zone="$_." and $count=$len;
}
}
unless ($func and $ip and ($net or $zone) and ($name or $func eq 'delete')) { exit };
$domain or $domain=Net::IP->new($ip)->reverse_ip;
$domain=~/^(0\.){16}/ or exit;
$zone or $zone=Net::IP->new($net)->reverse_ip;
$domain=~s/\.$zone$//;
chop($zone);
unless (-f "$nameddir/$zone" and open(FILE, "<$nameddir/$zone")){ exit }
while (<FILE>){
chomp;
/^((f\.){16,}.+(\.0))+\s+\d+\s+IN\s+PTR\s+ipv6ptr\.mod\.$/ and $pattern=$1;
push(@lines,$_);
}
close(FILE);
$pattern or exit;
$count = ($pattern =~ tr/f/f/);
unless ($domain =~ s/^(0\.){$count}// and $domain) { exit }
my $found=0;
my $skip=0;
my $last=$#lines;
$name and (substr($name, -1) ne '.') and $name.='.';
for (my $i=$#lines; $i>-1; $i--) {
if ($lines[$i]=~/^(\*.+)?$domain\s+(\d+\s+)?IN\s+(PTR|NS)\s+(.*)/) {
if ($func ne 'delete') {
if ($4 eq $name and $3 eq $type) {
if ($type eq 'PTR') {
$lines[$i]=~/^\*\.(0\.)*$domain\s/ and $found=1 and next;
} else { # $type eq 'NS'
$1 eq '' and $found=1 and next;
}
}
}
splice @lines, $i, 1;
}
}
if (!$found and $func ne 'delete') {
$mod=1;
my $str="$domain\tIN\t$type\t$name";
if ($type eq 'NS') {
push(@lines,$str);
} else {
for (my $i=0; $i<$count; $i++) {
$str=~s/^\*/0/;
$str="*.$str";
push(@lines,$str);
}
}
} else {
$mod=($#lines+$skip<$last);
}
if ($mod and open(FILE, ">$nameddir/$zone.new")) {
print FILE join("\n", @lines)."\n";
close (FILE);
rename ("$nameddir/$zone.new", "$nameddir/$zone");
}
|