#!/bin/bash
#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.


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=${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
	PACKETLOGFILE=${PACKETLOGFILE:-"/var/log/messages"}
	MASONEXE=${MASONEXE:-"/usr/bin/mason"}

	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...
	accept|ACCEPT)		LCPOLICY="accept" ;	UCPOLICY="ACCEPT"	;;
	reject|REJECT)		LCPOLICY="reject" ;	UCPOLICY="REJECT"	;;
	deny|DENY)			LCPOLICY="deny  " ;	UCPOLICY="DENY  "	;;
	*)	echo WARNING! NEWRULEPOLICY is neither accept, reject, nor deny >/dev/stderr
		echo in ${MASONCONF}.  It is being reset to \"accept\".  Please fix! >/dev/stderr
		LCPOLICY="accept" ;	UCPOLICY="ACCEPT"					;;
	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}.  It is being reset to \"accept\".  Please fix! >/dev/stderr
		DEFAULTPOLICY="accept"									;;
	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"					;;
	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 ]}

	SSP=${SSP:-""}
	SCP=${SCP:-""}

	LOWSSHPORT=${LOWSSHPORT:-"1010"}
} #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



#-------------------------------------------------------------------------
# convmasktobits function, returns the number of bits in the netmask parameter.
#-------------------------------------------------------------------------
convmasktobits () {
	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 convmasktobits



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
		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}/32"
	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}`/32"							;;
		NETWORK)
#Handle special addresses
			case $1 in
			0.0.0.0)			GIRETVAL="0.0.0.0/32"			ISASSIGNED="YES"	;;
			127.0.0.1)			GIRETVAL="localhost/32"			ISASSIGNED="YES"	;;
			255.255.255.255)	GIRETVAL="255.255.255.255/32"	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}`/32"
						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
								GIRETVAL="${ONENET}/`convmasktobits ${NETMASK}`"
								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
	unset I1O1 I1O2 I1O3 I1O4
	I1O1=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O2=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O3=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O4=$SPLITIP
	SPLITIP=$2
	unset I2O1 I2O2 I2O3 I2O4
	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
	unset I1O1 I1O2 I1O3 I1O4
	I1O1=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O2=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O3=${SPLITIP%%.*} ; SPLITIP=${SPLITIP#*.}
	I1O4=$SPLITIP
	SPLITIP=$2
	unset I2O1 I2O2 I2O3 I2O4
	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 and networks..." >/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
																;;
		esac
	done
	echo "Done." >/dev/stderr
	SIGGED="YES"	#We received a signal
#FIXME - put killall -SIGUSR1 mason in ip-up...
} #End of loadconf


#-------------------------------------------------------------------------
# nameof function, returns the hostname from the IP address parameter.
#-------------------------------------------------------------------------
nameof () {
#Use the namecache file, /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}'`
		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


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
			/sbin/ipchains -A forward -j DENY
		fi

		echo -n Incoming blocks...
		for OUTSIDEIF in $INCOMINGINTERFACES ; do
			for BLOCKPROTO in $NOINCOMING ; do
				/sbin/ipchains -I input -i $OUTSIDEIF -p ${BLOCKPROTO##*/} -d 0/0 ${BLOCKPROTO%%/*}   -j DENY $LOG
			done
		done

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

		echo -n Fixed rules...
		. $BASERULEFILE

		echo -n New rules...
		. $NEWRULEFILE

		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
		echo -n Untested - may have typos... >/dev/stderr
		DEFAULTPOLICY=`echo $DEFAULTPOLICY | tr A-Z a-z`

		if [ "`cat /proc/sys/net/ipv4/ip_forward`" = "0" ]; then
			/sbin/ipfwadm -F -i deny
		fi

		echo -n Incoming blocks...
		for OUTSIDEIF in $INCOMINGINTERFACES ; do
			for BLOCKPROTO in $NOINCOMING ; do
				/sbin/ipfwadm -I -i deny -W $OUTSIDEIF -P ${BLOCKPROTO##*/} -D 0/0 ${BLOCKPROTO%%/*} $LOG
			done
		done

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

		echo -n Fixed rules...
		. $BASERULEFILE

		echo -n New rules...
		. $NEWRULEFILE

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

		ALLCHAINS="I O F"

#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/ipfwadm -${ACHAIN} -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
			/sbin/ipchains -A forward -j DENY
		fi

		echo -n Incoming blocks...
		for OUTSIDEIF in $INCOMINGINTERFACES ; do
			for BLOCKPROTO in $NOINCOMING ; do
				/sbin/ipchains -I input -i $OUTSIDEIF -p ${BLOCKPROTO##*/} -d 0/0 ${BLOCKPROTO%%/*}   -j DENY $LOG
			done
		done

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

		echo -n Fixed rules...
		. $BASERULEFILE

		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
		echo -n Untested - may have typos... >/dev/stderr
		DEFAULTPOLICY=`echo $DEFAULTPOLICY | tr A-Z a-z`

		if [ "`cat /proc/sys/net/ipv4/ip_forward`" = "0" ]; then
			/sbin/ipfwadm -F -i deny
		fi

		echo -n Incoming blocks...
		for OUTSIDEIF in $INCOMINGINTERFACES ; do
			for BLOCKPROTO in $NOINCOMING ; do
				/sbin/ipfwadm -I -i deny -W $OUTSIDEIF -P ${BLOCKPROTO##*/} -D 0/0 ${BLOCKPROTO%%/*} $LOG
			done
		done

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

		echo -n Fixed rules...
		. $BASERULEFILE

		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 /etc/services | grep "${1}/${2}" | head -n 1 | awk '{print $1}'`
	#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
		READABLEPORT=${SERVICE} ;								PARTIALCOMMENT="${SERVICE}/$PROTO"
	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


