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

Me='ipopts'
MyVersion='0.3.5'
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 -m ipv4options --any-opt			-j $Me
		$IptablesBin $AppIn FORWARD -m ipv4options --any-opt				-j $Me
		$IptablesBin $AppIn OUTPUT -m ipv4options --any-opt				-j $Me
		;;
	unlink)
		$IptablesBin -D INPUT -i \! lo -m ipv4options --any-opt				-j $Me
		$IptablesBin -D FORWARD -m ipv4options --any-opt				-j $Me
		$IptablesBin -D OUTPUT -m ipv4options --any-opt					-j $Me
		$IptablesBin -X $Me >/dev/null 2>&1
		;;
	create)
		echo "Starting $Me" >&2
		FlushOrNewChain $Me
		#If you only want to block source routed packets, do just these:
		LogAs='ipopts-sr-s'	$Ipt -A $Me -m ipv4options --ssrr			$Tail
		LogAs='ipopts-sr-l'	$Ipt -A $Me -m ipv4options --lsrr			$Tail
		LogAs='ipopts-sr-r'	$Ipt -A $Me -m ipv4options --rr				$Tail
		#Otherwise, to block _all_ ip options:
		LogAs='ipopts'		$Ipt -A $Me -m ipv4options --any-opt			$Tail
		;;
	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 -m ipv4options --any-opt	-j $Me
			$IptablesBin -R FORWARD `$IptablesBin -L FORWARD -n --line-numbers | grep $TempChain | awk '{print $1}'` -m ipv4options --any-opt	-j $Me
			$IptablesBin -R OUTPUT `$IptablesBin -L OUTPUT -n --line-numbers | grep $TempChain | awk '{print $1}'` -m ipv4options --any-opt		-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 for any IP options and discards/logs those
packets.  The Source Route (strict source route, loose source route, and
record route) IP options are generally considered malicious as they can
circumvent Internet routing tables if the two hosts are no more than
nine hops apart.  IP options are generally not used legitimately, and
it\'s a common practice to block them at the firewall.
	IP options (generally malicious) are distinct from TCP options,
which are generally _not_ malicious and are in common use.
	These rules should be safe to use on any network.
EOTEXT
		;;
	*)
		echo "Unknown action $Action in $Me, no action taken." >&2
		;;
	esac
done
