#!/bin/sh - keep it for file(1) to get bourne shell script result

__set_modules()
{
	local _x _y _z v old_IFS kernelver
	{
		read _x _y v _z
		old_IFS=$IFS
		IFS='.'
		set -- $v
		IFS=$old_IFS

		# strip _* or -* from versions like: "2.6.25_vanilla-1", "2.6.25-1"
		kernelver=$(printf "%.3d%.3d%.3d" $1 $2 ${3%%[-_]*})
	} < /proc/version

	if [ "$kernelver" -lt "002006022" ]; then
		__NAT_MODULES=ip_nat
		__IP4_CONNTRACK=ip_conntrack
		__IP6_CONNTRACK=
		__NF_CONNTRACK=no
	else
		__NAT_MODULES=nf_nat
		__IP4_CONNTRACK=nf_conntrack_ipv4
		__IP6_CONNTRACK=nf_conntrack_ipv6
		__NF_CONNTRACK=yes
	fi

}

generic_load_modules()
{
	local i conn b

	__set_modules
	is_yes $__NF_CONNTRACK || return

	_modprobe die -a x_tables
	_modprobe die -a nf_conntrack

	if [ "$CONNTRACK_MODULES" = "all" -o -z "$CONNTRACK_MODULES" ] ; then
		conn=""
		for i in /lib/modules/`uname -r`/kernel/net/netfilter/nf_conntrack_*.ko{.gz,} ; do
			if [ -f "$i" ]; then
				for b in $CONNTRACK_MODULES_BLACKLIST ; do
					if [[ "$i" = */nf_conntrack_$b.ko* ]]; then
						i=
						break
					fi
				done
				if [ -n "$i" ]; then
					i=${i%.ko(.gz|)}
					conn="$conn ${i##*/}"
				fi
			fi
		done
		_modprobe die -a $conn
	elif [ "$CONNTRACK_MODULES" != "none" ] ; then
		conn=""
		for i in $CONNTRACK_MODULES ; do
			conn="$conn nf_conntrack_$i"
		done
		_modprobe die -a $conn
	fi
}

ipv4_load_modules()
{
	local i conn b

	__set_modules
	_modprobe die -a ip_tables
	_modprobe die -a $__IP4_CONNTRACK

	if [ "$CONNTRACK_MODULES" = "all" -o -z "$CONNTRACK_MODULES" ] ; then
	    conn=""
	    for i in /lib/modules/`uname -r`/kernel/net/ipv4/netfilter/ip_conntrack_*.ko{.gz,} ; do
		if [ -f "$i" ]; then
			for b in $CONNTRACK_MODULES_BLACKLIST ; do
				if [[ "$i" = */ip_conntrack_$b.ko* ]]; then
					i=
					break
				fi
			done
			if [ -n "$i" ]; then
				i=${i%.ko(.gz|)}
				conn="$conn ${i##*/}"
			fi
		fi
	    done
	    _modprobe die -a $conn
	elif [ "$CONNTRACK_MODULES" != "none" ] ; then
	    conn=""
	    for i in $CONNTRACK_MODULES ; do
		    conn="$conn ip_conntrack_$i"
	    done
	    _modprobe die -a $conn
	fi

	if echo "$ipv4_TABLES" | awk '!/nat/ {exit 1}' ; then
	    if [ "$NAT_MODULES" = "all" -o -z "$NAT_MODULES" ] ; then
		conn=""
		for i in /lib/modules/`uname -r`/kernel/net/ipv4/netfilter/${__NAT_MODULES}_*.ko{.gz,} ; do
			if [ -f "$i" ]; then
				for b in $NAT_MODULES_BLACKLIST ; do
					if [[ "$i" = */${__NAT_MODULES}_$b.ko* ]]; then
						i=
						break
					fi
				done
				if [ -n "$i" ]; then
					i=${i%.ko(.gz|)}
					conn="$conn ${i##*/}"
				fi
			fi
		done
		_modprobe die -a $conn
	    elif [ "$NAT_MODULES" != "none" ] ; then
		conn=""
		for i in $NAT_MODULES ; do
			    conn="$conn ${__NAT_MODULES}_$i"
		done
		_modprobe die -a $conn
	    fi
	fi
}

ipv6_load_modules()
{
	__set_modules
	_modprobe die -a ip6_tables
	[ -n "$__IP6_CONNTRACK" ] && _modprobe die -a $__IP6_CONNTRACK
}

generic_remove_modules()
{
	local modules

	modules="`lsmod | grep "^xt_" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	modules="`lsmod | grep "^nf_" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	modules="`lsmod | grep "^nfnetlink" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	rmmod x_tables
}

