From: Stefan Schantl Date: Fri, 14 Apr 2023 14:41:07 +0000 (+0200) Subject: ipset-functions.pl: Introduce new functions library. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1fb3f8f475abc46a9da57fdc9fa08281cf85c74b;p=people%2Fstevee%2Fipfire-2.x.git ipset-functions.pl: Introduce new functions library. This library uses the perl-IPset bindings and contains a lot of additional functions to deal with ipsets within perl. Signed-off-by: Stefan Schantl --- diff --git a/config/cfgroot/ipset-functions.pl b/config/cfgroot/ipset-functions.pl new file mode 100644 index 000000000..281f8f73c --- /dev/null +++ b/config/cfgroot/ipset-functions.pl @@ -0,0 +1,235 @@ +#!/usr/bin/perl -w +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007-2023 IPFire Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +package IPSet::Functions; + +use IPSet; +use strict; + +# Create ipset session +my $session = &init(); + +# +## Tiny function to init an ipset session. +# +sub init () { + # Initialize an ipset session + my $session = &IPSet::init(); + + # Return the session. + return $session; +} + +# +## Function to cleanup unused ipsets +# +sub cleanup_ipsets () { + # Get all used ipsets. + my @ipsets = &IPSet::get_sets($session); + + # Loop through the array of loaded ipsets. + foreach my $set (@ipsets) { + # Get set details. + my $set_data = &IPSet::get_set_data($session, $set); + + # Get the amount of how often the set is referenced. + my $refcount = $set_data->{references}; + + # If the refcount is zero the set is not used and can be + # unloaded. + if ($refcount eq "0") { + print "Delete unused set: $set\n"; + + # Unload/Destroy the set. + &IPSet::delete_set($session, $set); + } + } +} + +# +## Function to check if a given setname is loaded by +## the linux kernel. +# +sub ipset_exists ($) { + my ($name) = @_; + + # Call function from IPSet binding and return the result. + return (&IPSet::setname_exists($session, $name)); +} + +# +## Function to create a new empty ipset. +# +sub ipset_create ($$$$) { + my ($name, $type, $hashsize, $maxelem) = @_; + + # Call function from the IPSet bindings to create the set. + my $error = &IPSet::create_set($session, $name, $type, $hashsize, $maxelem); + + # Check if there was an error. + unless ($error) { + return "Could not create set $name"; + } + + # Everything worked well. + return; +} + +# +## Function to flush the items of a given set. +# +sub ipset_flush($) { + my ($set) = @_; + + # Call the function from the IPSet bindings and return the result. + return &IPSet::flush_set($session, $set); +} + +# +## Function to swap two sets. +# +sub ipset_swap ($$) { + my ($set1, $set2) = @_; + + # Call the function from the IPSet bindings and return the result. + return &IPSet::swap_set($session, $set1, $set2); +} + +# +## Function to rename a given set. +# +sub ipset_rename($$) { + my ($oldname, $newname) = @_; + + # Call the function from the IPSet bindings and return the result. + return &IPSet::rename_set($session, $oldname, $newname); +} + +# +## Function to remove (destroy) a given set. +# +sub ipset_remove($) { + my ($set) = @_; + + # Call the function from the IPSet bindings and return the result. + return &IPSet::delete_set($session, $set); +} + +# +## Function to add the elements of an given array to the desired set. +# +sub add_to_set ($@) { + my ($set, @data) = @_; + + # XXX - Currently only adding IPv4 addresses to a set is supported. + # Add more allowed datatypes at a later time if neccessary. + # + # Loop through the data array. + foreach my $element (@data) { + # Remove any newlines. + chomp($element); + + # Add the address to the given set. + &IPSet::add_address($session, $set, $element); + } +} + +# +## Function to get the details of a given set. +# +sub ipset_set_data($) { + my ($name) = @_; + + # Call the function from the IPSet bindings and return the result. + return &IPSet::get_set_data($session, $name); +} + +# +## Tiny helper function to detect the hashtype, based on the given data. +# +sub detect_hashtype (@) { + my @data = @_; + + # XXX - Currently we only support sets with single addresses and/or networks. + # Improve the detection if neccessary at a later time. + # + # Default to a hashtype of hash:ip for only single addresses. + my $hashtype = "hash:ip"; + + # Use perl grep to check if a "/" could be found in the data. + # In this case the list contains at least one network and we have to use the + # hash:net as hashtype. + if(grep(/\//, @data)) { + # The set contains a network, switching hashtype. + $hashtype = "hash:net"; + } + + return $hashtype; +} + +# +## Helper function to proper calculate the hashsize. +# +sub calculate_hashsize($) { + my ($list_entries) = @_; + + my $hashsize = 1; + $hashsize <<= 1 while ($hashsize < $list_entries); + + # Return the calculated hashsize. + return $hashsize; +} + +# +## Helper function to calculate a randum set name. +# +sub random_setname () { + # Defaults to a lenght of 10 characters. + my $lenght = 10; + + # Set allowd characters and digits. + my @chars = ('0'..'9', 'A'..'Z'); + + # Variable to store the random string. + my $string; + + # Loop over the desired lenght. + while($lenght--){ + # Add a random item of the alowed chars array to + # the string. + $string .= $chars[rand @chars] + }; + + # Return the generated random string. + return $string; +} + +# Custom END declaration which will be executed when perl +# ends, to release the opened ipset session. +END { + # Check if a database handle exists. + if ($session) { + # Destroy the session. + &IPSet::DESTROY($session); + } +} + +1; diff --git a/config/rootfiles/common/configroot b/config/rootfiles/common/configroot index b920dd248..92ddeb53d 100644 --- a/config/rootfiles/common/configroot +++ b/config/rootfiles/common/configroot @@ -85,6 +85,7 @@ var/ipfire/ipblocklist-functions.pl var/ipfire/ipblocklist #var/ipfire/ipblocklist/modified #var/ipfire/ipblocklist/settings +var/ipfire/ipset-functions.pl var/ipfire/key var/ipfire/lang.pl var/ipfire/langs diff --git a/lfs/configroot b/lfs/configroot index 66efe04b5..42c4ea8ec 100644 --- a/lfs/configroot +++ b/lfs/configroot @@ -81,6 +81,7 @@ $(TARGET) : cp $(DIR_SRC)/config/cfgroot/location-functions.pl $(CONFIG_ROOT)/ cp $(DIR_SRC)/config/cfgroot/ipblocklist-functions.pl $(CONFIG_ROOT)/ cp $(DIR_SRC)/config/cfgroot/ids-functions.pl $(CONFIG_ROOT)/ + cp $(DIR_SRC)/config/cfgroot/ipsec-functions.pl $(CONFIG_ROOT)/ cp $(DIR_SRC)/config/cfgroot/lang.pl $(CONFIG_ROOT)/ cp $(DIR_SRC)/config/cfgroot/countries.pl $(CONFIG_ROOT)/ cp $(DIR_SRC)/config/cfgroot/graphs.pl $(CONFIG_ROOT)/