#/bin/bash
# By Brielle Bruns <bruns@2mbit.com>
# URL: http://www.sosdg.org/freestuff/firewall
# License: GPLv3
#
#    Copyright (C) 2009 - 2011  Brielle Bruns
#    Copyright (C) 2009 - 2011  The Summit Open Source Development Group
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    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.
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

FW_VERSION="1.1"

# These option is here to help pre-1.0 users easily upgrade, defines critical defaults
# that would otherwise require remaking their options file.  I leave this on by default,
# but if you want to make sure you have a current options file, define this to 0.
COMPAT_CONFIG=1

BASEDIR=/etc/firewall-sosdg
PATH=/usr/sbin:/usr/bin:/sbin:/bin
#BASEDIR=`pwd`

# We require at least bash v3 or later at this point given some of the more complex
# operations we do to make the firewall script work.
if (( ${BASH_VERSINFO[0]} <= "2" )); then
	echo "Error: We can only run with bash 3.0 or higher.  Please upgrade your version"
	echo "of bash to something more recent, preferably the latest which is, as of this"
	echo "writing, 4.x"
	exit 1
fi

TWEAKS=$BASEDIR/tweaks

if [ ! -r $BASEDIR/include/static ] || [ ! -r $BASEDIR/include/functions ]; then
	echo "Error: Missing either include/static or include/functions. These are critical to operation"
	echo "of this script.  Please make sure they are readable and exist!"
	exit 1
fi

if [ -r $BASEDIR/include/static ]; then
	. $BASEDIR/include/static
else
	echo -e "${RED}Error: Can not load static variables file.  There is no way to make this tool work without it."
	exit 1
fi

if [ -r $BASEDIR/options ]; then
	. $BASEDIR/options
else
	echo -e "${RED}Error: Can not load options file.  Did you forget to rename options.default?"
	exit 1
fi

if [ -r $BASEDIR/include/functions ]; then
	. $BASEDIR/include/functions
else
	echo -e "${RED}Error: Can not load functions library file.  There is no way to make this tool work without it."
	exit 1
fi

while [ $# -gt 0 ]; do
	case "$1" in
	-f|--flush)
		iptables_policy_reset ipv4 ACCEPT
		iptables_policy_reset ipv6 ACCEPT
		iptables_rules_flush ipv4
		iptables_rules_flush ipv6
		exit 0
		;;
	-h|--help)
		show_help
		exit 0
		;;	
	--generate-cache)
		GEN_CACHE="force"
		;;
	esac
	shift
done

if [ ${PORTFW} ] && [ ! -r "${PORTFW}" ]; then
	display_c RED "Error: Missing ${PORTFW} as defined in the PORTFW option.  Please make sure"
	display_c RED "it exists, or comment out the PORTFW line in options."
	exit 1
fi

echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Firewall/SOSDG ${FW_VERSION}
 Brielle Bruns <bruns@2mbit.com>
 http://www.sosdg.org/freestuff/firewall
 This program comes with ABSOLUTELY NO WARRANTY.
 This is free software, and you are welcome to 
 redistribute it under certain conditions.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="

if [ "$UID" != "0" ]; then
	display_c RED "You must be root to run this script."
	exit 2
fi

if [ ! -x "${IPTABLES}" ]; then
	display_c RED "iptables command not found.  Please make sure you have the iptables"
	display_c RED "installed (package or source) and you have the IPTABLES option properly"
	display_c RED "defined in the 'options' file."
	exit 3
fi


if [ ! -x "${IP6TABLES}" ] && [ $IPV6 == "1" ]; then
	display_c RED "ip6tables command not found.  Please make sure you have the iptables"
	display_c RED "installed (package or source) and you have the IP6TABLES option properly"
	display_c RED "defined in the 'options' file."
	exit 3
fi


if [[ "${EXTIF}" == "auto" ]]; then
	EXTIF=`$EXTIF_FIND`
	display_c YELLOW "Found default interface at: ${BLUE}${EXTIF}${DEFAULT_COLOR}"
fi

if [[ "${EXTIP}" == "auto" ]]; then
	EXTIP=`$EXTIP_FIND ${EXTIF}`
	display_c YELLOW "Found default interface IP at: ${BLUE}${EXTIP}${DEFAULT_COLOR}"
fi

iptables_rules_flush ipv4

if [ -s "${BASEDIR}/include/ipv4_custom_flush" ]; then
	display_c YELLOW "Loading custom flush rules..."
	. "${BASEDIR}/include/ipv4_custom_flush"
fi

if [ -x "${PRERUN}" ]; then
	${PRERUN}
fi

if [ "$MODULES_LOAD" ]; then
	display_c YELLOW "Loading modules: " N
	for i in $MODULES_LOAD; do
		display_c BLUE "$i " N
		${MODPROBE} $i
	done
	echo -ne "\n"
fi

if [ "$STATE_TYPE" ]; then
	case $STATE_TYPE in
		conntrack|CONNTRACK|*)
			M_STATE="-m conntrack"
			C_STATE="--ctstate"
			;;
		state|STATE)
			M_STATE="-m state"
			C_STATE="--state"
	esac
else
	M_STATE="-m conntrack"
	C_STATE="--ctstate"
fi

# This function currently isn't implemented entirely or properly.  It's mostly
# used for debugging purposes, and to see what iptables rules will be generated
# before running.
if [ "$GEN_CACHE" ]; then
	case $GEN_CACHE in
		force)
			IPTABLES="write_out_rules"
			if [ "$IPV6" ]; then
				IP6TABLES="write_out_rules_v6"
				rm -f "${RULE_CACHE_V6}" &>/dev/null
			fi
			rm -f "${RULE_CACHE}" &>/dev/null
			;;
	esac
fi

if [ "$IPTABLES_MULTIPORT" ]; then
	case $IPTABLES_MULTIPORT in
	  auto|AUTO|Auto)
	  		if `${MODPROBE} ${NF_MULTIPORT} &>/dev/null`; then
	  			display_c YELLOW "Multiport successfully loaded."
	  			IPTABLES_MULTIPORT="yes"
	  		else
	  			display_c RED "Multiport was not loaded successfully.  Disabling."
	  			IPTABLES_MULTIPORT="no"
	  		fi ;;
	  yes|YES|Yes)
	  		${MODPROBE} ${NF_MULTIPORT}
	  		display_c PURPLE "Multiport loading forced, not error checking."
	  		IPTABLES_MULTIPORT="yes" ;;
	  *)  IPTABLES_MULTIPORT="no"
	  esac
fi

$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT

if [ -s "$BASEDIR/include/ipv4_custom_trust" ]; then
	display_c YELLOW "Loading custom trust rules..."
	. "$BASEDIR/include/ipv4_custom_trust"
fi

