]> git.ipfire.org Git - people/stevee/perl-ipset.git/commitdiff
Initial commit.
authorStefan Schantl <stefan.schantl@ipfire.org>
Sun, 14 Aug 2022 16:28:54 +0000 (18:28 +0200)
committerStefan Schantl <stefan.schantl@ipfire.org>
Sun, 14 Aug 2022 16:28:54 +0000 (18:28 +0200)
The module has the following support:
* Creating new sets.
* Checking if a set exists.

Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
IPSet.xs [new file with mode: 0644]
MANIFEST [new file with mode: 0644]
Makefile.PL [new file with mode: 0644]
lib/IPSet.pm [new file with mode: 0644]
t/IPSet.t [new file with mode: 0644]
typemap [new file with mode: 0644]

diff --git a/IPSet.xs b/IPSet.xs
new file mode 100644 (file)
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 <stdio.h>
+#include <string.h>
+
+#include <libipset/ipset.h>
+#include <libipset/data.h>
+#include <libipset/session.h>
+#include <libipset/types.h>
+
+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 (file)
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 (file)
index 0000000..d28c822
--- /dev/null
@@ -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 <stefan.schantl@ipfire.org>',
+    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 (file)
index 0000000..649e267
--- /dev/null
@@ -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 (file)
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 (file)
index 0000000..4f797b8
--- /dev/null
+++ b/typemap
@@ -0,0 +1,3 @@
+TYPEMAP
+struct ipset_session * T_PTRREF
+struct ipset_type * T_PTRREF