#!/bin/bash
#WARNING - remove the above before distribution!!!!!!!!!!
#A library of functions and subroutines for Mason
#Copyright 1999, William Stearns <wstearns@pobox.com>
#See the main Mason script for license and copyright information.


#ZZZZ
#-------------------------------------------------------------------------
# bits2mask function, returns the netmask for the number of bits parameter.
#-------------------------------------------------------------------------
bits2mask () {
#FIXME - double check numbers
	case $1 in
	32|*/32)			echo 255.255.255.255					;;
	31|*/31)			echo 255.255.255.254					;;
	30|*/30)			echo 255.255.255.252					;;
	29|*/29)			echo 255.255.255.248					;;
	28|*/28)			echo 255.255.255.240					;;
	27|*/27)			echo 255.255.255.224					;;
	26|*/26)			echo 255.255.255.192					;;
	25|*/25)			echo 255.255.255.128					;;
	24|*/24)			echo 255.255.255.0						;;
	23|*/23)			echo 255.255.254.0						;;
	22|*/22)			echo 255.255.252.0						;;
	21|*/21)			echo 255.255.248.0						;;
	20|*/20)			echo 255.255.240.0						;;
	19|*/19)			echo 255.255.224.0						;;
	18|*/18)			echo 255.255.192.0						;;
	17|*/17)			echo 255.255.128.0						;;
	16|*/16)			echo 255.255.0.0						;;
	15|*/15)			echo 255.254.0.0						;;
	14|*/14)			echo 255.252.0.0						;;
	13|*/13)			echo 255.248.0.0						;;
	12|*/12)			echo 255.240.0.0						;;
	11|*/11)			echo 255.224.0.0						;;
	10|*/10)			echo 255.192.0.0						;;
	9|*/9)				echo 255.128.0.0						;;
	8|*/8)				echo 255.0.0.0							;;
	7|*/7)				echo 254.0.0.0							;;
	6|*/6)				echo 252.0.0.0							;;
	5|*/5)				echo 248.0.0.0							;;
	4|*/4)				echo 240.0.0.0							;;
	3|*/3)				echo 224.0.0.0							;;
	2|*/2)				echo 192.0.0.0							;;
	1|*/1)				echo 128.0.0.0							;;
	0|*/0)				echo 0.0.0.0							;;
	*)					echo 255.255.255.255					;;
	esac
} #End of bits2mask


#-------------------------------------------------------------------------
# broadcastof function, returns the broadcast of the given network and netmask.
#-------------------------------------------------------------------------
broadcastof () {
	#Basically, the broadcast is (network bitwise-or (255.255.255.255-netmask))
	SPLITIP=$1
	I1O1=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O2=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O3=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O4=$SPLITIP
	SPLITIP=$2
	I2O1=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I2O2=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I2O3=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I2O4=$SPLITIP

	echo $[ $I1O1 | (255-$I2O1) ].$[ $I1O2 | (255-$I2O2) ].$[ $I1O3 | (255-$I2O3) ].$[ $I1O4 | (255-$I2O4) ]
} #End of broadcastof