if [ "$TRUSTEDIP" ]; then
	display_c YELLOW "Adding trusted IP: " N
	for i in $TRUSTEDIP; do
		echo -n "$i "
		$IPTABLES -A INPUT -s $i -j ACCEPT
		$IPTABLES -A OUTPUT -d $i -j ACCEPT
	done
	echo -ne "\n"
fi

if [ "$CLAMPMSS" ]; then
	display_c YELLOW "Clamping MSS to PMTU..."
	for i in $CLAMPMSS; do
		$IPTABLES -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS \
			--clamp-mss-to-pmtu -o $i -m tcpmss --mss 1400:1536
		$IPTABLES -A OUTPUT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS \
			--clamp-mss-to-pmtu -o $i -m tcpmss --mss 1400:1536
	done
echo -en "\n"
fi

if [ "$DNS_REQUESTS_OUT" ]; then
	display_c YELLOW "Adding DNS reply allows for trusted DNS servers.."
	for i in $DNS_REQUESTS_OUT; do
		if [[ "$i" =~ "|" ]]; then
			IFS_OLD=${IFS};IFS=\|
			DNSREQ=($i)
			IFS=${IFS_OLD}
			SRCIF=${DNSREQ[0]}
			DNSIP_NUM=${#DNSREQ[@]}
			DNSIP_COUNT_CURR=1
			for ((i=$DNSIP_COUNT_CURR; i <= $DNSIP_NUM; i++)); do
				if [ ${DNSREQ[$i]} ]; then
					${IPTABLES} -A INPUT -i ${SRCIF} -p udp --sport 53 -s ${DNSREQ[$i]} --destination-port 1024:65535 -j ACCEPT
				fi
			done			
		else
			${IPTABLES} -A INPUT -i $i -p udp --sport 53 --destination-port 1024:65535 -j ACCEPT
		fi
	done
fi

if [ -s "$BASEDIR/include/ipv4_custom_allowedports" ]; then
	display_c YELLOW "Loading custom allowed port rules..."
	. "$BASEDIR/include/ipv4_custom_allowedports"
fi

if [ "$IPV4_ALLOWED" ]; then
	display_c YELLOW "Adding allowed IPs and ports... "
	for i in `grep -v "\#" $IPV4_ALLOWED`; do
		if [[ "$i" =~ "|" ]]; then
			IFS_OLD=${IFS};IFS=\|
			ADVALLOWIP=($i)
			IFS=${IFS_OLD}
			SRCIF=${ADVALLOWIP[0]}
			SRCIP=${ADVALLOWIP[1]}
			SRCPORT=${ADVALLOWIP[2]}
			DSTIF=${ADVALLOWIP[3]}
			DSTIP=${ADVALLOWIP[4]}
			DSTPORT=${ADVALLOWIP[5]}
			DIRECTION=${ADVALLOWIP[6]}
			PROTO=${ADVALLOWIP[7]}
			if [ "$SRCIF" ]; then
				SRCIF="-i ${SRCIF} "
			fi
			if [ "$SRCIP" ]; then
				SRCIP="-s ${SRCIP} "
			fi
			if [ "$SRCPORT" ]; then
				SRCPORT="--sport ${SRCPORT/-/:} "
			fi
			if [ "$DSTIF" ]; then
				DSTIF="-o ${DSTIF} "
			fi
			if [ "$DSTIP" ]; then
				DSTIP="-d ${DSTIP} "
			fi
			if [ "$DSTPORT" ]; then
				DSTPORT="--dport ${DSTPORT/-/:} "
			fi
			if [ "$PROTO" ]; then
				case $PROTO in
					TCP|tcp) PROTO="-p tcp";;
					UDP|udp) PROTO="-p udp";;
					*) PROTO="-p ${PROTO}";;
				esac
			fi
			case $DIRECTION in
				IN) DIRECTION="INPUT" ;;
				OUT) DIRECTION="OUTPUT" ;;
				FWD) DIRECTION="FORWARD" ;;
				*) DIRECTION="INPUT" ;;
			esac
			${IPTABLES} -A ${DIRECTION} ${PROTO} ${SRCIF} ${SRCIP} ${SRCPORT} ${DSTIF} ${DSTIP} ${DSTPORT} -j ACCEPT
		fi
	done
fi

if [ -s "$BASEDIR/include/ipv4_custom_blockip" ]; then
	display_c YELLOW "Loading custom ip block rules..."
	. "$BASEDIR/include/ipv4_custom_blockip"
fi

if [ "$BLOCKEDIP" ]; then
	display_c YELLOW "Adding blocked IPs... "
	for i in `grep -v "\#" $BLOCKEDIP`; do
		#echo -n "$i "
		if [[ "$i" =~ "|" ]]; then
			IFS_OLD=${IFS};IFS=\|
			ADVBLKIP=($i)
			IFS=${IFS_OLD}
			SRCIF=${ADVBLKIP[0]}
			SRCIP=${ADVBLKIP[1]}
			SRCPORT=${ADVBLKIP[2]}
			DSTIF=${ADVBLKIP[3]}
			DSTIP=${ADVBLKIP[4]}
			DSTPORT=${ADVBLKIP[5]}
			DIRECTION=${ADVBLKIP[6]}
			PROTO=${ADVBLKIP[7]}
			if [ "$SRCIF" ]; then
				SRCIF="-i ${SRCIF} "
			fi
			if [ "$SRCIP" ]; then
				SRCIP="-s ${SRCIP} "
			fi
			if [ "$SRCPORT" ]; then
				SRCPORT="--sport ${SRCPORT/-/:} "
			fi
			if [ "$DSTIF" ]; then
				DSTIF="-o ${DSTIF} "
			fi
			if [ "$DSTIP" ]; then
				DSTIP="-d ${DSTIP} "
			fi
			if [ "$DSTPORT" ]; then
				DSTPORT="--dport ${DSTPORT/-/:} "
			fi
			if [ "$PROTO" ]; then
				case $PROTO in
					TCP|tcp) PROTO="-p tcp";;
					UDP|udp) PROTO="-p udp";;
					*) PROTO="-p ${PROTO}";;
				esac
			fi
			case $DIRECTION in
				IN) DIRECTION="INPUT" ;;
				OUT) DIRECTION="OUTPUT" ;;
				FWD) DIRECTION="FORWARD" ;;
				*) DIRECTION="INPUT" ;;
			esac
			${IPTABLES} -A ${DIRECTION} ${PROTO} ${SRCIF} ${SRCIP} ${SRCPORT} ${DSTIF} ${DSTIP} ${DSTPORT} -j DROP
		else
			$IPTABLES -A INPUT -s $i -j DROP
			$IPTABLES -A OUTPUT -d $i -j DROP
		fi
	done
fi


if [ "$BLOCK_OUTGOING_RFC1918" ]; then
	display_c YELLOW "Blocking RFC1918 space going out on: " N
		for i in $BLOCK_OUTGOING_RFC1918; do
			display_c BLUE "$i " N
			for x in $RFC1918_SPACE; do
				$IPTABLES -A INPUT -i $i -s $x -j DROP
				$IPTABLES -A FORWARD -i $i -s $x -j DROP
			done
		done
		echo -ne "\n"
		unset i x
