#!/bin/bash

. /ips/setup/.config

. /ips/ip2/.functions

MA0=$[ 1024 + ADR ]
MA1=$[ 1024 + 255 ]

ANYDEVS="$ANYDEV"
OURNETS=$OURNET
OURDEVS=$OURDEV
#test LANDEV="eth1 eth2" 
for DEV in $LANDEV; do 

    #echo $DEV
    I="`/sbin/ifconfig $DEV 2> /dev/null | grep 'inet addr' | cut -f2-2 -d ':'  | cut -f1-1 -d ' '  | cut -f1-4 -d '.'`"

    #echo $Y
    if [ "$I" = "" ]; then
       continue
    fi
    M="`/sbin/ifconfig $DEV 2> /dev/null | grep 'inet addr' | cut -f4-4 -d ':'  | cut -f1-1 -d ' '  | cut -f1-4 -d '.'`"


    X="$I/$M"
    #echo "[$X]"

    OURNETS="$OURNETS $X"
    OURDEVS="$OURDEVS $DEV"

done

#echo $OURNETS $OURDEVS ; exit

# allowed incoming / outgoing  TCP services 
TCPIN="smtp,www,ssh"
#TCPOUT="smtp,www,ssh,ftp,ftp-data,irc"
TCPOUT="smtp,www,ssh"

# allowed incoming / outgoing  UDP services 
UDPIN="domain"
UDPOUT="domain"

AUTHIN="auth"
AUTHOUT="auth"

# alowed incoming / outgoing ICMP messages
# look at /usr/include/netinet/ip_icmp.h for names associated with numbers
ICMPIN="0 3 11"
#ICMPIN="0 8 3 11"
ICMPOUT="8 3 11"


# againsta smurf : block ICMP messages coming in our inner net broadcast address
# below rule "-A FORWARD -p icmp -i $ANYDEV -d $OURBCAST -j DROP

# !

for DEV in $ANYDEVS; do

if [ "$QOS_BRIDGE" = "1" ]; then 
   IDEV="-m physdev --physdev-in $DEV"
else
   IDEV="-i $DEV"
fi

# against syn-flood
 #B=$[ WAN_SYN_FLO + 5 ]
 if [ "$WAN_SYN_FLO" != "" ]; then
   rule "-I INPUT -t mangle -p tcp --syn $IDEV -j DROP"
   rule "-I INPUT -t mangle -p tcp --syn $IDEV -m limit --limit $WAN_SYN_FLO/s -j ACCEPT"
 fi

# against ping of death
 #B=$[ WAN_PIN_DEA + 5 ]
 if [ "$WAN_PIN_DEA" != "" ]; then
   rule "-I INPUT -t mangle -p icmp --icmp-type echo-request $IDEV -j DROP"
   rule "-I INPUT -t mangle -p icmp --icmp-type echo-request $IDEV -m limit --limit $WAN_PIN_DEA/s -j ACCEPT"
 fi

 if [ "$WAN_LIM_UDP" != "" ]; then
   rule "-I INPUT -t mangle -p udp $IDEV -j DROP"
   rule "-I INPUT -t mangle -p udp $IDEV -m limit --limit $WAN_LIM_UDP/s -j ACCEPT"
 fi

done


# ?

# against syn-flood
if [ "$LAN_SYN_FLO" != "" ]; then
  #B=$[ LAN_SYN_FLO + 5 ]
  for DEV in $OURDEV $LANDEV; do 

    if [ "$QOS_BRIDGE" = "1" ]; then 
      ODEV="-m physdev --physdev-in $DEV"
    else
      ODEV="-i $DEV"
    fi

     rule "-I INPUT -t mangle -p tcp --syn $ODEV -j DROP"
     rule "-I INPUT -t mangle -p tcp --syn $ODEV -m limit --limit $LAN_SYN_FLO/s -j ACCEPT"

  done
fi

# against ping of death
if [ "$LAN_PIN_DEA" != "" ]; then
  #B=$[ LAN_PIN_DEA + 5 ]
  for DEV in $OURDEV $LANDEV; do 

    if [ "$QOS_BRIDGE" = "1" ]; then 
      ODEV="-m physdev --physdev-in $DEV"
    else
      ODEV="-i $DEV"
    fi

     rule "-I INPUT -t mangle -p icmp --icmp-type echo-request $ODEV -j DROP"
     rule "-I INPUT -t mangle -p icmp --icmp-type echo-request $ODEV -m limit --limit $LAN_PIN_DEA/s -j ACCEPT"

  done
fi

if [ "$LAN_LIM_UDP" != "" ]; then
  for DEV in $OURDEV $LANDEV; do 

    if [ "$QOS_BRIDGE" = "1" ]; then 
      ODEV="-m physdev --physdev-in $DEV"
    else
      ODEV="-i $DEV"
    fi

     rule "-I INPUT -t mangle -p udp $ODEV -j DROP"
     rule "-I INPUT -t mangle -p udp $ODEV -m limit --limit $LAN_LIM_UDP/s -j ACCEPT"

  done 
