summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniil Baturin <daniil.baturin@vyatta.com>2011-10-11 14:27:39 +0700
committerDaniil Baturin <daniil.baturin@vyatta.com>2011-10-11 14:27:39 +0700
commit6d93aa47b25ca83235ba59a532d2c461874e0fea (patch)
treeb6a92bf88b4cd001cdca88a57e7566088e5133c7 /lib
parentb06af0f993baafd0eaf49249ea08a1db015f500b (diff)
downloadvyatta-nat-6d93aa47b25ca83235ba59a532d2c461874e0fea.tar.gz
vyatta-nat-6d93aa47b25ca83235ba59a532d2c461874e0fea.zip
Bug 5682: Remove old NatRule.pm module now splitted into source and destination parts
Diffstat (limited to 'lib')
-rw-r--r--lib/Vyatta/NatRule.pm616
1 files changed, 0 insertions, 616 deletions
diff --git a/lib/Vyatta/NatRule.pm b/lib/Vyatta/NatRule.pm
deleted file mode 100644
index 5c3d525..0000000
--- a/lib/Vyatta/NatRule.pm
+++ /dev/null
@@ -1,616 +0,0 @@
-package Vyatta::NatRule;
-
-use strict;
-use lib "/opt/vyatta/share/perl5";
-require Vyatta::Config;
-require Vyatta::IpTables::AddressFilter;
-use Vyatta::Misc;
-use Vyatta::TypeChecker;
-
-my $src = new Vyatta::IpTables::AddressFilter;
-my $dst = new Vyatta::IpTables::AddressFilter;
-
-my %fields = (
- _rule_number => undef,
- _type => undef,
- _orig_type => undef,
- _inbound_if => undef,
- _outbound_if => undef,
- _proto => undef,
- _exclude => undef,
- _disable => undef,
- _log => undef,
- _inside_addr => {
- _addr => undef,
- _range => {
- _start => undef,
- _stop => undef,
- },
- _port => undef,
- },
- _outside_addr => {
- _addr => undef,
- _range => {
- _start => undef,
- _stop => undef,
- },
- _port => 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");
-
- $self->{_rule_number} = $config->returnParent("..");
- $self->{_type} = $config->returnValue("type");
- $self->{_orig_type} = $config->returnOrigValue("type");
- $self->{_inbound_if} = $config->returnValue("inbound-interface");
- $self->{_outbound_if} = $config->returnValue("outbound-interface");
- $self->{_proto} = $config->returnValue("protocol");
- $self->{_exclude} = $config->exists("exclude");
- $self->{_disable} = $config->exists("disable");
- $self->{_log} = $config->returnValue("log");
-
- $self->{_inside_addr}->{_addr}
- = $config->returnValue("inside-address address");
- $self->{_inside_addr}->{_range}->{_start} = undef;
- $self->{_inside_addr}->{_range}->{_stop} = undef;
- if (defined($self->{_inside_addr}->{_addr})
- && $self->{_inside_addr}->{_addr} =~ /^([^-]+)-([^-]+)$/) {
- $self->{_inside_addr}->{_range}->{_start} = $1;
- $self->{_inside_addr}->{_range}->{_stop} = $2;
- $self->{_inside_addr}->{_addr} = undef;
- }
- $self->{_inside_addr}->{_port}
- = $config->returnValue("inside-address port");
-
- $self->{_outside_addr}->{_addr}
- = $config->returnValue("outside-address address");
- $self->{_outside_addr}->{_range}->{_start} = undef;
- $self->{_outside_addr}->{_range}->{_stop} = undef;
- if (defined($self->{_outside_addr}->{_addr})
- && $self->{_outside_addr}->{_addr} =~ /^([^-]+)-([^-]+)$/) {
- $self->{_outside_addr}->{_range}->{_start} = $1;
- $self->{_outside_addr}->{_range}->{_stop} = $2;
- $self->{_outside_addr}->{_addr} = undef;
- }
- $self->{_outside_addr}->{_port}
- = $config->returnValue("outside-address port");
-
- $src->setup("$level source");
- $dst->setup("$level destination");
-
- return 0;
-}
-
-sub setupOrig {
- my ( $self, $level ) = @_;
- my $config = new Vyatta::Config;
-
- $config->setLevel("$level");
-
- $self->{_rule_number} = $config->returnParent("..");
- $self->{_type} = $config->returnOrigValue("type");
- $self->{_orig_type} = $config->returnOrigValue("type");
- $self->{_inbound_if} = $config->returnOrigValue("inbound-interface");
- $self->{_outbound_if} = $config->returnOrigValue("outbound-interface");
- $self->{_proto} = $config->returnOrigValue("protocol");
- $self->{_exclude} = $config->existsOrig("exclude");
- $self->{_disable} = $config->existsOrig("disable");
- $self->{_log} = $config->returnOrigValue("log");
-
- $self->{_inside_addr}->{_addr}
- = $config->returnOrigValue("inside-address address");
- $self->{_inside_addr}->{_range}->{_start} = undef;
- $self->{_inside_addr}->{_range}->{_stop} = undef;
- if (defined($self->{_inside_addr}->{_addr})
- && $self->{_inside_addr}->{_addr} =~ /^([^-]+)-([^-]+)$/) {
- $self->{_inside_addr}->{_range}->{_start} = $1;
- $self->{_inside_addr}->{_range}->{_stop} = $2;
- $self->{_inside_addr}->{_addr} = undef;
- }
- $self->{_inside_addr}->{_port}
- = $config->returnOrigValue("inside-address port");
-
- $self->{_outside_addr}->{_addr}
- = $config->returnOrigValue("outside-address address");
- $self->{_outside_addr}->{_range}->{_start} = undef;
- $self->{_outside_addr}->{_range}->{_stop} = undef;
- if (defined($self->{_outside_addr}->{_addr})
- && $self->{_outside_addr}->{_addr} =~ /^([^-]+)-([^-]+)$/) {
- $self->{_outside_addr}->{_range}->{_start} = $1;
- $self->{_outside_addr}->{_range}->{_stop} = $2;
- $self->{_outside_addr}->{_addr} = undef;
- }
- $self->{_outside_addr}->{_port}
- = $config->returnOrigValue("outside-address port");
-
- $src->setupOrig("$level source");
- $dst->setupOrig("$level destination");
-
- return 0;
-}
-
-sub is_disabled {
- my $self = shift;
- return 1 if defined $self->{_disable};
- return 0;
-}
-
-sub get_num_ipt_rules {
- my $self = shift;
- return 0 if defined $self->{_disable};
- my $ipt_rules = 1;
- if ("$self->{_log}" eq 'enable') {
- $ipt_rules++;
- }
- if (defined $self->{_proto} && $self->{_proto} eq 'tcp_udp') {
- $ipt_rules++;
- $ipt_rules++ if $self->{_log} eq 'enable';
- }
- return $ipt_rules;
-}
-
-my %nat_type_hash = (
- 'SNAT' => 'SNAT',
- 'DNAT' => 'DNAT',
- 'MASQUERADE' => 'MASQ',
- 'RETURN' => 'EXCLUDE',
- 'NETMAP' => 'NETMAP',
-);
-
-sub get_log_prefix {
- my ($rule_num, $jump_target) = @_;
-
- # In iptables it allows a 29 character log_prefix, but we ideally
- # want to include "[nat-type-$rule_num] "
- # 1 3 1 7 1 4 1 1 = 19
- # so no truncation is needed.
- my $nat_type = $nat_type_hash{$jump_target};
- my $log_prefix = "[NAT-$rule_num-$nat_type] ";
- return $log_prefix;
-}
-
-# returns (error, @rules)
-sub rule_str {
- my ($self) = @_;
- my $rule_str = "";
- my $can_use_port = 1;
- my $jump_target = '';
- my $jump_param = '';
- my $use_netmap = 0;
- my $tcp_and_udp = 0;
-
- if (!defined($self->{_proto}) ||
- (($self->{_proto} ne "tcp_udp")
- && ($self->{_proto} ne "tcp") && ($self->{_proto} ne "6")
- && ($self->{_proto} ne "udp") && ($self->{_proto} ne "17"))) {
- $can_use_port = 0;
- }
- if (($self->{_type} eq "source") || ($self->{_type} eq "masquerade")) {
- return ('cannot specify inbound interface with '
- . '"masquerade" or "source" rules', undef)
- if (defined($self->{_inbound_if}));
-
- if (defined($self->{_inside_addr}->{_addr}) ||
- defined($self->{_inside_addr}->{_port}) ||
- (defined($self->{_inside_addr}->{_range}->{_start})
- && defined($self->{_inside_addr}->{_range}->{_stop}))) {
- print "NAT configuration warning:\n'inside-address' is not a relevant option for 'type source'\n";
- }
-
- if ($self->{_exclude}) {
- $jump_target = 'RETURN';
- } elsif ($self->{_type} eq "masquerade") {
- $jump_target = 'MASQUERADE';
- } else {
- $jump_target = 'SNAT';
- }
- if (defined($self->{_outbound_if})) {
- if ($self->{_outbound_if} ne "any") {
- $rule_str .= " -o $self->{_outbound_if}";
- }
- } else {
- # "masquerade" requires outbound_if.
- # also make this a requirement for "source" to prevent users from
- # inadvertently NATing loopback traffic.
- return ('outbound-interface not specified', undef);
- }
-
- if (defined($self->{_proto})) {
- my $str = $self->{_proto};
- $str =~ s/^\!(.*)$/! $1/;
- if ($str eq 'tcp_udp') {
- $tcp_and_udp = 1;
- $rule_str .= " -p tcp"; # we'll add the '-p udp' to 2nd rule later
- } else {
- $rule_str .= " -p $str";
- }
- }
-
- my $to_src = '';
- if (defined($self->{_outside_addr}->{_addr})) {
- my $addr = $self->{_outside_addr}->{_addr};
- if ($addr =~ m/\//) {
- return ("\"$addr\" is not a valid IPv4net address", undef)
- if (!Vyatta::TypeChecker::validateType('ipv4net', $addr, 1));
- $to_src .= $addr;
- $use_netmap = 1;
- } else {
- return ("\"$addr\" is not a valid IP address", undef)
- if (!Vyatta::TypeChecker::validateType('ipv4', $addr, 1));
- $to_src .= $addr;
- }
- } elsif (defined($self->{_outside_addr}->{_range}->{_start})
- && defined($self->{_outside_addr}->{_range}->{_stop})) {
- my $start = $self->{_outside_addr}->{_range}->{_start};
- my $stop = $self->{_outside_addr}->{_range}->{_stop};
- return ("\"$start-$stop\" is not a valid IP range", undef)
- if (!Vyatta::TypeChecker::validateType('ipv4', $start, 1)
- || !Vyatta::TypeChecker::validateType('ipv4', $stop, 1));
- $to_src .= "$start-$stop";
- }
-
- if (($to_src ne "") && ($self->{_type} eq "masquerade")) {
- return ("cannot specify outside IP address with \"masquerade\"", undef);
- }
-
- if (defined($self->{_outside_addr}->{_port})) {
- if (!$can_use_port) {
- return ("ports can only be specified when protocol is \"tcp\" "
- . "\"udp\" or \"tcp_udp\" (currently \"$self->{_proto}\")", undef);
- }
- if ($use_netmap) {
- return ("Cannot use ports with an IPv4net type outside-address as it " .
- "statically maps a whole network of addresses onto another " .
- "network of addresses", undef);
- }
- if ($self->{_type} ne "masquerade") {
- $to_src .= ":";
- }
- my ($success, $err) = (undef, undef);
- my $port = $self->{_outside_addr}->{_port};
- if ($port =~ /-/) {
- ($success, $err)
- = Vyatta::Misc::isValidPortRange($port, '-');
- return ($err, undef) if (!defined($success));
- } elsif ($port =~ /^\d/) {
- ($success, $err)
- = Vyatta::Misc::isValidPortNumber($port);
- return ($err, undef) if (!defined($success));
- } else {
- if ($self->{_proto} eq 'tcp_udp') {
- ($success, $err) = Vyatta::Misc::isValidPortName($port, 'tcp');
- return ($err, undef) if !defined $success ;
- ($success, $err) = Vyatta::Misc::isValidPortName($port, 'udp');
- return ($err, undef) if !defined $success ;
- $port = getservbyname($port, 'tcp');
- } else {
- ($success, $err) = Vyatta::Misc::isValidPortName($port, $self->{_proto});
- return ($err, undef) if !defined $success ;
- $port = getservbyname($port, $self->{_proto});
- }
- }
- $to_src .= "$port";
- }
-
- if ($self->{_exclude}) {
- # outside-address has no effect for "exclude" rules
- } elsif ($to_src ne '') {
- if ($self->{_type} eq "masquerade") {
- $jump_param .= " --to-ports $to_src";
- } else {
- if ($use_netmap) {
- # replace "SNAT" with "NETMAP"
- $jump_target = 'NETMAP';
- $jump_param .= " --to $to_src";
- } else {
- $jump_param .= " --to-source $to_src";
- }
- }
- } elsif ($self->{_type} ne "masquerade") {
- return ('outside-address not specified', undef);
- }
- } elsif ($self->{_type} eq "destination") {
- # type is destination
- return ('cannot specify outbound interface with "destination" rules', undef)
- if (defined($self->{_outbound_if}));
-
- if (defined($self->{_outside_addr}->{_addr}) ||
- defined($self->{_outside_addr}->{_port}) ||
- (defined($self->{_outside_addr}->{_range}->{_start})
- && defined($self->{_outside_addr}->{_range}->{_stop}))) {
- print "NAT configuration warning:\n'outside-address' is not a relevant option for 'type destination'\n";
- }
-
- if ($self->{_exclude}) {
- $jump_target = 'RETURN';
- } else {
- $jump_target = 'DNAT';
- }
-
- if (defined($self->{_inbound_if})) {
- if ($self->{_inbound_if} ne "any") {
- $rule_str .= " -i $self->{_inbound_if}";
- }
- } else {
- # make this a requirement to prevent users from
- # inadvertently NATing loopback traffic.
- return ('inbound-interface not specified', undef);
- }
-
- if (defined($self->{_proto})) {
- my $str = $self->{_proto};
- $str =~ s/^\!(.*)$/! $1/;
- if ($str eq 'tcp_udp') {
- $tcp_and_udp = 1;
- $rule_str .= " -p tcp"; # we'll add the '-p udp' to 2nd rule later
- } else {
- $rule_str .= " -p $str";
- }
- }
-
- my $to_dst = "";
- if (defined($self->{_inside_addr}->{_addr})) {
- my $addr = $self->{_inside_addr}->{_addr};
- if ($addr =~ m/\//) {
- return ("\"$addr\" is not a valid IPv4net address", undef)
- if (!Vyatta::TypeChecker::validateType('ipv4net', $addr, 1));
- $to_dst = " --to ";
- $to_dst .= $addr;
- $use_netmap = 1;
- } else {
- return ("\"$addr\" is not a valid IP address", undef)
- if (!Vyatta::TypeChecker::validateType('ipv4', $addr, 1));
- $to_dst = " --to-destination ";
- $to_dst .= $addr;
- }
- } elsif (defined($self->{_inside_addr}->{_range}->{_start})
- && defined($self->{_inside_addr}->{_range}->{_stop})) {
- my $start = $self->{_inside_addr}->{_range}->{_start};
- my $stop = $self->{_inside_addr}->{_range}->{_stop};
- return ("\"$start-$stop\" is not a valid IP range", undef)
- if (!Vyatta::TypeChecker::validateType('ipv4', $start, 1)
- || !Vyatta::TypeChecker::validateType('ipv4', $stop, 1));
- $to_dst = " --to-destination ";
- $to_dst .= "$start-$stop";
- }
-
- if (defined($self->{_inside_addr}->{_port})) {
- if (!$can_use_port) {
- return ("ports can only be specified when protocol is \"tcp\" "
- . "\"udp\" or \"tcp_udp\" (currently \"$self->{_proto}\")", undef);
- }
- if ($use_netmap) {
- return ("Cannot use ports with an IPv4net type outside-address as it "
- . "statically maps a whole network of addresses onto another "
- . "network of addresses", undef);
- }
- my ($success, $err) = (undef, undef);
- my $port = $self->{_inside_addr}->{_port};
- if ($port =~ /-/) {
- ($success, $err) = Vyatta::Misc::isValidPortRange($port, '-');
- return ($err, undef) if (!defined($success));
- } elsif ($port =~ /^\d/) {
- ($success, $err) = Vyatta::Misc::isValidPortNumber($port);
- return ($err, undef) if (!defined($success));
- } else {
- if ($self->{_proto} eq 'tcp_udp') {
- ($success, $err) = Vyatta::Misc::isValidPortName($port, 'tcp');
- return ($err, undef) if !defined $success ;
- ($success, $err) = Vyatta::Misc::isValidPortName($port, 'udp');
- return ($err, undef) if !defined $success ;
- $port = getservbyname($port, 'tcp');
- } else {
- ($success, $err) = Vyatta::Misc::isValidPortName($port, $self->{_proto});
- return ($err, undef) if !defined $success ;
- $port = getservbyname($port, $self->{_proto});
- }
- }
- $to_dst = " --to-destination " if $to_dst eq "";
- $to_dst .= ":$port";
- }
-
- if ($self->{_exclude}) {
- # inside-address has no effect for "exclude" rules
- } elsif ($to_dst ne "") {
- if ($use_netmap) {
- # replace "DNAT" with "NETMAP"
- $jump_target = 'NETMAP';
- $jump_param .= " $to_dst";
- } else {
- $jump_param .= " $to_dst";
- }
- } else {
- return ("inside-address not specified", undef);
- }
- } else {
- return ("rule type not specified/valid", undef);
- }
-
- # source rule string
- my ($src_str, $src_err) = $src->rule();
- return ($src_err, undef) if (!defined($src_str));
-
- # destination rule string
- my ($dst_str, $dst_err) = $dst->rule();
- return ($dst_err, undef) if (!defined($dst_str));
-
- if ((grep /multiport/, $src_str) || (grep /multiport/, $dst_str)) {
- if ((grep /sport/, $src_str) && (grep /dport/, $dst_str)) {
- return ('cannot specify multiple ports when both source and destination '
- . 'ports are specified', undef);
- }
- }
-
- # if using netmap then source|destination address should have the same prefix
- # as the outside|inside address depending on the whether the type is src|dst
- if ($self->{_type} eq "source" && $use_netmap) {
-
- if (!defined $src->{_network}){
- return ("\nsource address needs to be defined as a subnet with the same network prefix as outside-address" .
- "\nwhen outside-address is defined with a prefix for static network mapping "
- , undef);
- }
-
- my $outside_addr_mask = $self->{_outside_addr}->{_addr};
- my $src_addr_mask = $src->{_network};
- $outside_addr_mask =~ s/.+\///;
- $src_addr_mask =~ s/.+\///;
-
- if (!($outside_addr_mask == $src_addr_mask)) {
- return ("\nsource address should be a subnet with the same network prefix as outside-address" .
- "\nwhen outside-address is defined with a prefix for static network mapping "
- , undef);
- }
-
- if ($src->{_network} =~ /\!/) {
- return ("\ncannot define a negated source address when outside-address" .
- "\nis defined with a prefix for static network mapping "
- , undef);
-
- }
- } elsif ($self->{_type} eq "destination" && $use_netmap) {
-
- if (!defined $dst->{_network}){
- return ("\ndestination address needs to be defined as a subnet with the same network prefix as inside-address" .
- "\nwhen inside-address is defined with a prefix for static network mapping "
- , undef);
- }
-
- my $inside_addr_mask = $self->{_inside_addr}->{_addr};
- my $dst_addr_mask = $dst->{_network};
- $inside_addr_mask =~ s/.+\///;
- $dst_addr_mask =~ s/.+\///;
-
- if (!($inside_addr_mask == $dst_addr_mask)) {
- return ("\ndestination address should be a subnet with the same network prefix as inside-address" .
- "\nwhen inside-address is defined with a prefix for static network mapping"
- , undef);
- }
-
- if ($dst->{_network} =~ /\!/) {
- return ("\ncannot define a negated destination address when inside-address" .
- "\nis defined with a prefix for static network mapping "
- , undef);
-
- }
- }
-
- return (undef, undef) if defined $self->{_disable};
-
- my $comment = "\"NAT-$self->{_rule_number}\" ";
- if ($tcp_and_udp == 1) {
- $comment = "\"NAT-$self->{_rule_number} tcp_udp\" ";
- }
- $rule_str .= " $src_str $dst_str" . " -m comment --comment " . $comment;
- if ("$self->{_log}" eq "enable") {
- my $rule_num = $self->{_rule_number};
- my $log_prefix = get_log_prefix($rule_num, $jump_target);
- if ($tcp_and_udp == 1) {
- my $tcp_log_rule = $rule_str;
- $tcp_log_rule .= " -j LOG --log-prefix \"$log_prefix\" ";
- my $udp_log_rule = $tcp_log_rule;
- $udp_log_rule =~ s/ \-p tcp / -p udp /;
- $rule_str .= " -j $jump_target $jump_param";
- my $udp_rule_str = $rule_str;
- $udp_rule_str =~ s/ \-p tcp / -p udp /;
- return (undef, $tcp_log_rule, $rule_str, $udp_log_rule, $udp_rule_str);
- } else {
- my $log_rule = $rule_str;
- $log_rule .= " -j LOG --log-prefix \"$log_prefix\" ";
- $rule_str .= " -j $jump_target $jump_param";
- return (undef, $log_rule, $rule_str);
- }
- } else {
- $rule_str .= " -j $jump_target $jump_param";
- if ($tcp_and_udp == 1) {
- # protocol is 'tcp_udp'; make another rule for protocol 'udp'
- my $udp_rule_str = $rule_str;
- $udp_rule_str =~ s/ \-p tcp / -p udp /;
- return (undef, $rule_str, $udp_rule_str);
- } else {
- return (undef, $rule_str);
- }
- }
-}
-
-sub orig_type {
- my ($self) = @_;
- return "source" if ($self->{_orig_type} eq "masquerade");
- return $self->{_orig_type};
-}
-
-sub new_type {
- my ($self) = @_;
- return "source" if ($self->{_type} eq "masquerade");
- return $self->{_type};
-}
-
-sub print_str {
- my ($self) = @_;
- my $str =
- "type[$self->{_type}] " .
- "in_if[$self->{_inbound_if}] out_if[$self->{_outbound_if}] " .
- "proto[$self->{_proto}] " .
- "inaddr[$self->{_inside_addr}->{_addr}] " .
- "inrange[$self->{_inside_addr}->{_range}->{_start}-" .
- "$self->{_inside_addr}->{_range}->{_stop}] " .
- "inp[$self->{_inside_addr}->{_port}] " .
- "outaddr[$self->{_outside_addr}->{_addr}] " .
- "outrange[$self->{_outside_addr}->{_range}->{_start}-" .
- "$self->{_outside_addr}->{_range}->{_stop}]" .
- "outp[$self->{_outside_addr}->{_port}] ";
-
- return $str;
-}
-
-sub outputXmlElem {
- my ($name, $value, $fh) = @_;
- print $fh " <$name>$value</$name>\n";
-}
-
-sub outputXml {
- my ($self, $fh) = @_;
- outputXmlElem("type", $self->{_type}, $fh);
- outputXmlElem("in_interface", $self->{_inbound_if}, $fh);
- outputXmlElem("out_interface", $self->{_outbound_if}, $fh);
- outputXmlElem("in_addr", $self->{_inside_addr}->{_addr}, $fh);
- outputXmlElem("in_addr_start", $self->{_inside_addr}->{_range}->{_start},
- $fh);
- outputXmlElem("in_addr_stop", $self->{_inside_addr}->{_range}->{_stop},
- $fh);
- outputXmlElem("in_port", $self->{_inside_addr}->{_port}, $fh);
- outputXmlElem("out_addr", $self->{_outside_addr}->{_addr}, $fh);
- outputXmlElem("out_addr_start", $self->{_outside_addr}->{_range}->{_start},
- $fh);
- outputXmlElem("out_addr_stop", $self->{_outside_addr}->{_range}->{_stop},
- $fh);
- outputXmlElem("out_port", $self->{_outside_addr}->{_port}, $fh);
-
- $src->outputXml("src", $fh);
- $dst->outputXml("dst", $fh);
- # no proto? ($self->{_proto})
-}
-
-1;
-
-# Local Variables:
-# mode: perl
-# indent-tabs-mode: nil
-# perl-indent-level: 2
-# End: