From: Stefan Schantl Date: Sun, 14 Aug 2022 16:28:54 +0000 (+0200) Subject: Initial commit. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5e680e0ed16a8537c51f5d65456038906a533f9a;p=people%2Fstevee%2Fperl-ipset.git Initial commit. The module has the following support: * Creating new sets. * Checking if a set exists. Signed-off-by: Stefan Schantl --- 5e680e0ed16a8537c51f5d65456038906a533f9a diff --git a/IPSet.xs b/IPSet.xs new file mode 100644 index 0000000..40d6295 --- /dev/null +++ b/IPSet.xs @@ -0,0 +1,156 @@ +#define PERL_NO_GET_CONTEXT +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#include +#include + +#include +#include +#include +#include + +MODULE = IPSet PACKAGE = IPSet + +struct ipset_session * +init() + CODE: + struct ipset_session *session; + + // Load IPSet types. + ipset_load_types(); + + // Init a new IPSet session + session = ipset_session_init(NULL, NULL); + + + // Abort if the session could not be initialized. + if (!session) { + croak("Cannot initialize ipset session.\n"); + } + + RETVAL = session; + OUTPUT: + RETVAL + +# +# Functions to directly deal with sets. +# +bool create_set(session, setname, typename, hashsize, maxelem) + struct ipset_session *session; + const char *setname; + const char *typename; + int hashsize; + int maxelem; + + PREINIT: + const struct ipset_type *type; + + // Family current is hardcoded to IPv4. + int family = NFPROTO_IPV4; + + CODE: + // Load everything + ipset_load_types(); + + // Assin the setname to the session data. + int r = ipset_session_data_set(session, IPSET_SETNAME, setname); + if (r < 0) { + printf("Could not set ipset name: %s\n", + ipset_session_report_msg(session)); + + return; + } + + // Assign additinal options to the session data. + r = ipset_parse_typename(session, IPSET_OPT_TYPE, typename); + if (r < 0) { + printf("Could not set set type: %s\n", + ipset_session_report_msg(session)); + + return; + } + + type = ipset_type_get(session, IPSET_CMD_CREATE); + if (!type) { + printf("Could not get hash type.\n"); + + return; + } + + r = ipset_session_data_set(session, IPSET_OPT_FAMILY, &family); + if (r < 0) { + printf("Could not set family: %s\n", + ipset_session_report_msg(session)); + + return; + } + + r = ipset_session_data_set(session, IPSET_OPT_HASHSIZE, &hashsize); + if (r < 0) { + printf("Could not set hashsize: %s\n", + ipset_session_report_msg(session)); + + return; + } + + r = ipset_session_data_set(session, IPSET_OPT_MAXELEM, &maxelem); + if (r < 0) { + printf("Could not set maxelem: %s\n", + ipset_session_report_msg(session)); + + return; + } + + r = ipset_cmd(session, IPSET_CMD_CREATE, 0); + if (r < 0) { + printf("Command failed: %s\n", + ipset_session_report_msg(session)); + + RETVAL = false; + } + + RETVAL = true; + + OUTPUT: + RETVAL + + +bool +setname_exists(session, setname) + struct ipset_session *session; + const char *setname; + + PREINIT: + enum ipset_cmd cmd = IPSET_CMD_HEADER; + + CODE: + // Assign the setname as session data. + int r = ipset_session_data_set(session, IPSET_SETNAME, setname); + if (r < 0) { + printf("Could not set setname: %s\n", + ipset_session_report_msg(session)); + } + + r = ipset_cmd(session, cmd, 0); + if (r < 0 ) { + printf("Command failed: %s\n", + ipset_session_report_msg(session)); + + RETVAL = false; + } + + RETVAL = true; + + OUTPUT: + RETVAL + + +void +DESTROY(session) + struct ipset_session *session; + + CODE: + // Release IPSet session + ipset_session_fini(session); diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..f0fb0d9 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,6 @@ +IPSet.xs +Makefile.PL +MANIFEST +typemap +t/IPSet.t +lib/IPSet.pm diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..d28c822 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,16 @@ +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + NAME => 'IPSet', + VERSION_FROM => 'lib/IPSet.pm', + PREREQ_PM => {}, + ABSTRACT_FROM => 'lib/IPSet.pm', + AUTHOR => 'Stefan Schantl ', + LICENSE => 'lgpl', + LIBS => ['-lipset', '-lmnl'], + DEFINE => '', # e.g., '-DHAVE_SOMETHING' + #INC => '-I. -I../../', + # Un-comment this if you add C files to link with later: + # OBJECT => '$(O_FILES)', # link all the C files too +); diff --git a/lib/IPSet.pm b/lib/IPSet.pm new file mode 100644 index 0000000..649e267 --- /dev/null +++ b/lib/IPSet.pm @@ -0,0 +1,69 @@ +package IPSet; + +use 5.028001; +use strict; +use warnings; + +require Exporter; + +our @ISA = qw(Exporter); + +# Items to export into callers namespace by default. Note: do not export +# names by default without a very good reason. Use EXPORT_OK instead. +# Do not simply export all your public functions/methods/constants. + +# This allows declaration use Location ':all'; +# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK +# will save memory. +our %EXPORT_TAGS = ( 'all' => [ qw() ] ); + +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); + +our @EXPORT = qw(); + +our $VERSION = '0.01'; + +require XSLoader; +XSLoader::load('IPSet', $VERSION); + +# Preloaded methods go here. + +1; +__END__ + +=head1 NAME + +perl-ipset - Provides a simple interface to kernel IPSet framework using libipset. + +=head1 SYNOPSIS + + use IPSet; + +=head1 DESCRIPTION + +perl-ipset is a simple interface to the kernel IPset subsystem, provided by the Netfilter framework. + +More details on the project website of IPSet: https://ipset.netfilter.org/ + +=head2 EXPORT + +None by default. + +=head1 SEE ALSO + +https://git.ipfire.org/?p=people/stevee/perl-ipset.git;a=summary + +=head1 AUTHOR + +Stefan Schantl, stefan.schantl@ipfire.org + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2022 by Stefan Schantl + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself, either Perl version 5.28.1 or, +at your option, any later version of Perl 5 you may have available. + + +=cut diff --git a/t/IPSet.t b/t/IPSet.t new file mode 100644 index 0000000..3501bc3 --- /dev/null +++ b/t/IPSet.t @@ -0,0 +1,31 @@ +# Before 'make install' is performed this script should be runnable with +# 'make test'. After 'make install' it should work as 'perl Location.t' + +######################### + +# change 'tests => 1' to 'tests => last_test_to_print'; + +use strict; +use warnings; + +use Test::More tests => 3; +BEGIN { use_ok('IPSet') }; + +######################### + +# Insert your test code below, the Test::More module is use()ed here so read +# its man page ( perldoc Test::More ) for help writing this test script. + +# Name of the testset. +my $setname = "TEST"; + +# Init the IPSet module and create a session. +my $session = &IPSet::init(); + +# Create new IPSet. +my $create_set = &IPSet::create_set($session, $setname, "hash:ip", "1024", "10"); +ok($create_set, "Sucessfully created set: $setname."); + +# Check if the testset exists. +my $exists = &IPSet::setname_exists($session, $setname); +ok($exists, "The testset exists."); diff --git a/typemap b/typemap new file mode 100644 index 0000000..4f797b8 --- /dev/null +++ b/typemap @@ -0,0 +1,3 @@ +TYPEMAP +struct ipset_session * T_PTRREF +struct ipset_type * T_PTRREF