forbids non-umts slices to access the UMTS interface
[planetlab-umts-tools.git] / backend / umts_functions
1 #!/bin/bash
2
3
4 STROK="remote IP address"
5 GCOM=""
6 LOGF="/tmp/umtslogs"
7 PPPD_PIDFILE="/var/run/umts_pppd.pid"
8 DESTS_FILE="/tmp/umts_dest_file"
9 FILE_TEMP_NID="/tmp/umts_temp_nid"
10 FILE_UMTS_INT="/tmp/umts_dev"
11 PPP_INT=ppp0
12 PPPD=pppd
13
14
15 function set_umts_dev(){
16         local umts_dev=$1
17         echo $umts_dev > $FILE_UMTS_INT
18 }
19
20 function get_umts_dev(){
21         if [ -e $FILE_UMTS_INT ]; then
22                 cat $FILE_UMTS_INT
23         fi
24 }
25
26 function unset_umts_dev(){
27         rm -f $FILE_UMTS_INT
28 }
29
30
31 function init_umts(){
32         local found=1
33
34         if [ -f /usr/bin/gcom ]; then 
35                 GCOM=/usr/bin/gcom
36         elif [ -f /usr/bin/comgt ]; then
37                 GCOM=/usr/bin/comgt
38         else
39                 echo "I couldn't find gcom"
40                 return 1;
41         fi
42
43         unset_umts_dev
44
45         for i in /dev/umts_modem /dev/umts_modem1; do   
46                 echo "Testing if the umts interface is present on the device $i..."
47                 if [ -e $i ]; then
48                         if $GCOM -d $i; then
49                                 found=0
50                                 set_umts_dev $i 
51                                 break
52                         fi
53                 fi      
54         done 
55         
56         if ! [  $found == 0 ]; then
57                 echo "I couldn't find the umts device. Make a symlink from it to /dev/umts_modem."
58                 return 1
59         fi
60
61         if ! grep "umts_table" /etc/iproute2/rt_tables > /dev/null 2>&1; then
62                 echo "20 umts_table" >> /etc/iproute2/rt_tables
63         fi
64
65         return 0
66
67 }
68
69
70 function get_temp_nid(){
71         cat $FILE_TEMP_NID
72 }
73
74
75 #called when the connection is started
76 function conn_on(){
77         local sliver=$1
78
79         #DESTS_FILE contains added destinations
80         rm -f $DESTS_FILE 
81         touch $DESTS_FILE
82
83         set_temp_nid $sliver_nid
84
85         set_routes $sliver
86
87         cat $LOGF | grep "local"
88         return 0
89
90 }
91
92 #called when the connection is terminated
93 function conn_off(){
94         local sliver=$1
95
96         unset_routes $sliver
97
98         for i in `cat $DESTS_FILE`; do
99                 del_destination $i $sliver > /dev/null 2>&1
100         done
101
102         rm $DESTS_FILE >/dev/null 2>&1
103 }
104
105 function start_umts(){
106     local sliver=$1
107     local sliver_nid=`get_nid $sliver`
108    
109     
110     if status_umts; then
111          echo "Already connected"
112          return 0; 
113     fi
114
115     if [[ `get_umts_dev` == "" ]]; then 
116         if [[ init_umts != 0 ]]; then   
117                 return 1
118         fi
119     fi
120
121     if ! [ -e `get_umts_dev` ];  then
122         echo "Umts interface is not present"
123         return 1
124     fi
125
126     rm -f $LOGF
127
128     exec /usr/sbin/pppd nodetach `get_umts_dev` 460800 \
129                 0.0.0.0:0.0.0.0 \
130                 connect "/usr/sbin/chat -v                     \
131                 TIMEOUT         6                              \
132                 ABORT           '\nBUSY\r'                     \
133                 ABORT           '\nNO ANSWER\r'                \
134                 ABORT           '\nRINGING\r\n\r\nRINGING\r'   \
135                 ''              ATZ     OK 'ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0' OK  \
136                 ATD*99***1#    CONNECT ''" > $LOGF &
137
138     echo $! > $PPPD_PIDFILE
139
140     sleep 5s;  #waiting for the interface to establish the link
141     if grep "$STROK" $LOGF >/dev/null 2>&1; then
142         conn_on $sliver $sliver_nid
143     else
144         #second try
145         sleep 5s;
146         if grep "$STROK" $LOGF >/dev/null 2>&1; then
147             conn_on $sliver $sliver_nid
148         else
149             stop_umts $sliver
150             return 1
151         fi
152     fi
153 }
154
155
156
157
158 function stop_umts(){
159     local sliver=$1
160     local sliver_nid=`get_nid $sliver`
161
162     if ! [ -e $PPPD_PIDFILE ]; then 
163         echo "Disconnected"
164         return 0;
165     fi
166
167     PID=`cat $PPPD_PIDFILE`;
168
169     if [ -d /proc/$PID ] &&  grep $PPPD /proc/$PID/cmdline >/dev/null 2>&1; then        
170         conn_off $sliver $sliver_nid
171         kill $PID;
172         sleep 2s;
173     fi
174
175     if status_umts; then
176         return 1;
177     else
178         cat $LOGF | grep "time"
179         rm $PPPD_PIDFILE
180         return 0
181     fi
182 }
183
184
185 function status_umts(){
186
187     if ! [ -e $PPPD_PIDFILE ]; then return 1; fi
188
189     PID=`cat $PPPD_PIDFILE`
190
191     if [ -d /proc/$PID ] &&  grep $PPPD /proc/$PID/cmdline >/dev/null 2>&1; then
192         return 0;
193     else 
194         return 1;
195     fi
196 }
197
198 #add the ppp interface from the slice - not used at the moment
199 function add_interface(){
200     local nid=`get_nid $1`
201     $NADDRESS --add --nid $nid --ip $PPP_INT >>$LOGFILE 2>&1;
202 }
203
204 #remove the ppp interface from the slice - not used at the moment
205 function del_interface(){
206     local nid=`get_nid $1`
207     #$NADDRESS --remove --nid $NID --ip $PPP_INT >>$LOGFILE 2>&1;
208 }
209
210 #get slice network id
211 function get_nid(){
212     id -u ${1}
213 }
214
215 function set_routes(){
216         local sliver=$1
217         local sliver_nid=`get_nid $sliver`
218         local temp_nid=`get_temp_nid`
219         local ppp_addr=`get_ppp_address`
220
221         #remarking of packets, to trigger rerouting, and SNAT
222         iptables -t mangle -A OUTPUT -j MARK --copy-xid 0x00
223         iptables -t mangle -A OUTPUT -m mark --mark $sliver_nid -j MARK --set-mark $temp_nid
224         iptables -t nat -A POSTROUTING -o $PPP_INT -j SNAT --to-source $ppp_addr
225         iptables -t mangle -I POSTROUTING 1 -m mark --mark $temp_nid -j MARK --set-mark $sliver_nid
226
227         #forbids other slices to use the UMTS interface
228         iptables -t nat -I POSTROUTING 1 -o $PPP_INT -m mark ! --mark $sliver_nid -j DROP
229         
230         #enable the explicit bind to the ppp interface
231         ip route flush table umts_table >/dev/null 2>&1 
232         ip rule add from $ppp_addr fwmark $temp_nid table umts_table >/dev/null 2>&1
233         ip route add default dev $PPP_INT src $ppp_addr table umts_table >/dev/null 2>&1
234         ip route flush cache  >/dev/null 2>&1
235 }
236
237 function unset_routes(){
238         local sliver=$1
239         local sliver_nid=`get_nid $sliver`
240         local temp_nid=`get_temp_nid`
241         local ppp_addr=`get_ppp_address`
242
243         #remarking and SNAT removed 
244         iptables -t mangle -D OUTPUT -j MARK --copy-xid 0x00
245         iptables -t mangle -D OUTPUT -m mark --mark $sliver_nid -j MARK --set-mark $temp_nid
246         iptables -t nat -D POSTROUTING -o $PPP_INT -j SNAT --to-source $ppp_addr
247         iptables -t mangle -D POSTROUTING -m mark --mark $temp_nid -j MARK --set-mark $sliver_nid
248
249         iptables -t nat -D POSTROUTING -o $PPP_INT -m mark ! --mark $sliver_nid -j DROP
250
251         #disable the explicit bind to the ppp interface
252         ip rule del from $ppp_addr fwmark $temp_nid table umts_table  >/dev/null 2>&1
253         ip route del default dev $PPP_INT  src $ppp_addr table umts_table >/dev/null 2>&1
254         ip route flush cache  >/dev/null 2>&1
255
256 }
257
258 function add_destination(){
259         local dest="$1"
260         local sliver=$2
261         local sliver_nid=`get_nid $sliver`
262         local temp_nid=`get_temp_nid`
263
264         if [[ ! $dest ]]; then return 1; fi
265
266         if ! status_umts; then
267                 return 1;
268         fi
269         
270         if ip rule add to "$dest" fwmark $temp_nid table umts_table >/dev/null 2>&1; then
271                 echo "$dest" >> $DESTS_FILE
272                 return 0
273         else 
274                 return 1        
275         fi
276         ip route flush cache  >/dev/null 2>&1
277 }
278
279 function del_destination(){
280         local dest="$1"
281         local sliver=$2
282         local sliver_nid=`get_nid $sliver`
283         local temp_nid=`get_temp_nid`
284
285         if [[ ! $dest ]]; then return 1; fi
286         if ip rule del to "$dest" fwmark $temp_nid table umts_table >/dev/null 2>&1; then
287                 return 0;
288         else 
289                 return 1;
290         fi
291         ip route flush cache  >/dev/null 2>&1
292 }
293
294
295 function get_ppp_address(){
296         ifconfig $PPP_INT | grep inet\ addr | cut -d ":" -f 2 | cut -d " " -f 1
297 }
298
299 function set_temp_nid(){
300         local sliver_nid=$1
301         local temp_nid=$((0x20000+$sliver_nid))
302
303         #k=0    
304         #while grep :$temp_nid: /etc/passwd; do
305         #       temp_nid=$((temp_nid+1))
306         #       k=$((k+1))
307         #       if [[ $k == 1000 ]]; then
308         #               logger "Fatal error: I couldn't find a temp_nid"
309         #               stop_umts
310         #               exit 1
311         #       fi
312         #done
313         echo $temp_nid > $FILE_TEMP_NID
314
315
316 }
317
318 # checks ip addresses  
319 function valid_dotted_quad(){
320     oldIFS=$IFS
321     IFS=.
322     set -f
323     set -- $1
324     if [ $# -eq 4 ]
325     then
326       for seg
327       do
328         case $seg in
329             ""|*[!0-9]*) return 1; break ;; ## Segment empty or non-numeric char
330             *) [ $seg -gt 255 ] && return 2 ;;
331         esac
332       done
333     else
334       return 3 ## Not 4 segments
335     fi
336     IFS=$oldIFS
337     set +f
338     return 0;
339 }
340