Add support for the Huawei e620 umts card
[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 4s;
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 4;
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         #enable the explicit bind to the ppp interface
228         ip route flush table umts_table >/dev/null 2>&1 
229         ip rule add from $ppp_addr fwmark $temp_nid table umts_table >/dev/null 2>&1
230         ip route add default dev $PPP_INT src $ppp_addr table umts_table >/dev/null 2>&1
231         ip route flush cache  >/dev/null 2>&1
232 }
233
234 function unset_routes(){
235         local sliver=$1
236         local sliver_nid=`get_nid $sliver`
237         local temp_nid=`get_temp_nid`
238         local ppp_addr=`get_ppp_address`
239
240         #remarking and SNAT removed 
241         iptables -t mangle -D OUTPUT -j MARK --copy-xid 0x00
242         iptables -t mangle -D OUTPUT -m mark --mark $sliver_nid -j MARK --set-mark $temp_nid
243         iptables -t nat -D POSTROUTING -o $PPP_INT -j SNAT --to-source $ppp_addr
244         iptables -t mangle -D POSTROUTING -m mark --mark $temp_nid -j MARK --set-mark $sliver_nid
245
246         #disable the explicit bind to the ppp interface
247         ip rule del from $ppp_addr fwmark $temp_nid table umts_table  >/dev/null 2>&1
248         ip route del default dev $PPP_INT  src $ppp_addr table umts_table >/dev/null 2>&1
249         ip route flush cache  >/dev/null 2>&1
250
251 }
252
253 function add_destination(){
254         local dest="$1"
255         local sliver=$2
256         local sliver_nid=`get_nid $sliver`
257         local temp_nid=`get_temp_nid`
258
259         if [[ ! $dest ]]; then return 1; fi
260
261         if ! status_umts; then
262                 return 1;
263         fi
264         
265         if ip rule add to "$dest" fwmark $temp_nid table umts_table >/dev/null 2>&1; then
266                 echo "$dest" >> $DESTS_FILE
267                 return 0
268         else 
269                 return 1        
270         fi
271         ip route flush cache  >/dev/null 2>&1
272 }
273
274 function del_destination(){
275         local dest="$1"
276         local sliver=$2
277         local sliver_nid=`get_nid $sliver`
278         local temp_nid=`get_temp_nid`
279
280         if [[ ! $dest ]]; then return 1; fi
281         if ip rule del to "$dest" fwmark $temp_nid table umts_table >/dev/null 2>&1; then
282                 return 0;
283         else 
284                 return 1;
285         fi
286         ip route flush cache  >/dev/null 2>&1
287 }
288
289
290 function get_ppp_address(){
291         ifconfig $PPP_INT | grep inet\ addr | cut -d ":" -f 2 | cut -d " " -f 1
292 }
293
294 function set_temp_nid(){
295         local sliver_nid=$1
296         local temp_nid=$((0x20000+$sliver_nid))
297
298         #k=0    
299         #while grep :$temp_nid: /etc/passwd; do
300         #       temp_nid=$((temp_nid+1))
301         #       k=$((k+1))
302         #       if [[ $k == 1000 ]]; then
303         #               logger "Fatal error: I couldn't find a temp_nid"
304         #               stop_umts
305         #               exit 1
306         #       fi
307         #done
308         echo $temp_nid > $FILE_TEMP_NID
309
310
311 }
312
313 # checks ip addresses  
314 function valid_dotted_quad(){
315     oldIFS=$IFS
316     IFS=.
317     set -f
318     set -- $1
319     if [ $# -eq 4 ]
320     then
321       for seg
322       do
323         case $seg in
324             ""|*[!0-9]*) return 1; break ;; ## Segment empty or non-numeric char
325             *) [ $seg -gt 255 ] && return 2 ;;
326         esac
327       done
328     else
329       return 3 ## Not 4 segments
330     fi
331     IFS=$oldIFS
332     set +f
333     return 0;
334 }
335