checkconf () {
#FIXME - double check all vars have default values.
	echo -n "Check vars..." >/dev/stderr

	MASONDIR=${MASONDIR:-"/var/lib/mason/"} ;					if [ ! -d $MASONDIR ]; then mkdir --parents $MASONDIR ; chown root.root $MASONDIR ; chmod 700 $MASONDIR ; fi
	MASONCONF=${MASONCONF:-"/etc/masonrc"} ;					if [ ! -f $MASONCONF ]; then touch $MASONCONF ; fi
	#NAMECACHE support has been disabled
	#NAMECACHE=${NAMECACHE:-"${MASONDIR}morehosts"} ;			if [ ! -f $NAMECACHE ]; then touch $NAMECACHE ; fi
	NETCACHE=${NETCACHE:-"${MASONDIR}netconvert"} ;				if [ ! -f $NETCACHE ]; then touch $NETCACHE ; fi
	BASERULEFILE=${BASERULEFILE:-"${MASONDIR}baserules"} ;		if [ ! -f $BASERULEFILE ]; then touch $BASERULEFILE ; fi
	NEWRULEFILE=${NEWRULEFILE:-"${MASONDIR}newrules"} ;			if [ ! -f $NEWRULEFILE ]; then touch $NEWRULEFILE ; fi
	#WARNING - remove second copy before distribution!!!!!!!!!!!!!!!!!!
	NEWRULEFILE=${NEWRULEFILE:-"${MASONDIR}newrules"} ;			if [ ! -f $NEWRULEFILE ]; then touch $NEWRULEFILE ; fi
	PACKETLOGFILE=${PACKETLOGFILE:-"/var/log/messages"}
	MASONEXE=${MASONEXE:-"/usr/bin/mason"}
	if [ -z "$SERVICES" ]; then
		SERVICES="/etc/services"
		#I used to add in the following 2 files.  I do not now because I got too many false matches from nmap-services.
		#if [ -f ${MASONDIR}moreservices ]; then SERVICES="$SERVICES ${MASONDIR}moreservices" ; fi
		#if [ -f ${MASONDIR}nmap-services ]; then SERVICES="$SERVICES ${MASONDIR}nmap-services" ; fi
	fi

	NOLOGSUFFIX=${NOLOGSUFFIX:-"N"}	#If you change this, change it in ruleshell too.
	DEBUG=${DEBUG:-"NO"}
	DYNIF=${DYNIF:-""}

	INCOMINGINTERFACES=${INCOMINGINTERFACES:-`/sbin/route -n | grep '^0\.0\.0\.0[ \t]' | awk '{print $8}'`}

	case $NEWRULEPOLICY in			#Set LCPOLICY (lower case) and UCPOLICY...
	a*|A*)				LCPOLICY="accept" ;	UCPOLICY="ACCEPT"	;;
	r*|R*)				LCPOLICY="reject" ;	UCPOLICY="REJECT"	;;
	d*|D*)				LCPOLICY="deny  " ;	UCPOLICY="DENY  "	;;
	*)	echo WARNING! NEWRULEPOLICY is neither accept, reject, nor deny >/dev/stderr
		echo in ${MASONCONF}.  >/dev/stderr
		while [ "$LCPOLICY" != "accept" ] && [ "$LCPOLICY" != "reject" ] && [ "$LCPOLICY" != "deny" ] ; do
			echo Please choose accept, reject, or deny: >/dev/stderr
			read NEWRULEPOLICY JUNK
			case "$NEWRULEPOLICY" in
			a*|A*)		LCPOLICY="accept" ;	UCPOLICY="ACCEPT"	;;
			r*|R*)		LCPOLICY="reject" ;	UCPOLICY="REJECT"	;;
			d*|D*)		LCPOLICY="deny  " ;	UCPOLICY="DENY  "	;;
			esac
		done
		echo "NEWRULEPOLICY=${NEWRULEPOLICY}" >>$MASONCONF
		echo NEWRULEPOLICY is being reset to \"${NEWRULEPOLICY}\". >/dev/stderr
																;;
	esac

	case $DEFAULTPOLICY in
	accept|ACCEPT)		DEFAULTPOLICY="accept" ;				;;
	reject|REJECT)		DEFAULTPOLICY="reject" ;				;;
	deny|DENY)			DEFAULTPOLICY="deny  " ;				;;
	*)	echo WARNING! DEFAULTPOLICY is neither accept, reject, nor deny. >/dev/stderr
		echo in ${MASONCONF}.  >/dev/stderr
		while [ "$DEFAULTPOLICY" != "accept" ] && [ "$DEFAULTPOLICY" != "reject" ] && [ "$DEFAULTPOLICY" != "deny" ] ; do
			echo Please choose accept, reject, or deny: >/dev/stderr
			read DEFAULTPOLICY JUNK
			case "$DEFAULTPOLICY" in
			a*|A*)		DEFAULTPOLICY="accept"					;;
			r*|R*)		DEFAULTPOLICY="reject"					;;
			d*|D*)		DEFAULTPOLICY="deny  "					;;
			esac
		done
		echo "DEFAULTPOLICY=${DEFAULTPOLICY}" >>$MASONCONF
		echo DEFAULTPOLICY is being reset to \"${DEFAULTPOLICY}\". >/dev/stderr
																;;
	esac

	case $LOGGINGPOLICY in
	accept|ACCEPT)		LOGGINGPOLICY="accept" ;				;;
	reject|REJECT)		LOGGINGPOLICY="reject" ;				;;
	deny|DENY)			LOGGINGPOLICY="deny  " ;				;;
	*)	LOGGINGPOLICY=$NEWRULEPOLICY							;;
	esac

	case $FLUSHEDPOLICY in
	accept|ACCEPT)		FLUSHEDPOLICY="accept" ;				;;
	reject|REJECT)		FLUSHEDPOLICY="reject" ;				;;
	deny|DENY)			FLUSHEDPOLICY="deny  " ;				;;
	*)	FLUSHEDPOLICY=accept									;;
	esac

	case $ECHOCOMMAND in
	ipfwadm|IPFWADM)				ECHOCOMMAND="ipfwadm"		;;
	ipchains|IPCHAINS)				ECHOCOMMAND="ipchains"		;;
	ipchains-save|IPCHAINS-SAVE)	ECHOCOMMAND="ipchains-save"	;;
	cisco|CISCO)					ECHOCOMMAND="cisco"			;;
	no|NO|none|NONE)				ECHOCOMMAND="none"			;;
	*)	if [ -f /proc/net/ip_fwchains ]; then		ECHOCOMMAND="ipchains"
		elif [ -f /proc/net/ip_input ]; then		ECHOCOMMAND="ipfwadm"
		else										ECHOCOMMAND="ipchains"			#Set default here
		fi														;;
	esac

	case $DOCOMMAND in
	ipfwadm|IPFWADM)
		DOCOMMAND="ipfwadm"
		if [ ! -f /proc/net/ip_input ]; then
			echo WARNING! User has requested ipfwadm, but it appears to be >/dev/stderr
			echo unavailable.  Proceeding, but this is not likely to work. >/dev/stderr
		fi
		if [ ! -x /sbin/ipfwadm ]; then
			echo WARNING! User has requested ipfwadm, but /sbin/ipfwadm is not >/dev/stderr
			echo executable.  Proceeding, but this is not likely to work. >/dev/stderr
		fi														;;
	ipchains|IPCHAINS)
		DOCOMMAND="ipchains"
		if [ ! -f /proc/net/ip_fwchains ]; then
			echo WARNING! User has requested ipchains, but it appears to be >/dev/stderr
			echo unavailable.  Proceeding, but this is not likely to work. >/dev/stderr
		fi
		if [ ! -x /sbin/ipchains ]; then
			echo WARNING! User has requested ipchains, but /sbin/ipchains is not >/dev/stderr
			echo executable.  Proceeding, but this is not likely to work. >/dev/stderr
		fi														;;
	no|NO|none|NONE)	DOCOMMAND="none"						;;
	*)
		if [ -f /proc/net/ip_fwchains ]; then
			DOCOMMAND="ipchains"
			if [ ! -x /sbin/ipchains ]; then
				echo WARNING! This kernel uses ipchains, but /sbin/ipchains is not >/dev/stderr
				echo executable.  Proceeding, but this is not likely to work. >/dev/stderr
				echo Please get a copy of the ipchains binary and place it in /sbin . >/dev/stderr
			fi
		elif [ -f /proc/net/ip_input ]; then
			DOCOMMAND="ipfwadm"
			if [ ! -x /sbin/ipfwadm ]; then
				echo WARNING! This kernel uses ipfwadm, but /sbin/ipfwadm is not >/dev/stderr
				echo executable.  Proceeding, but this is not likely to work. >/dev/stderr
				echo Please get a copy of the ipfwadm binary and place it in /sbin . >/dev/stderr
			fi
		else
			DOCOMMAND="none"				#Well, we can't _do_ either!
			echo WARNING! Neither ipchains nor ipfwadm appears to be >/dev/stderr
			echo unavailable.  Proceeding anyways. >/dev/stderr
		fi														;;
	esac

	case $HEARTBEAT in
	YES|yes|TRUE|true)					HEARTBEAT="YES"			;;
	NO|no|NONE|none|FALSE|false)		HEARTBEAT="NO"			;;
	*)									HEARTBEAT="YES"			;;
	esac

	case $IPCONV in
	HOSTNAME|hostname|HOST|host)		IPCONV="HOST"			;;
	NETWORK|network|NET|net)			IPCONV="NETWORK"		;;
	NO|no|NONE|none)					IPCONV="NONE"			;;
	#CUSTOM|custom)						IPCONV="CUSTOM"			;;
	*)									IPCONV="NETWORK"		;;
	esac

	case $HOSTLOOKUP in
	NO|no|NONE|none)					HOSTLOOKUP="NONE"		;;
	FILES|files|FILESONLY|filesonly)	HOSTLOOKUP="FILESONLY"	;;
	FULL|full|YES|yes)					HOSTLOOKUP="FULL"		;;
	*)									HOSTLOOKUP="FULL"		;;
	esac

	DOBEEP=${DOBEEP:-"YES"}	# "YES" = beep at user with new rule, "NO" = dont

	PORT_MASQ_BEGIN=${PORT_MASQ_BEGIN:-61000}
	PORT_MASQ_END=${PORT_MASQ_END:-65096}
	TRACEROUTE_BEGIN=${TRACEROUTE_BEGIN:-33434}
	TRACEROUTE_END=${TRACEROUTE_END:-33524}
	IRC_BEGIN=${IRC_BEGIN:-6666}
	IRC_END=${IRC_END:-6671}

	MAXDISPLAYS=${MAXDISPLAYS:-6}

	X_BEGIN=${X_BEGIN:-6000}
	X_END=${X_END:-$[ $X_BEGIN + $MAXDISPLAYS -1 ]}
	OPENWIN_BEGIN=${OPENWIN_BEGIN:-2000}
	OPENWIN_END=${OPENWIN_END:-$[ $OPENWIN_BEGIN + $MAXDISPLAYS -1 ]}
	VNCJAVA_BEGIN=${VNCJAVA_BEGIN:-5800}
	VNCJAVA_END=${VNCJAVA_END:-$[ $VNCJAVA_BEGIN + $MAXDISPLAYS -1 ]}
	VNC_BEGIN=${VNC_BEGIN:-5900}
	VNC_END=${VNC_END:-$[ $VNC_BEGIN + $MAXDISPLAYS -1 ]}

