Snippets

RuWeb.net ipmgr ipv6 ptr mod

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");
}

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.