#!/bin/bash
#Copyright 2003 William Stearns <wstearns@pobox.com>
#Released under the GPL.

Me='fwdsrcaddrtype'
MyVersion='0.3.3'
DefaultActions='DROP'

[ -r /etc/firebricks/firebricks.conf ] &&			. /etc/firebricks/firebricks.conf
[ -r /etc/firebricks/$Me.conf ] &&				. /etc/firebricks/$Me.conf
[ -r ${FBLibDir:-'/usr/lib/firebricks/'}/firebrickslib ] &&	. ${FBLibDir:-'/usr/lib/firebricks/'}/firebrickslib
if [ -z "$FBLibVer" ]; then
	echo 'It looks like firebrickslib was not loaded, why?  Exiting' >&2
	exit 1
fi

for OneTask in $Tasks ; do
	case "$OneTask" in
	link)
		$IptablesBin -N $Me >/dev/null 2>&1
		#$IptablesBin $AppIn INPUT -i \! lo						-j $Me
		$IptablesBin $AppIn FORWARD							-j $Me
		#$IptablesBin $AppIn OUTPUT							-j $Me
		;;
	unlink)
		#$IptablesBin -D INPUT -i \! lo							-j $Me
		$IptablesBin -D FORWARD								-j $Me
		#$IptablesBin -D OUTPUT								-j $Me
		$IptablesBin -X $Me >/dev/null 2>&1
		;;
	create)
		echo "Starting $Me" >&2
		FlushOrNewChain $Me
#FIXME - case, where approriate, on state NEW, ESABLISHED, and RELATED?
		LogAs='UNSPECSrc'	$IptablesBin -A $Me -m addrtype --src-type UNSPEC	-j RETURN
		LogAs='UNICASTSrc'	$IptablesBin -A $Me -m addrtype --src-type UNICAST	-j RETURN		#Gateway or direct route
		LogAs='LOCALSrc'	$Ipt -A $Me -m addrtype --src-type LOCAL		$Tail			#Accept locally
		LogAs='BROADCASTSrc'	$Ipt -A $Me -m addrtype --src-type BROADCAST		$Tail			#Accept locally as broadcast, send as broadcast
		LogAs='ANYCASTSrc'	$Ipt -A $Me -m addrtype --src-type ANYCAST		$Tail			#Accept locally as broadcast, but send as unicast
		LogAs='MULTICASTSrc'	$Ipt -A $Me -m addrtype --src-type MULTICAST		$Tail			#Multicast route
		LogAs='BLACKHOLESrc'	$Ipt -A $Me -m addrtype --src-type BLACKHOLE		$Tail			#Drop
		LogAs='UNREACHABLESrc'	$Ipt -A $Me -m addrtype --src-type UNREACHABLE		$Tail			#Destination is unreachable
		LogAs='PROHIBITSrc'	$Ipt -A $Me -m addrtype --src-type PROHIBIT		$Tail			#Administratively prohibited
		LogAs='THROWSrc'	$IptablesBin -A $Me -m addrtype --src-type THROW	-j RETURN		#Not in the kernel addrtype table
		LogAs='NATSrc'		$IptablesBin -A $Me -m addrtype --src-type NAT		-j RETURN		#Translate this address
		LogAs='XRESOLVESrc'	$IptablesBin -A $Me -m addrtype --src-type XRESOLVE	-j RETURN		#Use external resolver
		;;
	destroy)
		echo "Stopping $Me" >&2
		DestroyChain $Me
		;;
	renamechain)
		TempChain="$Me-$RANDOM"
		echo "Replacing existing rules in $Me with new rules" >&2
		$IptablesBin -E $Me $TempChain
		;;
	replacelinks)
		if [ -z "$TempChain" ]; then
			echo "No temporary chain to relink in $Me replacelinks, replace operation incomplete." >&2
		elif ! $IptablesBin -L $Me -n >/dev/null 2>&1 ; then
			echo "No $Me chain in $Me, replace operation incomplete." >&2
		elif ! $IptablesBin -L $TempChain -n >/dev/null 2>&1 ; then
			echo "No $TempChain chain in $Me, replace operation incomplete." >&2
		#elif [ "`$IptablesBin -L INPUT -n --line-numbers | grep $TempChain | wc -l`" -ne 1 ]; then
		#	echo "Too few/many references to $TempChain in INPUT in $Me replacelinks, replace operation incomplete." >&2
		elif [ "`$IptablesBin -L FORWARD -n --line-numbers | grep $TempChain | wc -l`" -ne 1 ]; then
			echo "Too few/many references to $TempChain in FORWARD in $Me replacelinks, replace operation incomplete." >&2
		#elif [ "`$IptablesBin -L OUTPUT -n --line-numbers | grep $TempChain | wc -l`" -ne 1 ]; then
		#	echo "Too few/many references to $TempChain in OUTPUT in $Me replacelinks, replace operation incomplete." >&2
		else
			#$IptablesBin -R INPUT `$IptablesBin -L INPUT -n --line-numbers | grep $TempChain | awk '{print $1}'` -i \! lo		-j $Me
			$IptablesBin -R FORWARD `$IptablesBin -L FORWARD -n --line-numbers | grep $TempChain | awk '{print $1}'`		-j $Me
			#$IptablesBin -R OUTPUT `$IptablesBin -L OUTPUT -n --line-numbers | grep $TempChain | awk '{print $1}'`			-j $Me
			DestroyChain $TempChain
			unset TempChain
		fi
		;;
	status)
		if $IptablesBin -L $Me -n >/dev/null 2>&1 ; then
			echo "$Me created" >&2
		else
			echo "$Me destroyed" >&2
		fi
		;;
	version)
		echo "$Me $MyVersion, firebrickslib $FBLibVer" >&2
		;;
	help)
		DefaultHelp
		cat <<EOTEXT >&2
	The $Me module checks the source address for valid and invalid
address types, as maintained by the kernel.  For example, should we
really be receiving packets from an address the kernel knows is
unreachable?
	This module is somewhat experimental, but the checks should be
conservative enough to safely use.
EOTEXT
		;;
	*)
		echo "Unknown action $Action in $Me, no action taken." >&2
		;;
	esac
done
