]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - config/firewall/rules.pl
firewall: rules.pl: Cleanup rule generation.
[people/pmueller/ipfire-2.x.git] / config / firewall / rules.pl
index d8adb156b0d4d6a1c6e4fe73430762ac9fb2c3aa..523f6e3422c28cadf746284f9928b729ce8217aa 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/perl -w
 ###############################################################################
 #                                                                             #
 # IPFire.org - A linux based firewall                                         #
 
 use strict;
 use Time::Local;
-no warnings 'uninitialized';
 
-# enable only the following on debugging purpose
-#use warnings;
-#use CGI::Carp 'fatalsToBrowser';
+require '/var/ipfire/general-functions.pl';
+require "${General::swroot}/lang.pl";
+require "/usr/lib/firewall/firewall-lib.pl";
+
+# Set to one to enable debugging mode.
+my $DEBUG = 0;
+
+my $IPTABLES = "iptables --wait";
+
+# iptables chains
+my $CHAIN                 = "FORWARDFW";
+my $CHAIN_NAT_SOURCE      = "NAT_SOURCE";
+my $CHAIN_NAT_DESTINATION = "NAT_DESTINATION";
 
 my %fwdfwsettings=();
 my %defaultNetworks=();
@@ -43,9 +52,6 @@ my %confignatfw=();
 my %aliases=();
 my @DPROT=();
 my @p2ps=();
-require '/var/ipfire/general-functions.pl';
-require "${General::swroot}/lang.pl";
-require "/usr/lib/firewall/firewall-lib.pl";
 
 my $configfwdfw                = "${General::swroot}/firewall/config";
 my $configinput            = "${General::swroot}/firewall/input";
@@ -57,10 +63,8 @@ my $errormessage     = '';
 my $orange                     = '';
 my $green                      = '';
 my $blue                       = '';
-my ($TYPE,$PROT,$SPROT,$DPROT,$SPORT,$DPORT,$TIME,$TIMEFROM,$TIMETILL,$SRC_TGT);
-my $CHAIN                      = "FORWARDFW";
+my ($TYPE,$PROT,$SPROT,$DPROT,$SPORT,$DPORT,$SRC_TGT);
 my $conexists          = 'off';
-my $command                    = 'iptables --wait -A';
 my $dnat                       ='';
 my $snat                       ='';
 
@@ -76,56 +80,58 @@ my $snat                    ='';
 open (CONN,"/var/ipfire/red/iface");
 my $con = <CONN>;
 close(CONN);
+
 if (-f "/var/ipfire/red/active"){
        $conexists='on';
 }
+
 open (CONN1,"/var/ipfire/red/local-ipaddress");
 my $redip = <CONN1>;
 close(CONN1);
