summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rwxr-xr-xlib/Vyatta/IpTables/AddressFilter.pm210
1 files changed, 210 insertions, 0 deletions
diff --git a/lib/Vyatta/IpTables/AddressFilter.pm b/lib/Vyatta/IpTables/AddressFilter.pm
new file mode 100755
index 0000000..9b1e318
--- /dev/null
+++ b/lib/Vyatta/IpTables/AddressFilter.pm
@@ -0,0 +1,210 @@
+#!/usr/bin/perl
+
+# Author: An-Cheng Huang <ancheng@vyatta.com>
+# Date: 2007
+# Description: IP tables address filter
+
+# **** 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) 2006, 2007, 2008 Vyatta, Inc.
+# All Rights Reserved.
+# **** End License ****
+
+package Vyatta::IpTables::AddressFilter;
+
+require Vyatta::Config;
+use Vyatta::Misc;
+use Vyatta::TypeChecker;
+
+use strict;
+use warnings;
+
+my %_protocolswithports = (
+ tcp => 1,
+ udp => 1,
+ 6 => 1,
+ 17 => 1,
+);
+
+my %fields = (
+ _srcdst => undef,
+ _range_start => undef,
+ _range_stop => undef,
+ _network => undef,
+ _address => undef,
+ _port => undef,
+ _protocol => undef,
+ _src_mac => undef,
+);
+
+sub new {
+ my $that = shift;
+ my $class = ref ($that) || $that;
+ my $self = {
+ %fields,
+ };
+
+ bless $self, $class;
+ return $self;
+}
+
+sub setup {
+ my ($self, $level) = @_;
+ my $config = new Vyatta::Config;
+
+ $config->setLevel("$level");
+
+ # setup needed parent nodes
+ $self->{_srcdst} = $config->returnParent("..");
+ $self->{_protocol} = $config->returnValue(".. protocol");
+
+ # setup address filter nodes
+ $self->{_address} = $config->returnValue("address");
+ $self->{_network} = undef;
+ $self->{_range_start} = undef;
+ $self->{_range_stop} = undef;
+ if (defined($self->{_address})) {
+ if ($self->{_address} =~ /\//) {
+ $self->{_network} = $self->{_address};
+ $self->{_address} = undef;
+ } elsif ($self->{_address} =~ /^([^-]+)-([^-]+)$/) {
+ $self->{_range_start} = $1;
+ $self->{_range_stop} = $2;
+ $self->{_address} = undef;
+ }
+ }
+
+ $self->{_port} = $config->returnValue("port");
+ $self->{_src_mac} = $config->returnValue("mac-address");
+
+ return 0;
+}
+
+sub setupOrig {
+ my ($self, $level) = @_;
+ my $config = new Vyatta::Config;
+
+ $config->setLevel("$level");
+
+ # setup needed parent nodes
+ $self->{_srcdst} = $config->returnParent("..");
+ $self->{_protocol} = $config->returnOrigValue(".. protocol");
+
+ # setup address filter nodes
+ $self->{_address} = $config->returnOrigValue("address");
+ $self->{_network} = undef;
+ $self->{_range_start} = undef;
+ $self->{_range_stop} = undef;
+ if (defined($self->{_address})) {
+ if ($self->{_address} =~ /\//) {
+ $self->{_network} = $self->{_address};
+ $self->{_address} = undef;
+ } elsif ($self->{_address} =~ /^([^-]+)-([^-]+)$/) {
+ $self->{_range_start} = $1;
+ $self->{_range_stop} = $2;
+ $self->{_address} = undef;
+ }
+ }
+
+ $self->{_port} = $config->returnOrigValue("port");
+ $self->{_src_mac} = $config->returnValue("mac-address");
+
+ return 0;
+}
+
+sub print {
+ my ($self) = @_;
+
+ print "srcdst: $self->{_srcdst}\n" if defined $self->{_srcdst};
+ print "range start: $self->{_range_start}\n" if defined $self->{_range_start};
+ print "range stop: $self->{_range_stop}\n" if defined $self->{_range_stop};
+ print "network: $self->{_network}\n" if defined $self->{_network};
+ print "address: $self->{_address}\n" if defined $self->{_address};
+ print "port: $self->{_port}\n" if defined $self->{_port};
+ print "protocol: $self->{_protocol}\n" if defined $self->{_protocol};
+ print "src-mac: $self->{_src_mac}\n" if defined $self->{_src_mac};
+
+ return 0;
+}
+
+sub rule {
+ my ($self) = @_;
+ my $rule = "";
+ my $can_use_port = 1;
+
+ if (!defined($self->{_protocol})
+ || !defined($_protocolswithports{$self->{_protocol}})) {
+ $can_use_port = 0;
+ }
+
+ if (($self->{_srcdst} eq "source") && (defined($self->{_src_mac}))) {
+ # handle src mac
+ my $str = $self->{_src_mac};
+ $str =~ s/^\!(.*)$/! $1/;
+ $rule .= "-m mac --mac-source $str ";
+ }
+
+ # set the address filter parameters
+ if (defined($self->{_network})) {
+ my $str = $self->{_network};
+ return (undef, "\"$str\" is not a valid IP subnet")
+ if (!VyattaTypeChecker::validateType('ipv4net_negate', $str, 1));
+ $str =~ s/^\!(.*)$/! $1/;
+ $rule .= "--$self->{_srcdst} $str ";
+ } elsif (defined($self->{_address})) {
+ my $str = $self->{_address};
+ return (undef, "\"$str\" is not a valid IP address")
+ if (!VyattaTypeChecker::validateType('ipv4_negate', $str, 1));
+ $str =~ s/^\!(.*)$/! $1/;
+ $rule .= "--$self->{_srcdst} $str ";
+ } elsif ((defined $self->{_range_start}) && (defined $self->{_range_stop})) {
+ my $start = $self->{_range_start};
+ my $stop = $self->{_range_stop};
+ return (undef, "\"$start-$stop\" is not a valid IP range")
+ if (!VyattaTypeChecker::validateType('ipv4_negate', $start, 1)
+ || !VyattaTypeChecker::validateType('ipv4', $stop, 1));
+ my $negate = '';
+ if ($self->{_range_start} =~ /^!(.*)$/) {
+ $start = $1;
+ $negate = '! '
+ }
+ if ("$self->{_srcdst}" eq "source") {
+ $rule .= ("-m iprange $negate--src-range $start-$self->{_range_stop} ");
+ }
+ elsif ("$self->{_srcdst}" eq "destination") {
+ $rule .= ("-m iprange $negate--dst-range $start-$self->{_range_stop} ");
+ }
+ }
+
+ my ($port_str, $port_err)
+ = VyattaMisc::getPortRuleString($self->{_port}, $can_use_port,
+ ($self->{_srcdst} eq "source") ? "s" : "d",
+ $self->{_protocol});
+ return (undef, $port_err) if (!defined($port_str));
+ $rule .= $port_str;
+ return ($rule, undef);
+}
+
+sub outputXmlElem {
+ my ($name, $value, $fh) = @_;
+ print $fh " <$name>$value</$name>\n";
+}
+
+sub outputXml {
+ my ($self, $prefix, $fh) = @_;
+ outputXmlElem("${prefix}_addr", $self->{_address}, $fh);
+ outputXmlElem("${prefix}_net", $self->{_network}, $fh);
+ outputXmlElem("${prefix}_addr_start", $self->{_range_start}, $fh);
+ outputXmlElem("${prefix}_addr_stop", $self->{_range_stop}, $fh);
+ outputXmlElem("${prefix}_port", $self->{_port}, $fh);
+}
+