#!/bin/bash -x
#
# Copyright (C) 2008, 2009  Eugene Prokopiev <enp@altlinux.org>
#
# fw-scripts functions
#
# This file 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 2 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, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.


IPTABLES="/sbin/iptables"

function fw_clear()
{
	$IPTABLES -F
	$IPTABLES -X
	$IPTABLES -t nat -F
	$IPTABLES -t nat -X
}

# params: policy name
function fw_policy()
{
	$IPTABLES -P INPUT   $1
	$IPTABLES -P OUTPUT  $1
	$IPTABLES -P FORWARD $1
}


function fw_define_allowed() 
{
	$IPTABLES -N allowed
	[ -z "$NETFLOW_PARAMS" ] || $IPTABLES -A allowed -j NETFLOW
	[ -z "$ULOG_PARAMS" ] || $IPTABLES -A allowed -j ULOG $ULOG_PARAMS --ulog-prefix allow
	$IPTABLES -A allowed -j ACCEPT
}

function fw_define_rejected()
{
	$IPTABLES -N rejected
	[ -z "$NETFLOW_PARAMS"  ] || $IPTABLES -A rejected -j NETFLOW
	[ -z "$ULOG_PARAMS"  ] || $IPTABLES -A rejected -j ULOG $ULOG_PARAMS --ulog-prefix drop
	[ -z "$LOG_PARAM_CRITERIA" ] && [ -z "$LOG_PARAM_PREFIX" ] || $IPTABLES -A rejected `echo "$LOG_PARAM_CRITERIA"` -j LOG --log-prefix "`echo "$LOG_PARAM_PREFIX"`"
	$IPTABLES -A rejected -p tcp -j REJECT --reject-with tcp-reset
	$IPTABLES -A rejected -j REJECT --reject-with icmp-port-unreachable
}

# params: interface name
function fw_allow_interface()
{
	$IPTABLES -A INPUT  -i $1 -j allowed
	$IPTABLES -A OUTPUT -o $1 -j allowed
}

# params: incoming and outgoing interface names
function fw_forward_between_interfaces()
{
	$IPTABLES -A FORWARD  -i $1 -o $2 -j allowed
	$IPTABLES -A FORWARD  -o $1 -i $2 -j allowed
}

function fw_validate_tcp()
{
	$IPTABLES -A INPUT -p tcp ! --syn -m state --state new -j rejected
	$IPTABLES -A INPUT -p tcp -m state --state established,related -j allowed
	$IPTABLES -A OUTPUT -p tcp ! --syn -m state --state new -j rejected
	$IPTABLES -A OUTPUT -p tcp -m state --state established,related -j allowed
	$IPTABLES -A FORWARD -p tcp ! --syn -m state --state new -j rejected
	$IPTABLES -A FORWARD -p tcp -m state --state established,related -j allowed
}

function fw_allow_icmp()
{
	$IPTABLES -A INPUT  -p icmp -j allowed
	$IPTABLES -A OUTPUT -p icmp -j allowed
}

function fw_allow_client_udp()
{
	$IPTABLES -A INPUT -m multiport -p udp --port 1024:65535 -j allowed
	$IPTABLES -A OUTPUT -m multiport -p udp --port 1024:65535 -j allowed
}

# params: source address, destination address, destination port, redirected host, redirected port, fake source address for incoming packets
#         destination address, source address, source port  for outgoing packets
function fw_allow_udp()
{
	case $# in
	2)
		$IPTABLES -A INPUT  -p udp -s $1 -d $2 -j allowed
		$IPTABLES -A OUTPUT -p udp -d $1 -s $2 -j allowed
		;;
	3)
		$IPTABLES -A INPUT  -p udp -s $1 -d $2 --dport $3 -j allowed
		$IPTABLES -A OUTPUT -p udp -d $1 -s $2 --sport $3 -j allowed
		;;
	6)
		$IPTABLES -t nat -A PREROUTING -p udp -s $1 -d $2 --dport $3 -j DNAT --to-destination $4:$5
		$IPTABLES -A FORWARD -p udp -s $1 -d $4 --dport $5 -j allowed
		$IPTABLES -A FORWARD -p udp -d $1 -s $4 --sport $5 -j allowed
		$IPTABLES -t nat -A POSTROUTING -p udp -s $1 -d $4 --dport $5 -j SNAT --to-source $6
		;;
	*)
		echo wrong arguments count
		;;
	esac
}