fi

if [ "$BLOCK_INCOMING_RFC1918" ]; then
	display_c YELLOW "Blocking RFC1918 space coming in on: " N
		for i in $BLOCK_INCOMING_RFC1918; do
			display_c BLUE "$i " N
			for x in $RFC1918_SPACE; do
				$IPTABLES -A INPUT -i $i -s $x -j DROP
				$IPTABLES -A FORWARD -i $i -s $x -j DROP
			done
		done
		echo -ne "\n"
		unset i x
fi

if [ "$STRIPECN" ]; then
	display_c YELLOW "Stripping ECN off of TCP packets to " N
	for i in $STRIPECN; do
		echo -en "$i "
		$IPTABLES -A PREROUTING -t mangle -p tcp -d $i -j ECN \
			--ecn-tcp-remove
	done
echo -ne "\n"
fi

if [ -s "$BASEDIR/include/ipv4_custom_mssclamp" ]; then
	display_c YELLOW "Loading custom MSS Clamp rules..."
	. "$BASEDIR/include/ipv4_custom_mssclamp"
fi


if [ "$HACK_IPV4" ]; then
	apply_ipv4_hack $HACK_IPV4
fi

if [ -s "$BASEDIR/include/ipv4_custom_conntrack" ]; then
	display_c YELLOW "Loading custom conntrack rules..."
	. "$BASEDIR/include/ipv4_custom_conntrack"
fi

if [ "$CONNTRACK" ]; then
	#$IPTABLES -A INPUT ${M_STATE} ${C_STATE} NEW -j ACCEPT
	$IPTABLES -A INPUT ${M_STATE} ${C_STATE} RELATED,ESTABLISHED -j ACCEPT
	# Now in the NAT rules
	#$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} RELATED,ESTABLISHED -j ACCEPT
	#$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} NEW -j ACCEPT
	$IPTABLES -A OUTPUT ${M_STATE} ${C_STATE} NEW,RELATED,ESTABLISHED -j ACCEPT 
	#$IPTABLES -A OUTPUT ${M_STATE} ${C_STATE} NEW -j ACCEPT
	$IPTABLES -A INPUT ${M_STATE} ${C_STATE} INVALID -j DROP
	$IPTABLES -A OUTPUT ${M_STATE} ${C_STATE} INVALID -j DROP
	#$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} INVALID -j DROP
fi

if [ -s "$BASEDIR/include/ipv4_custom_blockoutports" ]; then
	display_c YELLOW "Loading custom blocked outbound port rules..."
	. "$BASEDIR/include/ipv4_custom_blockoutports"
fi

if [ "$BLOCKTCPPORTS" ] || [ "$BLOCKUDPPORTS" ]; then
	display_c YELLOW "Blocking outbound port: " N

	if  [ "$BLOCKTCPPORTS" ]; then
		for i in $BLOCKTCPPORTS; do
			echo -en "${PURPLE}TCP${DEFAULT_COLOR}/${GREEN}$i "
			$IPTABLES -A OUTPUT -p tcp --dport $i --syn -j DROP
		done
	fi
	if  [ "$BLOCKUDPPORTS" ]; then
		for i in $BLOCKUDPPORTS; do
			echo -en "${BLUE}UDP${DEFAULT_COLOR}/${GREEN}$i "
			$IPTABLES -A OUTPUT -p udp --dport $i -j DROP
		done
	fi
	reset_color
fi


