#! /bin/bash

MYVERSION="1.0.1"

help()
{
    exec 1>&2
    echo `basename $0` v$MYVERSION: Script to restore firewall chains from stdin.
    echo
    echo "   With the -v option, prints out every rule."
    echo "   With the -f option, clears chains without asking."

    exit 1
}

IPCHAINS=/sbin/ipchains
#IPCHAINS=echo

IP_CHAINNAMES_FILE=/proc/net/ip_fwnames
#IP_CHAINNAMES_FILE=ip_fwnames.dummy

VERBOSE=0
FORCE=0

bugreport()
{
    echo "$@"
    echo This is $0 v$MYVERSION
    echo If this is the latest version of ipchains-restore, and the input
    echo was created using the latest version of ipchains-save, then I\'d
    echo really appreciate a bug report.  Please send the input you used,
    echo and all the output from this program to the author,
    echo \`ipchains@wantree.com.au\' with \`BUG-REPORT\' in the subject
    echo line so I know to read the message.
    echo
    echo Apologies for the inconvenience,
    echo Paul \`\`Rusty\'\' Russell.
    exit 1
}

for arg
do
    case "$arg"
    in
	-v) VERBOSE=1 ;;
	-f) FORCE=1 ;;
	*) help ;;
    esac
done

SKIP=0
while read LINE
do
    case "$LINE"
    in
	:*) CHAIN=`echo $LINE | cut -c2- | cut -d\  -f1`
	    SKIP=0
	    if [ $CHAIN = input -o $CHAIN = output -o $CHAIN = forward ]
	    then
		[ $VERBOSE = 1 ] && echo Setting policy for \`$CHAIN\'.
		POLICY=`echo $LINE | cut -c2- | cut -d\  -f2`
		case "$POLICY" 
		in
		# Old-style (numeric) policies.
		    -1) $IPCHAINS -P $CHAIN REJECT ;;
		    1) $IPCHAINS -P $CHAIN DENY ;;
		    2) $IPCHAINS -P $CHAIN ACCEPT ;;
		    3) $IPCHAINS -P $CHAIN REDIRECT ;;
		    4) $IPCHAINS -P $CHAIN MASQ ;;
		    *) $IPCHAINS -P $CHAIN $POLICY ;;
		esac
	    elif grep -q "^$CHAIN " $IP_CHAINNAMES_FILE
	    then
		if [ $FORCE = 1 ]; then REPL='f'
		else
		    echo -n Chain \`$CHAIN\' already exists.  "Skip or flush? [S/f]? "
		    read REPL < /dev/tty
		fi
		case $REPL
		in
		    [fF]*) $IPCHAINS -F $CHAIN 
			[ $FORCE = 1 ] || echo Flushing \`$CHAIN\'.
			;;
		    *) SKIP=1; [ $VERBOSE = 1 ] || echo Skipping \`$CHAIN\'. ;;
		esac
	    else
		echo Creating chain \`$CHAIN\'.
		$IPCHAINS -N $CHAIN
	    fi
	    ;;

	*)  if [ $SKIP = 1 ]
	    then
		[ $VERBOSE = 1 ] && echo SKIPPING $IPCHAINS $LINE 1>&2
	    else
		[ $VERBOSE = 1 ] && echo $IPCHAINS $LINE 1>&2
		$IPCHAINS $LINE || bugreport "ipchains command $LINE failed"
	    fi
	    ;;
    esac
done
