#!/bin/sh

#
# LRP/Debian network configuration system
#
# Ring a ding ding, my dang a lang dong	   Dave 'Kill a Cop' Cinege   GPL2

# 
# start)
# Auto config toggles ip_fowarding, sets up the loop back interface, 
# handles ifconfig for interfaces, static routes for nets and hosts, and 
# if ipfwadm is available:  Flush rules and toggle forwarding, IP spoof 
# protect on interfaces, and basic IP Masq for nets and hosts.
# Direct config is a sourced file that can contain any commands.
# 
# stop)
# brings down all interfaces listed in /proc/net/dev, and their associated
# routes. Flushes all rules for ipfwadm, ipchains, ipautofw, ipportfw.
#

#Used by update-rc.d
RCDLINKS="S,S39"	#LRP
FLAGS="start 39 S"	#Debian


#DEBUG=1

SP='   '
OIFS=$IFS

LOGFILE="/var/log/messages"

qt () { "$@" >/dev/null 2>&1 ; }
vb () { "$@"; }
#vb () { "$@" 2>&1 | tee -a $LOGFILE; }

source () { . $1 ; }


BANNER="# This file was generated by $0. It may be overwritten!"


#Default safe settings
DIRECT_SETTINGS_ONLY=YES
VERBOSE=YES
DHCP_SLEEP=30
MAX_LOOP=10
IPFWDING_KERNEL=NO
IPFWDING_FW=NO
CONFIG_DNS=NO

#==============================================================================#

[ -f /etc/network.conf ] && source /etc/network.conf

[ "$DEBUG" ] && qt () { "$@" ; }
[ "$VERBOSE" = "NO" ] && vb () { qt "$@" ; }


[ -f /proc/net/ip_forward ] && IPFWADM=1
[ -f /proc/net/ip_fwchains ] && IPCHAINS=1
[ -f /proc/net/ip_autofw ] && IPAUTOFW=1
[ -f /proc/net/ip_portfw ] && IPPORTFW=1

###############################################################################
#IP Forwarding configuration
###############################################################################
start-auto-ipforward () {
	if [ "$IPFWDING_KERNEL" = "YES" ]; then
		echo "1" >/proc/sys/net/ipv4/ip_forward && vb echo -n "[IP Forwarding: ON] "
	else
		echo "0" >/proc/sys/net/ipv4/ip_forward && vb echo -n "[IP Forwarding: OFF] "
	fi 
}

###############################################################################
#Loose UDP
###############################################################################
start-auto-dloose () {
	if [ "$IPMASQ_DLOOSE" = "YES" ]; then
		echo "1" >/proc/sys/net/ipv4/ip_masq_udp_dloose && vb echo -n "[MASQ Loose UDP: ON] "
	else
		echo "0" >/proc/sys/net/ipv4/ip_masq_udp_dloose && vb echo -n "[MASQ Loose UDP: OFF] "
	fi 
}

###############################################################################
#Interface configuration
###############################################################################
start-auto-if () {
	vb echo -n "$SP""Interfaces: "

	###
	#localhost interface
	############################################
	ifconfig lo 127.0.0.1 && vb echo -n "lo "  #
	############################################

	x=-1
	while [ $x -lt $MAX_LOOP ]; do
		x=$(($x + 1))
	
		eval IFNAME=\${"IF$x"_IFNAME:-""}	#Behold my genius. Kneel and repent!

		if [ "$IFNAME" != "" ]; then
			
			eval IPADDR=\${"IF$x"_IPADDR:-""}
			eval NETMASK=\${"IF$x"_NETMASK:-""}
			eval BROADCAST=\${"IF$x"_BROADCAST:-""}
	
			if [ "$IPADDR" = "dhcp" ]; then
				IFDHCP="$IFDHCP $IFNAME"
				continue
			fi
	
			ifconfig $IFNAME $IPADDR netmask $NETMASK broadcast $BROADCAST \
			&& vb echo -n "$IFNAME "
		fi
	done
	vb echo
}


ifconfig-ip () {
	echo -n "$(ifconfig $1 | sed -n 's/.*inet addr:\([^ ]*\).*/\1/p')"
}

ifconfig-ip_bcast_mask() {
	echo -n "$(ifconfig $1 | sed -n 's/.*inet addr:\([^ ]*\).*Bcast:\([^ ]*\).*Mask:\([^ ]*\)/\1 \2 \3/p')"
}