if [ "$TCPPORTS" ] || [ "$UDPPORTS" ]; then
	display_c YELLOW "Adding allowed port: " N
	if [ "$TCPPORTS" ]; then
		if [ "$IPTABLES_MULTIPORT" == "yes" ] && [ "$NF_MULTIPORT_MAX_PORTS" ]; then
			TCPPORTS=($TCPPORTS)
			PORTS_COUNT=${#TCPPORTS[@]}
			PORTS_COUNT_CURR=0
			while (( "$PORTS_COUNT_CURR" < "$PORTS_COUNT" )); do
				for ((i=$PORTS_COUNT_CURR; i <=(($PORTS_COUNT_CURR+(($NF_MULTIPORT_MAX_PORTS-1)))); i++)); do
					if [ ${TCPPORTS[$i]} ]; then
						PORTS="${PORTS},${TCPPORTS[$i]}"
					fi
				done
				echo -en "${PURPLE}Multiport-TCP${DEFAULT_COLOR}/${GREEN}${PORTS#,} "
				$IPTABLES -A INPUT -p tcp -m multiport --dports ${PORTS#,} -j ACCEPT
				unset PORTS
        		PORTS_COUNT_CURR=$i
			done
			unset i PORTS PORTS_COUNT_CURR PORTS_COUNT
		else
			for i in $TCPPORTS; do
				echo -en "${PURPLE}TCP${DEFAULT_COLOR}/${GREEN}$i "
				$IPTABLES -A INPUT -p tcp --dport $i -j ACCEPT
			done
		fi
	fi
	if [ "$UDPPORTS" ]; then
		for i in $UDPPORTS; do
			echo -en "${BLUE}UDP${DEFAULT_COLOR}/${GREEN}$i "
			#$IPTABLES -A INPUT -p udp --dport $i -j ACCEPT
			$IPTABLES -A OUTPUT -p udp --sport 1:65535 --dport $i -j ACCEPT
        	$IPTABLES -A INPUT -p udp --dport $i --sport 1:65535 -j ACCEPT
			$IPTABLES -A INPUT -p udp --sport $i --dport 1:65535 -j ACCEPT
		done
	fi
	reset_color
fi



if [ -s "$BASEDIR/include/ipv4_custom_proto" ]; then
	display_c YELLOW "Loading custom protocol rules..."
	. "$BASEDIR/include/ipv4_custom_proto"
fi

if [ "$ALLOWEDPROTO" ]; then
	display_c YELLOW "Adding allowed protocols: " N
	for i in $ALLOWEDPROTO; do
		echo -n "$i "
		$IPTABLES -A INPUT -p $i -j ACCEPT
		$IPTABLES -A OUTPUT -p $i -j ACCEPT
	done
	reset_color
fi

if [ "$IPV4_INTERCEPT" ]; then
	display_c YELLOW "Adding packet interception rules: "
		for i in `grep -v "\#" $IPV4_INTERCEPT`; do
		IFS_OLD=${IFS};IFS=\|
		INTERCEPTADD=($i)
		IFS=${IFS_OLD}
		SRCIF=${INTERCEPTADD[0]}
		SRCIP=${INTERCEPTADD[1]}
		DSTIP=${INTERCEPTADD[2]}
		DSTPROTO=${INTERCEPTADD[3]}
		DSTPORT=${INTERCEPTADD[4]}
		PROXY=${INTERCEPTADD[5]}
		if [ "$SRCIF" ]; then
			SRCIF="-i ${SRCIF}"
		fi
		if [ "$SRCIP" ]; then
			SRCIP="-s ${SRCIP}"
		fi
		if [ "$DSTIP" ]; then
			DSTIP="-d $DSTIP"
		fi
		if [ "$PROXY" != "BYPASS" ]; then
			FINAL_RULE="-j DNAT --to-destination ${PROXY}"
		else
			FINAL_RULE="-j ACCEPT"
		fi
		$IPTABLES -t nat -A PREROUTING ${SRCIF} ${SRCIP} ${DSTIP} -p ${DSTPROTO} --dport ${DSTPORT} \
			${FINAL_RULE}
		display_c DEFAULT "\t${GREEN}${INTERCEPTADD[0]}:${BLUE}${INTERCEPTADD[1]}:${PURPLE}${INTERCEPTADD[2]}->${INTERCEPTADD[3]}:${INTERCEPTADD[4]}${AQUA}:proxy->${BLUE}${INTERCEPTADD[5]} "
	done
	reset_color
fi


if [ -s "$BASEDIR/include/ipv4_custom_notrack" ]; then
	display_c YELLOW "Loading custom NOTRACK rules..."
	. "$BASEDIR/include/ipv4_custom_notrack"
fi

if [ $CONNTRACK ]; then
	for i in $DONTTRACK; do
		$IPTABLES -t raw -I PREROUTING -s $i -j NOTRACK
		$IPTABLES -t raw -I PREROUTING -d $i -j NOTRACK
		$IPTABLES -t raw -I OUTPUT -s $i -j NOTRACK
		$IPTABLES -t raw -I OUTPUT -d $i -j NOTRACK
	done
fi


if [ -s "$BASEDIR/include/ipv4_custom_routing" ]; then
	display_c YELLOW "Loading custom routing rules..."
	. "$BASEDIR/include/ipv4_custom_routing"
fi

if [ $ROUTING ]; then
	display_c YELLOW "Adding route: "
	for i in `grep -v "\#" $ROUTING`; do
		ROUTE=( ${i//:/ } )
		FWINT1=${ROUTE[0]}
		FWINT2=${ROUTE[2]}
		FWIP1=${ROUTE[1]}
		FWIP2=${ROUTE[3]}

		if [ -e "/proc/sys/net/ipv4/conf/$FWINT1/forwarding" ]; then
			echo 1 > /proc/sys/net/ipv4/conf/$FWINT1/forwarding
		fi
		if [ -e "/proc/sys/net/ipv4/conf/$FWINT2/forwarding" ]; then
			echo 1 > /proc/sys/net/ipv4/conf/$FWINT2/forwarding
		fi
		$IPTABLES -A FORWARD -i $FWINT1 -o $FWINT2 \
			-s $FWIP1 -d $FWIP2 -j ACCEPT
		if [ ${ROUTE[4]} == "1" ]; then
			display_c DEFAULT "\t${GREEN}$FWINT1:${PURPLE}$FWIP1${AQUA}<->${BLUE}$FWINT2:$FWIP2"
 			$IPTABLES -A FORWARD -o $FWINT1 -i $FWINT2 \
				-d $FWIP1 -s $FWIP2 -j ACCEPT
		else
			display_c DEFAULT "\t${GREEN}$FWINT1:${PURPLE}$FWIP1${AQUA}->${BLUE}$FWINT2:$FWIP2"
	fi
	done
echo -ne "\n"
fi


if [ -s "$BASEDIR/include/ipv4_custom_portforward" ]; then
	display_c YELLOW "Loading custom port forwarding rules..."
	. "$BASEDIR/include/ipv4_custom_portforward"
fi

if [ "$PORTFW" ] && [ "$NAT" ]; then
	display_c YELLOW "Adding port forward for:"
	for i in `grep -v "\#" $PORTFW`; do
		IFS_OLD=${IFS};IFS=\:
		PORTFWADD=($i)
		IFS=${IFS_OLD}
		DSTIF=${PORTFWADD[0]}
		SRCIP=${PORTFWADD[1]}
		DSTIP=${PORTFWADD[2]}
		DSTPORT=${PORTFWADD[3]}
		DSTPROTO=${PORTFWADD[4]}
		DSTINTIP=${PORTFWADD[5]}
		DSTINTPORT=${PORTFWADD[6]}
		if [ "$DSTIF" ]; then
			DSTIF="-i ${DSTIF}"
		fi
		if [ "$SRCIP" ]; then
			SRCIP="-s ${SRCIP}"
		fi
		if [ "$DSTIP" ]; then
			DSTIP="-d $DSTIP"
		fi
		if [ ! "$DSTIP" ] && [ ! "$DSTIF" ]; then
			DSTIP="-d $EXTIP"
		fi
		#PORTADD=( ${i//:/ } )
		$IPTABLES -A PREROUTING -t nat ${DSTIF} -p ${DSTPROTO} ${SRCIP} \
			--dport ${DSTPORT} ${DSTIP} -j DNAT --to \
			${DSTINTIP}:${DSTINTPORT}
		$IPTABLES -A INPUT -p ${DSTPROTO} ${M_STATE} ${C_STATE} NEW ${DSTIF} ${SRCIP} \
			--dport ${DSTPORT} ${DSTIP} -j ACCEPT
		display_c DEFAULT "\t${GREEN}${PORTFWADD[0]}:${BLUE}${PORTFWADD[1]}:${PURPLE}${PORTFWADD[2]}:${PORTFWADD[3]}:${PORTFWADD[4]}${AQUA}->${BLUE}${PORTFWADD[5]}:${PORTFWADD[6]} "
	done
reset_color
fi

if [ "$LANDHCPSERVER" ]; then
	for i in $LANDHCPSERVER; do
		$IPTABLES -A INPUT -i $i -p udp --sport 67:68 --dport 67:68 -j ACCEPT
		$IPTABLES -A OUTPUT -o $i -p udp --sport 67:68 --dport 67:68 -j ACCEPT
		#$IPTABLES -A INPUT -i $i -s 0.0.0.0 -j ACCEPT
		#$IPTABLES -A INPUT -i $i -p udp --dport 67:68 -j ACCEPT
		#$IPTABLES -A INPUT -i $i -p tcp --dport 67:68 -j ACCEPT
		#$IPTABLES -A OUTPUT -o $i -p udp --dport 67:68 -j ACCEPT
		#$IPTABLES -A OUTPUT -o $i -p tcp --dport 67:68 -j ACCEPT
		#$IPTABLES -A INPUT -i $i -p udp -d 255.255.255.255 --dport 67:68 -j ACCEPT
		#$IPTABLES -A INPUT -i $i -p tcp -d 255.255.255.255 --dport 67:68 -j ACCEPT
		#$IPTABLES -A OUTPUT -o $i -p udp -d 255.255.255.255 --dport 67:68 -j ACCEPT
		#$IPTABLES -A OUTPUT -o $i -p tcp -d 255.255.255.255 --dport 67:68 -j ACCEPT
	done
fi

if [ -s "$BASEDIR/include/ipv4_custom_mark" ]; then
	display_c YELLOW "Loading custom mark rules..."
	. "$BASEDIR/include/ipv4_custom_mark"
fi

if [ -r "$IPv4_MARK" ]; then
	display_c YELLOW "Adding mark: "
	for i in `grep -v "\#" $IPv4_MARK`; do
		MARK=( ${i//|/ } )
		INIF=${MARK[0]}
		INIP=${MARK[1]}
		DSTIP=${MARK[2]}
		IPMARK=${MARK[3]}

		case $INIP in
			!*) INNEG="!"
				INIP=${INIP#\!};;
		esac
		case $DSTIP in
			!*) DSTNEG="!"
				DSTIP=${DSTIP#\!};;
		esac

		$IPTABLES -t mangle -A PREROUTING -i ${INIF} ${INNEG} -s ${INIP} \
   		     ${DSTNEG} -d ${DSTIP} -j MARK --set-mark=${IPMARK}
		display_c DEFAULT "\t${GREEN}${INNEG}${INIF}:${PURPLE}${INIP}${AQUA}->${BLUE}${DSTNEG}${DSTIP}:${RED}${IPMARK}"
		unset INNEG DSTNEG
	done
echo -ne "\n"
fi



if [ -s "$BASEDIR/include/ipv4_custom_nat" ]; then
	display_c YELLOW "Loading custom nat rules..."
	. "$BASEDIR/include/ipv4_custom_nat"
fi

if [ $NAT ]; then
	if [ "$NAT_RANGE" ]; then
		display_c YELLOW "Adding NAT rule:"
		unset INIF_EXISTS FWDIF_EXISTS
		for i in $NAT_RANGE; do
			NAT_RULE=( ${i//:/ } )
			case ${NAT_RULE[0]} in
			SNAT)
				$IPTABLES -A POSTROUTING -t nat -s ${NAT_RULE[2]} -j SNAT \
					-o ${NAT_RULE[3]} --to-source ${NAT_RULE[4]} 
				$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} NEW,RELATED,ESTABLISHED -i ${NAT_RULE[1]} -s ${NAT_RULE[2]} -o ${NAT_RULE[3]} -j ACCEPT
				$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} RELATED,ESTABLISHED -o ${NAT_RULE[1]} -d ${NAT_RULE[2]} -i ${NAT_RULE[3]} -j ACCEPT
				$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} INVALID -o ${NAT_RULE[1]} -d ${NAT_RULE[2]} -i ${NAT_RULE[3]} -j DROP
				display_c DEFAULT "\t${GREEN}SNAT:${PURPLE}${NAT_RULE[1]}:${NAT_RULE[2]}${AQUA}->${BLUE}${NAT_RULE[3]}:${NAT_RULE[4]}"
				if [[ ! "$INIF_EXISTS" =~ "${NAT_RULE[1]}:${NAT_RULE[2]}" ]]; then
					$IPTABLES -A INPUT -p icmp --icmp-type time-exceeded -i ${NAT_RULE[1]} \
						-s ${NAT_RULE[2]} -j ACCEPT
					$IPTABLES -A INPUT -p icmp --icmp-type fragmentation-needed -i ${NAT_RULE[1]} \
						-s ${NAT_RULE[2]} -j ACCEPT
					INIF_EXISTS="${INIF_EXISTS} ${NAT_RULE[1]}:${NAT_RULE[2]}"
				fi
				if [[ ! "$FWDIF_EXISTS" =~ "${NAT_RULE[1]}:${NAT_RULE[2]}:${NAT_RULE[3]}" ]]; then
					$IPTABLES -A FORWARD -p icmp --icmp-type time-exceeded -i ${NAT_RULE[1]} -s ${NAT_RULE[2]} \
						-o ${NAT_RULE[3]} -j ACCEPT
					$IPTABLES -A FORWARD -p icmp --icmp-type fragmentation-needed -i ${NAT_RULE[1]} -s ${NAT_RULE[2]} \
						-o ${NAT_RULE[3]} -j ACCEPT
					FWDIF_EXISTS="${FWDIF_EXISTS} ${NAT_RULE[1]}:${NAT_RULE[2]}:${NAT_RULE[3]}"
				fi
					;;
			MASQ)
				$IPTABLES -A POSTROUTING -t nat -s ${NAT_RULE[2]} -j MASQUERADE -o ${NAT_RULE[3]}
				$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} NEW,RELATED,ESTABLISHED -i ${NAT_RULE[1]} -s ${NAT_RULE[2]} -o ${NAT_RULE[3]} -j ACCEPT
				$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} RELATED,ESTABLISHED -o ${NAT_RULE[1]} -d ${NAT_RULE[2]} -i ${NAT_RULE[3]} -j ACCEPT
				$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} INVALID -o ${NAT_RULE[1]} -d ${NAT_RULE[2]} -i ${NAT_RULE[3]} -j DROP
				display_c DEFAULT "\t${GREEN}MASQ:${PURPLE}${NAT_RULE[2]}${AQUA}->${BLUE}${NAT_RULE[3]}"
				if [[ ! "$INIF_EXISTS" =~ "${NAT_RULE[1]}:${NAT_RULE[2]}" ]]; then
					$IPTABLES -A INPUT -p icmp --icmp-type time-exceeded -i ${NAT_RULE[1]} \
						-s ${NAT_RULE[2]} -j ACCEPT
					$IPTABLES -A INPUT -p icmp --icmp-type fragmentation-needed -i ${NAT_RULE[1]} \
						-s ${NAT_RULE[2]} -j ACCEPT
					INIF_EXISTS="${INIF_EXISTS} ${NAT_RULE[1]}:${NAT_RULE[2]}"
				fi
				if [[ ! "$FWDIF_EXISTS" =~ "${NAT_RULE[1]}:${NAT_RULE[2]}:${NAT_RULE[3]}" ]]; then
					$IPTABLES -A FORWARD -p icmp --icmp-type time-exceeded -i ${NAT_RULE[1]} -s ${NAT_RULE[2]} \
						-o ${NAT_RULE[3]} -j ACCEPT
					$IPTABLES -A FORWARD -p icmp --icmp-type fragmentation-needed -i ${NAT_RULE[1]} -s ${NAT_RULE[2]} \
						-o ${NAT_RULE[3]} -j ACCEPT
					FWDIF_EXISTS="${FWDIF_EXISTS} ${NAT_RULE[1]}:${NAT_RULE[2]}:${NAT_RULE[3]}"
				fi
					;;
			NETMAP)
				$IPTABLES -A PREROUTING -t nat -s ${NAT_RULE[2]} -j NETMAP --to ${NAT_RULE[4]}
				$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} NEW,RELATED,ESTABLISHED -i ${NAT_RULE[1]} -s ${NAT_RULE[2]} -o ${NAT_RULE[3]} -j ACCEPT
				$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} RELATED,ESTABLISHED -o ${NAT_RULE[1]} -d ${NAT_RULE[2]} -i ${NAT_RULE[3]} -j ACCEPT
				$IPTABLES -A FORWARD ${M_STATE} ${C_STATE} INVALID -o ${NAT_RULE[1]} -d ${NAT_RULE[2]} -i ${NAT_RULE[3]} -j DROP
				display_c DEFAULT "\t${GREEN}NETMAP:${PURPLE}${NAT_RULE[2]}${AQUA}->${BLUE}${NAT_RULE[4]}"
				if [[ ! "$INIF_EXISTS" =~ "${NAT_RULE[1]}:${NAT_RULE[2]}" ]]; then
					$IPTABLES -A INPUT -p icmp --icmp-type time-exceeded -i ${NAT_RULE[1]} \
						-s ${NAT_RULE[2]} -j ACCEPT
					$IPTABLES -A INPUT -p icmp --icmp-type fragmentation-needed -i ${NAT_RULE[1]} \
						-s ${NAT_RULE[2]} -j ACCEPT
					INIF_EXISTS="${INIF_EXISTS} ${NAT_RULE[1]}:${NAT_RULE[2]}"
				fi
				if [[ ! "$FWDIF_EXISTS" =~ "${NAT_RULE[1]}:${NAT_RULE[2]}:${NAT_RULE[3]}" ]]; then
					$IPTABLES -A FORWARD -p icmp --icmp-type time-exceeded -i ${NAT_RULE[1]} -s ${NAT_RULE[2]} \
						-o ${NAT_RULE[3]} -j ACCEPT
					$IPTABLES -A FORWARD -p icmp --icmp-type fragmentation-needed -i ${NAT_RULE[1]} -s ${NAT_RULE[2]} \
						-o ${NAT_RULE[3]} -j ACCEPT
					FWDIF_EXISTS="${FWDIF_EXISTS} ${NAT_RULE[1]}:${NAT_RULE[2]}:${NAT_RULE[3]}"
				fi
					;;
				*) display_c RED "Invalid NAT rule in NAT_RANGE" ;;
			esac
		done
		reset_color
	fi
