ipv4_load_modules()
{
	local i conn

	_modprobe die -k -a ip_tables

	conn=""
	for i in /lib/modules/`uname -r`/kernel/net/ipv4/netfilter/ip_conntrack_*.o ; do
		conn="$conn `echo $i | awk '!/ftp|irc|egg/ { gsub(/.*\//,"") ; gsub(/\.o$/,"") ; print $1 }'`"
	done
	_modprobe die -k -a ip_conntrack \
		`[ -z "$CONNTRACK_HASHSIZE" ] || echo "hashsize=$CONNTRACK_HASHSIZE"`
	_modprobe die -k -a ip_conntrack_ftp \
				`[ -z "$FTP_PORTS" ] || ports=$FTP_PORTS` \
				`[ -z "$FTP_FXP" ] || echo "fxp=1"`
	_modprobe die -k -a ip_conntrack_irc \
				`[ -z "$FTP_PORTS" ] || ports=$IRC_PORTS`
	_modprobe die -k -a ip_conntrack_egg \
				`[ -z "$FTP_PORTS" ] || ports=$EGGDROP_PORTS`
	_modprobe die -k -a $conn

	if echo "$ipv4_TABLES" | awk '!/nat/ {exit 1}' ; then
		conn=""
		for i in /lib/modules/`uname -r`/kernel/net/ipv4/netfilter/ip_nat_*.o ; do
			conn="$conn `echo $i | awk '!/ftp|irc/ { gsub(/.*\//,"") ; gsub(/\.o$/,"") ; print $1 }'`"
		done
		_modprobe die -k -a ip_nat_ftp \
				`[ -z "$FTP_PORTS" ] || ports=$FTP_PORTS`
		_modprobe die -k -a ip_nat_irc \
				`[ -z "$FTP_PORTS" ] || ports=$IRC_PORTS`
		_modprobe die -k -a $conn
	fi
}

ipv6_load_modules()
{
	_modprobe die -k -a ip6_tables
}

ipv4_remove_modules()
{
	local modules

	modules="`lsmod | grep "^ipt_" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	modules="`lsmod | grep "^ip_nat_" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	modules="`lsmod | grep "^ip_conntrack" | cut -f 1 -d ' '`"
	[ -n "$modules" ] && rmmod $modules
	modules="`lsmod | grep "^iptable_" | 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
}

ipv4_create_chains()
{
	echo -n "Create some usefull chains (IPv4): "
	echo -n "LDROP "
	$iptables -N LDROP
	$iptables -A LDROP -p tcp  -j LOG --log-level info --log-prefix "TCP Drop "
	$iptables -A LDROP -p udp  -j LOG --log-level info --log-prefix "UDP Drop "
	$iptables -A LDROP -p icmp -j LOG --log-level info --log-prefix "ICMP Drop "
	$iptables -A LDROP -p gre  -j LOG --log-level info --log-prefix "GRE Drop "
	$iptables -A LDROP -f -j LOG --log-level emerg --log-prefix "FRAG. Drop "
	$iptables -A LDROP -j DROP

	echo -n "WATCH "
	$iptables -N WATCH
	$iptables -A WATCH -m limit -j LOG --log-level warn --log-prefix "ACCEPT "
	$iptables -A WATCH -j ACCEPT

	# Log and drop portscans:
	echo -n "SCAN "
	$iptables -N SCAN
	$iptables -A SCAN -m limit --limit 30/m -j LOG --log-prefix "PORTSCAN " --log-ip-options --log-tcp-options --log-level 1
	$iptables -A SCAN -j DROP

	# Log and drop DOS attacks:
	echo -n "DOS "
	$iptables -N DOS
	$iptables -A DOS -p tcp --syn -m limit -j LOG --log-prefix "SYN Flood "
	$iptables -A DOS -p icmp -m limit -j LOG --log-prefix "PING Flood "
	$iptables -A DOS -j DROP

	# Drop new connections (syn-flood protection):
	echo -n "SAFEDROP "
	$iptables -N SAFEDROP
	$iptables -A SAFEDROP -p tcp -m state --state NEW -m limit --limit 1/s -j LDROP
	$iptables -A SAFEDROP -p tcp -m state --state NEW -j DOS
	$iptables -A SAFEDROP -j LDROP

	# Accept new connections (syn-flood protection):
	echo -n "SAFEACCEPT "
	$iptables -N SAFEACCEPT
	$iptables -A SAFEACCEPT -p tcp -m state --state NEW -m limit --limit 1/s -j ACCEPT
	$iptables -A SAFEACCEPT -p udp -m state --state NEW -j ACCEPT
	$iptables -A SAFEACCEPT -p tcp -m state --state NEW -j DOS

	echo -n "ICMP "
	# If you deny all ICMP messages you head for trouble since it would
	# break lots of tcp/ip algorithm
	$iptables -N ICMP
	# Ping of death:
	$iptables -A ICMP -p icmp --icmp-type echo-request -m limit --limit 1/s -j WATCH
	$iptables -A ICMP -p icmp --icmp-type echo-request -j DOS
	# others:
	$iptables -A ICMP -p icmp --icmp-type echo-reply                   -j ACCEPT
	$iptables -A ICMP -p icmp --icmp-type destination-unreachable      -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   network-unreachable        -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   host-unreachable           -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   protocol-unreachable       -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   port-unreachable           -j ACCEPT
	$iptables -A ICMP -p icmp --icmp-type   fragmentation-needed       -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   source-route-failed        -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   network-unknown            -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   host-unknown               -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   network-prohibited         -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   host-prohibited            -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   TOS-network-unreachable    -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   TOS-host-unreachable       -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   communication-prohibited   -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   host-precedence-violation  -j LDROP
	$iptables -A ICMP -p icmp --icmp-type   precedence-cutoff          -j LDROP
	$iptables -A ICMP -p icmp --icmp-type source-quench                -j WATCH
	$iptables -A ICMP -p icmp --icmp-type redirect                     -j LDROP
	$iptables -A ICMP -p icmp --icmp-type   network-redirect           -j LDROP
	$iptables -A ICMP -p icmp --icmp-type   host-redirect              -j LDROP
	$iptables -A ICMP -p icmp --icmp-type   TOS-network-redirect       -j LDROP
	$iptables -A ICMP -p icmp --icmp-type   TOS-host-redirect          -j LDROP
	$iptables -A ICMP -p icmp --icmp-type router-advertisement         -j WATCH
	$iptables -A ICMP -p icmp --icmp-type router-solicitation          -j WATCH
	$iptables -A ICMP -p icmp --icmp-type time-exceeded                -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   ttl-zero-during-transit    -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   ttl-zero-during-reassembly -j WATCH
	$iptables -A ICMP -p icmp --icmp-type parameter-problem            -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   ip-header-bad              -j WATCH
	$iptables -A ICMP -p icmp --icmp-type   required-option-missing    -j WATCH
	$iptables -A ICMP -p icmp --icmp-type timestamp-request            -j LDROP
	$iptables -A ICMP -p icmp --icmp-type timestamp-reply              -j LDROP
	$iptables -A ICMP -p icmp --icmp-type address-mask-request         -j LDROP
	$iptables -A ICMP -p icmp --icmp-type address-mask-reply           -j LDROP
	$iptables -A ICMP -p icmp -j LDROP
	echo
}

