OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / utils / _startklips
1 #!/bin/sh
2 # KLIPS startup script
3 # Copyright (C) 1998, 1999, 2001, 2002  Henry Spencer.
4
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2 of the License, or (at your
8 # option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 # for more details.
14 #
15 # RCSID $Id: _startklips,v 1.6.2.1 2002/04/09 21:34:56 mcr Exp $
16
17 me='ipsec _startklips'          # for messages
18
19 # KLIPS-related paths
20 sysflags=/proc/sys/net/ipsec
21 modules=/proc/modules
22 # full rp_filter path is $rpfilter1/interface/$rpfilter2
23 rpfilter1=/proc/sys/net/ipv4/conf
24 rpfilter2=rp_filter
25 ipsecversion=/proc/net/ipsec_version
26 modulesdir=/lib/modules/ipsec
27 moduleplace=/lib/modules/`uname -r`/kernel/net/ipsec
28 modulename=ipsec.o
29
30 info=/dev/null
31 log=daemon.error
32 for dummy
33 do
34         case "$1" in
35         --log)          log="$2" ; shift        ;;
36         --info)         info="$2" ; shift       ;;
37         --debug)        debug="$2" ; shift      ;;
38         --omtu)         omtu="$2" ; shift       ;;
39         --fragicmp)     fragicmp="$2" ; shift   ;;
40         --hidetos)      hidetos="$2" ; shift    ;;
41         --default)      packetdefault="$2" ; shift      ;;
42         --)     shift ; break   ;;
43         -*)     echo "$me: unknown option \`$1'" >&2 ; exit 2   ;;
44         *)      break   ;;
45         esac
46         shift
47 done
48
49
50
51 # some shell functions, to clarify the actual code
52
53 # set up a system flag based on a variable
54 # sysflag value shortname default flagname
55 sysflag() {
56         case "$1" in
57         '')     v="$3"  ;;
58         *)      v="$1"  ;;
59         esac
60         if test ! -f $sysflags/$4
61         then
62                 if test " $v" != " $3"
63                 then
64                         echo "cannot do $2=$v, $sysflags/$4 does not exist"
65                         exit 1
66                 else
67                         return  # can't set, but it's the default anyway
68                 fi
69         fi
70         case "$v" in
71         yes|no) ;;
72         *)      echo "unknown (not yes/no) $2 value \`$1'"
73                 exit 1
74                 ;;
75         esac
76         case "$v" in
77         yes)    echo 1 >$sysflags/$4    ;;
78         no)     echo 0 >$sysflags/$4    ;;
79         esac
80 }
81
82 # set up a Klips interface
83 klipsinterface() {
84         # pull apart the interface spec
85         virt=`expr $1 : '\([^=]*\)=.*'`
86         phys=`expr $1 : '[^=]*=\(.*\)'`
87         case "$virt" in
88         ipsec[0-9])     ;;
89         *)      echo "invalid interface \`$virt' in \`$1'" ; exit 1     ;;
90         esac
91
92         # figure out ifconfig for interface
93         addr=
94         eval `ifconfig $phys |
95                 awk '$1 == "inet" && $2 ~ /^addr:/ && $NF ~ /^Mask:/ {
96                         gsub(/:/, " ", $0)
97                         print "addr=" $3
98                         other = $5
99                         if ($4 == "Bcast")
100                                 print "type=broadcast"
101                         else if ($4 == "P-t-P")
102                                 print "type=pointopoint"
103                         else if (NF == 5) {
104                                 print "type="
105                                 other = ""
106                         } else
107                                 print "type=unknown"
108                         print "otheraddr=" other
109                         print "mask=" $NF
110                 }'`
111         if test " $addr" = " "
112         then
113                 echo "unable to determine address of \`$phys'"
114                 exit 1
115         fi
116         if test " $type" = " unknown"
117         then
118                 echo "\`$phys' is of an unknown type"
119                 exit 1
120         fi
121         if test " $omtu" != " "
122         then
123                 mtu="mtu $omtu"
124         else
125                 mtu=
126         fi
127         echo "KLIPS $virt on $phys $addr/$mask $type $otheraddr $mtu" | logonly
128
129         # attach the interface and bring it up
130         ipsec tncfg --attach --virtual $virt --physical $phys
131         ifconfig $virt inet $addr $type $otheraddr netmask $mask $mtu
132
133         # if %defaultroute, note the facts
134         if test " $2" != " "
135         then
136                 (
137                         echo "defaultroutephys=$phys"
138                         echo "defaultroutevirt=$virt"
139                         echo "defaultrouteaddr=$addr"
140                         if test " $2" != " 0.0.0.0"
141                         then
142                                 echo "defaultroutenexthop=$2"
143                         fi
144                 ) >>$info
145         else
146                 echo '#dr: no default route' >>$info
147         fi
148
149         # check for rp_filter trouble
150         checkif $phys                   # thought to be a problem only on phys
151 }
152
153 # check an interface for problems
154 checkif() {
155         rpf=$rpfilter1/$1/$rpfilter2
156         if test -f $rpf
157         then
158                 r="`cat $rpf`"
159                 if test " $r" != " 0"
160                 then
161                         echo "WARNING: $1 has route filtering turned on, KLIPS may not work"
162                         echo " ($rpf = \`$r', should be 0)"
163                 fi
164         fi
165 }
166
167 # interfaces=%defaultroute:  put ipsec0 on top of default route's interface
168 defaultinterface() {
169         phys=`netstat -nr |
170                 awk '$1 == "0.0.0.0" && $3 == "0.0.0.0" { print $NF }'`
171         if test " $phys" = " "
172         then
173                 echo "no default route, %defaultroute cannot cope!!!"
174                 exit 1
175         fi
176         if test `echo " $phys" | wc -l` -gt 1
177         then
178                 echo "multiple default routes, %defaultroute cannot cope!!!"
179                 exit 1
180         fi
181         next=`netstat -nr |
182                 awk '$1 == "0.0.0.0" && $3 == "0.0.0.0" { print $2 }'`
183         klipsinterface "ipsec0=$phys" $next
184 }
185
186 # log only to syslog, not to stdout/stderr
187 logonly() {
188         logger -p $log -t ipsec_setup
189 }
190
191 # sort out which module is appropriate, changing it if necessary
192 setmodule() {
193         if test ! -d $modulesdir
194         then
195                 return                  # nothing we can do anyway
196         fi
197         wantgoo="`sed -n '/ netif_rx_R/s/.*_R//p' /proc/ksyms`"
198         module=$moduleplace/$modulename
199         if test -f $module
200         then
201                 goo="`nm -ug $module | sed -n '/ netif_rx_R/s/.*_//p'`"
202                 if test " $wantgoo" = " $goo"
203                 then
204                         return          # looks right
205                 fi
206         fi
207         if test -f $modulesdir/$wantgoo
208         then
209                 echo "KLIPS module needed changing (to $wantgoo)" | logonly
210                 rm -f $module
211                 mkdir -p $moduleplace
212                 cp -p $modulesdir/$wantgoo $module
213                 # "depmod -a" gets done by caller
214         fi
215 }
216
217
218
219 # main line
220
221 # load module if necessary
222 if test ! -f $ipsecversion
223 then
224         if test -r $modules             # kernel does have modules
225         then
226                 setmodule
227                 unset MODPATH MODULECONF        # no user overrides!
228                 depmod -a >/dev/null 2>&1 && modprobe ipsec
229         fi
230         if test ! -f $ipsecversion
231         then
232                 echo "kernel appears to lack KLIPS"
233                 exit 1
234         fi
235 fi
236
237 # figure out debugging flags
238 case "$debug" in
239 '')     debug=none      ;;
240 esac
241 if test -r /proc/net/ipsec_klipsdebug
242 then
243         echo "KLIPS debug \`$debug'" | logonly
244         case "$debug" in
245         none)   ipsec klipsdebug --none ;;
246         all)    ipsec klipsdebug --all  ;;
247         *)      ipsec klipsdebug --none
248                 for d in $debug
249                 do
250                         ipsec klipsdebug --set $d
251                 done
252                 ;;
253         esac
254 else
255         if test " $debug" != " none"
256         then
257                 echo "klipsdebug=\`$debug' ignored, KLIPS lacks debug facilities"
258         fi
259 fi
260
261 # figure out misc. kernel config
262 if test -d $sysflags
263 then
264         sysflag "$fragicmp" "fragicmp" yes icmp
265         echo 1 >$sysflags/inbound_policy_check          # no debate
266         sysflag no "no_eroute_pass" no no_eroute_pass   # obsolete parm
267         sysflag no "opportunistic" no opportunistic     # obsolete parm
268         sysflag "$hidetos" "hidetos" yes tos
269 else
270         echo "WARNING: cannot adjust KLIPS flags, no $sysflags directory!"
271         # carry on
272 fi
273
274 # clear tables out in case dregs have been left over
275 ipsec eroute --clear
276 ipsec spi --clear
277
278 # figure out interfaces
279 for i
280 do
281         case "$i" in
282         ipsec*=?*)      klipsinterface "$i"     ;;
283         %defaultroute)  defaultinterface        ;;
284         *)      echo "interface \`$i' not understood"
285                 exit 1
286                 ;;
287         esac
288 done
289
290 # set up default eroute if necessary
291 case "$packetdefault" in
292 pass|reject)
293         ipsec eroute --label "packetdefault" --replace --eraf inet \
294                 --src 0/0 --dst 0/0 --said "%$packetdefault"
295         ;;
296 drop)   ;;              # default
297 *)      echo "unknown packetdefault value \`$packetdefault'"
298         exit 1
299         ;;
300 esac
301
302 exit 0