summaryrefslogtreecommitdiff
path: root/lib/Vyatta/IpTables/IpSet.pm
diff options
context:
space:
mode:
authorStig Thormodsrud <stig@io.vyatta.com>2009-02-02 19:50:21 -0800
committerStig Thormodsrud <stig@io.vyatta.com>2009-02-02 19:50:21 -0800
commit299adf5bb38fa7e026ccd3604fc05ba812520700 (patch)
tree1df602c721dafae568a14b79d4af9b58e6c0e4b3 /lib/Vyatta/IpTables/IpSet.pm
parent3ea4540b14ad999386c4b359a963bf362d545ee2 (diff)
downloadvyatta-cfg-firewall-299adf5bb38fa7e026ccd3604fc05ba812520700.tar.gz
vyatta-cfg-firewall-299adf5bb38fa7e026ccd3604fc05ba812520700.zip
Add 1st pass of firewall group support (ipset netfilter module
integration).
Diffstat (limited to 'lib/Vyatta/IpTables/IpSet.pm')
-rwxr-xr-xlib/Vyatta/IpTables/IpSet.pm225
1 files changed, 225 insertions, 0 deletions
diff --git a/lib/Vyatta/IpTables/IpSet.pm b/lib/Vyatta/IpTables/IpSet.pm
new file mode 100755
index 0000000..c8508c6
--- /dev/null
+++ b/lib/Vyatta/IpTables/IpSet.pm
@@ -0,0 +1,225 @@
+#!/usr/bin/perl
+#
+# Module: IpSet.pm
+#
+# **** License ****
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# 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.
+#
+# This code was originally developed by Vyatta, Inc.
+# Portions created by Vyatta are Copyright (C) 2009 Vyatta, Inc.
+# All Rights Reserved.
+#
+# Author: Stig Thormodsrud
+# Date: January 2009
+# Description: vyatta interface to ipset
+#
+# **** End License ****
+#
+
+package Vyatta::IpTables::IpSet;
+
+use Vyatta::Config;
+use Vyatta::TypeChecker;
+use Vyatta::Misc;
+use NetAddr::IP;
+
+use strict;
+use warnings;
+
+my %fields = (
+ _name => undef,
+ _type => undef,
+ _debug => undef,
+);
+
+my $logger = 'logger -t IpSet.pm -p local0.warn --';
+
+sub new {
+ my ($that, $name, $type) = @_;
+
+ my $class = ref ($that) || $that;
+ my $self = {
+ %fields,
+ };
+ $self->{_name} = $name;
+ $self->{_type} = $type;
+
+ bless $self, $class;
+ return $self;
+}
+
+sub debug {
+ my ($self, $onoff) = @_;
+
+ $self->{_debug} = undef;
+ $self->{_debug} = 1 if $onoff eq "on";
+}
+
+sub exists {
+ my ($self) = @_;
+
+ return 0 if ! defined $self->{_name};
+ my $func = (caller(0))[3];
+ my $cmd = "ipset -L $self->{_name}";
+ my $rc = system("sudo $cmd > /dev/null &>2");
+ system("$logger [$func] [$cmd] = [$rc]") if defined $self->{_debug};
+ return $rc ? 0 : 1;
+}
+
+sub create {
+ my ($self) = @_;
+
+ return "Error: undefined group name" if ! defined $self->{_name};
+ return "Error: undefined group type" if ! defined $self->{_type};
+ return "Error: group [$self->{_name}] already exists" if $self->exists();
+
+ my $ipset_param;
+ if ($self->{_type} eq 'address') {
+ $ipset_param = 'iphash';
+ } elsif ($self->{_type} eq 'network') {
+ $ipset_param = 'nethash';
+ } elsif ($self->{_type} eq 'port') {
+ $ipset_param = 'portmap --from 1 --to 65535';
+ } else {
+ return "Error: invalid group type";
+ }
+
+ my $func = (caller(0))[3];
+ my $cmd = "ipset -N $self->{_name} $ipset_param";
+ my $rc = system("sudo $cmd");
+ system("$logger [$func] [$cmd] = [$rc]") if defined $self->{_debug};
+ return "Error: call to ipset failed [$rc]" if $rc;
+ return undef;
+}
+
+sub references {
+ my ($self) = @_;
+
+ return 0 if ! $self->exists();
+ my @lines = `sudo ipset -L $self->{_name}`;
+ foreach my $line (@lines) {
+ if ($line =~ /^References:\s+(\d+)$/) {
+ return $1;
+ }
+ }
+ return 0;
+}
+
+sub delete {
+ my ($self) = @_;
+
+ return "Error: undefined group name" if ! defined $self->{_name};
+ return "Error: group [$self->{_name}] doesn't exists\n" if !$self->exists();
+
+ my $refs = $self->references();
+ return "Error: group [$self->{_name}] still in use.\n" if $refs != 0;
+
+ my $func = (caller(0))[3];
+ my $cmd = "ipset -X $self->{_name}";
+ my $rc = system("sudo $cmd");
+ system("$logger [$func] [$cmd] = [$rc]") if defined $self->{_debug};
+ return "Error: call to ipset failed [$rc]" if $rc;
+ return undef;
+}
+
+sub check_member {
+ my ($self, $member) = @_;
+
+ return "Error: undefined group name" if ! defined $self->{_name};
+ return "Error: undefined group type" if ! defined $self->{_type};
+
+ if ($self->{_type} eq 'address') {
+ if (!Vyatta::TypeChecker::validateType('ipv4', $member, 1)) {
+ return "Error: [$member] isn't valid IPv4 address\n";
+ }
+ } elsif ($self->{_type} eq 'network') {
+ if (!Vyatta::TypeChecker::validateType('ipv4net', $member, 1)) {
+ return "Error: [$member] isn't valid IPv4 network\n";
+ }
+ } elsif ($self->{_type} eq 'port') {
+ if ($member =~ /^\d/) {
+ my ($success, $err) = Vyatta::Misc::isValidPortNumber($member);
+ if (!defined $success) {
+ return "Error: [$member] isn't valid port number\n";
+ }
+ } else {
+ my ($success, $err) = Vyatta::Misc::isValidPortName($member);
+ if (!defined $success) {
+ return "Error: [$member] isn't valid port name\n";
+ }
+ }
+ } else {
+ return "Error: invalid set type [$self->{_type}]";
+ }
+ return undef;
+}
+
+sub member_exists {
+ my ($self, $member) = @_;
+
+ my $func = (caller(0))[3];
+ my $cmd = "ipset -T $self->{_name} $member -q";
+ my $rc = system("sudo $cmd");
+ system("$logger [$func] [$cmd] = [$rc]") if defined $self->{_debug};
+ return $rc ? 0 : 1;
+}
+
+sub add_member {
+ my ($self, $member) = @_;
+
+ return "Error: undefined group name" if ! defined $self->{_name};
+ return "Error: group [$self->{_name}] doesn't exists\n" if !$self->exists();
+
+ if ($self->member_exists($member)) {
+ return "Error: member [$member] already exists in [$self->{_name}]\n";
+ }
+ my $func = (caller(0))[3];
+ my $cmd = "ipset -A $self->{_name} $member";
+ my $rc = system("sudo $cmd");
+ system("$logger [$func] [$cmd] = [$rc]") if defined $self->{_debug};
+ return "Error: call to ipset failed [$rc]" if $rc;
+ return undef;
+}
+
+sub delete_member {
+ my ($self, $member) = @_;
+
+ return "Error: undefined group name" if ! defined $self->{_name};
+ return "Error: group [$self->{_name}] doesn't exists\n" if !$self->exists();
+
+ if (!$self->member_exists($member)) {
+ return "Error: member [$member] doesn't exists in [$self->{_name}]\n";
+ }
+ my $func = (caller(0))[3];
+ my $cmd = "ipset -D $self->{_name} $member";
+ my $rc = system("sudo $cmd");
+ system("$logger [$func] [$cmd] = [$rc]") if defined $self->{_debug};
+ return "Error: call to ipset failed [$rc]" if $rc;
+ return undef;
+}
+
+sub rule {
+ my ($self, $direction) = @_;
+
+ if (! $self->exists()) {
+ my $rc = $self->create();
+ return (undef, $rc) if $rc;
+ }
+
+ my $srcdst;
+ my $grp = $self->{_name};
+ $srcdst = 'src' if $direction eq 'source';
+ $srcdst = 'dst' if $direction eq 'destination';
+
+ return (undef, "Invalid direction [$direction]") if ! defined $srcdst;
+ return ("-m set --set $grp $srcdst ", );
+}
+
+1;