function fw_allow_client_tcp()
{
	$IPTABLES -A OUTPUT -p tcp --syn -j allowed
}

# params: source address, fake destination address, fake source address, destination address
function fw_allow_host()
{
	$IPTABLES -t nat -A PREROUTING -s $1 -d $2 -j DNAT --to-destination $4
	$IPTABLES -t nat -A POSTROUTING -s $1 -d $4 -j SNAT --to-source $3
	$IPTABLES -A FORWARD -s $1 -d $4 -j allowed
	$IPTABLES -A FORWARD -s $4 -d $1 -j allowed
}

function fw_allow_tcp()
{
	case $# in
	2)
		# params: source address, destination address 
		# for new incoming packets
		$IPTABLES -A INPUT -p tcp --syn -s $1 -d $2 -j allowed
		;;
	3)
		# params: source address, destination address, destination port 
		# for new incoming packets
		$IPTABLES -A INPUT -p tcp --syn -s $1 -d $2 --dport $3 -j allowed
		;;
	4)
		# params: source address, destination address, destination port, redirected port 
		# for new incoming packets
		$IPTABLES -t nat -A PREROUTING -p tcp -s $1 -d $2 --dport $3 -j DNAT --to-destination $2:$4
		$IPTABLES -A INPUT -p tcp --syn -s $1 -d $2 --dport $4 -j allowed
		;;
	5)
		# params: source address, destination address, destination port, redirected host, redirected port 
		# for new incoming packets
		$IPTABLES -t nat -A PREROUTING -p tcp -s $1 -d $2 --dport $3 -j DNAT --to-destination $4:$5
		$IPTABLES -A FORWARD -p tcp --syn -s $1 -d $4 --dport $5 -j allowed
		;;
	6)
		# params: source address, destination address, destination port, redirected host, redirected port, fake source address 
		# for new incoming packets
		$IPTABLES -t nat -A PREROUTING -p tcp -s $1 -d $2 --dport $3 -j DNAT --to-destination $4:$5
		$IPTABLES -A FORWARD -p tcp --syn -s $1 -d $4 --dport $5 -j allowed
		$IPTABLES -t nat -A POSTROUTING -p tcp -s $1 -d $4 --dport $5 -j SNAT --to-source $6
		;;
	*)
		echo wrong arguments count
		;;
	esac
}

function fw_forward_to_interface()
{
	case $# in
	2)
		# params: destination interface name, source address for outgoing packets
		#         source interface name, destination address for incoming packets
		$IPTABLES -A FORWARD -o $1 -s $2 -j allowed
		$IPTABLES -A FORWARD -i $1 -d $2 -j allowed
		;;
	3)
		# params: destination interface name, source address, fake source address for outgoing packets
		#         source interface name, destination address for incoming packets
		$IPTABLES -A FORWARD -o $1 -s $2 -j allowed
		$IPTABLES -A FORWARD -i $1 -d $2 -j allowed
		$IPTABLES -t nat -A POSTROUTING -o $1 -s $2 -j SNAT --to-source $3
		;;
	4)
		# params: destination interface name, source address, fake source address, destination address for outgoing packets
		#         source interface name, destination address for incoming packets
		$IPTABLES -A FORWARD -o $1 -s $2 -d $4 -j allowed
		$IPTABLES -A FORWARD -i $1 -d $2 -s $4 -j allowed
		$IPTABLES -t nat -A POSTROUTING -o $1 -s $2 -d $4 -j SNAT --to-source $3
		;;
	*)
		echo wrong arguments count
		;;
	esac
}

function fw_drop()
{
	$IPTABLES -A INPUT   -j rejected
	$IPTABLES -A OUTPUT  -j rejected
	$IPTABLES -A FORWARD -j rejected
}

function fw_begin()
{
	fw_clear
	fw_policy DROP
	fw_define_allowed
	fw_define_rejected
	fw_allow_interface lo
	fw_allow_icmp
	fw_allow_client_udp
	fw_allow_client_tcp
	fw_validate_tcp
}

function fw_begin_no_client_udp()
{
	fw_clear
	fw_policy DROP
	fw_define_allowed
	fw_define_rejected
	fw_allow_interface lo
	fw_allow_icmp
	fw_allow_client_tcp
	fw_validate_tcp
}

function fw_end()
{
	fw_drop
}