fi

$IPTABLES --policy INPUT ${IPV4_PINPUT}
$IPTABLES --policy OUTPUT ${IPV4_POUTPUT}
$IPTABLES --policy FORWARD ${IPV4_PFORWARD}

if [ -s "$BASEDIR/include/ipv4_custom_blockincoming" ]; then
	display_c YELLOW "Loading custom incoming blocked rules..."
	. "$BASEDIR/include/ipv4_custom_blockincoming"
fi

if [ $BLOCKINCOMING ]; then
		$IPTABLES -A INPUT -p tcp --syn -j DROP
		$IPTABLES -A INPUT -p udp -j DROP
fi


#================[IPv6]================
if [ $IPV6 ]; then
	iptables_rules_flush ipv6
	if [ -s "$BASEDIR/include/ipv6_custom_flush" ]; then
		display_c YELLOW "Loading custom IPv6 flush rules..."
		. "$BASEDIR/include/ipv6_custom_flush"
	fi

	display_c YELLOW "Adding trusted IPv6: " N

	$IP6TABLES -A INPUT -i lo -j ACCEPT
	$IP6TABLES -A OUTPUT -o lo -j ACCEPT

	if [ -s "$BASEDIR/include/ipv6_custom_trust" ]; then
		display_c YELLOW "Loading custom IPv6 trust rules..."
		. "$BASEDIR/include/ipv6_custom_trust"
	fi
	if [ "$IPV6_TRUSTED" ]; then
		for i in $IPV6_TRUSTED; do
			echo -n "$i "
			$IP6TABLES -A INPUT -s $i -j ACCEPT
			$IP6TABLES -A OUTPUT -d $i -j ACCEPT
		done
	fi
	reset_color
	
	if [ -s "$BASEDIR/include/ipv6_custom_blockip" ]; then
	display_c YELLOW "Loading custom IPv6 block rules..."
	. "$BASEDIR/include/ipv6_custom_blockip"
