#!/bin/bash
#
#------------------------------------------------
MAKE_IP_DRIVER_TARGET="naslite_netlink_ether"
MAKE_LTE_ACCESS_STRATUM_TARGET="oaisim"
IP_DRIVER_NAME=oai_nw_drv
###########################################################
#  CONFIGURE OPTIONS
EMULIF="eth1"
LTEIF="oai0"
EXTIF="eth0"
INTIF=$LTEIF
#----------------------------------------------------------
LTE_NETWORK_CIDR="10.0.1.0/24"
ENB_IPv4="10.0.1.1"
ENB_IPv6="2001:1::1"
ENB_IPv6_CIDR=$ENB_IPv6"/64"
ENB_IPv4_CIDR=$ENB_IPv4"/24"
ENB_IF_ID="3,9,1,8,3,6,6,2,0,0,0,0,0,0"
#----------------------------------------------------------
UE_IPv4="10.0.1.2"
UE_IPv6="2001:1::2"
UE_IPv6_CIDR=$UE_IPv6"/64"
UE_IPv4_CIDR=$UE_IPv4"/24"
#----------------------------------------------------------

#         +-------+                     +-------+
#         | eNB   | EMULIF              | UE    |
#         |       +---------------------+       |
#         |       |                     |       |
#         |       |                     |       |
#         |       |                     |       |
#         |       |                     |       |
#         |       |                     |       |
#         |       |                     |       |
#         |       | LTEIF               |       |
#         |       +.................... +       |
#         |       |ENB_IPv4 UE_IPv4_CIDR|       |
#         +-------+    LTE link over    +-------+
#                       UDP over ethernet
###########################################################
IPTABLES=/sbin/iptables
THIS_SCRIPT_PATH=$(dirname $(readlink -f $0))
declare -x OPENAIR_DIR=""
declare -x OPENAIR1_DIR=""
declare -x OPENAIR2_DIR=""
declare -x OPENAIR3_DIR=""
declare -x OPENAIR_TARGETS=""
###########################################################


black='\E[30m'
red='\E[31m'
green='\E[32m'
yellow='\E[33m'
blue='\E[34m'
magenta='\E[35m'
cyan='\E[36m'
white='\E[37m'

ROOT_UID=0
E_NOTROOT=67


cecho()   # Color-echo
          # arg1 = message
          # arg2 = color
{
local default_msg="No Message."
    message=${1:-$default_msg}
    color=${2:-$black}
    echo -e "$color"
    echo -n "$message"
    tput sgr0
    echo
    return
}

echo_error() {
local my_string=""
  until [ -z "$1" ]
  do
    my_string="$my_string$1"
    shift
  done
  cecho "$my_string" $red
}

echo_warning() {
local my_string=""
  until [ -z "$1" ]
  do
    my_string="$my_string$1"
    shift
  done
  cecho "$my_string" $yellow
}

echo_success() {
local my_string=""
  until [ -z "$1" ]
  do
    my_string="$my_string$1"
    shift
  done
  cecho "$my_string" $green
}

