summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGaurav <gaurav.sinha@vyatta.com>2012-02-16 15:03:55 -0800
committerGaurav Sinha <gaurav.sinha@vyatta.com>2012-03-16 16:40:42 -0700
commit4c2e2d79f28734c97a0e374ca217e24ff954fe96 (patch)
tree026f1205c9cd0f96ab060816ee19ee645d64cd25 /lib
parentf0118dc081cfa4e4efd9cbfe6f008cd322539b10 (diff)
downloadvyatta-conntrack-4c2e2d79f28734c97a0e374ca217e24ff954fe96.tar.gz
vyatta-conntrack-4c2e2d79f28734c97a0e374ca217e24ff954fe96.zip
Adding rule and address setup/parsing libraries
(cherry picked from commit 2f59f3ef67d70981ff0501868d5ea206eb9359ae)
Diffstat (limited to 'lib')
-rw-r--r--lib/Vyatta/Conntrack/AddressFilterCT.pm204
-rw-r--r--lib/Vyatta/Conntrack/RuleCT.pm431
2 files changed, 635 insertions, 0 deletions
diff --git a/lib/Vyatta/Conntrack/AddressFilterCT.pm b/lib/Vyatta/Conntrack/AddressFilterCT.pm
new file mode 100644
index 0000000..c7dac8d
--- /dev/null
+++ b/lib/Vyatta/Conntrack/AddressFilterCT.pm
@@ -0,0 +1,204 @@
+# Author: Vyatta <eng@vyatta.com>
+# Date: 2007
+# Description: IP tables address filter
+#
+# Gaurav Sinha: Re-using AddressFilter.pm from vyatta-cfg-firewall package.
+#
+
+# **** 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-2009 Vyatta, Inc.
+# All Rights Reserved.
+# **** End License ****
+
+package Vyatta::Conntrack::AddressFilterCT;
+
+require Vyatta::Config;
+require Vyatta::IpTables::IpSet;
+use Vyatta::Misc qw(getPortRuleString);
+use Vyatta::TypeChecker;
+
+use strict;
+use warnings;
+
+my %_protocolswithports = (
+ tcp_udp => 1,
+ # 'tcp_udp' is to be allowed for nat and firewall rules only.
+ # features should have syntax checks for allowing or forbiding
+ # the use of 'tcp_udp' as protocol. to allow tcp_udp see syntax check
+ # in protocol/node.def for NAT rules and to forbid tcp_udp see syntax
+ # check in protocol/node.def for load-balancing rules
+ # when allowed : tcp_udp creates 2 iptable rules - one for tcp, other for udp
+ 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,
+ _port_group => undef,
+);
+
+sub new {
+ my $that = shift;
+ my $class = ref ($that) || $that;
+ my $self = {
+ %fields,
+ };
+
+ bless $self, $class;
+ return $self;
+}
+
+sub setup_base {
+ my ($self, $level, $func) = @_;
+ my $config = new Vyatta::Config;
+
+ $config->setLevel("$level");
+
+ # setup needed parent nodes
+ $self->{_srcdst} = $config->returnParent("..");
+# $self->{_protocol} = $config->$func(".. protocol");
+
+ # setup address filter nodes
+ $self->{_address} = $config->$func("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->$func("port");
+
+ return 0;
+}
+
+sub setup {
+ my ($self, $level) = @_;
+
+ $self->setup_base($level, 'returnValue');
+ return 0;
+}
+
+sub setupOrig {
+ my ($self, $level) = @_;
+
+ $self->setup_base($level, 'returnOrigValue');
+ 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};
+
+ return 0;
+}
+
+sub rule {
+ my ($self) = @_;
+ my $rule = "";
+ my $can_use_port = 1;
+
+ my $addr_checker;
+ my $prefix_checker;
+ my $pure_addr_checker;
+ my $ip_term;
+ my $prefix_term;
+
+ $addr_checker = 'ipv4_negate';
+ $prefix_checker = 'ipv4net_negate';
+ $pure_addr_checker = 'ipv4';
+ $ip_term = "IPv4";
+ $prefix_term = "subnet";
+
+ if (!defined($self->{_protocol})
+ || !defined($_protocolswithports{$self->{_protocol}})) {
+ $can_use_port = 0;
+ }
+
+ # set the address filter parameters
+ if (defined($self->{_network})) {
+ my $str = $self->{_network};
+ return (undef, "\"$str\" is not a valid $ip_term $prefix_term")
+ if (!Vyatta::TypeChecker::validateType($prefix_checker, $str, 1));
+ my $negate = '';
+ if ($str =~ /^\!(.*)$/) {
+ $str = $1;
+ $negate = '! ';
+ }
+ $rule .= "$negate --$self->{_srcdst} $str ";
+ } elsif (defined($self->{_address})) {
+ my $str = $self->{_address};
+ return (undef, "\"$str\" is not a valid $ip_term address")
+ if (!Vyatta::TypeChecker::validateType($addr_checker, $str, 1));
+ my $negate = '';
+ if ($str =~ /^\!(.*)$/) {
+ $str = $1;
+ $negate = '! ';
+ }
+ $rule .= "$negate --$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 (!Vyatta::TypeChecker::validateType($addr_checker, $start, 1)
+ || !Vyatta::TypeChecker::validateType($pure_addr_checker, $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)
+ = 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);
+}
+1;
+
+# Local Variables:
+# mode: perl
+# indent-tabs-mode: nil
+# perl-indent-level: 2
+# End:
diff --git a/lib/Vyatta/Conntrack/RuleCT.pm b/lib/Vyatta/Conntrack/RuleCT.pm
new file mode 100644
index 0000000..9329603
--- /dev/null
+++ b/lib/Vyatta/Conntrack/RuleCT.pm
@@ -0,0 +1,431 @@
+package Vyatta::Conntrack::RuleCT;
+
+use strict;
+use Vyatta::Config;
+require Vyatta::Conntrack::AddressFilterCT;
+
+my $src = new Vyatta::Conntrack::AddressFilterCT;
+my $dst = new Vyatta::Conntrack::AddressFilterCT;
+
+my %fields = (
+ _rule_number => undef,
+ _protocol => undef,
+ _state => {
+ _established => undef,
+ _new => undef,
+ _related => undef,
+ _invalid => undef,
+ },
+);
+
+my %dummy_rule = (
+ _rule_number => 10000,
+ _protocol => "all",
+ _state => {
+ _established => undef,
+ _new => undef,
+ _related => undef,
+ _invalid => undef,
+ },
+);
+
+my $DEBUG = 'false';
+
+sub new {
+ my $that = shift;
+ my $class = ref ($that) || $that;
+ my $self = {
+ %fields,
+ };
+
+ bless $self, $class;
+ return $self;
+}
+
+sub setupDummy {
+ my ($self, $level) = @_;
+
+ %{$self} = %dummy_rule;
+ $src = new Vyatta::Conntrack::AddressFilterCT;
+ $dst = new Vyatta::Conntrack::AddressFilterCT;
+
+ # set the default policy
+ my $config = new Vyatta::Config;
+ $config->setLevel("$level");
+}
+
+sub setup_base {
+ my ($self, $level, $val_func, $exists_func, $addr_setup) = @_;
+ my $config = new Vyatta::Config;
+
+ $config->setLevel("$level");
+
+ $self->{_rule_number} = $config->returnParent("..");
+ $self->{_protocol} = $config->$val_func("protocol");
+ $self->{_state}->{_established} = $config->$val_func("state established");
+ $self->{_state}->{_new} = $config->$val_func("state new");
+ $self->{_state}->{_related} = $config->$val_func("state related");
+ $self->{_state}->{_invalid} = $config->$val_func("state invalid");
+
+ $src->$addr_setup("$level source");
+ $dst->$addr_setup("$level destination");
+
+ return 0;
+}
+
+sub setup {
+ my ($self, $level) = @_;
+
+ $self->setup_base($level, 'returnValue', 'exists', 'setup');
+ return 0;
+}
+
+sub setupOrig {
+ my ($self, $level) = @_;
+ $self->setup_base($level, 'returnOrigValue', 'existsOrig', 'setupOrig');
+ return 0;
+}
+
+sub print {
+ my ( $self ) = @_;
+
+ print "rulenum: $self->{_rule_number}\n" if defined $self->{_rule_number};
+ print "protocol: $self->{_protocol}\n" if defined $self->{_protocol};
+ print "state: $self->{_state}\n" if defined $self->{_state};
+ $src->print();
+ $dst->print();
+
+}
+
+sub rule {
+ my ( $self ) = @_;
+ my ($rule, $srcrule, $dstrule, $err_str);
+ my $tcp_and_udp = 0;
+
+ # set CLI rule num as comment
+ my @level_nodes = split (' ', $self->{_comment});
+ $rule .= "-m comment --comment \"$level_nodes[2]-$level_nodes[4]\" ";
+
+ # set the protocol
+ if (defined($self->{_protocol})) {
+ my $str = $self->{_protocol};
+ my $negate = '';
+ if ($str =~ /^\!(.*)$/) {
+ $str = $1;
+ $negate = '! ';
+ }
+ if ($str eq 'tcp_udp') {
+ $tcp_and_udp = 1;
+ $rule .= " $negate -p tcp "; # we'll add the '-p udp' to 2nd rule later
+ } else {
+ $rule .= " $negate -p $str ";
+ }
+ }
+
+ my $state_str = uc (get_state_str($self));
+ if ($state_str ne "") {
+ $rule .= "-m state --state $state_str ";
+ }
+
+ # set tcp flags if applicable
+ my $tcp_flags = undef;
+ if (defined $self->{_tcp_flags}) {
+ if (($self->{_protocol} eq "tcp") || ($self->{_protocol} eq "6")) {
+ $tcp_flags = get_tcp_flags_string($self->{_tcp_flags});
+ } else {
+ return ("TCP flags can only be set if protocol is set to TCP", );
+ }
+ }
+ if (defined($tcp_flags)) {
+ $rule .= " -m tcp --tcp-flags $tcp_flags ";
+ }
+
+ # set the icmp code and type if applicable
+ if (($self->{_protocol} eq "icmp") || ($self->{_protocol} eq "1")) {
+ if (defined $self->{_icmp_name}) {
+ if (defined($self->{_icmp_type}) || defined($self->{_icmp_code})){
+ return ("Cannot use ICMP type/code with ICMP type-name", );
+ }
+ $rule .= "--icmp-type $self->{_icmp_name} ";
+ } elsif (defined $self->{_icmp_type}) {
+ $rule .= "--icmp-type $self->{_icmp_type}";
+ if (defined $self->{_icmp_code}) {
+ $rule .= "/$self->{_icmp_code}";
+ }
+ $rule .= " ";
+ } elsif (defined $self->{_icmp_code}) {
+ return ("ICMP code can only be defined if ICMP type is defined", );
+ }
+ } elsif (defined($self->{_icmp_type}) || defined($self->{_icmp_code})
+ || defined($self->{_icmp_name})) {
+ return ("ICMP type/code or type-name can only be defined if protocol is ICMP", );
+ }
+
+ # Setup ICMPv6 rule if configured
+ # ICMPv6 parameters are only valid if the rule is matching on the
+ # ICMPv6 protocol ID.
+ #
+ if (($self->{_protocol} eq "icmpv6") ||
+ ($self->{_protocol} eq "ipv6-icmp") ||
+ ($self->{_protocol} eq "58")) {
+ if (defined($self->{_icmpv6_type})) {
+ $rule .= "-m icmpv6 --icmpv6-type $self->{_icmpv6_type}";
+ }
+ }
+
+ # add the source and destination rules
+ ($srcrule, $err_str) = $src->rule();
+ return ($err_str, ) if (!defined($srcrule));
+ ($dstrule, $err_str) = $dst->rule();
+ return ($err_str, ) if (!defined($dstrule));
+ if ((grep /multiport/, $srcrule) ^ (grep /multiport/, $dstrule)) {
+ if ((grep /sport/, $srcrule) && (grep /dport/, $dstrule)) {
+ return ('Cannot specify multiple ports when both '
+ . 'source and destination ports are specified', );
+ }
+ }
+ $rule .= " $srcrule $dstrule ";
+
+ return ('Cannot specify both "match-frag" and "match-non-frag"', )
+ if (defined($self->{_frag}) && defined($self->{_non_frag}));
+ if (defined($self->{_frag})) {
+ $rule .= ' -f ';
+ } elsif (defined($self->{_non_frag})) {
+ $rule .= ' ! -f ';
+ }
+
+ # note: "out" is not valid in the INPUT chain.
+ return ('Cannot specify both "match-ipsec" and "match-none"', )
+ if (defined($self->{_ipsec}) && defined($self->{_non_ipsec}));
+ if (defined($self->{_ipsec})) {
+ $rule .= ' -m policy --pol ipsec --dir in ';
+ } elsif (defined($self->{_non_ipsec})) {
+ $rule .= ' -m policy --pol none --dir in ';
+ }
+
+ my $p2p = undef;
+ if (defined($self->{_p2p}->{_all})) {
+ $p2p = '--apple --bit --dc --edk --gnu --kazaa ';
+ } else {
+ my @apps = qw(apple bit dc edk gnu kazaa);
+ foreach (@apps) {
+ if (defined($self->{_p2p}->{"_$_"})) {
+ $p2p .= "--$_ ";
+ }
+ }
+ }
+ if (defined($p2p)) {
+ $rule .= " -m ipp2p $p2p ";
+ }
+
+ my $time = undef;
+ if (defined($self->{_time}->{_utc})) {
+ $time .= " --utc ";
+ }
+ if (defined($self->{_time}->{_startdate})) {
+ my $check_date = validate_date($self->{_time}->{_startdate}, "startdate");
+ if (!($check_date eq "")) {
+ return ($check_date, );
+ }
+ $time .= " --datestart $self->{_time}->{_startdate} ";
+ }
+ if (defined($self->{_time}->{_stopdate})) {
+ my $check_date = validate_date($self->{_time}->{_stopdate}, "stopdate");
+ if (!($check_date eq "")) {
+ return ($check_date, );
+ }
+ $time .= " --datestop $self->{_time}->{_stopdate} ";
+ }
+ if (defined($self->{_time}->{_starttime})) {
+ return ("Invalid starttime $self->{_time}->{_starttime}.
+Time should use 24 hour notation hh:mm:ss and lie in between 00:00:00 and 23:59:59", )
+ if (!validate_timevalues($self->{_time}->{_starttime}, "time"));
+ $time .= " --timestart $self->{_time}->{_starttime} ";
+ }
+ if (defined($self->{_time}->{_stoptime})) {
+ return ("Invalid stoptime $self->{_time}->{_stoptime}.
+Time should use 24 hour notation hh:mm:ss and lie in between 00:00:00 and 23:59:59", )
+ if (!validate_timevalues($self->{_time}->{_stoptime}, "time"));
+ $time .= " --timestop $self->{_time}->{_stoptime} ";
+ }
+ if (defined($self->{_time}->{_monthdays})) {
+ my $negate = " ";
+ if ($self->{_time}->{_monthdays} =~ m/^!/) {
+ $negate = "! ";
+ $self->{_time}->{_monthdays} = substr $self->{_time}->{_monthdays}, 1;
+ }
+ return ("Invalid monthdays value $self->{_time}->{_monthdays}.
+Monthdays should have values between 1 and 31 with multiple days separated by commas
+eg. 2,12,21 For negation, add ! in front eg. !2,12,21", )
+ if (!validate_timevalues($self->{_time}->{_monthdays}, "monthdays"));
+ $time .= " $negate --monthdays $self->{_time}->{_monthdays} ";
+ }
+ if (defined($self->{_time}->{_weekdays})) {
+ my $negate = " ";
+ if ($self->{_time}->{_weekdays} =~ m/^!/) {
+ $negate = "! ";
+ $self->{_time}->{_weekdays} = substr $self->{_time}->{_weekdays}, 1;
+ }
+ return ("Invalid weekdays value $self->{_time}->{_weekdays}.
+Weekdays should be specified using the first three characters of the day with the
+first character capitalized eg. Mon,Thu,Sat For negation, add ! in front eg. !Mon,Thu,Sat", )
+ if (!validate_timevalues($self->{_time}->{_weekdays}, "weekdays"));
+ $time .= " $negate --weekdays $self->{_time}->{_weekdays} ";
+ }
+ if (defined($time)) {
+ $rule .= " -m time $time ";
+ }
+
+ my $limit = undef;
+ if (defined $self->{_limit}->{_rate}) {
+ my $rate_integer = $self->{_limit}->{_rate};
+ $rate_integer =~ s/\/(second|minute|hour|day)//;
+ if ($rate_integer < 1) {
+ return ("integer value in rate cannot be less than 1", );
+ }
+ $limit = "--limit $self->{_limit}->{_rate} --limit-burst $self->{_limit}->{_burst}";
+ }
+ $rule .= " -m limit $limit " if defined $limit;
+
+ # recent match condition SHOULD BE DONE IN THE LAST so
+ # all options in $rule are copied to $recent_rule below
+ my $recent_rule = undef;
+ if (defined($self->{_recent_time}) || defined($self->{_recent_cnt})) {
+ my $recent_rule1 = undef;
+ my $recent_rule2 = undef;
+ $recent_rule1 .= ' -m recent --update ';
+ $recent_rule2 .= ' -m recent --set ';
+ if (defined($self->{_recent_time})) {
+ $recent_rule1 .= " --seconds $self->{_recent_time} ";
+ }
+ if (defined($self->{_recent_cnt})) {
+ $recent_rule1 .= " --hitcount $self->{_recent_cnt} ";
+ }
+
+ $recent_rule = $rule;
+
+ if ($rule =~ m/\-m\s+set\s+\-\-match\-set/) {
+ # firewall group being used in this rule. iptables complains if recent
+ # match condition is placed after group match conditions [see bug 5744]
+ # so instead of appending recent match place it before group match
+ my @split_rules = ();
+
+ @split_rules = split(/(\-m\s+set\s+\-\-match\-set)/, $rule, 2);
+ $rule = $split_rules[0] . $recent_rule1 .
+ $split_rules[1] . $split_rules[2];
+
+ @split_rules = split(/(\-m\s+set\s+\-\-match\-set)/, $recent_rule, 2);
+ $recent_rule = $split_rules[0] . $recent_rule2 .
+ $split_rules[1] . $split_rules[2];
+ } else {
+ # append recent match conditions to the two rules needed for recent match
+ $rule .= $recent_rule1;
+ $recent_rule .= $recent_rule2;
+ }
+ }
+
+ my $chain = $self->{_name};
+ my $rule_num = $self->{_rule_number};
+ my $rule2 = undef;
+ # set the jump target. Depends on action and log
+ if ("$self->{_log}" eq "enable") {
+ $rule2 = $rule;
+ my $log_prefix = get_log_prefix($chain, $rule_num, $self->{_action});
+ $rule2 .= "-j LOG --log-prefix \"$log_prefix\" ";
+ }
+ if ("$self->{_action}" eq "drop") {
+ $rule .= "-j DROP ";
+ } elsif ("$self->{_action}" eq "accept") {
+ $rule .= "-j RETURN ";
+ } elsif ("$self->{_action}" eq "reject") {
+ $rule .= "-j REJECT ";
+ } elsif ("$self->{_action}" eq 'inspect') {
+ my $target = ipt_get_queue_target('SNORT');
+ return ('Undefined target for inspect', ) if ! defined $target;
+ $rule .= "-j $target ";
+ } elsif ("$self->{_action}" eq 'modify') {
+ # mangle actions
+ my $count = 0;
+ if (defined($self->{_mod_mark})) {
+ # MARK
+ $rule .= "-j MARK --set-mark $self->{_mod_mark} ";
+ $count++;
+ }
+ if (defined($self->{_mod_dscp})) {
+ # DSCP
+ $rule .= "-j DSCP --set-dscp $self->{_mod_dscp} ";
+ $count++;
+ }
+ if (defined($self->{_mod_tcpmss})) {
+ # TCP-MSS
+ # check for SYN flag
+ if (!defined $self->{_tcp_flags} ||
+ !(($self->{_tcp_flags} =~ m/SYN/) && !($self->{_tcp_flags} =~ m/!SYN/))) {
+ return ('need to set TCP SYN flag to modify TCP MSS', );
+ }
+
+ if ($self->{_mod_tcpmss} =~ m/\d/) {
+ $rule .= "-j TCPMSS --set-mss $self->{_mod_tcpmss} ";
+ } else {
+ $rule .= "-j TCPMSS --clamp-mss-to-pmtu ";
+ }
+ $count++;
+ }
+
+ # others
+
+ if ($count == 0) {
+ return ('Action "modify" requires more specific configuration under '
+ . 'the "modify" node', );
+ } elsif ($count > 1) {
+ return ('Cannot define more than one modification under '
+ . 'the "modify" node', );
+ }
+ } else {
+ return ("\"action\" must be defined", );
+ }
+ if (defined($rule2)) {
+ my $tmp = $rule2;
+ $rule2 = $rule;
+ $rule = $tmp;
+ } elsif (defined($recent_rule)) {
+ $rule2 = $recent_rule;
+ $recent_rule = undef;
+ }
+
+ return (undef, undef) if defined $self->{_disable};
+
+ my ($udp_rule, $udp_rule2, $udp_recent_rule) = (undef, undef, undef);
+ if ($tcp_and_udp == 1) {
+ # create udp rules
+ $udp_rule = $rule;
+ $udp_rule2 = $rule2 if defined $rule2;
+ $udp_recent_rule = $recent_rule if defined $recent_rule;
+ foreach my $each_udprule ($udp_rule, $udp_rule2, $udp_recent_rule) {
+ $each_udprule =~ s/ \-p tcp / -p udp / if defined $each_udprule;
+ }
+ }
+
+ if ($DEBUG eq 'true') {
+ # print all potential iptables rules that could be formed for
+ # a single CLI rule. see get_num_ipt_rules to see exact count
+ print "rule :\n$rule\n" if defined $rule;
+ print "rule2 :\n$rule2\n" if defined $rule2;
+ print "recent rule :\n$recent_rule\n" if defined $recent_rule;
+ print "udp rule :\n$udp_rule\n" if defined $udp_rule;
+ print "udp rule2 :\n$udp_rule2\n" if defined $udp_rule2;
+ print "udp recent rule :\n$udp_recent_rule\n" if defined $udp_recent_rule;
+ }
+
+ return (undef, $rule, $rule2, $recent_rule, $udp_rule, $udp_rule2, $udp_recent_rule);
+}
+
+
+
+1;
+
+# Local Variables:
+# mode: perl
+# indent-tabs-mode: nil
+# perl-indent-level: 2
+# End: