diff --git a/combine-counts.pl b/combine-counts.pl new file mode 100755 index 0000000..0694c05 --- /dev/null +++ b/combine-counts.pl @@ -0,0 +1,16 @@ +#!/usr/bin/perl -nl +# print the name and total number of records in each unique ipset +#(c)2026 Corwin Brust +# You may use this program under the terms of the GNU Public License version three (3) or, at your option, any later version of that license. (GPLv3+) +# +# Input is expected on stdin as NAME COUNT and may contain duplicates NAMES +# + +END { + print qq($_ $h{$_} ) + for sort keys %h +} + +$h{$1} += $2 + if /^(\S+) (\d+)$/ + diff --git a/combine-saves.pl b/combine-saves.pl new file mode 100755 index 0000000..f93d3b5 --- /dev/null +++ b/combine-saves.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl -p +# +# save-combine - filter and combine output from ipset(1) save +# +# (c)2026 Corwin Brust +# +# You may use this program under the terms of the GNU Public License version three (3) or, at your option, any later version of that license. (GPLv3+) +# +# Use a flat-file "DB" of ipset per row in the form NAME MAX +# Drop create/add lines for any set not mentioned in the DB +# Take DB file-name from first program arg, otherwise "ipset-counts.txt" +# Input is expected on stdin in the same format as output by ipset save +# + +sub max2 { + my $val = $_[0] || 1; + my $rv = 2; + $rv *= 2 until $rv > $val; + return $rv; +} + +BEGIN { + my $SET_COUNTS = @ARGV ? shift : q(max-counts.txt); + open my$FH,q(<),$SET_COUNTS or die $!; + while(<$FH>) { + chomp; + my($k,$v)=split; + $m{$k}=max2( $v ) if $k and $v + } +} + +if(/^create (\S+)/) { + if(exists $h{$1}) { + $_ = ''; + } elsif(exists $m{$1}) { + $h{$1} = 1; # don't reissue creates + $n = $1; # grab the name + $v = $m{$n}; # lookup max + s/^create $n (.*?maxelem) \d+ (.*)$/create $n $1 $v $2/ + and warn qq[set $n=$v] + } + else { + $_ = ''; # skip create when no max defined + } +} +elsif(/^add (\S+)/) +{ + # $_ = '' unless exists $m{$1}; + if (exists $m{$1}) { + s/$/ -exist/; # make dup-safe + } else { + $_ = ''; + } +} diff --git a/destroy-all.sh b/destroy-all.sh new file mode 100755 index 0000000..1afc9f9 --- /dev/null +++ b/destroy-all.sh @@ -0,0 +1,4 @@ +#!/usr/bin/bash + +for s in $( ipset -n list ) ; do ipset destroy $s ; done + diff --git a/save-add-deduplicate.pl b/save-add-deduplicate.pl new file mode 100755 index 0000000..5a9c345 --- /dev/null +++ b/save-add-deduplicate.pl @@ -0,0 +1,36 @@ +#!/usr/bin/perl -p +# combine ipset save files setting max per a flat file of ipset per row in the form NAME MAX +# +#(c)2026 Corwin Brust +# You may use this program under the terms of the GNU Public License version three (3) or, at your option, any later version of that license. (GPLv3+) +# +# Input is expected on stdin in the same format as output by ipset save +# + +BEGIN { + my $SET_COUNTS = @ARGV ? shift : q(max-counts.txt); + open my$FH,q(<),$SET_COUNTS or die $!; + while(<$FH>) { + chomp; + my($k,$v)=split; + $m{$k}=$v if $k and $v + } +} + +if(/^create (\S+)/) { + if(exists $h{$1}) { + $_ = ''; + } elsif(exists $m{$1}) { + $h{$1} = $1; + $n = $m{$1}; + s/^(create (\S+).*?hashsize) \d+ (.*)$/$1 $n $3/ + } + else { + $_ = ''; # skip create when no max defined + } +} +elsif(/^add (\S+)/) +{ + $_ = '' unless exists $m{$1}; +} + diff --git a/save-add-deduplicate.sh b/save-add-deduplicate.sh new file mode 100755 index 0000000..0988e5f --- /dev/null +++ b/save-add-deduplicate.sh @@ -0,0 +1,41 @@ +#!/usr/bin/perl -p +# combine ipset save files setting max per a flat file of ipset per row in the form NAME MAX +# +#(c)2026 Corwin Brust +# You may use this program under the terms of the GNU Public License version three (3) or, at your option, any later version of that license. (GPLv3+) +# +# Input is expected on stdin in the same format as output by ipset save +# + +BEGIN { + my $SET_COUNTS = @ARGV + ? shift + : q(max-counts.txt); + + open my$FH,q(<),$SET_COUNTS + or die $!; + + while(<$FH>) { + chomp; + my($k,$v)=split; + $m{$k}=$v if $k and $v + } +} + +if(/^create (\S+)/) { + if(exists $h{$1}) { + $_ = ''; + } elsif(exists $m{$1}) { + $h{$1} = $1; + $n = $m{$1}; + s/^(create (\S+).*?hashsize) \d+ (.*)$/$1 $n $3/ + } + else { + $_ = ''; # skip create when no max defined + } +} +elsif(/^add (\S+)/) +{ + $_ = '' unless exists $m{$1}; +} + diff --git a/save-count.pl b/save-count.pl new file mode 100755 index 0000000..76ba2bb --- /dev/null +++ b/save-count.pl @@ -0,0 +1,8 @@ +#!/usr/bin/perl -nl +# print the name and number of records in each non-empty ipset +#(c)2026 Corwin Brust +# You may use this program under the terms of the GNU Public License version three (3) or, at your option, any later version of that license. (GPLv3+) +sub p{ print qq($n $c) if $n and $c } +if ( /^create (\S+)/ ) { p(); $c=0; $n=$1 } else { ++$c if $n and /^add/ } +END{ p() } +