set_openair() {
    path=`pwd`
    declare -i length_path
    declare -i index
    length_path=${#path}

    index=`echo $path | grep -b -o 'targets' | cut -d: -f1`
    #echo ${path%$token*}
    if [[ $index -lt $length_path  && index -gt 0 ]]
       then
           declare -x OPENAIR_DIR
           index=`expr $index - 1`
           openair_path=`echo $path | cut -c1-$index`
           #openair_path=`echo ${path:0:$index}`
           export OPENAIR_DIR=$openair_path
           export OPENAIR1_DIR=$openair_path/openair1
           export OPENAIR2_DIR=$openair_path/openair2
           export OPENAIR3_DIR=$openair_path/openair3
           export OPENAIR_TARGETS=$openair_path/targets
           return 0
    fi
    return -1
}

bash_exec() {
  output=$($1 2>&1)
  result=$?
  if [ $result -eq 0 ]
     then
        echo_success "$1"
     else
        echo_error "$1: $output"
  fi
}

wait_process_started () {
  if  [ -z "$1" ]
  then
    echo_error "WAITING FOR PROCESS START: NO PROCESS"
    return 1
  fi
  ps -C $1 > /dev/null 2>&1
  while [ $? -ne 0 ]; do
    echo_warning "WAITING FOR $1 START"
    sleep 2
    ps -C $1 > /dev/null 2>&1
  done
  echo_success "PROCESS $1 STARTED"
  return 0
}

assert() {
  # If condition false
  # exit from script with error message
  E_PARAM_ERR=98
  E_PARAM_FAILED=99
  
  if [ -z "$2" ] # Not enought parameters passed.
  then
    return $E_PARAM_ERR
  fi
  
  lineno=$2
  if [ ! $1 ]
  then
    echo "Assertion failed:  \"$1\""
    echo "File \"$0\", line $lineno"
    exit $E_ASSERT_FAILED
  fi
}

#bash_exec "set_openair"
set_openair
cecho "OPENAIR_DIR     = $OPENAIR_DIR" $green
cecho "OPENAIR1_DIR    = $OPENAIR1_DIR" $green
cecho "OPENAIR2_DIR    = $OPENAIR2_DIR" $green
cecho "OPENAIR3_DIR    = $OPENAIR3_DIR" $green
cecho "OPENAIR_TARGETS = $OPENAIR_TARGETS" $green


echo "Bringup UE interface"
bash_exec "rmmod $IP_DRIVER_NAME"
cecho "make $MAKE_IP_DRIVER_TARGET $MAKE_LTE_ACCESS_STRATUM_TARGET....." $green
bash_exec "make $MAKE_IP_DRIVER_TARGET $MAKE_LTE_ACCESS_STRATUM_TARGET"
bash_exec "insmod  $OPENAIR2_DIR/NAS/DRIVER/LITE/$IP_DRIVER_NAME.ko oai_nw_drv_IMEI=$ENB_IF_ID"


echo "   Enabling proxy ARP.."
bash_exec "sysctl -w net.ipv4.conf.all.proxy_arp=1"
assert "`sysctl -n net.ipv4.conf.all.proxy_arp` -eq 1" $LINENO

echo "   Enabling ipv4 forwarding.."
bash_exec "sysctl -w net.ipv4.ip_forward=1"
assert "`sysctl -n net.ipv4.ip_forward` -eq 1" $LINENO

bash_exec "sysctl -w net.ipv4.conf.all.forwarding=1"
assert "`sysctl -n net.ipv4.conf.all.forwarding` -eq 1" $LINENO

echo "   Enabling ipv6 forwarding.."
bash_exec "sysctl -w net.ipv6.conf.all.forwarding=1"
assert "`sysctl -n net.ipv6.conf.all.forwarding` -eq 1" $LINENO

echo "   Enabling DynamicAddr.."
bash_exec "sysctl -w net.ipv4.ip_dynaddr=1"
assert "  `sysctl -n net.ipv4.ip_dynaddr` -eq 1" $LINENO

bash_exec "ip route flush cache"
bash_exec "ip route add 239.0.0.160/28 dev $EMULIF"

bash_exec "ip link set $LTEIF broadcast ff:ff:ff:ff:ff:ff"
bash_exec "ip link set $LTEIF up"
sleep 1


assert " -x $IPTABLES " $LINENO

bash_exec "$IPTABLES -P INPUT ACCEPT"
bash_exec "$IPTABLES -F INPUT"
bash_exec "$IPTABLES -P OUTPUT ACCEPT"
bash_exec "$IPTABLES -F OUTPUT"
bash_exec "$IPTABLES -P FORWARD DROP"
bash_exec "$IPTABLES -F FORWARD"
bash_exec "$IPTABLES -t nat    -F"
bash_exec "$IPTABLES -t mangle -F"
bash_exec "$IPTABLES -t filter -F"



echo "   External Interface:  $EXTIF"
echo "   Internal Interface:  $INTIF"

bash_exec "modprobe ip_tables"
bash_exec "modprobe ip_conntrack"
bash_exec "modprobe ip_conntrack_ftp"
bash_exec "modprobe nf_conntrack_h323"
bash_exec "modprobe nf_conntrack_irc"
bash_exec "modprobe nf_conntrack_pptp"
bash_exec "modprobe nf_conntrack_proto_gre"
bash_exec "modprobe nf_conntrack_proto_sctp"
bash_exec "modprobe nf_conntrack_tftp"
bash_exec "modprobe nf_conntrack_sip"
bash_exec "modprobe iptable_nat"
bash_exec "modprobe x_tables"


bash_exec "sysctl -w net.ipv4.conf.all.log_martians=1"
assert "  `sysctl -n net.ipv4.conf.all.log_martians` -eq 1" $LINENO

bash_exec "sysctl -w net.ipv4.conf.$LTEIF.log_martians=1"
assert "  `sysctl -n net.ipv4.conf.$LTEIF.log_martians` -eq 1" $LINENO

bash_exec "sysctl -w net.ipv4.conf.$EXTIF.log_martians=1"
assert "  `sysctl -n net.ipv4.conf.$EXTIF.log_martians` -eq 1" $LINENO

bash_exec "sysctl -w net.ipv4.conf.$INTIF.log_martians=1"
assert "  `sysctl -n net.ipv4.conf.$INTIF.log_martians` -eq 1" $LINENO

echo "   Disabling reverse path filtering"
bash_exec "sysctl -w net.ipv4.conf.all.rp_filter=0"
assert "  `sysctl -n net.ipv4.conf.all.rp_filter` -eq 0" $LINENO

bash_exec "sysctl -w net.ipv4.conf.$LTEIF.rp_filter=0"
assert "  `sysctl -n net.ipv4.conf.$LTEIF.rp_filter` -eq 0" $LINENO

bash_exec "sysctl -w net.ipv4.conf.$EXTIF.rp_filter=0"
assert "  `sysctl -n net.ipv4.conf.$EXTIF.rp_filter` -eq 0" $LINENO

bash_exec "sysctl -w net.ipv4.conf.$INTIF.rp_filter=0"
assert "  `sysctl -n net.ipv4.conf.$INTIF.rp_filter` -eq 0" $LINENO


bash_exec "$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT"
bash_exec "$IPTABLES -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT"
bash_exec "$IPTABLES -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE"

bash_exec "ip route flush cache"


bash_exec "ip addr add dev $LTEIF $ENB_IPv4_CIDR"
sleep 1
bash_exec "ip addr add dev $LTEIF $ENB_IPv6_CIDR"
sleep 1

# -a     -> Add RB
# -d    -> Delete RB
# -cxx  -> lcr
# -ixx  -> instance
# -zxx  -> dscp
# -fxxx -> classref (uid of a classifier entry) if fn is used , fn is used for send classifier and n+1 for receive classifier
# -sxxx -> source ipv4 address
# -txxx -> destination ipv4 address
# -x    -> source ipv6 address
# -y    -> destination ipv6 address
# -r    -> radio bearer id
bash_exec "$OPENAIR2_DIR/NAS/DRIVER/LITE/RB_TOOL/rb_tool -a -c0 -f0 -i0 -z0  -x $ENB_IPv6      -y $UE_IPv6     -r 1"
bash_exec "$OPENAIR2_DIR/NAS/DRIVER/LITE/RB_TOOL/rb_tool -a -c0 -f2 -i0 -z64 -s $ENB_IPv4/32   -t $UE_IPv4/32  -r 1"
bash_exec "$OPENAIR2_DIR/NAS/DRIVER/LITE/RB_TOOL/rb_tool -a -c0 -f4 -i0 -z64 -s 0.0.0.0/32     -t 0.0.0.0/32   -r 1"
sleep 1

echo "#####################################################################"
echo "iptables -t nat -nvL"
echo "---------------------------------------------------------------------"
iptables -t nat -nvL
echo "#####################################################################"
echo "ip route show table main"
echo "---------------------------------------------------------------------"
ip route show table main

echo "$OPENAIR_TARGETS/SIMU/USER/oaisim  -u0 -M0 -p2  -g3 -l3  > /dev/null"
nice -10 $OPENAIR_TARGETS/SIMU/USER/oaisim  -u0 -M0 -p2  -g3 -l3 > /dev/null


