my @out;
my @added;
my @in = split /\s+/, $line;
-return (1, "set/badip: need IP, IP-IP or IP/24") unless @in;
+my $suffix = 'local';
+if ($in[0] =~ /^[_\d\w]+$/) {
+ $suffix = shift @in;
+}
+return (1, "set/badip: need [suffix (def: local])] IP, IP-IP or IP/24") unless @in;
for my $ip (@in) {
my $r;
eval{ $r = DXCIDR::find($ip); };
push @out, "set/badip: $ip exists, not added";
next;
}
- DXCIDR::add($ip);
+ DXCIDR::add($suffix, $ip);
push @added, $ip;
}
my $count = @added;
my $list = join ' ', @in;
DXCIDR::clean_prep();
-DXCIDR::save();
-push @out, "set/badip: added $count entries: $list" if $count;
+DXCIDR::append($suffix, @added);
+push @out, "set/badip: added $count entries to badip.$suffix : $list" if $count;
return (1, @out);
my $count4 = 0;
my $count6 = 0;
-# load the badip file
-sub load
-{
- if ($active) {
- _load();
- }
- LogDbg('DXProt', "DXCIDR: loaded $count4 IPV4 addresses and $count6 IPV6 addresses");
- return $count4 + $count6;
-}
-
sub _fn
{
return localdata($badipfn);
}
-sub _load
+sub _read
{
+ my $suffix = shift;
my $fn = _fn();
+ $fn .= ".$suffix" if $suffix;
my $fh = IO::File->new($fn);
- my $count = 0;
+ my @out;
- new();
-
if ($fh) {
while (<$fh>) {
chomp;
next if /^\s*\#/;
next unless /[\.:]/;
- add($_);
- ++$count;
+ push @out, $_;
}
$fh->close;
- } elsif (-r $fn) {
- LogDbg('err', "DXCIDR: $fn not found ($!)");
+ } else {
+ LogDbg('err', "DXCIDR: $fn read error ($!)");
}
+ return @out;
+}
- clean_prep();
-
- return $count;
+sub _load
+{
+ my $suffix = shift;
+ my @in = _read($suffix);
+ return scalar add(@in);
}
sub _put
{
- my $fn = _fn();
+ my $suffix = shift;
+ my $fn = _fn() . ".$suffix";
my $r = rand;
my $fh = IO::File->new (">$fn.$r");
my $count = 0;
++$count;
}
move "$fn.$r", $fn;
+ LogDbg('cmd', "DXCIDR: put (re-)written $fn");
} else {
LogDbg('err', "DXCIDR: cannot write $fn.$r $!");
}
return $count;
}
+sub append
+{
+ my $suffix = shift;
+ my @in = @_;
+ my @out;
+
+ if ($suffix) {
+ my $fn = _fn() . ".$suffix";
+ my $r = rand;
+ my $fh = IO::File->new (">>$fn.$r");
+ if ($fh) {
+ print $fh "$_\n" for @in;
+ $fh->close;
+ move "$fn.$r", $fn;
+ } else {
+ LogDbg('err', "DXCIDR::append error appending to $fn.$r $!");
+ }
+ } else {
+ LogDbg('err', "DXCIDR::append require badip suffix");
+ }
+ return scalar @in;
+}
+
sub add
{
my $count = 0;
for my $ip (@_) {
# protect against stupid or malicious
- next if /^127\./;
- next if /^::1$/;
- if (/\./) {
+ next if $ip =~ /^127\./;
+ next if $ip =~ /^::1$/;
+ if ($ip =~ /\./) {
$ipv4->add_any($ip);
++$count;
++$count4;
- } elsif (/:/) {
+ } elsif ($ip =~ /:/) {
$ipv6->add_any($ip);
++$count;
++$count6;
- LogDbg('DXProt', "DXCIDR: Added IPV6 $ip address");
+ } else {
+ LogDbg('err', "DXCIDR::add non-ip address '$ip' read");
}
}
return $count;
}
}
-sub save
-{
- return 0 unless $active;
- _put() if $count4 || $count6;
-}
-
sub _sort
{
my @in;
import Net::CIDR::Lite;
$active = 1;
+ my $fn = _fn();
+ if (-e $fn) {
+ move $fn, "$fn.base";
+ }
+
+ _touch("$fn.local");
+
+ reload();
+
+}
+
+sub _touch
+{
+ my $fn = shift;
+ my $now = time;
+ local (*TMP);
+ utime ($now, $now, $fn) || open (TMP, ">>$fn") || LogDbg('err', "DXCIDR::touch: Couldn't touch $fn: $!");
+}
+
+sub reload
+{
new();
- load();
+ my $count = _load('base');
+ $count += _load('local');
+
+ LogDbg('DXProt', "DXCIDR::reload $count ip addresses found (IPV4: $count4 IPV6: $count6)" );
+
+ return $count;
}
sub new