fi

if [ "$IPV6_LANDHCPSERVER" ]; then
	for i in $IPV6_LANDHCPSERVER; do
		$IP6TABLES -A INPUT -i $i -p udp --sport 546:547 --dport 546:547 -j ACCEPT
		#$IP6TABLES -A INPUT -i $i -p tcp --sport 546:547 --dport 546:547 -j ACCEPT
		$IP6TABLES -A OUTPUT -o $i -p udp --sport 546:547 --dport 546:547 -j ACCEPT
		#$IP6TABLES -A OUTPUT -o $i -p tcp --sport 546:547 --dport 546:547 -j ACCEPT
		#$IP6TABLES -A INPUT -i $i -p udp -d ff02::1:2 --sport 546:547 --dport 546:547 -j ACCEPT
		#$IP6TABLES -A INPUT -i $i -p tcp -d ff02::1:2 --sport 546:547 --dport 546:547 -j ACCEPT
		#$IP6TABLES -A OUTPUT -o $i -p udp -d fe80::/16 --sport 546:547 --dport 546:547 -j ACCEPT
		#$IP6TABLES -A OUTPUT -o $i -p tcp -d fe80::/16 --sport 546:547 --dport 546:547 -j ACCEPT
	done
fi

if [ -s "$BASEDIR/include/ipv6_custom_conntrack" ]; then
	display_c YELLOW "Loading custom IPv6 conntrack rules..."
	. "$BASEDIR/include/ipv6_custom_conntrack"
fi

if [ "$IPV6_CONNTRACK" ]; then
	#$IP6TABLES -A INPUT ${M_STATE} ${C_STATE} NEW -j ACCEPT
	$IP6TABLES -A INPUT ${M_STATE} ${C_STATE} RELATED,ESTABLISHED -j ACCEPT
	$IP6TABLES -A FORWARD ${M_STATE} ${C_STATE} RELATED,ESTABLISHED -j ACCEPT
	#$IP6TABLES -A FORWARD ${M_STATE} ${C_STATE} NEW -j ACCEPT
	$IP6TABLES -A OUTPUT ${M_STATE} ${C_STATE} RELATED,ESTABLISHED -j ACCEPT 
	$IP6TABLES -A OUTPUT ${M_STATE} ${C_STATE} NEW -j ACCEPT
	$IP6TABLES -A INPUT ${M_STATE} ${C_STATE} INVALID -j DROP
	$IP6TABLES -A OUTPUT ${M_STATE} ${C_STATE} INVALID -j DROP
	$IP6TABLES -A FORWARD ${M_STATE} ${C_STATE} INVALID -j DROP
fi