#Remove duplicates
	if [ -n "$SSP" ]; then 			SSP=`echo "$SSP" | tr ' ' '\012' | sort | uniq` ; 				  else SSP="" ; fi
	if [ -n "$SCP" ]; then			SCP=`echo "$SCP" | tr ' ' '\012' | sort | uniq` ; 				  else SCP="" ; fi
	if [ -n "$BLOCKEDHOSTS" ]; then BLOCKEDHOSTS=`echo "$BLOCKEDHOSTS" | tr ' ' '\012' | sort | uniq` ; else BLOCKEDHOSTS="" ; fi
	if [ -n "$NOINCOMING" ]; then	NOINCOMING=`echo "$NOINCOMING" | tr ' ' '\012' | sort | uniq` ;	  else NOINCOMING="" ; fi
	#if [ -n "$POISONPROTOCOLS" ]; then
	#	POISONPROTOCOLS=`echo "$POISONPROTOCOLS" | tr ' ' '\012' | sort | uniq`
	#else
	#	POISONPROTOCOLS=""
	#fi

	LOWSSHPORT=${LOWSSHPORT:-"1010"}

	if [ -z "$EDITOR" ]; then
		for TRYEDITOR in `type -path mcedit` \
						   `type -path pico` \
						   `type -path vi` \
						   `type -path jove` \
						   `type -path nedit` \
						   `type -path emacs`; do
			if [ -z "$EDITOR" ]; then
				EDITOR=$TRYEDITOR
				echo Editor default of $EDITOR taken. >/dev/stderr
			fi
		done
		unset TRYEDITOR || /bin/true
		if [ -z "$EDITOR" ]; then
			echo No editor was specified by the EDITOR= variable and >/dev/stderr
			echo this script was unable to find mcedit, pico, vi, jove, nedit or emacs >/dev/stderr
			echo on your system.  Please set EDITOR=the_name_of_an_editor >/dev/stderr
			echo in $MASONCONF or your environment and re-start. >/dev/stderr
		fi #no suitable editor found
	fi
	if [ "$ECHOCOMMAND" = "cisco" ]; then
		SINGLEMACHSPEC=" 0.0.0.0"
		CMNT='!'
	else
		SINGLEMACHSPEC="/32"
		CMNT="#"
	fi
} #End of checkconf


checksys () {
	if [ ! -d /proc/1 ]; then
		echo WARNING! Proc filesystem not supported or not mounted.  Please fix and restart.
		exit
	fi

	if [ -f /proc/net/ip_fwchains ]; then
		:
	elif [ -f /proc/net/ip_input ]; then
		:
	else
		echo This kernel supports neither ipchains nor ipfwadm! >/dev/stderr
		#DOCOMMAND="none"		#Should we force to none?
	fi	
} #End of checksys


#-------------------------------------------------------------------------
# clientportrange function, returns the individual port or range of 
# ports for the given client port, server port, and protocol parameters.
#-------------------------------------------------------------------------
clientportrange () {
	CLIENTPORT=$1 ; SERVERPORT=$2 ; PRPROTO=$3
	CPRRETVAL="1024:65535"

	if [ $CLIENTPORT -ge $PORT_MASQ_BEGIN ] && [ $CLIENTPORT -le $PORT_MASQ_END ]; then
		CPRRETVAL="${PORT_MASQ_BEGIN}:${PORT_MASQ_END}"
	elif [ $CLIENTPORT -ge $TRACEROUTE_BEGIN ] && [ $CLIENTPORT -le $TRACEROUTE_END ] && [ "$PRPROTO" = "udp" ]; then
		CPRRETVAL="${TRACEROUTE_BEGIN}:${TRACEROUTE_END}"
	elif [ $SERVERPORT -ge $TRACEROUTE_BEGIN ] && [ $SERVERPORT -le $TRACEROUTE_END ] && [ "$PRPROTO" = "udp" ]; then
		if [ $CLIENTPORT -ge 32768 ]; then CPRRETVAL="32768:65535" ; fi
		#According to the traceroute 1.4a5 source, the source port for a udp traceroute is set to the pid
		#with the high bit set.  This translates into 32768-65535; remember, the pid could be 32768.
	elif [ "$PRPROTO" = "udp" ] && [ $SERVERPORT -ge 6770 ] && [ $SERVERPORT -le 7170 ]; then	#RealAudio
		if [ $CLIENTPORT -ge 6970 ] && [ $CLIENTPORT -le 7170 ]; then
			CPRRETVAL="6970:7170"
		elif [ $CLIENTPORT -ge 6770 ] && [ $CLIENTPORT -le 7170 ]; then
			CPRRETVAL="6770:7170"
		fi
	else
		case "${SERVERPORT}/${PRPROTO}" in
		"22/tcp"|"ssh/tcp")
			if [ $CLIENTPORT -le 1023 ]; then
				while [ "$CLIENTPORT" -lt "$LOWSSHPORT" ]; do
					#LOWSSHPORT=`expr $LOWSSHPORT - 10`
					LOWSSHPORT=$[ $LOWSSHPORT - 10 ]
				done
				CPRRETVAL="${LOWSSHPORT}:1023"
			fi													;;
		"111/tcp"|"sunrpc/tcp"|"rpcbind/tcp"|"111/udp"|"sunrpc/udp"|"rpcbind/tcp"|"635/tcp"|"mount/tcp"|"635/udp"|"mount/udp"|"2049/udp"|"nfs/udp")
#sunrpc/tcp: 600-1014 viewed with rpcinfo client, sunrpc/udp: 600-1022 viewed with nfs mount and unmount
#mount/tcp: 605-1022 viewed with nfs mount and unmount, mount/udp: 601-1022 viewed with nfs mount and unmount
#nfs/udp: 610-1014 and nfs viewed
			if [ $CLIENTPORT -le 1023 ]; then
				if [ $CLIENTPORT -ge 600 ]; then
					CPRRETVAL="600:1023"
				else
					CPRRETVAL="$CLIENTPORT"
				fi
			fi													;;
		"2049/tcp"|"nfs/tcp")	#Starts at 800 and works its way down, may reuse ports?
#Probably do a min port like ssh.  For the moment, use 760 to 800
			if [ $CLIENTPORT -le 1023 ]; then
				if [ $CLIENTPORT -ge 760 ] && [ $CLIENTPORT -le 800 ]; then
					CPRRETVAL="760:800"
				else
					CPRRETVAL="$CLIENTPORT"
				fi
			fi													;;
		*)
			if [ $CLIENTPORT -le 1023 ]; then CPRRETVAL="$CLIENTPORT" ; fi
																;;
		esac
	fi
	echo $CPRRETVAL
} #End of clientportrange



