#!/bin/bash
#
# 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; either version 2, or (at your option)
# any later version.
#
# Author: José Miguel Silva Caldeira
# Email: miguel@ncdc.pt
# Site: http://www.ncdc.pt
# Date: 7 May 2015
#
# For many paths that may exist, we all try to mark our.
# Always go your way, but learn at intersections!
# Only we all know everything!

######################################################
#                   ChangeLog                        #
######################################################
##2015-7-5 - v0.1                                    #
# Foi removido a dependência do comando dialog.      #
# Desta forma já não é necessário instalar software  #
# para correr este script.                           #
######################################################

print_options_list () {
	echo
	echo -e "\033[1m\e[1;32m$1 \e[0m"
	echo
  	shift
  	local list=("$@")
	for (( x=0 ; x < ${#list[@]} ; x++ )); do
		echo -e "\t\033[1m\e[1;31m$x \e[0m -  ${list[$x]}"
	done
	echo
}

print_message () {
	echo
	echo -e "\033[1m\e[1;32m $1\e[0m"
	echo
}

read_interface_number() {
	read -p "$1"$'\033[1m\e[1;31m' USER_RESPONSE
	if [[ $USER_RESPONSE =~ ^[0-9]+$ ]] && [ $USER_RESPONSE -lt $2 ]; then
		echo $USER_RESPONSE
		return 0
	else
		echo $USER_RESPONSE
		return 1
	fi
}

read_yes_or_no () {
	read -p "$1"$'\033[1m\e[1;31m' USER_RESPONSE
	if [[ $USER_RESPONSE =~ ^[Ss]$ ]]; then
		return 0
	else
		return 1
	fi
}

read_name() {
	read -p "$1"$'\033[1m\e[1;31m' USER_RESPONSE
	if [[ $USER_RESPONSE != "" ]]; then
		echo $USER_RESPONSE
		return 0
	else
		return 1
	fi
}

cancel(){
	print_message "\033[1m\e[1;31mOperação cancelada..\e[0m"
	exit 1;
}

list_wired_interfaces(){
	local x=0
	local wired_interfaces=(/sys/class/net/*)
	for inface in ${wired_interfaces[@]}; do
		if [[ ! -d "$inface/device" ]]; then
			continue
		fi
		if [[ -d "$inface/wireless" ]]; then
			continue
		fi
		_wired_interfaces+=("${inface##*/}")
		let "x++"
	done
	if [[ ${#_wired_interfaces} -eq 0 ]]; then
		return 1
	fi
	return 0;
}

remove_listed_wired_interface(){
	local x;
	for (( x=0; x < ${#_wired_interfaces[@]}; x++ )); do
		if [[ "$1" == "${_wired_interfaces[$x]}" ]]; then
			unset _wired_interfaces[$x]
			_wired_interfaces=(${_wired_interfaces[@]})
			return 0
		fi
	done
	return 1
}

trap "cancel" SIGINT
trap 'echo -ne "\e[0m"' DEBUG

if [ "$(id -u)" != "0" ]; then
print_message "Devido à necessidade de escrever em ficheiros de configuração,
 este script tem de correr como root!\n
 Use: sudo $0"
	exit 1;
fi

# List all interfaces
_wired_interfaces=()
list_wired_interfaces

# Check if there is at least two interfaces
num_infaces=${#_wired_interfaces[@]}

if [[ $num_infaces -lt 2  ]]; then
	print_message "São necessárias pelo menos duas interfaces, para o Linux agir como roter!"
	cancel
fi

# External interface
print_options_list "Escolha a interface externa:" "${_wired_interfaces[@]}"

red_iface_id=$(read_interface_number "Insira o número da interface: " "$((${#_wired_interfaces[@]}))")

if [[ $? -eq 0 ]]; then
	red_iface=${_wired_interfaces["$red_iface_id"]}
else
	print_message "O número '$red_iface_id' não corresponde a nunhuma interface!"
	cancel
fi

remove_listed_wired_interface "$red_iface"

# Internal interface
print_options_list "Escolha a interface interna:" "${_wired_interfaces[@]}"

green_iface_id=$(read_interface_number "Insira o número da interface: " "$((${#_wired_interfaces[@]}))")

if [[ $? -eq 0 ]]; then
	green_iface=${_wired_interfaces["$green_iface_id"]}
else
	print_message "O número '$green_iface_id' não corresponde a nunhuma interface!"
	cancel
fi

print_message "Os dados necessários foram recolhidos.
Pretende continuar e escrever as configurações no disco?"

read_yes_or_no "Pretende continuar?: "
if [[ $? -eq 1 ]]; then
	cancel
fi

# Injectar as regras para que não seja necessário
# reiniciar o servidor

# Para que seja possível rotear entre interfaces
iptables --table nat --append POSTROUTING --out-interface $red_iface -j MASQUERADE;
iptables --append FORWARD --in-interface $green_iface -j ACCEPT;
#Permitir o forward de pacotes v4 no Kernel
echo 1 > /proc/sys/net/ipv4/ip_forward;

# Injectar as regras no rc.local para
# que sejam lidas a cada boot
cat << EOF > /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Para que seja possível rotear entre interfaces
iptables --table nat --append POSTROUTING --out-interface $red_iface -j MASQUERADE;
iptables --append FORWARD --in-interface $green_iface -j ACCEPT;

#Permitir o forward de pacotes v4 no Kernel
echo 1 > /proc/sys/net/ipv4/ip_forward;

exit 0
EOF

print_message "Está feito..\n\nA partir deste momento serão roteadas os pacotes
da interface interna para a interface externa e vise versa!\n\n
Caso haja qualquer troca nas interfaces volte a correr este script.\n\n
Até à próxima!"

exit 0