start-auto-if-dhcp () {

	[ "$IFDHCP" = "" ] && return
	vb echo -n "$SP""DHCP: "
	
	qt killall dhclient
	
	for f in $IFDHCP; do
		qt dhclient $f
	done
	
	for f in $IFDHCP; do
		st=0
		while :; do
			ip="$(ifconfig-ip $f)"
			qt ping -c 1 $ip
			if [ $? -eq 0 ]; then
				vb echo -n "$f=$ip "
				break
			fi
			
			sleep 3
			st=$(($st + 3))
			
			if [ $st -ge $DHCP_SLEEP ]; then
				vb echo -n "$f=TIMEOUT "
				break
			fi
		done
	done
	
	x=0
	while [ $x -lt $MAX_LOOP ]; do		# Set ip, bcast, and mask from interface
	
		eval IFNAME=\${"IF$x"_IFNAME:-""}
		if [ "$IFNAME" != "" ]; then
			
			eval IPADDR=\${"IF$x"_IPADDR:-""}
	
			if [ "$IPADDR" = "dhcp" ]; then
				set -- $(ifconfig-ip_bcast_mask $IFNAME)
				eval "IF$x"_IPADDR=\$1
				eval "IF$x"_BROADCAST=\$2
				eval "IF$x"_NETMASK=\$3
			fi

		fi
		x=$(($x + 1))
	done
	vb echo
	
}

###############################################################################
# Static Host Routes
###############################################################################
start-auto-static-host () {
	x=0; y=0
	while [ $x -lt $MAX_LOOP ]; do

		eval IPADDR=\${"HOST$x"_IPADDR:-""}

		if [ "$IPADDR" != "" ]; then
		
			[ $y -eq 0 ] && vb echo -n "$SP""Static Hosts: " && y=1
		
			eval GATEWAY_IF=\${"HOST$x"_GATEWAY_IF:-""}
			eval GATEWAY_IP=\${"HOST$x"_GATEWAY_IP:-""}
			
			[ "$GATEWAY_IF" = "default" ] && GATEWAY_IF=""
				
			if [ "$GATEWAY_IP" = "default" ]; then
			 	GATEWAY_IP=""
			else
				GATEWAY_IP="gw $GATEWAY_IP"
			fi
		
			route add -host $IPADDR $GATEWAY_IF $GATEWAY_IP \
			&& vb echo -n "$IPADDR "
		fi
		x=$(($x + 1))
	done
	[ $y -eq 1 ] && vb echo
}

###############################################################################
# Static Network Routes
###############################################################################
start-auto-static-net () {
	vb echo -n "$SP""Static Networks: "

	###
	#localhost network
	###########################################################################
	[ ! "$IPCHAINS" ] && route add -net 127.0.0.0 && vb echo -n "127.0.0.0 "  #
	###########################################################################

	x=-1
	while [ $x -lt $MAX_LOOP ]; do	x=$(($x + 1))

		eval NETADDR=\${"NET$x"_NETADDR:-""}

		if [ "$NETADDR" != "" ]; then
	
			eval NETMASK=\${"NET$x"_NETMASK:-""}
			eval GATEWAY_IF=\${"NET$x"_GATEWAY_IF:-""}
			eval GATEWAY_IP=\${"NET$x"_GATEWAY_IP:-""}
					
			[ "$GATEWAY_IF" = "default" ] && GATEWAY_IF=""
								
			if [ "$GATEWAY_IP" = "default" ]; then
				GATEWAY_IP=""
			else
				GATEWAY_IP="gw $GATEWAY_IP"
			fi
				
			NTEST="$(route -n | grep $NETADDR)"	# Skip already present nets
			[ "$NTEST" ] && continue
				
			route add -net $NETADDR	netmask $NETMASK $GATEWAY_IP $GATEWAY_IF \
			&& vb echo -n "$NETADDR "
		fi
	done
	vb echo
}

###############################################################################
# Default Routes
###############################################################################
start-auto-static-default () {
	x=0; y=0
	while [ $x -lt $MAX_LOOP ]; do

	eval IPADDR=\${"GW$x"_IPADDR:-""}

		if [ "$IPADDR" != "" ]; then
		
			[ $y -eq 0 ] && vb echo -n "$SP""Default Routes: " && y=1
		
			eval IFNAME=\${"GW$x"_IFNAME:-""}
			eval METRIC=\${"GW$x"_METRIC:-""}
		
			[ "$IFNAME" = "default" ] && IFNAME=""
		
			route add default gw $IPADDR metric $METRIC $IFNAME \
			&& vb echo -n "$IPADDR "
		fi
		x=$(($x + 1))
	done
	[ $y -eq 1 ] && vb echo
}