flushfirewall () {
#Flush the existing rules so we start with a clean slate.
	if [ -f /proc/net/ip_fwchains ]; then
		echo -n Flushing... >/dev/stderr
		FLUSHEDPOLICY=`echo $FLUSHEDPOLICY | tr a-z A-Z`
		/sbin/ipchains -P output $FLUSHEDPOLICY
		/sbin/ipchains -F output
		/sbin/ipchains -P forward $FLUSHEDPOLICY
		/sbin/ipchains -F forward
		/sbin/ipchains -P input $FLUSHEDPOLICY
		/sbin/ipchains -F input
#Flush the nolog chains if they exists, create them if not.
		if [ -n "$NOLOGSUFFIX" ]; then
			if [ `ipchains -L -n | grep "^Chain output${NOLOGSUFFIX}" | wc -l` -gt 0 ]; then
				/sbin/ipchains -F output${NOLOGSUFFIX} >/dev/null 2>/dev/null
			else
				/sbin/ipchains -N output${NOLOGSUFFIX} >/dev/null 2>/dev/null
			fi

			if [ `ipchains -L -n | grep "^Chain forward${NOLOGSUFFIX}" | wc -l` -gt 0 ]; then
				/sbin/ipchains -F forward${NOLOGSUFFIX} >/dev/null 2>/dev/null
			else
				/sbin/ipchains -N forward${NOLOGSUFFIX} >/dev/null 2>/dev/null
			fi

			if [ `ipchains -L -n | grep "^Chain input${NOLOGSUFFIX}" | wc -l` -gt 0 ]; then
				/sbin/ipchains -F input${NOLOGSUFFIX} >/dev/null 2>/dev/null
			else
				/sbin/ipchains -N input${NOLOGSUFFIX} >/dev/null 2>/dev/null
			fi
		fi
		echo Done!
	elif [ -f /proc/net/ip_input ]; then
		echo -n Flushing... >/dev/stderr
		FLUSHEDPOLICY=`echo $FLUSHEDPOLICY | tr A-Z a-z`
		/sbin/ipfwadm -O -p $FLUSHEDPOLICY
		/sbin/ipfwadm -O -f
		/sbin/ipfwadm -F -p $FLUSHEDPOLICY
		/sbin/ipfwadm -F -f
		/sbin/ipfwadm -I -p $FLUSHEDPOLICY
		/sbin/ipfwadm -I -f
		echo Done!
	else
		echo This kernel supports neither ipchains nor ipfwadm! >/dev/stderr
	fi
} #End of flushfirewall


#-------------------------------------------------------------------------
# generalizeip function.  For the given ip address parameter, return one
# of the following:
# - $DYNIFADDR for interfaces with dynamic IP addresses.
# - the corresponding hostname
# - itself, if a local address, broadcast address, or special address.
# - its IP network 
# - as a last resort, 0/0
# User can select operation with IPCONV= in masonconf.
#-------------------------------------------------------------------------
generalizeip () {
	GIRETVAL="${1}${SINGLEMACHSPEC}"
	ISASSIGNED="NO"
	for ONEIF in $DYNIF ; do
		DYNIP=$(eval echo \${$(eval echo ${ONEIF}ADDR)})	#No, really.
		if [ "$1" = "$DYNIP" ]; then
			GIRETVAL="\${${ONEIF}ADDR}"		#Do not add /32 here - that shell variable _has_ /32 in it.
			ISASSIGNED="YES"
			#LINEHASDYNAMIC="YES"		#Not exported from a function - not currently used
		fi
	done

	if [ "$ISASSIGNED" = "NO" ]; then
		case $IPCONV in
		HOST)
			GIRETVAL="`nameof ${1}`${SINGLEMACHSPEC}"							;;
		NETWORK)
#Handle special addresses
			case $1 in
			0.0.0.0)			GIRETVAL="0.0.0.0${SINGLEMACHSPEC}"			ISASSIGNED="YES"	;;
			127.0.0.1)			GIRETVAL="localhost${SINGLEMACHSPEC}"		ISASSIGNED="YES"	;;
			255.255.255.255)	GIRETVAL="255.255.255.255${SINGLEMACHSPEC}"	ISASSIGNED="YES"	;;
			esac

#Leave local IP addresses and broadcasts as they are.
			if [ "$ISASSIGNED" = "NO" ]; then
				for ONELOCALIP in $ALLIPS $ALLBCS ; do
					if [ "$1" = "$ONELOCALIP" ]; then 
						GIRETVAL="`nameof ${1}`${SINGLEMACHSPEC}"
						ISASSIGNED="YES"
					fi
				done
			fi

#If IP is in a local netblock, generalize to that netblock.
			if [ "$ISASSIGNED" = "NO" ]; then
				for ONENET in `cat ${NETCACHE}` ; do
					if [ "$ISASSIGNED" = "NO" ]; then
						NETMASK=${ONENET##*/}	; ONENET=${ONENET%/*}
						BROADCAST=${ONENET##*-}	; ONENET=${ONENET%-*}
						if iple $ONENET $1 ; then
							if iple $1 $BROADCAST ; then
								if [ "$ECHOCOMMAND" = "cisco" ]; then
									GIRETVAL="$ONENET `mask2cisco $NETMASK`"
								else
									GIRETVAL="${ONENET}/`mask2bits $NETMASK`"
								fi
								ISASSIGNED="YES"
							fi
						fi
					fi
				done
			fi

			if [ "$ISASSIGNED" = "NO" ]; then	GIRETVAL="0/0" ; ISASSIGNED="YES" ; fi
																;;
		NONE)													;;
		#CUSTOM)												;;
		esac
	fi
	echo $GIRETVAL
} #End of generalizeip



#-------------------------------------------------------------------------
# ipeq function, returns true/false: ip addresses are equal? 
#-------------------------------------------------------------------------
#Not currently used...
ipeq () {
	SPLITIP=$1
	I1O1=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O2=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O3=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O4=$SPLITIP
	SPLITIP=$2
	I2O1=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I2O2=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I2O3=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I2O4=$SPLITIP

	if [ $I1O1 -eq $I2O1 ] && [ $I1O2 -eq $I2O2 ] && [ $I1O3 -eq $I2O3 ] && [ $I1O4 -eq $I2O4 ]; then
		return 0 #True
	else
		return 1 #False
	fi
} #End of ipeq


#-------------------------------------------------------------------------
# iple function, returns true (0) if first IP <= second IP, else false(1)
#-------------------------------------------------------------------------
iple () {
#if iple 128.2.3.4 127.0.0.1 ; then echo less than or eq >/dev/stderr ; else echo ge >/dev/stderr ; fi
	SPLITIP=$1
	I1O1=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O2=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O3=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O4=$SPLITIP
	SPLITIP=$2
	I2O1=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I2O2=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I2O3=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I2O4=$SPLITIP

	  if [ $I1O1 -lt $I2O1 ]; then	return 0
	elif [ $I1O1 -gt $I2O1 ]; then	return 1
	elif [ $I1O2 -lt $I2O2 ]; then	return 0
	elif [ $I1O2 -gt $I2O2 ]; then	return 1
	elif [ $I1O3 -lt $I2O3 ]; then	return 0
	elif [ $I1O3 -gt $I2O3 ]; then	return 1
	elif [ $I1O4 -lt $I2O4 ]; then	return 0
	elif [ $I1O4 -gt $I2O4 ]; then	return 1
	else							return 0
	fi
} #End of iple