if [ "$IPV6_DNS_REQUESTS_OUT" ]; then
	display_c YELLOW "Adding IPv6 DNS reply allows for trusted DNS servers.."
	for i in $DNS_REQUESTS_OUT; do
		if [[ "$i" =~ "|" ]]; then
			IFS_OLD=${IFS};IFS=\|
			DNSREQ=($i)
			IFS=${IFS_OLD}
			SRCIF=${DNSREQ[0]}
			DNSIP_NUM=${#DNSREQ[@]}
			DNSIP_COUNT_CURR=1
			for ((i=$DNSIP_COUNT_CURR; i <= $DNSIP_NUM; i++)); do
				if [ ${DNSREQ[$i]} ]; then
					${IP6TABLES} -A INPUT -i ${SRCIF} -p udp --sport 53 -s ${DNSREQ[$i]} --destination-port 1024:65535 -j ACCEPT
				fi
			done			
		else
			${IP6TABLES} -A INPUT -i $i -p udp --sport 53 --destination-port 1024:65535 -j ACCEPT
		fi
	done
fi
	if [ -s "$BASEDIR/include/ipv6_custom_blockoutports" ]; then
		display_c YELLOW "Loading custom IPv6 blocked outbound port rules..."
		. "$BASEDIR/include/ipv6_custom_blockoutports"
	fi
	
if [ "$IPV6_BLOCKEDIP" ]; then
	display_c YELLOW "Adding blocked IPv6 addresses... "
	for i in `grep -v "\#" $IPV6_BLOCKEDIP`; do
		if [[ "$i" =~ "|" ]]; then
			IFS_OLD=${IFS};IFS=\|
			ADVBLKIP=($i)
			IFS=${IFS_OLD}
			SRCIF=${ADVBLKIP[0]}
			SRCIP=${ADVBLKIP[1]}
			SRCPORT=${ADVBLKIP[2]}
			DSTIF=${ADVBLKIP[3]}
			DSTIP=${ADVBLKIP[4]}
			DSTPORT=${ADVBLKIP[5]}
			DIRECTION=${ADVBLKIP[6]}
			PROTO=${ADVBLKIP[7]}
			if [ "$SRCIF" ]; then
				SRCIF="-i ${SRCIF} "
			fi
			if [ "$SRCIP" ]; then
				SRCIP="-s ${SRCIP} "
			fi
			if [ "$SRCPORT" ]; then
				SRCPORT="--sport ${SRCPORT/-/:} "
			fi
			if [ "$DSTIF" ]; then
				DSTIF="-o ${DSTIF} "
			fi
			if [ "$DSTIP" ]; then
				DSTIP="-d ${DSTIP} "
			fi
			if [ "$DSTPORT" ]; then
				DSTPORT="--dport ${DSTPORT/-/:} "
			fi
			if [ "$PROTO" ]; then
				case $PROTO in
					TCP|tcp) PROTO="-p tcp";;
					UDP|udp) PROTO="-p udp";;
					*) PROTO="-p ${PROTO}";;
				esac
			fi
			case $DIRECTION in
				IN) DIRECTION="INPUT" ;;
				OUT) DIRECTION="OUTPUT" ;;
				FWD) DIRECTION="FORWARD" ;;
				*) DIRECTION="INPUT" ;;
			esac
			${IP6TABLES} -A ${DIRECTION} ${PROTO} ${SRCIF} ${SRCIP} ${SRCPORT} ${DSTIF} ${DSTIP} ${DSTPORT} -j DROP
		else
			$IP6TABLES -A INPUT -s $i -j DROP
			$IP6TABLES -A OUTPUT -d $i -j DROP
		fi
	done
