--- /dev/null
+#!/usr/bin/perl -w
+###############################################################################
+# #
+# IPFire.org - A linux based firewall #
+# Copyright (C) 2007-2023 IPFire Team <info@ipfire.org> #
+# #
+# 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 <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+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;