#-------------------------------------------------------------------------
# loadconf function, called at start and on receipt of SIGUSR1
#-------------------------------------------------------------------------
loadconf () {
	if [ "$NEEDLF" = "YES" ]; then echo >/dev/stderr ; NEEDLF="NO" ; fi
	#This is the configuration file mason uses.  The parameters in it can be 
	#changed while Mason is running as long as the SIGUSR1 signal is sent to 
	#Mason afterwards.  This can be done by typing "killall -USR1 mason"
	if [ -f $MASONCONF ]; then
		echo -n "Loading options from ${MASONCONF}..." >/dev/stderr
		. $MASONCONF
	else
		touch $MASONCONF
		chmod 700 $MASONCONF
		echo Unable to load options, $MASONCONF does not exist. >/dev/stderr
	fi

	checkconf

	echo -n "Load IPs, networks and nameservers..." >/dev/stderr				#set ALLIPS and ALLBCS (broadcasts)
	ALLIPS="`ifconfig | grep 'inet addr' | sed -e 's/.*addr://' -e 's/ .*//'` \
	`route -n | grep '^[0-9\.]* *[0-9\.]* *255\.255\.255\.255' | awk '{print $1}'`"
	ALLBCS=`ifconfig | grep 'Bcast' | sed -e 's/.*Bcast://' -e 's/ .*//'`
#FIXME: ALLBCS includes net addresses too?

	#load the NETCACHE file with all non-trivial networks in the routing table.
	rm -f $NETCACHE
	touch $NETCACHE
	chmod 700 $NETCACHE
	for ONENET in `route -n | grep -v '^127\.' | grep -v '^0\.0\.0\.0' | grep '^[0-9]' | awk '{print $1 "/" $3}'` ; do
		case $ONENET in
		*/255.255.255.255)	:									;;
		*/255.255.255.254)	:									;;
		*/255.255.255.252)	:									;;
		*/0.0.0.0)			:									;;
		*)	
			#eval `ipcalc --broadcast ${ONENET%%/*} ${ONENET##*/}`
			#echo ${ONENET%%/*}-${BROADCAST}/${ONENET##*/} >>$NETCACHE #network-broadcast/netmask
			echo ${ONENET%%/*}-`broadcastof ${ONENET%%/*} ${ONENET##*/}`/${ONENET##*/} >>$NETCACHE #network-broadcast/netmask
																;;
		esac
	done
	DNSSERVERS=`cat /etc/resolv.conf | grep '^nameserver' | awk '{print $2}'`

	echo "Done." >/dev/stderr
	SIGGED="YES"	#We received a signal
#FIXME - put killall -SIGUSR1 mason in ip-up...
} #End of loadconf


#-------------------------------------------------------------------------
# mask2bits function, returns the number of bits in the netmask parameter.
#-------------------------------------------------------------------------
mask2bits () {
	case $1 in
	255.255.255.255)	echo 32									;;
	255.255.255.254)	echo 31									;;
	255.255.255.252)	echo 30									;;
	255.255.255.248)	echo 29									;;
	255.255.255.240)	echo 28									;;
	255.255.255.224)	echo 27									;;
	255.255.255.192)	echo 26									;;
	255.255.255.128)	echo 25									;;
	255.255.255.0)		echo 24									;;
	255.255.254.0)		echo 23									;;
	255.255.252.0)		echo 22									;;
	255.255.248.0)		echo 21									;;
	255.255.240.0)		echo 20									;;
	255.255.224.0)		echo 19									;;
	255.255.192.0)		echo 18									;;
	255.255.128.0)		echo 17									;;
	255.255.0.0)		echo 16									;;
	255.254.0.0)		echo 15									;;
	255.252.0.0)		echo 14									;;
	255.248.0.0)		echo 13									;;
	255.240.0.0)		echo 12									;;
	255.224.0.0)		echo 11									;;
	255.192.0.0)		echo 10									;;
	255.128.0.0)		echo 9									;;
	255.0.0.0)			echo 8									;;
	254.0.0.0)			echo 7									;;
	252.0.0.0)			echo 6									;;
	248.0.0.0)			echo 5									;;
	240.0.0.0)			echo 4									;;
	224.0.0.0)			echo 3									;;
	192.0.0.0)			echo 2									;;
	128.0.0.0)			echo 1									;;
	0.0.0.0)			echo 0									;;
	*)					echo 32									;;
	esac
} #End of mask2bits



#-------------------------------------------------------------------------
# mask2cisco function, returns the cisco "reverse netmask" of the netmask parameter.
#-------------------------------------------------------------------------
mask2cisco () {
#This could be done in fewer lines by subtracting each octet from 255.
#I'm trying to avoid forking as it hurts performance.
	case $1 in
	255.255.255.255)	echo 0.0.0.0							;;
	255.255.255.254)	echo 0.0.0.1							;;
	255.255.255.252)	echo 0.0.0.3							;;
	255.255.255.248)	echo 0.0.0.7							;;
	255.255.255.240)	echo 0.0.0.15							;;
	255.255.255.224)	echo 0.0.0.31							;;
	255.255.255.192)	echo 0.0.0.63							;;
	255.255.255.128)	echo 0.0.0.127							;;
	255.255.255.0)		echo 0.0.0.255							;;
	255.255.254.0)		echo 0.0.1.255							;;
	255.255.252.0)		echo 0.0.3.255							;;
	255.255.248.0)		echo 0.0.7.255							;;
	255.255.240.0)		echo 0.0.15.255							;;
	255.255.224.0)		echo 0.0.31.255							;;
	255.255.192.0)		echo 0.0.63.255							;;
	255.255.128.0)		echo 0.0.127.255						;;
	255.255.0.0)		echo 0.0.255.255						;;
	255.254.0.0)		echo 0.1.255.255						;;
	255.252.0.0)		echo 0.3.255.255						;;
	255.248.0.0)		echo 0.7.255.255						;;
	255.240.0.0)		echo 0.15.255.255						;;
	255.224.0.0)		echo 0.31.255.255						;;
	255.192.0.0)		echo 0.63.255.255						;;
	255.128.0.0)		echo 0.127.255.255						;;
	255.0.0.0)			echo 0.255.255.255						;;
	254.0.0.0)			echo 1.255.255.255						;;
	252.0.0.0)			echo 3.255.255.255						;;
	248.0.0.0)			echo 7.255.255.255						;;
	240.0.0.0)			echo 15.255.255.255						;;
	224.0.0.0)			echo 31.255.255.255						;;
	192.0.0.0)			echo 63.255.255.255						;;
	128.0.0.0)			echo 127.255.255.255					;;
	0.0.0.0)			echo 255.255.255.255					;;
	*)					echo 0.0.0.0							;;
	esac
} #End of mask2cisco



#-------------------------------------------------------------------------
# nameof function, returns the hostname from the IP address parameter.
#-------------------------------------------------------------------------
nameof () {
#Use the namecache file(now disabled), /etc/hosts, and finally "host" command to look
#up names for source and destination addresses.
	NAMEOFRETVAL=$1
	if [ "$HOSTLOOKUP" = "FILESONLY" ] || [ "$HOSTLOOKUP" = "FULL" ]; then
		#ONEHOSTNAME=`cat $NAMECACHE /etc/hosts | egrep "^${1}[^0-9]" | tail --lines=1 | awk '{print $2}'`
		ONEHOSTNAME=`cat /etc/hosts | egrep "^${1}[^0-9]" | tail --lines=1 | awk '{print $2}'`
		if [ -n "$ONEHOSTNAME" ]; then
			NAMEOFRETVAL="$ONEHOSTNAME"
		fi
	fi

	if [ "$HOSTLOOKUP" = "FULL" ] && [ -z "$ONEHOSTNAME" ] && [ "$SRCPORT" != "53" ] && [ "$DESTPORT" != "53" ]; then
		if host -t ptr $1 >/dev/null 2>/dev/null ; then
			ONEHOSTNAME=`host -t ptr $1 2>/dev/null | grep 'domain name pointer' | head --lines=1 | sed -e 's/.* //'`
			if [ -n "$ONEHOSTNAME" ]; then
				#echo -e "${1}\t${ONEHOSTNAME}" >>$NAMECACHE
				NAMEOFRETVAL="$ONEHOSTNAME"
			fi
		fi
	fi
	echo $NAMEOFRETVAL
} #End of nameof


#-------------------------------------------------------------------------
# protonum2name procedure, sets PROTO to the readable protocol name from protocol number and sets IGNOREPORT.
#-------------------------------------------------------------------------
protonum2name () {
	unset IGNOREPORT || /bin/true
	case $1 in
	0)		PROTO="ip"		IGNOREPORT="YES"				;;
	1)		PROTO="icmp"									;;
	2)		PROTO="igmp"	IGNOREPORT="YES"				;;
	3)		PROTO="ggp"		IGNOREPORT="YES"				;;
	4)		PROTO="ipip"	IGNOREPORT="YES"				;;
	6)		PROTO="tcp"										;;
	8)		PROTO="egp"		IGNOREPORT="YES"				;;
	12)		PROTO="pup"		IGNOREPORT="YES"				;;
	17)		PROTO="udp"										;;
	22)		PROTO="idp"		IGNOREPORT="YES"				;;
	41)		PROTO="ipv6"	IGNOREPORT="YES"				;;
	46)		PROTO="rsvp"	IGNOREPORT="YES"				;;
	47)		PROTO="gre"		IGNOREPORT="YES"				;;
	50)		PROTO="esp"		IGNOREPORT="YES"				;;
	103)	PROTO="pim"		IGNOREPORT="YES"				;;
	255)	PROTO="raw"		IGNOREPORT="YES"				;;
	*)
		PROTONAME=`cat /etc/protocols | grep "^[a-zA-Z]*\W*${1} *" | awk '{print $1}'`
		if [ -n "$PROTONAME" ]; then
			PROTO=$PROTONAME
		else
			PROTO=$1
		fi
		unset PROTONAME
		IGNOREPORT="YES"
															;;
	esac
} #End of protonum2name


#-------------------------------------------------------------------------
# reservedip function, returns true/false: ip address is reserved (rfc1918)?
#-------------------------------------------------------------------------
reservedip () {
	SPLITIP=$1
	I1O1=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O2=${SPLITIP%%.*}
						  #SPLITIP=${SPLITIP#*.}
	#I1O3=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	#I1O4=$SPLITIP

	if [ $I1O1 -eq 10 ]; then
		return 0 #True
	elif [ $I1O1 -eq 172 ] && [ $I1O2 -ge 16 ] && [ $I1O2 -le 31 ]; then
		return 0 #True
	elif [ $I1O1 -eq 192 ] && [ $I1O2 -eq 168 ]; then
		return 0 #True
	else
		return 1 #False
	fi
} #End of ipeq


runlearnfirewall () {
	if [ -f /proc/net/ip_fwchains ]; then
		DEFAULTPOLICY=`echo $DEFAULTPOLICY | tr a-z A-Z`
		if [ "`cat /proc/sys/net/ipv4/ip_forward`" = "0" ]; then
			echo "Please note that forwarding is disabled in the kernel." >/dev/stderr
			#/sbin/ipchains -A forward -j DENY		#Possible to add, but unncessary.
		fi

		if [ -n "$BLOCKEDHOSTS" ]; then
			echo -n Blockedhost blocks...
			for BLOCKEDHOST in $BLOCKEDHOSTS ; do
				/sbin/ipchains -I input  -s $BLOCKEDHOST -j DENY $LOG
				/sbin/ipchains -I output -s $BLOCKEDHOST -j DENY $LOG
				/sbin/ipchains -I input  -d $BLOCKEDHOST -j DENY $LOG
				/sbin/ipchains -I output -d $BLOCKEDHOST -j DENY $LOG
			done
		else
			echo -n No Blockedhost blocks...
		fi

		if [ -n "$NOINCOMING" ] && [ -n "$INCOMINGINTERFACES" ]; then
			echo -n Incoming blocks...
			for OUTSIDEIF in $INCOMINGINTERFACES ; do
				for BLOCKPROTO in $NOINCOMING ; do
					case $BLOCKPROTO in
					*/*)	/sbin/ipchains -I input -i $OUTSIDEIF -p ${BLOCKPROTO##*/} -d 0/0 ${BLOCKPROTO%%/*} -j DENY $LOG	;;
					*)		/sbin/ipchains -I input -i $OUTSIDEIF -p ${BLOCKPROTO##*/} -j DENY $LOG								;;
					esac
				done
			done
		else
			echo -n No incoming blocks...
		fi

		#cp -pf /etc/hosts /etc/hosts.bak ; cat $NAMECACHE >>/etc/hosts

		set +e		#Turn off failure checking; Mason has no control over the final contents of these files
		echo -n Fixed rules...
		. $BASERULEFILE

		echo -n New rules...
		. $NEWRULEFILE
		set -e

		#mv -f /etc/hosts.bak /etc/hosts

		#ALLCHAINS=`ipchains -L -n | grep '^Chain' | awk '{print $2}'`
		ALLCHAINS="input output forward"

#Finally, create a "nolog' chain for each of the existing chains, have each existing 
#chain jump to it, then log everything else.
		echo -n Adding logging rules...
		for ACHAIN in $ALLCHAINS ; do
			/sbin/ipchains -F ${ACHAIN}${NOLOGSUFFIX} >/dev/null 2>/dev/null				#Flush it as it might have existed before.
			if ! /sbin/ipchains -L ${ACHAIN}${NOLOGSUFFIX} >/dev/null 2>/dev/null ; then	#If nolog chain does not exist
				/sbin/ipchains -N ${ACHAIN}${NOLOGSUFFIX}					#Create it
		  	fi
			/sbin/ipchains -A $ACHAIN -j ${ACHAIN}${NOLOGSUFFIX}
			/sbin/ipchains -A $ACHAIN -l
			/sbin/ipchains -P $ACHAIN $DEFAULTPOLICY
		done
		echo Done!
	elif [ -f /proc/net/ip_input ]; then
		DEFAULTPOLICY=`echo $DEFAULTPOLICY | tr A-Z a-z`

		if [ "`cat /proc/sys/net/ipv4/ip_forward`" = "0" ]; then
			echo "Please note that forwarding is disabled in the kernel." >/dev/stderr
			#/sbin/ipfwadm -F -i deny				#Possible to add, but unncessary.
		fi

		if [ -n "$BLOCKEDHOSTS" ]; then
			echo -n Blockedhost blocks...
			for BLOCKEDHOST in $BLOCKEDHOSTS ; do
				/sbin/ipfwadm -I -i deny -S $BLOCKEDHOST $LOG
				/sbin/ipfwadm -O -i deny -S $BLOCKEDHOST $LOG
				/sbin/ipfwadm -I -i deny -D $BLOCKEDHOST $LOG
				/sbin/ipfwadm -O -i deny -D $BLOCKEDHOST $LOG
			done
		else
			echo -n No Blockedhost blocks...
		fi

		if [ -n "$NOINCOMING" ] && [ -n "$INCOMINGINTERFACES" ]; then
			echo -n Incoming blocks...
			for OUTSIDEIF in $INCOMINGINTERFACES ; do
				for BLOCKPROTO in $NOINCOMING ; do
					case $BLOCKPROTO in
					*/*)	/sbin/ipfwadm -I -i deny -W $OUTSIDEIF -P ${BLOCKPROTO##*/} -D 0/0 ${BLOCKPROTO%%/*} $LOG	;;
					*)		/sbin/ipfwadm -I -i deny -W $OUTSIDEIF -P ${BLOCKPROTO##*/} $LOG							;;
					esac
				done
			done
		else
			echo -n No incoming blocks...
		fi

		#cp -pf /etc/hosts /etc/hosts.bak ; cat $NAMECACHE >>/etc/hosts

		set +e		#Turn off failure checking; Mason has no control over the final contents of these files
		echo -n Fixed rules...
		. $BASERULEFILE

		echo -n New rules...
		. $NEWRULEFILE
		set -e

		#mv -f /etc/hosts.bak /etc/hosts

		ALLCHAINS="I O F"

#Finally, log everything else.
		echo -n Adding logging rules...
		for ACHAIN in $ALLCHAINS ; do
			/sbin/ipfwadm -${ACHAIN} -a ${LOGGINGPOLICY} -o
			/sbin/ipfwadm -${ACHAIN} -p $DEFAULTPOLICY
		done
		echo Done!
	else
		echo This kernel supports neither ipchains nor ipfwadm! >/dev/stderr
	fi
} #End of runlearnfirewall


runstandardfirewall () {
	if [ -f /proc/net/ip_fwchains ]; then
		DEFAULTPOLICY=`echo $DEFAULTPOLICY | tr a-z A-Z`
		if [ "`cat /proc/sys/net/ipv4/ip_forward`" = "0" ]; then
			echo "Please note that forwarding is disabled in the kernel." >/dev/stderr
			#/sbin/ipchains -A forward -j DENY		#Possible to add, but unncessary.
		fi

		if [ -n "$BLOCKEDHOSTS" ]; then
			echo -n Blockedhost blocks...
			for BLOCKEDHOST in $BLOCKEDHOSTS ; do
				/sbin/ipchains -I input  -s $BLOCKEDHOST -j DENY $LOG
				/sbin/ipchains -I output -s $BLOCKEDHOST -j DENY $LOG
				/sbin/ipchains -I input  -d $BLOCKEDHOST -j DENY $LOG
				/sbin/ipchains -I output -d $BLOCKEDHOST -j DENY $LOG
			done
		else
			echo -n No Blockedhost blocks...
		fi

		if [ -n "$NOINCOMING" ] && [ -n "$INCOMINGINTERFACES" ]; then
			echo -n Incoming blocks...
			for OUTSIDEIF in $INCOMINGINTERFACES ; do
				for BLOCKPROTO in $NOINCOMING ; do
					case $BLOCKPROTO in
					*/*)	/sbin/ipchains -I input -i $OUTSIDEIF -p ${BLOCKPROTO##*/} -d 0/0 ${BLOCKPROTO%%/*} -j DENY $LOG	;;
					*)		/sbin/ipchains -I input -i $OUTSIDEIF -p ${BLOCKPROTO##*/} -j DENY $LOG								;;
					esac
				done
			done
		else
			echo -n No incoming blocks...
		fi

		#cp -pf /etc/hosts /etc/hosts.bak ; cat $NAMECACHE >>/etc/hosts

		set +e		#Turn off failure checking; Mason has no control over the final contents of this file.
		echo -n Fixed rules...
		. $BASERULEFILE
		set -e

		#mv -f /etc/hosts.bak /etc/hosts

		#ALLCHAINS=`ipchains -L -n | grep '^Chain' | awk '{print $2}'`
		ALLCHAINS="input output forward"

		for ACHAIN in $ALLCHAINS ; do
			/sbin/ipchains -P $ACHAIN $DEFAULTPOLICY
		done
		echo Done!
	elif [ -f /proc/net/ip_input ]; then
		DEFAULTPOLICY=`echo $DEFAULTPOLICY | tr A-Z a-z`

		if [ "`cat /proc/sys/net/ipv4/ip_forward`" = "0" ]; then
			echo "Please note that forwarding is disabled in the kernel." >/dev/stderr
			#/sbin/ipfwadm -F -i deny				#Possible to add, but unncessary.
		fi

		if [ -n "$BLOCKEDHOSTS" ]; then
			echo -n Blockedhost blocks...
			for BLOCKEDHOST in $BLOCKEDHOSTS ; do
				/sbin/ipfwadm -I -i deny -S $BLOCKEDHOST $LOG
				/sbin/ipfwadm -O -i deny -S $BLOCKEDHOST $LOG
				/sbin/ipfwadm -I -i deny -D $BLOCKEDHOST $LOG
				/sbin/ipfwadm -O -i deny -D $BLOCKEDHOST $LOG
			done
		else
			echo -n No Blockedhost blocks...
		fi

		if [ -n "$NOINCOMING" ] && [ -n "$INCOMINGINTERFACES" ]; then
			echo -n Incoming blocks...
			for OUTSIDEIF in $INCOMINGINTERFACES ; do
				for BLOCKPROTO in $NOINCOMING ; do
					case $BLOCKPROTO in
					*/*)	/sbin/ipfwadm -I -i deny -W $OUTSIDEIF -P ${BLOCKPROTO##*/} -D 0/0 ${BLOCKPROTO%%/*} $LOG	;;
					*)		/sbin/ipfwadm -I -i deny -W $OUTSIDEIF -P ${BLOCKPROTO##*/} $LOG							;;
					esac
				done
			done
		else
			echo -n No incoming blocks...
		fi

		#cp -pf /etc/hosts /etc/hosts.bak ; cat $NAMECACHE >>/etc/hosts

		set +e		#Turn off failure checking; Mason has no control over the final contents of this file.
		echo -n Fixed rules...
		. $BASERULEFILE
		set -e

		#mv -f /etc/hosts.bak /etc/hosts

		ALLCHAINS="I O F"

		for ACHAIN in $ALLCHAINS ; do
			/sbin/ipfwadm -${ACHAIN} -p $DEFAULTPOLICY
		done
		echo Done!
	else
		echo This kernel supports neither ipchains nor ipfwadm! >/dev/stderr
	fi
} #End of runstandardfirewall



#-------------------------------------------------------------------------
# serverportrange subroutine, tries to determine whether the given numeric
# port and protocol specify a server port.  If so, returns the appropriate
# readable representation for that server and sets the comment.
# If no corresponding server port is known, both are left blank.
#-------------------------------------------------------------------------
serverportrange () {
#Params: numeric port, proto
	PARTIALCOMMENT="" ; READABLEPORT=""
	SERVICE="`cat $SERVICES | grep "${1}/${2}" | head -n 1 | awk '{print $1}'`"
	#Mason will not be manipulating /etc/services.
	#SERVICELINE="`cat $SERVICES | grep "${1}/${2}" | head -n 1`"
	#if [ `cat /etc/services | grep "${1}/${2}" | wc -l` -eq 0 ]; then	#Merge line from additional services files to /etc/services if necessary
	#	if [ -n "$SERVICELINE" ]; then
	#		echo -e "$SERVICELINE ##(added by Mason)" >>/etc/services
	#	fi
	#fi

	#if #registered in sunrpc
		#process sunrpc port, change following to elif
	if [ "$2" = "udp" ] && [ $1 -ge $TRACEROUTE_BEGIN ] && [ $1 -le $TRACEROUTE_END ]; then
		READABLEPORT="${TRACEROUTE_BEGIN}:${TRACEROUTE_END}" ;	PARTIALCOMMENT="TRACEROUTE/$PROTO"
	elif [ "$2" = "udp" ] && [ $1 -ge 6970 ] && [ $1 -le 7170 ]; then
		READABLEPORT="6970:7170" ;								PARTIALCOMMENT="RADATA/$PROTO"
	elif [ "$2" = "udp" ] && [ $1 -ge 6770 ] && [ $1 -le 7170 ]; then
		READABLEPORT="6770:7170" ;								PARTIALCOMMENT="RA30DATA/$PROTO"
	elif [ "$2" = "tcp" ] && [ $1 -ge $X_BEGIN ] && [ $1 -le $X_END ]; then
		READABLEPORT="${X_BEGIN}:${X_END}" ;					PARTIALCOMMENT="X/$PROTO"
	elif [ "$2" = "tcp" ] && [ $1 -ge $OPENWIN_BEGIN ] && [ $1 -le $OPENWIN_END ]; then
		READABLEPORT="${OPENWIN_BEGIN}:${OPENWIN_END}" ;		PARTIALCOMMENT="OPENWIN/$PROTO"
	elif [ "$2" = "tcp" ] && [ $1 -ge $VNCJAVA_BEGIN ] && [ $1 -le $VNCJAVA_END ]; then
		READABLEPORT="${VNCJAVA_BEGIN}:${VNCJAVA_END}" ;		PARTIALCOMMENT="VNCJAVA/$PROTO"
	elif [ "$2" = "tcp" ] && [ $1 -ge $VNC_BEGIN ] && [ $1 -le $VNC_END ]; then
		READABLEPORT="${VNC_BEGIN}:${VNC_END}" ;				PARTIALCOMMENT="VNC/$PROTO"
	elif [ "$2" = "tcp" ] && [ $1 -ge $IRC_BEGIN ] && [ $1 -le $IRC_END ]; then
		READABLEPORT="${IRC_BEGIN}:${IRC_END}" ;				PARTIALCOMMENT="IRC/$PROTO"
	elif [ -n "$SERVICE" ]; then
		if [ "$ECHOCOMMAND" != "ipchains-save" ]; then
			READABLEPORT=$SERVICE ;								PARTIALCOMMENT="${SERVICE}/$PROTO"
		else
			READABLEPORT=$1 ;									PARTIALCOMMENT="${SERVICE}/$PROTO"
		fi
	fi
	#echo $READABLEPORT		#Can't do this because we need to return PARTIALCOMMENT as well.
} #end of serverportrange


#-------------------------------------------------------------------------
# sigexitscript function, called on receipt of SIGHUP
#-------------------------------------------------------------------------
sigexitscript () {
	if [ "$NEEDLF" = "YES" ]; then echo >/dev/stderr ; NEEDLF="NO" ; fi
	echo Received HUP signal, exiting at next pass >/dev/stderr
	EXITMASON="YES"
} #End of sigexitscript


#-------------------------------------------------------------------------
# settos subroutine, sets the TOS variable for the given port, port range, and protocol.
#-------------------------------------------------------------------------
# Once Cisco's TOS format is known, that will get set here as well.
#params: port, port range, protocol
settos () {
	if [ "$INFORMAT" != "ipchains-lv" ]; then
		#http://www.cis.ohio-state.edu/htbin/rfc/rfc1349.html, esp. Appendix 2
		#I generally follow what's in the IPCHAINS-Howto and RFC 1349 (with the exception of SMTP), and 
		#chose to put pop3 and imap in the minimize cost category and web as maximize throughput.
		#I would truly welcome any dialog, public or private, on whether the following set of 
		#TOS settings is appropriate for a general purpose firewall.
		TOS=""
		#I specifically do _not_ test for what policy is being used.  Even if the policy is currently
		#reject or deny, the user might change it to accept later in the rule file, in which case the TOS flag should be set.
		case "${2}/${3}" in
		"${IRC_BEGIN}:${IRC_END}/tcp")	TOS=" -t 0x01 0x10"	;;	#IRC				Minimize delay
		esac
		case "${1}/${3}" in
		"21/tcp")						TOS=" -t 0x01 0x10"	;;	#FTP				Minimize delay
		"23/tcp"|"22/tcp"|"513/tcp")	TOS=" -t 0x01 0x10"	;;	#Telnet,SSH,rlogin	Minimize delay
		"53/udp")						TOS=" -t 0x01 0x10"	;;	#dns				Minimize delay
		"69/udp")						TOS=" -t 0x01 0x10"	;;	#tftp				Minimize delay
		"20/tcp"|"25/tcp")				TOS=" -t 0x01 0x08"	;;	#FTP-data,SMTP		Maximize throughput
		"53/tcp")						TOS=" -t 0x01 0x08"	;;	#DNS zone transfer	Maximize throughput
		"80/tcp"|"443/tcp"|"563/tcp")	TOS=" -t 0x01 0x08"	;;	#Web & secure web	Maximize throughput
		"8080/tcp"|"3128/tcp")			TOS=" -t 0x01 0x08"	;;	#Web Caches			Maximize throughput
		"161/udp")						TOS=" -t 0x01 0x04"	;;	#SNMP				Maximize reliability
		"119/tcp"|"110/tcp"|"143/tcp")	TOS=" -t 0x01 0x02"	;;	#NNTP,POP3,IMAP		Minimize cost
		esac
	fi

	if [ "$ECHOCOMMAND" = "cisco" ]; then
		case "$TOS" in		#FIXME - these are the wrong strings.  See cisco docs to fix.
		" -t 0x01 0x02")	TOS=" mincost"	;;
		" -t 0x01 0x04")	TOS=" maxreliability"	;;
		" -t 0x01 0x08")	TOS=" maxthroughput"	;;
		" -t 0x01 0x10")	TOS=" mindelay"	;;
		esac
	elif [ "$ECHOCOMMAND" = "ipchains-save" ]; then
		case "$TOS" in
		" -t 0x01 0x02")	TOS=" -t 01 02"	;;
		" -t 0x01 0x04")	TOS=" -t 01 04"	;;
		" -t 0x01 0x08")	TOS=" -t 01 08"	;;
		" -t 0x01 0x10")	TOS=" -t 01 10"	;;
		esac
	fi
} #End of settos