###############################################################################
# Firewall rules
###############################################################################
start-auto-fw-rules () {

	vb echo

	vb echo -n "$SP""Firewall Rules - "

	if ! qt ipfwadm -F -f; then	#BEGIN - Firewall check
		vb echo "Kernel lacks Firewall support. Skipping..."
	else


		#Flush all Forward, Input, Output, and Accting rules
		vb echo -n "[Flushing: "
		ipfwadm -F -f && ipfwadm -I -f && ipfwadm -O -f && \
		ipfwadm -A -f && vb echo -n "F,I,O,A] "

		if [ "$IPFWDING_FW" != "YES" ]; then
			ipfwadm -F -p deny && vb echo -n "[Forwarding: DENY] "
		else 
			ipfwadm -F -p accept && vb echo -n "[Forwarding: ACCEPT] "
		fi

		vb echo

	###############################################################################
	# IP Spoof protection
	###############################################################################

		x=0; y=0
		while [ $x -lt $MAX_LOOP ]; do

			eval IFNAME=\${"IF$x"_IFNAME:-""}
			eval IP_SPOOF=\${"IF$x"_IP_SPOOF:-""}

			if [ "$IFNAME" != "" ] && [ "$IP_SPOOF" != "NO" ]; then
	
				[ $y -eq 0 ] && vb echo -n "$SP$SP""IP spoofing protection: " && y=1
	
				eval IPADDR=\${"IF$x"_IPADDR:-""}
	
				ipfwadm -I -i deny -o -P all -S 127.0.0.0/8 -W $IFNAME -D 0/0  && \
				ipfwadm -I -i deny -o -P all -S $IPADDR -W $IFNAME -D 0/0 \
				&& vb echo -n "$IFNAME "
			fi
			x=$(($x + 1))
		done
		[ $y -eq 1 ] && vb echo


	###############################################################################
	# IP Masquerade
	###############################################################################

		#nets
		x=0; y=0
		while [ $x -lt $MAX_LOOP ]; do

			eval NETADDR=\${"NET$x"_NETADDR:-""}
			eval IPMASQ=\${"NET$x"_IPMASQ:-""}
			eval IPMASQ_IF=\${"NET$x"_IPMASQ_IF:-"default"}
					
			[ "$IPMASQ_IF" = "default" ] && IPMASQ_IF="" || IPMASQ_IF="-W $IPMASQ_IF"
			
	
			if [ "$NETADDR" != "" ] && [ "$IPMASQ" = "YES" ]; then
	
				[ $y -eq 0 ] && vb echo -n "$SP$SP""IP Masquerade: " && y=1
		
				eval NETMASK=\${"NET$x"_NETMASK:-"24"}

				ipfwadm -F -a m -S $NETADDR/$NETMASK -D 0/0 $IPMASQ_IF \
				&& vb echo -n "$NETADDR "
			fi
			x=$(($x + 1))
		done

		#hosts
		x=0
		while [ $x -lt $MAX_LOOP ]; do

			eval IPADDR=\${"HOST$x"_IPADDR:-""}
			eval IPMASQ=\${"HOST$x"_IPMASQ:-""}
			eval IPMASQ_IF=\${"HOST$x"_IPMASQ_IF:-"default"}
					
			[ "$IPMASQ_IF" = "default" ] && IPMASQ_IF="" || IPMASQ_IF="-W $IPMASQ_IF"
	
			if [ "$IPADDR" != "" ] && [ "$IPMASQ" = "YES" ]; then
	
				[ $y -eq 0 ] && vb echo -n "$SP$SP""IP Masquerade: " && y=1

				ipfwadm -F -a m -S $IPADDR -D 0/0 $IPMASQ_IF \
				&& vb echo -n "$IPADDR "
			fi
			x=$(($x + 1))
		done
		[ $y -eq 1 ] && vb echo


	fi	#END - Firewall check

	start-auto-portfw
	
	vb echo
}