-#################
-#    DEBUG/TEST #
-#################
-my $MODE=0;     # 0 - normal operation
-                # 1 - print configline and rules to console
-                #
-#################
-my $param=shift;
-
-if($param eq 'flush'){
-       if ($MODE eq '1'){
-               print " Flushing chains...\n";
-       }
-       &flush;
-}else{
-       if ($MODE eq '1'){
-               print " Flushing chains...\n";
-       }
-       &flush;
-       if ($MODE eq '1'){
-               print " Preparing rules...\n";
-       }
-       &preparerules;
-       if($MODE eq '0'){
-               if ($fwdfwsettings{'POLICY'} eq 'MODE1'){
-                       &p2pblock;
-                       system ("/usr/sbin/firewall-policy");
-               }elsif($fwdfwsettings{'POLICY'} eq 'MODE2'){
-                       &p2pblock;
-                       system ("/usr/sbin/firewall-policy");
-                       system ("/etc/sysconfig/firewall.local reload");
-               }
+
+# MAIN
+&main();
+
+sub main {
+       # Flush all chains.
+       &flush();
+
+       # Reload firewall rules.
+       &preparerules();
+
+       # Load P2P block rules.
+       &p2pblock();
+
+       # Reload firewall policy.
+       run("/usr/sbin/firewall-policy");
+}
+
+sub run {
+       # Executes or prints the given shell command.
+       my $command = shift;
+
+       if ($DEBUG) {
+               print "$command\n";
+       } else {
+               system "$command";
        }
 }
-sub flush
-{
-       system ("iptables --wait -F FORWARDFW");
-       system ("iptables --wait -F INPUTFW");
-       system ("iptables --wait -F OUTGOINGFW");
-       system ("iptables --wait -t nat -F NAT_DESTINATION");
-       system ("iptables --wait -t nat -F NAT_SOURCE");
+
+sub print_error {
+       my $message = shift;
+
+       print STDERR "$message\n";
+}
+
+sub flush {
+       run("$IPTABLES -F FORWARDFW");
+       run("$IPTABLES -F INPUTFW");
+       run("$IPTABLES -F OUTGOINGFW");
+       run("$IPTABLES -t nat -F NAT_DESTINATION");
+       run("$IPTABLES -t nat -F NAT_SOURCE");
 }
-sub preparerules
-{
+
+sub preparerules {
        if (! -z  "${General::swroot}/firewall/config"){
                &buildrules(\%configfwdfw);
        }
@@ -136,35 +142,59 @@ sub preparerules
                &buildrules(\%configoutgoingfw);
        }
 }
-sub buildrules
-{
+
+sub buildrules {
        my $hash=shift;
        my $STAG;
-       my $natip;
        my $snatport;
        my $fireport;
-       my $nat;
        my $fwaccessdport;
        my $natchain;
        my $icmptype;
        foreach my $key (sort {$a <=> $b} keys %$hash){
                next if (($$hash{$key}[6] eq 'RED' || $$hash{$key}[6] eq 'RED1') && $conexists eq 'off' );
-               $command="iptables --wait -A";
-               if ($$hash{$key}[28] eq 'ON'){
-                       $command='iptables --wait -t nat -A';
-                       $natip=&get_nat_ip($$hash{$key}[29],$$hash{$key}[31]);
-                       if($$hash{$key}[31] eq 'dnat'){
-                               $nat='DNAT';
-                               if ($$hash{$key}[30] =~ /\|/){
+
+               my $TIME = "";
+               my $TIMEFROM;
+               my $TIMETILL;
+               my $natip = "";
+
+               # Check if logging should be enabled.
+               my $LOG = 0;
+               if ($$hash{$key}[17] eq 'ON') {
+                       $LOG = 1;
+               }
+
+               my $NAT = 0;
+               my $NAT_MODE;
+
+               # Check if NAT is enabled and initialize variables, that we use for that.
+               if ($$hash{$key}[28] eq 'ON') {
+                       $NAT = 1;
+
+                       # Destination NAT
+                       if ($$hash{$key}[31] eq 'dnat') {
+                               $NAT_MODE = "DNAT";
+
+                               if ($$hash{$key}[30] =~ /\|/) {
                                        $$hash{$key}[30]=~ tr/|/,/;
                                        $fireport='-m multiport --dport '.$$hash{$key}[30];
-                               }else{
+                               } else {
                                        $fireport='--dport '.$$hash{$key}[30] if ($$hash{$key}[30]>0);
                                }
-                       }else{
-                               $nat='SNAT';
+
+                       # Source NAT
+                       } elsif ($$hash{$key}[31] eq 'snat') {
+                               $NAT_MODE = "SNAT";
+
+                       } else {
+                               print_error("Invalid NAT mode: $$hash{$key}[31]");
+                               next;
                        }
+
+                       $natip = &get_nat_ip($$hash{$key}[29], $NAT_MODE);
                }
+
                $STAG='';
                if($$hash{$key}[2] eq 'ON'){
                        #get source ip's
@@ -225,7 +255,7 @@ sub buildrules
                        #get time if defined
                        if($$hash{$key}[18] eq 'ON'){
                                my ($time1,$time2,$daylight);
-                               my $daylight=$$hash{$key}[28];
+                               $daylight=$$hash{$key}[28];
                                $time1=&get_time($$hash{$key}[26],$daylight);
                                $time2=&get_time($$hash{$key}[27],$daylight);
                                if($$hash{$key}[19] ne ''){push (@timeframe,"Mon");}
@@ -241,175 +271,84 @@ sub buildrules
                                $TIMETILL="--timestop $time2 ";
                                $TIME="-m time --weekdays $TIME $TIMEFROM $TIMETILL";
                        }
-                       if ($MODE eq '1'){
-                               print "NR:$key ";
-                               foreach my $i (0 .. $#{$$hash{$key}}){
-                                       print "$i: $$hash{$key}[$i]  ";
+                       foreach my $DPROT (@DPROT){
+                               $DPORT = &get_port($hash,$key,$DPROT);
+                               $PROT=$DPROT;
+                               $PROT="-p $PROT" if ($PROT ne '' && $PROT ne ' ');
+                               if ($DPROT ne 'TCP' && $DPROT ne'UDP' && $DPROT ne 'ICMP' ){
+                                       $DPORT='';
                                }
-                               print "\n";
-                               print"##################################\n";
-                               #print rules to console
-                               foreach my $DPROT (@DPROT){
-                                       $DPORT = &get_port($hash,$key,$DPROT);
-                                       if ($DPROT ne 'TCP' && $DPROT ne 'UDP' && $DPROT ne 'ICMP' ){
-                                               $DPORT='';
-                                       }
-                                       $PROT=$DPROT;
-                                       $PROT="-p $PROT" if ($PROT ne '' && $PROT ne ' ');
-                                       foreach my $a (sort keys %sourcehash){
-                                               foreach my $b (sort keys %targethash){
-                                                       next if ($targethash{$b}[0] eq 'none');
-                                                       $STAG='';
-                                                       if ($sourcehash{$a}[0] ne $targethash{$b}[0] && $targethash{$b}[0] ne 'none' || $sourcehash{$a}[0] eq '0.0.0.0/0.0.0.0'){
-                                                               if($DPROT ne ''){
-                                                                       if(substr($sourcehash{$a}[0], 3, 3) ne 'mac' && $sourcehash{$a}[0] ne ''){ $STAG="-s";}
-                                                                       #Process ICMP RULE
-                                                                       if(substr($DPORT, 2, 4) eq 'icmp'){
-                                                                               my @icmprule= split(",",substr($DPORT, 12,));
-                                                                               foreach (@icmprule){
-                                                                                       $icmptype="--icmp-type ";
-                                                                                       if ($_ eq "BLANK") {
-                                                                                                       $icmptype="";
-                                                                                                       $_="";
-                                                                                       }
-                                                                                       if ($$hash{$key}[17] eq 'ON'){
-                                                                                               print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $icmptype $_ $TIME -j LOG\n";
-                                                                                       }
-                                                                                               print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $icmptype $_ $TIME -j $$hash{$key}[0]\n";
-                                                                               }
-                                                                       #PROCESS DNAT RULE (Portforward)
-                                                                       }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'dnat'){
-                                                                               $natchain='NAT_DESTINATION';
-                                                                               if ($$hash{$key}[17] eq 'ON'){
-                                                                                       print "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j LOG --log-prefix 'DNAT' \n";
-                                                                               }
-                                                                               my ($ip,$sub) =split("/",$targethash{$b}[0]);
-                                                                               #Process NAT with servicegroup used
-                                                                               if ($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'dnat' && $$hash{$key}[14] eq 'cust_srvgrp'){
-                                                                                       print "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $nat --to-destination $ip $DPORT\n";
-                                                                                       $fwaccessdport=$DPORT;
-                                                                               }else{
-                                                                                       print "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $nat --to-destination $ip$DPORT\n";
-                                                                                       $DPORT =~ s/\-/:/g;
-                                                                                       if ($DPORT){
-                                                                                               $fwaccessdport="--dport ".substr($DPORT,1,);
-                                                                                       }elsif(! $DPORT && $$hash{$key}[30] ne ''){
-                                                                                               if ($$hash{$key}[30]=~m/|/i){
-                                                                                                       $$hash{$key}[30] =~ s/\|/,/g;
-                                                                                                       $fwaccessdport="-m multiport --dport $$hash{$key}[30]";
-                                                                                               }else{
-                                                                                                       $fwaccessdport="--dport $$hash{$key}[30]";
-                                                                                               }
-                                                                                       }
-                                                                               }
-                                                                               print "iptables --wait -A FORWARDFW $PROT $STAG $sourcehash{$a}[0] -d $ip $fwaccessdport $TIME -j $$hash{$key}[0]\n";
-                                                                               next;
-                                                                       #PROCESS SNAT RULE
-                                                                       }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'snat'){
-                                                                               $natchain='NAT_SOURCE';
-                                                                               if ($$hash{$key}[17] eq 'ON' ){
-                                                                                       print "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG --log-prefix 'SNAT' \n";
+                               foreach my $a (sort keys %sourcehash){
+                                       foreach my $b (sort keys %targethash){
+                                               if(! $sourcehash{$a}[0] || ! $targethash{$b}[0] || ($natip eq '-d ' && $NAT) || (!$natip && $NAT)){
+                                                       #Skip rules when no RED IP is set (DHCP,DSL)
+                                                       next;
+                                               }
+                                               next if ($targethash{$b}[0] eq 'none');
+                                               $STAG='';
+                                               if ($sourcehash{$a}[0] ne $targethash{$b}[0] && $targethash{$b}[0] ne 'none' || $sourcehash{$a}[0] eq '0.0.0.0/0.0.0.0'){
+                                                       if($DPROT ne ''){
+                                                               if(substr($sourcehash{$a}[0], 3, 3) ne 'mac' && $sourcehash{$a}[0] ne ''){ $STAG="-s";}
+                                                               #Process ICMP RULE
+                                                               if(substr($DPORT, 2, 4) eq 'icmp'){
+                                                                       my @icmprule= split(",",substr($DPORT, 12,));
+                                                                       foreach (@icmprule){
+                                                                               $icmptype="--icmp-type ";
+                                                                               if ($_ eq "BLANK") {
+                                                                                               $icmptype="";
+                                                                                               $_="";
                                                                                }
-                                                                               print "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $nat --to-source $natip\n";
-                                                                       }
-                                                                       #PROCESS EVERY OTHER RULE (If NOT ICMP, else the rule would be applied double)
-                                                                       if ($PROT ne '-p ICMP'){
-                                                                               if ($$hash{$key}[17] eq 'ON' && $$hash{$key}[28] ne 'ON'){
-                                                                                       print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG\n";
+                                                                               if ($LOG) {
+                                                                                       run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $icmptype $_ $TIME -j LOG");
                                                                                }
-                                                                               print "iptables --wait -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]\n";
+                                                                               run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $icmptype $_ $TIME -j $$hash{$key}[0]");
                                                                        }
-                                                                       #PROCESS Prot ICMP and type = All ICMP-Types
-                                                                       if ($PROT eq '-p ICMP' && $$hash{$key}[9] eq 'All ICMP-Types'){
-                                                                               if ($$hash{$key}[17] eq 'ON' && $$hash{$key}[28] ne 'ON'){
-                                                                                       print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG\n";
-                                                                               }
-                                                                               print "iptables --wait -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]\n";
+                                                               #PROCESS DNAT RULE (Portforward)
+                                                               } elsif ($NAT && $NAT_MODE eq "DNAT") {
+                                                                       if ($LOG) {
+                                                                               run("$IPTABLES -t nat -A $CHAIN_NAT_DESTINATION $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j LOG --log-prefix 'DNAT'");
                                                                        }
-                                                               }
-                                                       }
-                                               }
-                                       }
-                                       print"\n";
-                               }
-                       }elsif($MODE eq '0'){
-                               foreach my $DPROT (@DPROT){
-                                       $DPORT = &get_port($hash,$key,$DPROT);
-                                       $PROT=$DPROT;
-                                       $PROT="-p $PROT" if ($PROT ne '' && $PROT ne ' ');
-                                       if ($DPROT ne 'TCP' && $DPROT ne'UDP' && $DPROT ne 'ICMP' ){
-                                               $DPORT='';
-                                       }
-                                       foreach my $a (sort keys %sourcehash){
-                                               foreach my $b (sort keys %targethash){
-                                                       next if ($targethash{$b}[0] eq 'none');
-                                                       $STAG='';
-                                                       if ($sourcehash{$a}[0] ne $targethash{$b}[0] && $targethash{$b}[0] ne 'none' || $sourcehash{$a}[0] eq '0.0.0.0/0.0.0.0'){
-                                                               if($DPROT ne ''){
-                                                                       if(substr($sourcehash{$a}[0], 3, 3) ne 'mac' && $sourcehash{$a}[0] ne ''){ $STAG="-s";}
-                                                                       #Process ICMP RULE
-                                                                       if(substr($DPORT, 2, 4) eq 'icmp'){
-                                                                               my @icmprule= split(",",substr($DPORT, 12,));
-                                                                               foreach (@icmprule){
-                                                                                       $icmptype="--icmp-type ";
-                                                                                       if ($_ eq "BLANK") {
-                                                                                                       $icmptype="";
-                                                                                                       $_="";
-                                                                                       }
-                                                                                       if ($$hash{$key}[17] eq 'ON'){
-                                                                                               system ("$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $icmptype $_ $TIME -j LOG");
-                                                                                       }
-                                                                                               system ("$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $icmptype $_ $TIME -j $$hash{$key}[0]");
-                                                                               }
-                                                                       #PROCESS DNAT RULE (Portforward)
-                                                                       }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'dnat'){
-                                                                               $natchain='NAT_DESTINATION';
-                                                                               if ($$hash{$key}[17] eq 'ON'){
-                                                                                       system "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j LOG --log-prefix 'DNAT' \n";
-                                                                               }
-                                                                               my ($ip,$sub) =split("/",$targethash{$b}[0]);
-                                                                               #Process NAT with servicegroup used
-                                                                               if ($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'dnat' && $$hash{$key}[14] eq 'cust_srvgrp'){
-                                                                                       system "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $nat --to-destination $ip $DPORT\n";
-                                                                                       $fwaccessdport=$DPORT;
-                                                                               }else{
-                                                                                       system "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $nat --to-destination $ip$DPORT\n";
-                                                                                       $DPORT =~ s/\-/:/g;
-                                                                                       if ($DPORT){
-                                                                                               $fwaccessdport="--dport ".substr($DPORT,1,);
-                                                                                       }elsif(! $DPORT && $$hash{$key}[30] ne ''){
-                                                                                               if ($$hash{$key}[30]=~m/|/i){
-                                                                                                       $$hash{$key}[30] =~ s/\|/,/g;
-                                                                                                       $fwaccessdport="-m multiport --dport $$hash{$key}[30]";
-                                                                                               }else{
-                                                                                                       $fwaccessdport="--dport $$hash{$key}[30]";
-                                                                                               }
+                                                                       my ($ip,$sub) =split("/",$targethash{$b}[0]);
+                                                                       #Process NAT with servicegroup used
+                                                                       if ($$hash{$key}[14] eq 'cust_srvgrp') {
+                                                                               run("$IPTABLES -t nat -A $CHAIN_NAT_DESTINATION $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j DNAT --to-destination $ip $DPORT");
+                                                                               $fwaccessdport=$DPORT;
+                                                                       } else {
+                                                                               run("$IPTABLES -t nat -A $CHAIN_NAT_DESTINATION $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j DNAT --to-destination $ip$DPORT");
+                                                                               $DPORT =~ s/\-/:/g;
+                                                                               if ($DPORT){
+                                                                                       $fwaccessdport="--dport ".substr($DPORT,1,);
+                                                                               }elsif(! $DPORT && $$hash{$key}[30] ne ''){
+                                                                                       if ($$hash{$key}[30]=~m/|/i){
+                                                                                               $$hash{$key}[30] =~ s/\|/,/g;
+                                                                                               $fwaccessdport="-m multiport --dport $$hash{$key}[30]";
+                                                                                       }else{
+                                                                                               $fwaccessdport="--dport $$hash{$key}[30]";
                                                                                        }
                                                                                }
-                                                                               system "iptables --wait -A FORWARDFW $PROT $STAG $sourcehash{$a}[0] -d $ip $fwaccessdport $TIME -j $$hash{$key}[0]\n";
-                                                                               next;
-                                                                       #PROCESS SNAT RULE
-                                                                       }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'snat'){
-                                                                               $natchain='NAT_SOURCE';
-                                                                               if ($$hash{$key}[17] eq 'ON' ){
-                                                                                       system "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG --log-prefix 'SNAT' \n";
-                                                                               }
-                                                                               system "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $nat --to-source $natip\n";
                                                                        }
-                                                                       #PROCESS EVERY OTHER RULE (If NOT ICMP, else the rule would be applied double)
-                                                                       if ($PROT ne '-p ICMP'){
-                                                                               if ($$hash{$key}[17] eq 'ON' && $$hash{$key}[28] ne 'ON'){
-                                                                                       system "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG\n";
-                                                                               }
-                                                                               system "iptables --wait -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]\n";
+                                                                       run("$IPTABLES -A FORWARDFW $PROT $STAG $sourcehash{$a}[0] -d $ip $fwaccessdport $TIME -j $$hash{$key}[0]");
+                                                                       next;
+                                                               #PROCESS SNAT RULE
+                                                               } elsif ($NAT && $NAT_MODE eq "SNAT") {
+                                                                       if ($LOG) {
+                                                                               run("$IPTABLES -t nat -A $CHAIN_NAT_SOURCE $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG --log-prefix 'SNAT'");
                                                                        }
-                                                                       #PROCESS Prot ICMP and type = All ICMP-Types
-                                                                       if ($PROT eq '-p ICMP' && $$hash{$key}[9] eq 'All ICMP-Types'){
-                                                                               if ($$hash{$key}[17] eq 'ON' && $$hash{$key}[28] ne 'ON'){
-                                                                                       system "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG\n";
-                                                                               }
-                                                                               system "iptables --wait -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]\n";
+                                                                       run("$IPTABLES -t nat -A $CHAIN_NAT_SOURCE $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j SNAT --to-source $natip");
+                                                               }
+                                                               #PROCESS EVERY OTHER RULE (If NOT ICMP, else the rule would be applied double)
+                                                               if ($PROT ne '-p ICMP'){
+                                                                       if ($LOG && !$NAT) {
+                                                                               run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG");
+                                                                       }
+                                                                       run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]");
+                                                               }
+                                                               #PROCESS Prot ICMP and type = All ICMP-Types
+                                                               if ($PROT eq '-p ICMP' && $$hash{$key}[9] eq 'All ICMP-Types'){
+                                                                       if ($LOG && !$NAT) {
+                                                                               run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG");
                                                                        }
+                                                                       run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]");
                                                                }
                                                        }
                                                }
@@ -419,14 +358,11 @@ sub buildrules
                }
                %sourcehash=();
                %targethash=();
-               undef $TIME;
-               undef $TIMEFROM;
-               undef $TIMETILL;
                undef $fireport;
        }
 }
-sub get_nat_ip
-{
+
+sub get_nat_ip {
        my $val=shift;
        my $type=shift;
        my $result;
@@ -434,23 +370,23 @@ sub get_nat_ip
                $result=$defaultNetworks{$val.'_ADDRESS'};
        }elsif($val eq 'ALL'){
                $result='-i '.$con;
-       }elsif($val eq 'Default IP' && $type eq 'dnat'){
+       }elsif($val eq 'Default IP' && $type eq "DNAT"){
                $result='-d '.$redip;
-       }elsif($val eq 'Default IP' && $type eq 'snat'){
+       }elsif($val eq 'Default IP' && $type eq "SNAT"){
                $result=$redip;
        }else{
                foreach my $al (sort keys %aliases){
-                       if($val eq $al && $type eq 'dnat'){
+                       if($val eq $al && $type eq "DNAT"){
                                $result='-d '.$aliases{$al}{'IPT'};
-                       }elsif($val eq $al && $type eq 'snat'){
+                       }elsif($val eq $al && $type eq "SNAT"){
                                $result=$aliases{$al}{'IPT'};
                        }
                }
        }
        return $result;
 }
-sub get_time
-{
+
+sub get_time {
        my $val=shift;
        my $val1=shift;
        my $time;
@@ -463,8 +399,8 @@ sub get_time
        $time=sprintf "%02d:%02d", $ruletime / 60, $ruletime % 60;
        return $time;
 }
-sub time_get_utc
-{
+
+sub time_get_utc {
        # Calculates the UTCtime from a given time
        my $val=shift;
        my @localtime=localtime(time);
@@ -472,16 +408,16 @@ sub time_get_utc
        my $diff = ($gmtime[2]*60+$gmtime[1]%60)-($localtime[2]*60+$localtime[1]%60);
        return $diff;
 }
-sub utcmin
-{
+
+sub utcmin {
        my $ruletime=shift;
        my ($hrs,$min) = split(":",$ruletime);
        my $newtime = $hrs*60+$min;
        return $newtime;
 }
-sub p2pblock
-{
-       my $P2PSTRING;
+
+sub p2pblock {
+       my $P2PSTRING = "";
        my $DO;
        open( FILE, "< $p2pfile" ) or die "Unable to read $p2pfile";
        @p2ps = <FILE>;
@@ -501,18 +437,13 @@ sub p2pblock
                        }
                }
        }
-       if ($MODE eq 1){
-               if($P2PSTRING){
-                       print"/sbin/iptables --wait -A FORWARDFW $CMD $P2PSTRING -j $DO\n";
-               }
-       }else{
-               if($P2PSTRING){
-                       system("/sbin/iptables --wait -A FORWARDFW $CMD $P2PSTRING -j $DO");
-               }
+
+       if($P2PSTRING) {
+               run("$IPTABLES -A FORWARDFW $CMD $P2PSTRING -j $DO");
        }
 }
-sub get_address
-{
+
+sub get_address {
        my $base=shift; #source of checking ($configfwdfw{$key}[x] or groupkey
        my $base2=shift;
        my $type=shift; #src or tgt
@@ -557,7 +488,7 @@ sub get_address
                        $$hash{$key}[0]='0.0.0.0/0';
                }
                if($base2 eq 'RED' || $base2 eq 'RED1'){
-                       open(FILE, "/var/ipfire/red/local-ipaddress")or die "Couldn't open local-ipaddress";
+                       open(FILE, "/var/ipfire/red/local-ipaddress");
                        $$hash{$key}[0]= <FILE>;
                        close(FILE);
                }else{
@@ -569,8 +500,8 @@ sub get_address
                }
        }
 }
-sub get_prot
-{
+
+sub get_prot {
        my $hash=shift;
        my $key=shift;
        #check AH,GRE,ESP or ICMP
@@ -598,8 +529,8 @@ sub get_prot
                return "$$hash{$key}[8]";
        }
 }
-sub get_port
-{
+
+sub get_port {
        my $hash=shift;
        my $key=shift;
        my $prot=shift;