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