#!/bin/sh
#
startacct()
{
	ipchains -N acctin
	ipchains -N acctio
	ipchains -N acctout
	ipchains -A input  -j acctin
	ipchains -A input  -j acctio
	ipchains -A output -j acctout
	ipchains -A output -j acctio
}
stopacct()
{
	ipchains -F acctin
	ipchains -F acctio
	ipchains -F acctout
	ipchains -X acctin
	ipchains -X acctio
	ipchains -X acctout
}
noacct()
{
	if [ "$2" = "" ]
	then
		mode=""
		target="$1"
	else
		mode="-b"
		target="$2"
	fi
	ipchains -A acctin  -p all $mode -s $1 -d $target -j RETURN
	ipchains -A acctio  -p all $mode -s $1 -d $target -j RETURN
	ipchains -A acctout -p all $mode -s $1 -d $target -j RETURN
}
doacct()
{
	if [ "$2" = "" ]
	then
		ipchains -A acctin  -p all -s 0.0.0.0/0 -d $1
		ipchains -A acctout -p all -s $1 -d 0.0.0.0/0
	else
		ipchains -A acctin  -p tcp -s 0.0.0.0/0 -d $1 $2
		ipchains -A acctout -p tcp -s $1 $2 -d 0.0.0.0/0
	fi
}
create()
{
	ipchains -N $1
}
delete()
{
	ipchains -F $1
	ipchains -X $1
}
allow()
{
if [ "$4" != "any" ]
then
	ifc="$4"
else
	ifc=""
fi
if [ "$ifc" = "" ]
then
	ipchains -A input   -p $1 -b -s $2 -d $3 $5 -j ACCEPT
	ipchains -A forward -p $1 -b -s $2 -d $3 $5 -j ACCEPT
	ipchains -A output  -p $1 -b -s $2 -d $3 $5 -j ACCEPT
else
	if [ "$ifc" != "lo" ]
	then
		ipchains -A input   -p $1 -b -s $3 -d $3 $5 -i lo -j ACCEPT
		ipchains -A forward -p $1 -b -s $3 -d $3 $5 -i lo -j ACCEPT
		ipchains -A output  -p $1 -b -s $3 -d $3 $5 -i lo -j ACCEPT
	fi
	ipchains -A input   -p $1 -b -s $2 -d $3 $5 -i $ifc -j ACCEPT
	ipchains -A forward -p $1 -b -s $2 -d $3 $5 -i $ifc -j ACCEPT
	ipchains -A output  -p $1 -b -s $2 -d $3 $5 -i $ifc -j ACCEPT
fi
}
redirect()
{
if [ "$4" != "any" ]
then
	ifc="$4"
else
	ifc=""
fi
if [ "$ifc" = "" ]
then
	ipchains -A input   -p $1 -b -s $2 -d $3 $5 -j REDIRECT
else
	if [ "$ifc" != "lo" ]
	then
		ipchains -A input   -p $1 -b -s $3 -d $3 $5 -i lo -j REDIRECT
	fi
	ipchains -A input   -p $1 -b -s $2 -d $3 $5 -i $ifc -j REDIRECT
fi
}
virtual()
{
chain="$1"
shift
if [ "$4" != "any" ]
then
	ifc="$4"
else
	ifc=""
fi
if [ "$ifc" = "" ]
then
	ipchains -A input   -p $1 -b -s $2 -d $3 $5 -j $chain
	ipchains -A forward -p $1 -b -s $2 -d $3 $5 -j $chain
	ipchains -A output  -p $1 -b -s $2 -d $3 $5 -j $chain
else
	if [ "$ifc" != "lo" ]
	then
		ipchains -A input   -p $1 -b -s $3 -d $3 $5 -i lo -j $chain
		ipchains -A forward -p $1 -b -s $3 -d $3 $5 -i lo -j $chain
		ipchains -A output  -p $1 -b -s $3 -d $3 $5 -i lo -j $chain
	fi
	ipchains -A input   -p $1 -b -s $2 -d $3 $5 -i $ifc -j $chain
	ipchains -A forward -p $1 -b -s $2 -d $3 $5 -i $ifc -j $chain
	ipchains -A output  -p $1 -b -s $2 -d $3 $5 -i $ifc -j $chain
fi
}
connect()
{
if [ "$4" != "any" ]
then
	ifc="$4"
else
	ifc=""
fi
if [ "$ifc" = "" ]
then
	ipchains -A input   -p $1 -s $2 -d $3 $5      -j ACCEPT
	ipchains -A input   -p $1 -d $2 -s $3 $5 ! -y -j ACCEPT
	ipchains -A forward -p $1 -s $2 -d $3 $5      -j ACCEPT
	ipchains -A forward -p $1 -d $2 -s $3 $5 ! -y -j ACCEPT
	ipchains -A output  -p $1 -s $2 -d $3 $5      -j ACCEPT
	ipchains -A output  -p $1 -d $2 -s $3 $5 ! -y -j ACCEPT
else
	if [ "$ifc" != "lo" ]
	then
		ipchains -A input   -p $1 -s $3 -d $3 $5 -i lo      -j ACCEPT
		ipchains -A input   -p $1 -d $3 -s $3 $5 -i lo ! -y -j ACCEPT
		ipchains -A forward -p $1 -s $3 -d $3 $5 -i lo      -j ACCEPT
		ipchains -A forward -p $1 -d $3 -s $3 $5 -i lo ! -y -j ACCEPT
		ipchains -A output  -p $1 -s $3 -d $3 $5 -i lo      -j ACCEPT
		ipchains -A output  -p $1 -d $3 -s $3 $5 -i lo ! -y -j ACCEPT
	fi
	ipchains -A input   -p $1 -s $2 -d $3 $5 -i $ifc      -j ACCEPT
	ipchains -A input   -p $1 -d $2 -s $3 $5 -i $ifc ! -y -j ACCEPT
	ipchains -A forward -p $1 -s $2 -d $3 $5 -i $ifc      -j ACCEPT
	ipchains -A forward -p $1 -d $2 -s $3 $5 -i $ifc ! -y -j ACCEPT
	ipchains -A output  -p $1 -s $2 -d $3 $5 -i $ifc      -j ACCEPT
	ipchains -A output  -p $1 -d $2 -s $3 $5 -i $ifc ! -y -j ACCEPT
fi
}
deny()
{
	if [ "$1" != "0.0.0.0/0" ]
	then
		mode="-b"
	else
		mode=""
	fi
	ipchains -A input   -p all $mode -s $1 -d 0.0.0.0/0 -j DENY -l
	ipchains -A forward -p all $mode -s $1 -d 0.0.0.0/0 -j DENY -l
	ipchains -A output  -p all $mode -s $1 -d 0.0.0.0/0 -j DENY -l
}
ignore()
{
	if [ "$3" != "" ]
	then
		ipchains -A input   -p udp -b -s $1 -d $2 $3 -j DENY
		ipchains -A forward -p udp -b -s $1 -d $2 $3 -j DENY
		ipchains -A output  -p udp -b -s $1 -d $2 $3 -j DENY
		ipchains -A input   -p tcp -b -s $1 -d $2 $3 -j DENY
		ipchains -A forward -p tcp -b -s $1 -d $2 $3 -j DENY
		ipchains -A output  -p tcp -b -s $1 -d $2 $3 -j DENY
	else
		ipchains -A input   -p all -b -s $1 -d $2 -j DENY
		ipchains -A forward -p all -b -s $1 -d $2 -j DENY
		ipchains -A output  -p all -b -s $1 -d $2 -j DENY
	fi
}
forward()
{
	ipchains -A input   -p all -b -s $1 -d $2 -j ACCEPT
	ipchains -A forward -p all -b -s $1 -d $2 -j ACCEPT
	ipchains -A output  -p all -b -s $1 -d $2 -j ACCEPT
}
flush()
{
	ipchains -F input
	ipchains -F forward
	ipchains -F output
}
policy()
{
	case "$1" in
		deny)	ipchains -P input   DENY
			ipchains -P forward DENY
			ipchains -P output  DENY
			;;
		accept)	ipchains -P input   ACCEPT
			ipchains -P forward ACCEPT
			ipchains -P output  ACCEPT
			;;
	esac
}
sourceaddressverify()
{
	case "$1" in
		on)	mode=1
			;;
		off)	mode=0
			;;
		*)	return
			;;
	esac
	if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]
	then
		for i in /proc/sys/net/ipv4/conf/*/rp_filter
		do
			echo $mode > $i
		done
	fi
}
ipforwarding()
{
	case "$1" in
		on)	mode=1
			;;
		off)	mode=0
			;;
		*)	return
			;;
	esac
	if [ -e /proc/sys/net/ipv4/conf/all/forwarding ]
	then
		for i in /proc/sys/net/ipv4/conf/*/forwarding
		do
			echo $mode > $i
		done
	fi
}
start()
{
	#
	# flush all chain rules
	#
	flush
	#
	# deny all packets by default
	#
	policy deny
	#
	# let the kernel routing do IP spoofing prevention
	#
	sourceaddressverify off
	#
	# create accounting chains
	#
	startacct
	#
	# create dialup chains
	#
	create ppp
	create diald
	#
	# do not account internal traffic
	#
	noacct 10.0.0.0/8
	noacct 10.0.0.0/8       a.b.c.0/24
	#
	# allow all packets from localhost to localhost
	#
	allow all 127.0.0.0/8 127.0.0.0/8 lo
	#
	# socks/proxy redirection
	#
	redirect tcp 10.1.9.0/24 a.b.c.11/32 any 8080
	redirect tcp 10.1.9.0/24 a.b.c.11/32 any 1080
	#
	# allow all internal traffic
	#
	forward 10.0.0.0/8 10.0.0.0/8
	forward a.b.c.0/24 10.0.0.0/8
	#
	# hmmm, dhcp...
	#
	allow udp 0.0.0.0/0  255.255.255.255/32 bootps
	ignore    0.0.0.0/0  255.255.255.255/32 bootps
	#
	# now for the internet traffic
	#
	virtual ppp all 0.0.0.0/0 0.0.0.0/0 any
	virtual diald all 0.0.0.0/0 0.0.0.0/0 any
	#
	# Catchall for logging
	#
	deny 0.0.0.0/0
	#
	# firewall set up, enable ip forwarding
	#
	ipforwarding on
}
stop()
{
	#
	# disallow ip forwarding first
	#
	ipforwarding off
	#
	# flush all chain rules
	#
	flush
	#
	# delete dialup chains
	#
	delete ppp
	delete diald
	#
	# delete accounting chains
	#
	stopacct
	#
	# deny all packets by default
	#
	policy accept
	#
	# let the kernel routing do IP spoofing prevention
	#
	sourceaddressverify off
}
case "$1" in
	start)	echo "Starting Firewall..."
		start
		;;
	stop)	echo "Stopping Firewall..."
		stop
		;;
esac
