
#-----------------------------------------------------------------------
# Copyright (C) 2000-2001, Jean-Sebastien Morisset <jsmoriss@mvlan.net>
#-----------------------------------------------------------------------
# $Id: forward_hostports.sh,v 1.4 2001/08/11 17:01:20 jsmoriss Exp $
#-----------------------------------------------------------------------
#  $RCSfile: forward_hostports.sh,v $
#   $Author: jsmoriss $
# $Revision: 1.4 $
#     $Date: 2001/08/11 17:01:20 $
#   $Locker:  $ 
#     $Name:  $
#-----------------------------------------------------------------------
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by 
# the Free Software Foundation <http://www.gnu.org/copyleft/gpl.txt>.
# 
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License (LICENSE file in archive) for more details.
#
#-----------------------------------------------------------------------
# README
#-----------------------------------------------------------------------
#
# A bourne shell function used by rcf; a very secure, fast, and complete
# firewall for linux <http://jsmoriss.mvlan.net/linux/rcf.html>.
#
#-----------------------------------------------------------------------
# FUNCTION
#-----------------------------------------------------------------------

Forward_Hostports () {
	#
	# This function expects each host to have an accompanying port number.
	#
	# Syntax:
	#   Forward_Hostports {protocol} {description} {internal host and port)
	#
	# Examples:
	#   Forward_Hostports tcp "HTTP" trillian.localdomain 80
	#   Forward_Hostports tcp "My Game" pc1.localdomain 1234, pc2.localdomain 5678
	#
	PROTOCOL="$1"
	[ "$2" ] && SERVDESC="$2 " || SERVDESC=""
	shift 2

	if [ "$2" -a ! -x "`which ipmasqadm 2>/dev/null`" ]
	then
		echo "UNABLE TO LOCATE THE ipmasqadm BINARY!"
	elif [ "$2" -a -x "`which ipmasqadm 2>/dev/null`" ]
	then
		LCASE_PROTOCOL="`echo $PROTOCOL|To_Lower`"
		FORWARDING=`echo $*|sed -e 's/,/ *separator* /g'`

		# Usage: portfw -a -P PROTO -L LADDR LPORT -R RADDR RPORT [-p PREF] add entry
		#        portfw -d -P PROTO -L LADDR LPORT [-R RADDR RPORT]         delete entry
		#        portfw -f                                                  clear table
		#        portfw -l                                                  list table
		#        portfw <args> -n                                           no names
		#
		# PROTO is the protocol, can be "tcp" or "udp"
		# LADDR is the local interface receiving packets to be forwarded.
		# LPORT is the port being redirected.
		# RADDR is the remote address.
		# RPORT is the port being redirected to.
		# PREF  is the preference level (load balancing, default=10)

		TARGET_HOST=''
		for FIELD in $FORWARDING
		do
			if [ "$FIELD" = "*separator*" ]
			then
				TARGET_HOST=""
			elif [ ! "$TARGET_HOST" ]
			then
				TARGET_HOST="$FIELD"
			else
				case $FIELD in
					[:0-9]*-\>[:0-9]*)
						LOCAL_PORTS="`echo $FIELD|sed -e 's/\([:0-9]*\)->[:0-9]*/\1/'`"
						REMOTE_PORTS="`echo $FIELD|sed -e 's/[:0-9]*->\([:0-9]*\)/\1/'`"
						;;
					*)
						LOCAL_PORTS="$FIELD"
						REMOTE_PORTS="$FIELD"
						;;
				esac

				case $LOCAL_PORTS in
					[0-9]*:[0-9]*)
						BEGIN_LOCAL_PORT="`echo $LOCAL_PORTS|sed -e 's/\([0-9]*\):[0-9]*/\1/'`"
						END_LOCAL_PORT="`echo $LOCAL_PORTS|sed -e 's/[0-9]*:\([0-9]*\)/\1/'`"
						;;
					*)
						BEGIN_LOCAL_PORT="$LOCAL_PORTS"
						END_LOCAL_PORT="$LOCAL_PORTS"
				esac

				case $REMOTE_PORTS in
					[0-9]*:[0-9]*)
						BEGIN_REMOTE_PORT="`echo $REMOTE_PORTS|sed -e 's/\([0-9]*\):[0-9]*/\1/'`"
						END_REMOTE_PORT="`echo $REMOTE_PORTS|sed -e 's/[0-9]*:\([0-9]*\)/\1/'`"
						;;
					*)
						BEGIN_REMOTE_PORT="$REMOTE_PORTS"
						END_REMOTE_PORT="$REMOTE_PORTS"
				esac

				echo -n "Forward ${IPADDR} ${SERVDESC}Port# ${LOCAL_PORTS}/$LCASE_PROTOCOL -> "
				echo "${TARGET_HOST} Port# ${REMOTE_PORTS}"

				CURRENT_LOCAL_PORT="$BEGIN_LOCAL_PORT"
				CURRENT_REMOTE_PORT="$BEGIN_REMOTE_PORT"

				while [ "$CURRENT_LOCAL_PORT" -le "$END_LOCAL_PORT" \
					-a "$CURRENT_REMOTE_PORT" -le "$END_REMOTE_PORT" ]
				do
					ipmasqadm portfw -a -P $LCASE_PROTOCOL \
						-L ${IPADDR} ${CURRENT_LOCAL_PORT} \
						-R ${TARGET_HOST} ${CURRENT_REMOTE_PORT}
					CURRENT_LOCAL_PORT=`expr $CURRENT_LOCAL_PORT + 1`
					CURRENT_REMOTE_PORT=`expr $CURRENT_REMOTE_PORT + 1`
				done
				unset LOCAL_PORTS REMOTE_PORTS
				unset BEGIN_LOCAL_PORT END_LOCAL_PORT
				unset BEGIN_REMOTE_PORT END_REMOTE_PORT
				unset CURRENT_LOCAL_PORT CURRENT_REMOTE_PORT
			fi
		done
	fi
}

