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