fi

	if [ "$IPV6_ICMP_CRITICAL" ]; then
			# This is necessary to make sure that PMTU works
			$IP6TABLES -A OUTPUT -p icmpv6 --icmpv6-type time-exceeded \
			-j ACCEPT
			$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type time-exceeded \
			-j ACCEPT
			$IP6TABLES -A OUTPUT -p icmpv6 --icmpv6-type packet-too-big \
			-j ACCEPT
			$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type packet-too-big \
			-j ACCEPT
			if [ "$IPV6_FORWARDRANGE" ]; then
				$IP6TABLES -A FORWARD -p icmpv6 --icmpv6-type time-exceeded -j ACCEPT
				$IP6TABLES -A FORWARD -p icmpv6 --icmpv6-type packet-too-big -j ACCEPT
			fi
	fi
	
	if [ "$IPV6_ICMP_OPT" ]; then
			$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT
			$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type parameter-problem -j ACCEPT
			$IP6TABLES -A OUTPUT -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT
			$IP6TABLES -A OUTPUT -p icmpv6 --icmpv6-type parameter-problem -j ACCEPT
			if [ "$IPV6_FORWARDRANGE" ]; then
				$IP6TABLES -A FORWARD -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT
				$IP6TABLES -A FORWARD -p icmpv6 --icmpv6-type parameter-problem -j ACCEPT
			fi
	fi
	
	if [ -s "$BASEDIR/include/ipv6_custom_mssclamp" ]; then
		display_c YELLOW "Loading custom IPv6 MSS Clamp rules..."
		. "$BASEDIR/include/ipv6_custom_mssclamp"
	fi


	if [ "$IPV6_CLAMPMSS" ]; then
		display_c YELLOW "Clamping IPV6 MSS to PMTU..."
		for i in $IPV6_CLAMPMSS; do
			$IP6TABLES -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
			-j TCPMSS --clamp-mss-to-pmtu -o $i -m tcpmss \
			--mss 1280:1536
			$IP6TABLES -A OUTPUT -p tcp --tcp-flags SYN,RST SYN \
			-j TCPMSS --clamp-mss-to-pmtu -o $i -m tcpmss \
			--mss 1280:1536
		done
	fi

	if [ -s "$BASEDIR/include/ipv6_custom_allowedports" ]; then
		display_c YELLOW "Loading custom IPv6 allowed port rules..."
		. "$BASEDIR/include/ipv6_custom_allowedports"
	fi
	
	if [ "$IPV6_ALLOWED" ]; then
	display_c YELLOW "Adding allowed IPv6 IPs and ports... "
	for i in `grep -v "\#" $IPV6_ALLOWED`; do
		if [[ "$i" =~ "|" ]]; then
			IFS_OLD=${IFS};IFS=\|
			ADVALLOWIP=($i)
			IFS=${IFS_OLD}
			SRCIF=${ADVALLOWIP[0]}
			SRCIP=${ADVALLOWIP[1]}
			SRCPORT=${ADVALLOWIP[2]}
			DSTIF=${ADVALLOWIP[3]}
			DSTIP=${ADVALLOWIP[4]}
			DSTPORT=${ADVALLOWIP[5]}
			DIRECTION=${ADVALLOWIP[6]}
			PROTO=${ADVALLOWIP[7]}
			if [ "$SRCIF" ]; then
				SRCIF="-i ${SRCIF} "
			fi
			if [ "$SRCIP" ]; then
				SRCIP="-s ${SRCIP} "
			fi
			if [ "$SRCPORT" ]; then
				SRCPORT="--sport ${SRCPORT/-/:} "
			fi
			if [ "$DSTIF" ]; then
				DSTIF="-o ${DSTIF} "
			fi
			if [ "$DSTIP" ]; then
				DSTIP="-d ${DSTIP} "
			fi
			if [ "$DSTPORT" ]; then
				DSTPORT="--dport ${DSTPORT/-/:} "
			fi
			if [ "$PROTO" ]; then
				case $PROTO in
					TCP|tcp) PROTO="-p tcp";;
					UDP|udp) PROTO="-p udp";;
					*) PROTO="-p ${PROTO}";;
				esac
			fi
			case $DIRECTION in
				IN) DIRECTION="INPUT" ;;
				OUT) DIRECTION="OUTPUT" ;;
				FWD) DIRECTION="FORWARD" ;;
				*) DIRECTION="INPUT" ;;
			esac
			${IP6TABLES} -A ${DIRECTION} ${PROTO} ${SRCIF} ${SRCIP} ${SRCPORT} ${DSTIF} ${DSTIP} ${DSTPORT} -j ACCEPT
		fi
	done
  fi
	if [ "$IPV6_TCPPORTS" ] || [ "$IPV6_UDPPORTS" ]; then
		display_c YELLOW "Adding allowed IPv6 port: " N
		if [ "$IPV6_TCPPORTS" ]; then
			if [ "$IPTABLES_MULTIPORT" == "yes" ] && [ "$NF_MULTIPORT_MAX_PORTS" ]; then
				IPV6_TCPPORTS=($IPV6_TCPPORTS)
				PORTS_COUNT=${#IPV6_TCPPORTS[@]}
				PORTS_COUNT_CURR=0
				while (( "$PORTS_COUNT_CURR" < "$PORTS_COUNT" )); do
					for ((i=$PORTS_COUNT_CURR; i <=(($PORTS_COUNT_CURR+(($NF_MULTIPORT_MAX_PORTS-1)))); i++)); do
						if [ ${IPV6_TCPPORTS[$i]} ]; then
							PORTS="${PORTS},${IPV6_TCPPORTS[$i]}"
						fi
					done
					echo -en "${PURPLE}Multiport-TCP${DEFAULT_COLOR}/${GREEN}${PORTS#,} "
					$IP6TABLES -A INPUT -p tcp -m multiport --dports ${PORTS#,} -j ACCEPT
					unset PORTS
        			PORTS_COUNT_CURR=$i
				done
				unset i PORTS PORTS_COUNT_CURR PORTS_COUNT
			else
				for i in $IPV6_TCPPORTS; do
					echo -en "${PURPLE}TCP${DEFAULT_COLOR}/${GREEN}$i "
					$IP6TABLES -A INPUT -p tcp --dport $i -j ACCEPT
				done
			fi
		fi
		if [ "$IPV6_UDPPORTS" ]; then
			for i in $IPV6_UDPPORTS; do
				echo -en "${BLUE}UDP${DEFAULT_COLOR}/${GREEN}$i "
				$IP6TABLES -A OUTPUT -p udp --sport 1:65535 --dport $i -j ACCEPT
	        		$IP6TABLES -A INPUT -p udp --dport $i --sport 1:65535 -j ACCEPT
        			$IP6TABLES -A INPUT -p udp --sport $i --dport 1:65535 -j ACCEPT
			done
		fi
		reset_color
	fi
	
	if [ -s "$BASEDIR/include/ipv6_custom_mark" ]; then
		display_c YELLOW "Loading custom IPv6 mark rules..."
		. "$BASEDIR/include/ipv6_custom_mark"
	fi

	if [ -r "$IPV6_MARK" ]; then
		display_c YELLOW "Adding IPv6 mark: "
		for i in `grep -v "\#" $IPV6_MARK`; do
			MARK=( ${i//|/ } )
			INIF=${MARK[0]}
			INIP=${MARK[1]}
			DSTIP=${MARK[2]}
			IPMARK=${MARK[3]}

			case $INIP in
				!*) INNEG="!"
					INIP=${INIP#\!};;
			esac
			case $DSTIP in
				!*) DSTNEG="!"
					DSTIP=${DSTIP#\!};;
			esac

			${IP6TABLES} -t mangle -A PREROUTING -i ${INIF} ${INNEG} -s ${INIP} \
   			     ${DSTNEG} -d ${DSTIP} -j MARK --set-mark=${IPMARK}
			display_c DEFAULT "\t${GREEN}${INNEG}${INIF};${PURPLE}${INIP}${AQUA}->${BLUE}${DSTNEG}${DSTIP};${RED}${IPMARK}"
			unset INNEG DSTNEG
		done
	echo -ne "\n"
	fi

	if [ "$IPV6_ROUTEDCLIENTBLOCK" ]; then
		for i in $IPV6_ROUTEDCLIENTBLOCK; do
			$IP6TABLES -A OUTPUT -d $i -p tcp --syn -j DROP
			$IP6TABLES -A OUTPUT -d $i -p udp ! --dport 32768:65535 -j DROP
			$IP6TABLES -A FORWARD -d $i -p tcp --syn -j DROP
			$IP6TABLES -A FORWARD -d $i -p udp ! --dport 32768:65535 -j DROP
		done
	fi
	

	if [ -s "$BASEDIR/include/ipv6_custom_routing" ]; then
		display_c YELLOW "Loading custom IPv6 routing rules..."
		. "$BASEDIR/include/ipv6_custom_routing"
	fi
	if [ "$IPV6_FORWARDRANGE" ]; then
		for i in $IPV6_FORWARDRANGE; do
			$IP6TABLES -A FORWARD -s $i -j ACCEPT
			$IP6TABLES -A FORWARD -d $i -j ACCEPT
		done
	fi
	
	if [ -s "$BASEDIR/include/ipv6_custom_blockincoming" ]; then
		display_c YELLOW "Loading custom IPv6 incoming blocked port rules..."
		. "$BASEDIR/include/ipv6_custom_blockincoming"
	fi
	if [ $IPV6_BLOCKINCOMING ]; then
		$IP6TABLES -A INPUT -p tcp --syn -j DROP
		$IP6TABLES -A INPUT -p udp -j DROP
	fi
	$IP6TABLES --policy INPUT ${IPV6_PINPUT}
	$IP6TABLES --policy OUTPUT ${IPV6_POUTPUT}
	$IP6TABLES --policy FORWARD ${IPV6_PFORWARD}
fi

if [ $TWEAKS ]; then
	for i in `grep -v "\#" $TWEAKS`; do
		PROCOPT=( ${i//=/ } )
		echo ${PROCOPT[1]} > /proc/sys/net/${PROCOPT[0]}
	done
fi

if [ -x $POSTRUN ]; then
	$POSTRUN
fi