start-auto-fwchains-rules () {

	vb echo

	vb echo -n "$SP""Firewall Rules - "

	if ! qt ipchains -F forward; then	#BEGIN - Firewall check
		vb echo "Kernel lacks Firewall support. Skipping..."
	else


		#Flush all Forward, Input, Output, and Accting rules
		vb echo -n "[Flushing: "
		qt ipchains -F vb echo -n "F,I,O,A] "

		if [ "$IPFWDING_FW" != "YES" ]; then
			ipchains -A forward -j DENY && vb echo -n "[Forwarding: DENY] "
		else 
			vb echo -n "[Forwarding: ACCEPT] "
		fi

		vb echo

	###############################################################################
	# IP Spoof protection
	###############################################################################

		x=-1; y=0
		while [ $x -lt $MAX_LOOP ]; do
			x=$(($x + 1))

			eval IFNAME=\${"IF$x"_IFNAME:-""}
			eval IP_SPOOF=\${"IF$x"_IP_SPOOF:-""}

			if [ "$IFNAME" != "" ]; then
			
				[ ! -f "/proc/sys/net/ipv4/conf/$IFNAME/rp_filter" ] && continue
				if [ "$IP_SPOOF" != "NO" ]; then
	
					[ $y -eq 0 ] && vb echo -n "$SP$SP""IP spoofing protection: " && y=1
		
					echo "1" >/proc/sys/net/ipv4/conf/$IFNAME/rp_filter \
					&& vb echo -n "$IFNAME "
				else
					echo "0" >/proc/sys/net/ipv4/conf/$IFNAME/rp_filter
				fi
			fi
		done
		[ $y -eq 1 ] && vb echo


	###############################################################################
	# IP Masquerade
	###############################################################################

		#nets
		x=0; y=0
		while [ $x -lt $MAX_LOOP ]; do

			eval NETADDR=\${"NET$x"_NETADDR:-""}
			eval IPMASQ=\${"NET$x"_IPMASQ:-""}
			eval IPMASQ_IF=\${"NET$x"_IPMASQ_IF:-"default"}
					
			[ "$IPMASQ_IF" = "default" ] && IPMASQ_IF="" || IPMASQ_IF="-i $IPMASQ_IF"
			
	
			if [ "$NETADDR" != "" ] && [ "$IPMASQ" = "YES" ]; then
	
				[ $y -eq 0 ] && vb echo -n "$SP$SP""IP Masquerade: " && y=1
		
				eval NETMASK=\${"NET$x"_NETMASK:-"24"}

				ipchains -A forward -s $NETADDR/$NETMASK -d 0/0 -j MASQ $IPMASQ_IF \
				&& vb echo -n "$NETADDR "
			fi
			x=$(($x + 1))
		done

		#hosts
		x=0
		while [ $x -lt $MAX_LOOP ]; do

			eval IPADDR=\${"HOST$x"_IPADDR:-""}
			eval IPMASQ=\${"HOST$x"_IPMASQ:-""}
			eval IPMASQ_IF=\${"HOST$x"_IPMASQ_IF:-"default"}
					
			[ "$IPMASQ_IF" = "default" ] && IPMASQ_IF="" || IPMASQ_IF="-i $IPMASQ_IF"
	
			if [ "$IPADDR" != "" ] && [ "$IPMASQ" = "YES" ]; then
	
				[ $y -eq 0 ] && vb echo -n "$SP$SP""IP Masquerade: " && y=1

				ipchains -A forward -s $IPADDR -d 0/0 -j MASQ $IPMASQ_IF \
				&& vb echo -n "$IPADDR "
			fi
			x=$(($x + 1))
		done
		[ $y -eq 1 ] && vb echo

	fi	#END - Firewall check

	start-auto-portfw

	vb echo
}

###############################################################################
# Port Fowarding
###############################################################################
start-auto-portfw () {

	vb echo -n "$SP$SP""Portfw: "

	#Flush all
	[ "$IPCHAINS" ] && ipmasqadm portfw -f || ipportfw -C

	x=-1
	while [ $x -lt $MAX_LOOP ]; do	x=$(($x + 1))
	
	eval IFNAME=\${"PF$x"_IFNAME:-""}

		if [ "$IFNAME" != "" ]; then
			
			SOURCEIP="$(ifconfig-ip $IFNAME)"
			
			eval DESTIP=\${"PF$x"_DESTIP:-""}
			eval TPORTS=\${"PF$x"_TPORTS:-""}
			eval UPORTS=\${"PF$x"_UPORTS:-""}
	
			IFS=','
			for p in $TPORTS; do
				IFS=':'
				set -- $p
				[ "$3" ] && PREF="-p $3"
				if [ "$IPCHAINS" ]; then
					ipmasqadm portfw -a -P tcp -L $SOURCEIP $1 -R $DESTIP $2 $PREF
				else
					ipportfw -A -t $SOURCEIP/$1 -R $DESTIP/$2
				fi
			done
			
			IFS=','
			for p in $UPORTS; do
				IFS=':'
				set -- $p
				[ "$3" ] && PREF="-p $3"
				if [ "$IPCHAINS" ]; then
					ipmasqadm portfw -a -P udp -L $SOURCEIP $1 -R $DESTIP $2 $PREF
				else
					ipportfw -A -u $SOURCEIP/$1 -R $DESTIP/$2
				fi			
			done

			IFS=$OIFS

			vb echo -n "$SOURCEIP->$DESTIP"
		fi
	done
	vb echo

}