fi


# accept fragmented packets 
rule "-A FORWARD -f -j ACCEPT"
#rule "-A INPUT -f -j ACCEPT"

# TCP
for OURNET in $OURNETS; do
    rule "-A FORWARD -m multiport -p tcp -d $OURNET --destination-port $TCPIN ! --tcp-flags SYN,ACK ACK -j ACCEPT"
    rule "-A FORWARD -m multiport -p tcp -s $OURNET --source-port $TCPIN ! --tcp-flags SYN,ACK ACK -j ACCEPT"
done

for OURDEV in $OURDEVS; do

  if [ "$QOS_BRIDGE" = "1" ]; then 
    #MARK="-m mark ! --mark 1024/0xfc00"
    MARK=
    IOURDEV="-m physdev --physdev-in $OURDEV"
  else
    MARK=
    IOURDEV="-i $OURDEV"
  fi

    rule "-A FORWARD -m multiport -p udp $MARK $IOURDEV --destination-port $UDPOUT -j ACCEPT"
    rule "-A FORWARD -m multiport -p udp $MARK $IOURDEV --source-port $UDPOUT -j ACCEPT"
    rule "-A FORWARD -p tcp $MARK $IOURDEV -m multiport --destination-port $TCPOUT --syn -j ACCEPT"

    for I in $ICMPOUT ; do
	rule "-A FORWARD  -p icmp $MARK $IOURDEV --icmp-type $I -j ACCEPT"
    done
done


### defence 
# !


if [ "$QOS_BRIDGE" = "1" ]; then 
   IDEV="-m physdev --physdev-in $ANYDEV"
else
   IDEV="-i $ANYDEV"
fi

for I in $OURIP $OURIP2; do 

 for OURNET in $OURNETS; do

# against smurf : block ICMP messages coming in our inner net broadcast address
    BCAST="`echo $OURNET | cut -f1-1 -d "/" | cut -f1-3 -d "."`.255"
    rule "-I FORWARD -p icmp $IDEV -d $BCAST -j DROP"
    rule "-I INPUT -p icmp $IDEV -d $BCAST -j DROP"

if [ "$QOS_BRIDGE" != "1" ]; then 
# against spoofingiem : drop all packets incoming with our source address
    rule "-I FORWARD -s $OURNET  $IDEV -j DROP"
    rule "-I INPUT -s $OURNET $IDEV -j DROP"
fi

    for I in $ICMPIN ; do
	rule "-A FORWARD  -p icmp $IDEV -d $OURNET  --icmp-type $I -j ACCEPT"
    done

 done

done



# !

if [ "$TOTAL_LIMITS" = "1" ]; then
# these rules are redundant, packets go through the default route interface
 for DEV in $ANYDEVS; do

if [ "$QOS_BRIDGE" = "1" ]; then 
   OMARK="-m mark ! --mark 1024/0xfc00"
   IMARK="-m mark --mark 1024/0xfc00"
   ODEV=
   IDEV=
else
   OMARK=
   IMARK=
   ODEV="-o $DEV"
   IDEV="-i $DEV"
fi


    CON=${CONNLIMIT_OUT}
    if [ "$CON" != "" ]; then
	rule "-I FORWARD -p tcp --syn $OMARK $ODEV -m connlimit --connlimit-above $CON -j REJECT"
    fi

    CON=${CONNLIMIT_IN}
    if [ "$CON" != "" ]; then
	 rule "-I FORWARD -p tcp --syn $IMARK $IDEV -m connlimit --connlimit-above $CON -j REJECT"
    fi



    LIM=${LIMIT_OUT}
    if [ "$LIM" != "" ]; then
        rule "-I FORWARD -t mangle -p tcp --syn $OMARK $ODEV -j DROP"
        rule "-I FORWARD -t mangle -p tcp --syn $OMARK $ODEV -m limit --limit $LIM/s -j ACCEPT"
    fi

    LIM=${LIMIT_IN}
    if [ "$LIM" != "" ]; then
        rule "-I FORWARD -t mangle -p tcp --syn $IMARK $IDEV -j DROP"
        rule "-I FORWARD -t mangle -p tcp --syn $IMARK $IDEV -m limit --limit $LIM/s -j ACCEPT"
    fi

    LIM=${LIMIU_OUT}
    if [ "$LIM" != "" ]; then
        rule "-I FORWARD -t mangle -p udp $OMARK $ODEV -j DROP"
        rule "-I FORWARD -t mangle -p udp $OMARK $ODEV -m limit --limit $LIM/s -j ACCEPT"
    fi

    LIM=${LIMIU_IN}
    if [ "$LIM" != "" ]; then
	rule "-I FORWARD -t mangle -p udp $IMARK $IDEV  -j DROP"
        rule "-I FORWARD -t mangle -p udp $IMARK $IDEV -m limit --limit $LIM/s -j ACCEPT"
    fi

 done
 
fi