ipv4_remove_modules()
{
	local modules

	__set_modules
	modules="`lsmod | grep "^ipt_" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	modules="`lsmod | grep "^iptable_" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	modules="`lsmod | grep "^${__NAT_MODULES}" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	modules="`lsmod | grep "^ip_conntrack" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	rmmod ip_tables
}

ipv6_remove_modules()
{
	local modules

	modules="`lsmod | grep "^ip6t_" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	modules="`lsmod | grep "^ip6table_" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	rmmod ip6_tables
}

setup_rules()
{
	local table TABLES chain policy CHAINS proto ipt

	case "$1" in
	    ipv4)
		proto="ipv4"
		TABLES="$ipv4_TABLES" 
		ipt="$iptables"
		;;
	    ipv6)
		proto="ipv6"
		TABLES="$ipv6_TABLES" 
		ipt="$ip6tables"
		;;
	    *)
		return
		;;
	esac
	[ -z "$TABLES" ] && return
	for table in $TABLES; do
		. $FIREWALL_DIR/$proto/$table
		[ -z "$CHAINS" ] && continue
		for chain in $CHAINS ; do
			$(${proto}_${table}_${chain}_rules)
			eval policy="\$${proto}_${table}_${chain}"
			$ipt -t $table -P $chain $policy
		done
	done
}

clean_rules()
{
	local table chain CHAINS

	case "$1" in
	    ipv4)
		proto="ipv4"
		TABLES="$ipv4_TABLES" 
		ipt="$iptables"
		;;
	    ipv6)
		proto="ipv6"
		TABLES="$ipv6_TABLES" 
		ipt="$ip6tables"
		;;
	    *)
		return
		;;
	esac
	[ -z "$TABLES" ] && TABLES=filter
	for table in $TABLES ; do
		$ipt -t $table -F
		. $FIREWALL_DIR/$proto/$table
		[ -z "$CHAINS" ] && continue
		for chain in $CHAINS ; do
			$ipt -t $table -P $chain ACCEPT
		done
	done

	# 2nd step because of dependencies
	for table in $TABLES ; do
		$ipt -t $table -X
	done
}

ipv4_pre_init_block()
{
	$iptables -P INPUT DROP
	$iptables -P OUTPUT ACCEPT
	$iptables -P FORWARD DROP

	$iptables -A INPUT -i lo -j ACCEPT
	$iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
}

ipv6_pre_init_block()
{
	local ns

	$ip6tables -P INPUT DROP
	$ip6tables -P OUTPUT DROP
	$ip6tables -P FORWARD DROP

	for ns in `awk '/^nameserver/ && /:/ { print $2 }' < /etc/resolv.conf` ; do
		[ -z "$ns" ] && continue
		$ip6tables -A INPUT -p udp -s $ns --sport 53 -j ACCEPT
		$ip6tables -A OUTPUT -p udp -d $ns --dport 53 -j ACCEPT
	done

	$ip6tables -A INPUT -i lo -s ::1 -j ACCEPT
	$ip6tables -A OUTPUT -o lo -d ::1 -j ACCEPT
}

ipv4_forward_set()
{
	# Turn IP forwarding on or off. We do this before bringing up the
	# interfaces to make sure we don't forward when we shouldn't, and
	# we do it even if networking isn't configured (why not?).
	if [ -d /proc/sys/net/ipv4 ]; then
		value=$1
		if [ $value != 1 ]; then
			value=0
			message="Disabling IPv4 packet forwarding"
		else
			value=1
			message="Enabling IPv4 packet forwarding"
		fi
		show "$message"
		busy
		if [ ! -f /proc/sys/net/ipv4/ip_forward ] ; then
			deltext
			fail
			exit 1
		else
			echo "$value" > /proc/sys/net/ipv4/ip_forward
			deltext
			ok
		fi
	fi
}

ipv4_spoof_protection()
{
	# This is the best method: turn on Source Address Verification and get
	# spoof protection on all current and future interfaces.
	if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then
		show "Setting up IP spoofing protection"
		busy
		for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
			echo 1 > $f
		done
		deltext
		ok
	else
		deltext
		fail
		echo "PROBLEMS SETTING UP IP SPOOFING PROTECTION.  BE WORRIED!"
	fi
}

ipv6_forward_set()
{
	if [ -e /proc/sys/net/ipv6/conf/all/forwarding ]; then
		value=$1
		if [ $value != 1 ]; then
			value=0
			message="Disabling IPv6 packet forwarding"
		else
			value=1
			message="Enabling IPv6 packet forwarding"
		fi
		show "$message"
		busy
		for f in /proc/sys/net/ipv6/conf/*/forwarding; do
			echo $value > $f
		done
		deltext
		ok
	fi
}
