--- /dev/null
+#!/bin/bash
+
+
+STROK="remote IP address"
+GCOMP="comgt"
+GCOM="/usr/bin/"${GCOMP}
+LOGF="/tmp/umtslogs"
+PPPD_PIDFILE="/var/run/umts_pppd.pid"
+DESTS_FILE="/tmp/umts_dest_file"
+FILE_TEMP_NID="/tmp/umts_temp_nid"
+FILE_UMTS_INT="/tmp/umts_dev"
+LOCK_DIR="/var/run/umts_lock"
+FILE_LOCK_SLIVER="/var/run/umts_locking_sliver"
+PPP_INT="ppp0"
+PPPD="pppd"
+CHAT_SCRIPTS="/etc/chatscripts"
+UMTS_CONF="/etc/umts.conf"
+
+
+
+function get_umts_dev(){
+ echo "/dev/umts_modem"
+}
+
+function init_umts(){
+ #local found=1
+
+ if [ -e $LOCK_DIR ]; then
+ rmdir $LOCK_DIR
+ fi
+
+ #if ! grep "umts_table" /etc/iproute2/rt_tables > /dev/null 2>&1; then
+ # echo "20 umts_table" >> /etc/iproute2/rt_tables
+ #fi
+
+ return 0
+
+}
+
+
+function get_temp_nid(){
+ cat $FILE_TEMP_NID
+}
+
+
+#called when the connection is started
+function conn_on(){
+ local sliver=$1
+
+ #DESTS_FILE contains added destinations
+ rm -f $DESTS_FILE
+
+ set_temp_nid $sliver_nid
+ set_routes $sliver
+
+ cat $LOGF | grep "local"
+ return 0
+
+}
+
+#called when the connection is terminated
+function conn_off(){
+ local sliver=$1
+ local ppp_addr=$2
+
+ unset_routes $sliver $ppp_addr
+
+ for i in `cat $DESTS_FILE`; do
+ del_destination $i $sliver > /dev/null 2>&1
+ done
+
+ rm $DESTS_FILE >/dev/null 2>&1
+}
+
+function start_umts(){
+ local sliver=$1
+ local sliver_nid=`get_nid $sliver`
+
+ if ! grep "umts_table" /etc/iproute2/rt_tables > /dev/null 2>&1; then
+ echo "20 umts_table" >> /etc/iproute2/rt_tables
+ fi
+
+ if ! lock $sliver; then
+ return 1
+ fi
+
+ if status_umts; then
+ echo "Already connected"
+ return 0;
+ fi
+
+ echo "Starting GCOM..."
+ if ! $GCOM -d `get_umts_dev`; then
+ unlock $sliver
+ return 1
+ fi
+
+ rm -f $LOGF
+
+ if [ -e $UMTS_CONF ]; then
+ . $UMTS_CONF
+ fi
+
+ if ! [[ $APN ]]; then
+ APN="web.omnitel.it"
+ fi
+ if ! [[ $NUM ]]; then
+ NUM="*99***1#"
+ fi
+
+
+ exec /usr/sbin/pppd nodetach `get_umts_dev` 460800 \
+ 0.0.0.0:0.0.0.0 \
+ connect "/usr/sbin/chat -v \
+ TIMEOUT 6 \
+ ABORT '\nBUSY\r' \
+ ABORT '\nNO ANSWER\r' \
+ ABORT '\nRINGING\r\n\r\nRINGING\r' \
+ '' ATZ OK 'ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0' OK \
+ 'AT+CGDCONT=1,\"IP\",\"$APN\"' OK \
+ ATD$NUM CONNECT ''" > $LOGF &
+
+
+ #exec /usr/sbin/pppd nodetach `get_umts_dev` 460800 \
+ # 0.0.0.0:0.0.0.0 \
+ # connect "/usr/sbin/chat -f ${CHAT_SCRIPTS}/vodaphone-it" > $LOGF &
+
+ echo $! > $PPPD_PIDFILE
+
+ sleep 5s; #waiting for the interface to establish the link
+ if grep "$STROK" $LOGF >/dev/null 2>&1; then
+ conn_on $sliver $sliver_nid
+ else
+ #second try
+ sleep 5s;
+ if grep "$STROK" $LOGF >/dev/null 2>&1; then
+ conn_on $sliver $sliver_nid
+ else
+ stop_umts $sliver
+ return 1
+ fi
+ fi
+}
+
+
+function stop_umts(){
+ local sliver=$1
+ local sliver_nid=`get_nid $sliver`
+ local ppp_addr
+
+ if ! [ -e $PPPD_PIDFILE ]; then
+ echo "Disconnected"
+ return 0;
+ fi
+
+ ppp_addr=`get_ppp_address`
+
+ if ! check_who_locked $sliver; then
+ return 1
+ fi
+
+ PID=`cat $PPPD_PIDFILE`;
+
+ if [ -d /proc/$PID ] && grep $PPPD /proc/$PID/cmdline >/dev/null 2>&1; then
+ kill $PID; touch $DESTS_FILE
+
+ sleep 2s;
+ fi
+
+ if status_umts; then
+ return 1;
+ else
+ conn_off $sliver $ppp_addr
+ cat $LOGF | grep "time"
+ rm $PPPD_PIDFILE
+ unlock $sliver;
+ return 0
+ fi
+}
+
+
+function status_umts(){
+ local sliver=$1
+
+ if ! [ -e $PPPD_PIDFILE ]; then return 1; fi
+ PID=`cat $PPPD_PIDFILE`
+
+ if [ -d /proc/$PID ] && grep $PPPD /proc/$PID/cmdline >/dev/null 2>&1; then
+ return 0;
+ else
+ return 1;
+ fi
+}
+
+#add the ppp interface to the slice - not used at the moment
+function add_interface(){
+ local nid=`get_nid $1`
+ $NADDRESS --add --nid $nid --ip $PPP_INT >>$LOGFILE 2>&1;
+}
+
+#remove the ppp interface from the slice - not used at the moment
+function del_interface(){
+ local nid=`get_nid $1`
+ #$NADDRESS --remove --nid $NID --ip $PPP_INT >>$LOGFILE 2>&1;
+}
+
+#get slice network id
+function get_nid(){
+ id -u ${1}
+}
+
+function set_routes(){
+ local sliver=$1
+ local sliver_nid=`get_nid $sliver`
+ local temp_nid=`get_temp_nid`
+ local ppp_addr=`get_ppp_address`
+
+ #Asks VNET+ to tag all the packets with the respective sliver id
+ iptables -t mangle -A OUTPUT -j MARK --copy-xid 0x00
+
+ #Changes the netfilter mark of packets to trigger rerouting.
+ #We need to change the mark because the kernel triggers the rerouting process only
+ #if it sees that the netfilter mark has been altered in the mangle iptables chain
+ iptables -t mangle -A OUTPUT -m mark --mark $sliver_nid -j MARK --set-mark $temp_nid
+
+ #Adds an SNAT rule to set the source IP address of packets that are about to go out through the UMTS
+ #interface. The kernel sets the source address of packets when the first routing process happens
+ #so, without this rule, packets would have the source ip address set on the first routing process of the ethernet interface
+ iptables -t nat -A POSTROUTING -o $PPP_INT -j SNAT --to-source $ppp_addr
+
+ #Restores the original netfilter mark for planetflow
+ iptables -t mangle -I POSTROUTING 1 -m mark --mark $temp_nid -j MARK --set-mark $sliver_nid
+
+ #Forbids other slices to use the UMTS interface
+ iptables -t mangle -I POSTROUTING 2 -o $PPP_INT -m mark ! --mark $sliver_nid -j DROP
+
+ #Enables the explicit bind to the UMTS interface. Applications launched by the user in the slice that is using the UMTS and that
+ #bind to the UMTS interface will have packets going out through the UMTS interface
+ ip route flush table umts_table >/dev/null 2>&1
+ ip rule add from $ppp_addr fwmark $temp_nid table umts_table >/dev/null 2>&1
+ ip route add default dev $PPP_INT src $ppp_addr table umts_table >/dev/null 2>&1
+ ip route flush cache >/dev/null 2>&1
+}
+
+function unset_routes(){
+ local sliver=$1
+ local ppp_addr=$2
+ local sliver_nid=`get_nid $sliver`
+ local temp_nid=`get_temp_nid`
+
+
+ #removing the rules for changing the mark and the rules for SNAT
+ iptables -t mangle -D OUTPUT -j MARK --copy-xid 0x00
+ iptables -t mangle -D OUTPUT -m mark --mark $sliver_nid -j MARK --set-mark $temp_nid
+ iptables -t nat -D POSTROUTING -o $PPP_INT -j SNAT --to-source $ppp_addr
+ iptables -t mangle -D POSTROUTING -m mark --mark $temp_nid -j MARK --set-mark $sliver_nid
+
+ iptables -t mangle -D POSTROUTING -o $PPP_INT -m mark ! --mark $sliver_nid -j DROP
+
+ #disable the explicit bind to the ppp interface
+ ip rule del from $ppp_addr fwmark $temp_nid table umts_table >/dev/null 2>&1
+ ip route del default dev $PPP_INT src $ppp_addr table umts_table >/dev/null 2>&1
+ ip route flush cache >/dev/null 2>&1
+
+}
+
+function add_destination(){
+ local dest="$1"
+ local sliver=$2
+ local sliver_nid=`get_nid $sliver`
+ local temp_nid=`get_temp_nid`
+
+ if [[ ! $dest ]]; then return 1; fi
+
+ if ! status_umts; then
+ return 1;
+ fi
+
+ if ! check_who_locked $sliver; then
+ return 1;
+ fi
+
+ if ip rule add to "$dest" fwmark $temp_nid table umts_table >/dev/null 2>&1; then
+ echo "$dest" >> $DESTS_FILE
+ return 0
+ else
+ return 1
+ fi
+ ip route flush cache >/dev/null 2>&1
+}
+
+function del_destination(){
+ local dest="$1"
+ local sliver=$2
+ local sliver_nid=`get_nid $sliver`
+ local temp_nid=`get_temp_nid`
+
+ if [[ ! $dest ]]; then return 1; fi
+
+ if ! check_who_locked $sliver; then
+ return 1;
+ fi
+
+ if ip rule del to "$dest" fwmark $temp_nid table umts_table >/dev/null 2>&1; then
+ return 0;
+ else
+ return 1;
+ fi
+ ip route flush cache >/dev/null 2>&1
+}
+
+
+function get_ppp_address(){
+ ifconfig $PPP_INT | grep inet\ addr | cut -d ":" -f 2 | cut -d " " -f 1
+}
+
+function set_temp_nid(){
+ local sliver_nid=$1
+ local temp_nid=$((0x20000+$sliver_nid))
+ echo $temp_nid > $FILE_TEMP_NID
+}
+
+
+function check_who_locked(){
+ local sliver=$1
+ local sliver_nid=`get_nid $sliver`
+ local ret=0
+
+ if [ -e $LOCK_DIR ]; then
+ if [[ `cat $FILE_LOCK_SLIVER` != $sliver_nid ]]; then
+ echo "Interface in use by another slice.";
+ ret=1
+ fi
+ else
+ ret=1
+ fi
+
+ return $ret
+
+}
+
+function kill_gcom(){
+
+ killall $GCOMP
+ sleep 3
+ if ! ps -C $GCOMP >/dev/null 2>&1; then
+ echo "$GCOMP terminated."
+ else
+ echo "$GCOMP still alive. Try kill -9"
+ sleep 2
+
+ killall -9 $GCOMP
+
+ if ! ps -C $GCOMP >/dev/null 2>&1; then
+ echo "$GCOMP terminated."
+ else
+ echo "Couldn't stop $GCOMP. Please contact administrators for assistance."
+ fi
+ fi
+}
+
+function lock(){
+ local sliver=$1
+ local sliver_nid=`get_nid $sliver`
+ local ret=0
+
+ if [ -e $LOCK_DIR ]; then
+ if ! check_who_locked $sliver; then
+ ret=1
+ fi
+ else
+ if mkdir $LOCK_DIR >/dev/null 2>&1; then
+ echo "$sliver_nid" > $FILE_LOCK_SLIVER
+ else
+ ret=1
+ fi
+ fi
+
+ return $ret
+}
+
+function unlock(){
+ local sliver=$1
+ local sliver_nid=`get_nid $sliver`
+ local ret=0
+
+ if ! [ -e $LOCK_DIR ]; then
+ ret=1
+ else
+ if ! check_who_locked $sliver; then
+ ret=1
+ else
+ if ! rmdir $LOCK_DIR; then
+ ret=1
+ fi
+ fi
+ fi
+
+ return $ret
+}
+
+
+
+
+# checks ip addresses
+function valid_dotted_quad(){
+ oldIFS=$IFS
+ IFS=.
+ set -f
+ set -- $1
+ if [ $# -eq 4 ]
+ then
+ for seg
+ do
+ case $seg in
+ ""|*[!0-9]*) return 1; break ;; ## Segment empty or non-numeric char
+ *) [ $seg -gt 255 ] && return 2 ;;
+ esac
+ done
+ else
+ return 3 ## Not 4 segments
+ fi
+ IFS=$oldIFS
+ set +f
+ return 0;
+}
+