ipv6_create_chains()
{
	echo -n "Create some usefull chains (IPv6): "
	echo -n "LDROP "
	$ip6tables -N LDROP
	$ip6tables -A LDROP -p tcp -j LOG --log-level info --log-prefix "TCP Drop "
	$ip6tables -A LDROP -p udp -j LOG --log-level info --log-prefix "UDP Drop "
	$ip6tables -A LDROP -p ipv6-icmp -j LOG --log-level info --log-prefix "ICMPv6 Drop "
#	$ip6tables -A LDROP -f -j LOG --log-level emerg --log-prefix "FRAG. Drop "
	$ip6tables -A LDROP -j DROP

	echo -n "WATCH "
	$ip6tables -N WATCH
	$ip6tables -A WATCH -m limit -j LOG --log-level warn --log-prefix "ACCEPT "
	$ip6tables -A WATCH -j ACCEPT

	# Log and drop portscans:
	echo -n "SCAN "
	$ip6tables -N SCAN
	$ip6tables -A SCAN -m limit --limit 30/m -j LOG --log-prefix "PORTSCAN " --log-ip-options --log-tcp-options --log-level 1
	$ip6tables -A SCAN -j DROP

	# Log and drop DOS attacks:
	echo -n "DOS "
	$ip6tables -N DOS
	$ip6tables -A DOS -p tcp --syn -m limit -j LOG --log-prefix "SYN Flood "
	$ip6tables -A DOS -p ipv6-icmp -m limit -j LOG --log-prefix "PING Flood "
	$ip6tables -A DOS -j DROP

	# Drop new connections (syn-flood protection):
	echo -n "SAFEDROP "
	$ip6tables -N SAFEDROP
	$ip6tables -A SAFEDROP -p tcp --syn -m limit --limit 1/s -j LDROP
	$ip6tables -A SAFEDROP -p tcp --syn -j DOS
	$ip6tables -A SAFEDROP -j LDROP

	# Accept new connections (syn-flood protection):
	echo -n "SAFEACCEPT "
	$ip6tables -N SAFEACCEPT
	$ip6tables -A SAFEACCEPT -p tcp --syn -m limit --limit 1/s -j ACCEPT
	$ip6tables -A SAFEACCEPT -p udp -j ACCEPT
	$ip6tables -A SAFEACCEPT -p tcp --syn -j DOS

	echo -n "ICMP6 "
	# If you deny all ICMP messages you head for trouble since it would
	# break lots of tcp/ip algorithm
	$ip6tables -N ICMP6
	# Ping of death:
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type echo-request -m limit --limit 1/s -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type echo-request -j DOS
	# others:                   
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type echo-reply                   -j ACCEPT
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type destination-unreachable      -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type   no-route                   -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type   communication-prohibited   -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type   address-unreachable        -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type   port-unreachable           -j ACCEPT
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type packet-too-big               -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type time-exceeded                -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type   ttl-zero-during-transit    -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type   ttl-zero-during-reassembly -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type parameter-problem            -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type   bad-header                 -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type   unknown-header-type        -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type   unknown-option             -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type redirect                     -j WATCH
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type router-solicitation          -j ACCEPT
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type router-advertisement         -j ACCEPT
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type neighbour-solicitation       -j ACCEPT
	$ip6tables -A ICMP6 -p ipv6-icmp --icmp-type neighbour-advertisement      -j ACCEPT
	$ip6tables -A ICMP6 -p ipv6-icmp -j LDROP
	echo
}

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
		CHAINS="`cat $FIREWALL_DIR/$proto/$table/chains`"
		[ -z "$CHAINS" ] && continue
		for chain in $CHAINS ; do
			. $FIREWALL_DIR/$proto/$table/$chain
			${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
		CHAINS="`cat $FIREWALL_DIR/$proto/$table/chains`"
		[ -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
}

# This must be last line !
# vi:syntax=sh:tw=78:ts=8:sw=4