###############################################################################
#Hostname 
###############################################################################
start-auto-hostname () {
	if [ "$CONFIG_HOSTNAME" = "YES" ]; then
		vb echo "$SP""Hostname: $HOSTNAME"
#		hostname --file /etc/hostname		#bad idea...
		echo "$BANNER" >/etc/hostname		#Clear file
		echo "$HOSTNAME" >>/etc/hostname
	fi
}

###############################################################################
#Hosts file
###############################################################################
start-auto-hosts () {
	if [ "$CONFIG_HOSTSFILE" = "YES" ]; then
		vb echo -n "$SP""Static NS: "

		HOSTSF="/etc/hosts"
		echo "$BANNER" > $HOSTSF	#Clear file
		
		x=0;y=0
		while [ $x -lt $MAX_LOOP ]; do

			eval HOSTS="\$HOSTS$x"

			if [ "$HOSTS" != "" ]; then
				echo "$HOSTS" >>$HOSTSF 
				y=$(($y + 1))
			fi
			x=$(($x + 1))
		done
	
		echo "127.0.0.1	localhost" >>$HOSTSF 

		vb echo "$(($y + 1)) hosts"
	fi
}

###############################################################################
#DNS configuration
###############################################################################
start-auto-DNS () {

	if [ "$CONFIG_DNS" = "YES" ]; then
		vb echo -n "$SP""DNS: "

		RESOLV="/etc/resolv.conf"
		
		echo "$BANNER" >$RESOLV		#Clear file
		
		echo "search		$DOMAINS"	>>$RESOLV

		x=0
		while [ $x -lt $MAX_LOOP ]; do

			eval DNS="\$DNS$x"

			if [ "$DNS" != "" ]; then
				echo "nameserver	$DNS" >>$RESOLV \
				&& vb echo -n "$DNS "
			fi
			x=$(($x + 1))
		done
	
		echo "nameserver	127.0.0.1" >>$RESOLV \
		&& vb echo -n "127.0.0.1"

		vb echo
	fi
}


###############################################################################
# Direct Network Settings
###############################################################################
start-direct () {

	vb echo

	if [ -f /etc/network_direct.conf ]; then 
		vb echo "$SP""Direct Network Settings: "
		source /etc/network_direct.conf
		vb echo
	fi

	[ "$VERBOSE" = "NO" ] && echo "done."

}	#END start-direct ()


start () {

	echo -n "Starting Network: "

	if [ "$DIRECT_SETTINGS_ONLY" = "YES" ]; then
		vb echo "Direct Settings Only"
		start-direct
	else
		start-auto-ipforward
		[ "$IPCHAINS" ] && start-auto-dloose
		vb echo
		start-auto-if
		start-auto-if-dhcp
		start-auto-static-host
		start-auto-static-net
		start-auto-static-default
		[ "$IPCHAINS" ] && start-auto-fwchains-rules || start-auto-fw-rules
		start-auto-hostname
		start-auto-hosts
		start-auto-DNS
		
		start-direct
	fi
	
}	#END start ()

stop () {

	echo -n "Stoping Network: "
	
	qt killall dhclient
	[ $? ] && echo -n "dhclient, "

	echo -n "Interfaces, Routes"
	INTERFACES=$(cat /proc/net/dev | sed -n '1,2d;s/\([^:]*\).*/\1/p')
	for interface in $INTERFACES; do
		qt ifconfig "$interface" down
	done 

	if [ "$IPFWADM" ]; then
		ipfwadm -F -f && ipfwadm -I -f && ipfwadm -O -f && \
		ipfwadm -A -f && echo -n ", FW Rules"
	fi
	
	if [ "$IPCHAINS" ]; then
		qt ipchains -F echo -n ", FW Rules"
	fi	
	
	#fixme ?
	#[ "$IPAUTOFW" ] && ipautofw -F && echo -n ", AutoFW"
	#[ "$IPPORTFW" ] && ipportfw -C && echo -n ", PortFW"

	echo

}	#END stop ()


case "$1" in
	start)	start	;;
	stop)	stop	;; 
	reload|force-reload)
		$0 stop
		sleep 1
		$0 start
		;;
	*)	echo "Usage: $0 start|stop|reload"; exit 1 
        ;;
esac
exit 0


# Well she's walking through the clouds, 
# with a circus man that's running 'round.
# Butterflys and zebras, and movies, and fairy tales;
# that's all she ever thinks of, riding with the wind.
#
# When I'm sad she comes to me,
# with a thousand smiles, she gets to be free.
# It's alright she says, it's alright.
# Take anything thing from you want from me. Anything.
#
# Fly on Little Wing...

