Documentat mount_mfs -C
[dragonfly.git] / sbin / dhclient / dhclient-script.sh
1 #!/bin/sh
2
3 #############################################################################
4 #
5 # Copyright (c) 1999, MindStep Corporation
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
10 # are met:
11 # 1. Redistributions of source code must retain the above copyright
12 #    notice, this list of conditions and the following disclaimer.
13 # 2. Redistributions in binary form must reproduce the above copyright
14 #    notice, this list of conditions and the following disclaimer in the
15 #    documentation and/or other materials provided with the distribution.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 # SUCH DAMAGE.
28 #
29 #
30 #############################################################################
31 #
32 # This script was written by Patrick Bihan-Faou, patrick@mindstep.com,
33 # Please contact us for bug reports, etc.
34 #
35 #############################################################################
36 # $MindStep_Id: dhclient-script.sh,v 1.8 1999/12/07 22:11:08 patrick Exp $
37 # $MindStep_Tag: CONTRIB_19991207 $
38 # $FreeBSD: src/sbin/dhclient/dhclient-script.sh,v 1.2.2.1 2002/04/11 10:21:20 murray Exp $
39 # $DragonFly: src/sbin/dhclient/Attic/dhclient-script.sh,v 1.2 2003/06/17 04:27:32 dillon Exp $
40 #############################################################################
41
42
43 #############################################################################
44 # hook functions prototypes
45 #
46 # The "pre_state_XXX_hook" functions are called before the main
47 # work is done for the state XXX
48 #
49 # The "post_state_XXX_hook" functions are called after the main
50 # work is done for the state XXX
51 #
52 # These functions are meant to be overridden by the user's
53 # dhclient-enter-hooks file
54 #############################################################################
55
56 pre_state_MEDIUM_hook () { }
57 pre_state_PREINIT_hook () { }
58 pre_state_ARPCHECK_hook () { }
59 pre_state_ARPSEND_hook () { }
60 pre_state_RENEW_hook () { }
61 pre_state_REBIND_hook () { }
62 pre_state_BOUND_hook () { }
63 pre_state_REBOOT_hook () { }
64 pre_state_EXPIRE_hook () { }
65 pre_state_FAIL_hook () { }
66 pre_state_TIMEOUT_hook () { }
67 post_state_MEDIUM_hook () { }
68 post_state_PREINIT_hook () { }
69 post_state_ARPCHECK_hook () { }
70 post_state_ARPSEND_hook () { }
71 post_state_RENEW_hook () { }
72 post_state_REBIND_hook () { }
73 post_state_BOUND_hook () { }
74 post_state_REBOOT_hook () { }
75 post_state_EXPIRE_hook () { }
76 post_state_FAIL_hook () { }
77 post_state_TIMEOUT_hook () { }
78
79 #############################################################################
80 # make_resolv_conf
81 #
82 # This function is called to update the information related to the
83 # DNS configuration (the resolver part)
84 #############################################################################
85 make_resolv_conf () 
86 {
87    if [ "x$new_domain_name" != x ] && [ "x$new_domain_name_servers" != x ]; then
88      echo search $new_domain_name >/etc/resolv.conf
89      for nameserver in $new_domain_name_servers; do
90        echo nameserver $nameserver >>/etc/resolv.conf
91      done
92    fi
93 }
94
95 # Must be used on exit.   Invokes the local dhcp client exit hooks, if any.
96 exit_with_hooks () {
97   exit_status=$1
98   if [ -x /etc/dhclient-exit-hooks ]; then
99     . /etc/dhclient-exit-hooks
100   fi
101 # probably should do something with exit status of the local script
102   return $exit_status
103 }
104
105 #############################################################################
106 # set_XXX
107 # unset_XXX
108 #
109 # These function each deal with one particular setting.
110 # They are OS dependent and may be overridden in the 
111 # dhclient-enter-hooks file if needed.
112 #
113 # These functions are called with either "new" or "old" to indicate which
114 # set of variables to use (new_ip_address or old_ip_address...)
115 #
116 #############################################################################
117
118 update_hostname ()
119 {
120         local current_hostname=`/bin/hostname`
121         if      [ "$current_hostname" = "" ] || \
122                 [ "$current_hostname" = "$old_host_name" ]
123         then
124                 if [ "$new_host_name" != "$old_host_name" ]
125                 then
126                         $LOGGER "New Hostname: $new_host_name"
127                         hostname $new_host_name
128                 fi
129         fi
130 }
131
132 set_ip_address () 
133 {
134         local ip
135         local mask
136         local bcast
137
138         if [ $# -lt 1 ]
139         then
140                 return  1
141         fi
142
143         eval ip="\$${1}_ip_address"
144         eval mask="\$${1}_subnet_mask"
145         eval bcast="\$${1}_broadcast_address"
146
147         if [ "$ip" != "" ]
148         then
149                 ifconfig $interface inet $ip netmask $mask broadcast $bcast $medium
150 #               route add $ip 127.0.0.1 > /dev/null 2>&1
151         fi
152 }
153
154 unset_ip_address () 
155 {
156         local ip
157
158         if [ $# -lt 1 ]
159         then
160                 return  1
161         fi
162
163         eval ip="\$${1}_ip_address"
164
165         if [ "$ip" != "" ]
166         then
167                 ifconfig $interface inet -alias $ip $medium
168 #               route delete $ip 127.0.0.1 > /dev/null 2>&1
169         fi
170 }
171
172 set_ip_alias () 
173 {
174         if [ "$alias_ip_address" != "" ]
175         then
176                 ifconfig $interface inet alias $alias_ip_address netmask $alias_subnet_mask
177 #               route add $alias_ip_address 127.0.0.1
178         fi
179 }
180
181 unset_ip_alias () 
182 {
183         if [ "$alias_ip_address" != "" ]
184         then
185                 ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
186 #               route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
187         fi
188 }
189
190 set_routers () 
191 {
192         local router_list
193
194         if [ $# -lt 1 ]
195         then
196                 return  1
197         fi
198
199         eval router_list="\$${1}_routers"
200
201         for router in $router_list
202         do
203                 route add default $router >/dev/null 2>&1
204         done
205 }
206
207 unset_routers () 
208 {
209         local router_list
210
211         if [ $# -lt 1 ]
212         then
213                 return  1
214         fi
215
216         eval router_list="\$${1}_routers"
217
218         for router in $router_list
219         do
220                 route delete default $router >/dev/null 2>&1
221         done
222 }
223
224 set_static_routes () 
225 {
226         local static_routes
227
228         if [ $# -lt 1 ]
229         then
230                 return  1
231         fi
232
233         eval static_routes="\$${1}_static_routes"
234
235         set static_routes
236
237         while [ $# -ge 2 ]
238         do
239                 $LOGGER "New Static Route: $1 -> $2"
240                 route add $1 $2
241                 shift; shift
242         done
243 }
244
245 unset_static_routes () 
246 {
247         local static_routes
248
249         if [ $# -lt 1 ]
250         then
251                 return  1
252         fi
253
254         eval static_routes="\$${1}_static_routes"
255
256         set static_routes
257
258         while [ $# -ge 2 ]
259         do
260                 route delete $1 $2
261                 shift; shift
262         done
263 }
264
265 #############################################################################
266 #
267 # utility functions grouping what needs to be done in logical units.
268 #
269 #############################################################################
270
271 set_all ()
272 {
273         set_ip_address new
274         set_routers new
275         set_static_routes new
276
277         if      [ "$new_ip_address" != "$alias_ip_address" ]
278         then
279                 set_ip_alias
280         fi
281 }
282
283 set_others ()
284 {
285         update_hostname
286         make_resolv_conf
287 }
288
289 clear_arp_table () 
290 {
291         arp -d -a
292 }
293
294 unset_all ()
295 {
296         if [ "$alias_ip_address" != "$old_ip_address" ]
297         then
298                 unset_ip_alias
299         fi
300
301         if [ "$old_ip_address" != "" ] 
302         then
303                 unset_ip_address old
304                 unset_routers old
305                 unset_static_routes old
306                 clear_arp_table
307         fi
308 }
309
310 test_new_lease () 
311 {
312         local rc
313
314         set $new_routers
315
316         if [ $# -ge 1 ]
317         then
318                 set_ip_address new
319         if ping -q -c 1 $1
320                 then
321                         rc=0
322                 else
323                         rc=1
324                 fi
325                 unset_ip_address new
326         else
327                 rc=1
328         fi
329         return  $rc
330 }
331
332 #############################################################################
333 # Main State functions.
334 #
335 # There is a state function for each state of the DHCP client
336 # These functions are OS specific and should be be tampered with.
337 #############################################################################
338
339 in_state_MEDIUM () 
340 {
341   ifconfig $interface $medium
342   ifconfig $interface inet -alias 0.0.0.0 $medium >/dev/null 2>&1
343   sleep 1
344   exit_status=0
345 }
346
347 in_state_PREINIT () 
348 {
349         unset_ip_alias
350
351         ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 \
352                         broadcast 255.255.255.255 up
353         exit_status=0
354 }
355
356 in_state_ARPCHECK () 
357 {
358   exit_status=0
359 }
360
361 in_state_ARPSEND () 
362 {
363   exit_status=0
364 }
365
366 in_state_RENEW () 
367 {
368         if [ "$old_ip_address" != "$new_ip_address" ]
369         then
370                 unset_all
371                 set_all
372         fi
373
374         set_others
375 }
376
377 in_state_REBIND () {
378         in_state_RENEW
379 }
380
381 in_state_BOUND () {
382         unset_all
383         set_all
384         set_others
385 }
386
387 in_state_REBOOT () {
388         in_state_BOUND
389 }
390
391 in_state_EXPIRE () 
392 {
393         unset_all
394         set_ip_alias
395         exit_status=0
396 }
397
398 in_state_FAIL () {
399         in_state_EXPIRE
400 }
401
402 in_state_TIMEOUT () 
403 {
404         unset_all
405
406         if test_new_lease
407         then
408                 set_all
409                 set_others
410         else
411                 $LOGGER "No good lease information in TIMEOUT state"    
412                 set_ip_alias
413                 exit_status=1
414         fi
415 }
416
417 #############################################################################
418 # Main functions:
419 #
420 # dhclient_script_init() parses the optional "enter_hooks" script which can
421 #   override any of the state functions
422 #
423 # This function also parses the variables and notifies the detected changes.
424 #############################################################################
425 dhclient_script_init ()
426 {
427         if [ -x /usr/bin/logger ]; then
428                 LOGGER="/usr/bin/logger -s -p user.notice -t dhclient"
429         else
430                 LOGGER=echo
431         fi
432
433         # Invoke the local dhcp client enter hooks, if they exist.
434         if [ -x /etc/dhclient-enter-hooks ]
435         then
436                 exit_status=0
437                 . /etc/dhclient-enter-hooks
438                 # allow the local script to abort processing of this state
439                 # local script must set exit_status variable to nonzero.
440                 if [ $exit_status -ne 0 ]
441                 then
442                         exit $exit_status
443                 fi
444         fi
445
446         if [ "$new_network_number" != "" ]
447         then
448                 $LOGGER "New Network Number: $new_network_number"
449         fi
450
451         if [ "$new_ip_address" != "" ]
452         then
453                 $LOGGER "New IP Address: $new_ip_address"
454         fi
455
456         if [ "$new_broadcast_address" != "" ]
457         then
458                 $LOGGER "New Broadcast Address: $new_broadcast_address"
459         fi
460
461         if [ "$new_subnet_mask" != "" ]
462         then
463                 $LOGGER "New Subnet Mask for $interface: $new_subnet_mask"
464         fi
465
466         if [ "$alias_subnet_mask" != "" ]
467         then
468         fi
469 }
470
471 #############################################################################
472 # dhclient_main() does the appropriate work depending on the state of
473 # the dhcp client
474 #############################################################################
475 dhclient_script_main ()
476 {
477 #       set -x
478         exit_status=0
479
480         case $reason in
481                 MEDIUM|\
482                 PREINIT|\
483                 ARPCHECK|\
484                 ARPSEND|\
485                 RENEW|\
486                 REBIND|\
487                 BOUND|\
488                 REBOOT|\
489                 EXPIRE|\
490                 FAIL|\
491                 TIMEOUT)
492                         pre_state_${reason}_hook
493                         in_state_${reason}
494                         post_state_${reason}_hook
495                         ;;
496                 *)
497                         $LOGGER "dhclient-script called with invalid reason $reason"
498                         exit_status=1
499                         ;;
500         esac
501
502         exit_with_hooks $exit_status
503 }
504
505 #############################################################################
506 # Let's do the work...
507 #############################################################################
508
509 dhclient_script_init
510 dhclient_script_main
511 exit $exit_status
512
513 #############################################################################
514 # That's all folks
515 #############################################################################