xref: /dragonfly/sbin/dhclient/dhclient-script (revision 65c3a6937214062f86893797ad33baa1fbc0b372)
1#!/bin/sh
2#
3# $OpenBSD: src/sbin/dhclient/Attic/dhclient-script,v 1.23 2012/09/18 18:27:55 krw Exp $
4#
5# Copyright (c) 2003 Kenneth R Westerback <krw@openbsd.org>
6#
7# Permission to use, copy, modify, and distribute this software for any
8# purpose with or without fee is hereby granted, provided that the above
9# copyright notice and this permission notice appear in all copies.
10#
11# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18#
19#
20
21#
22# Helper functions that implement common actions.
23#
24
25delete_old_address() {
26          if [ -n "$old_ip_address" ]; then
27                    ifconfig $interface inet $old_ip_address delete
28                    #route delete "$old_ip_address" 127.0.0.1 >/dev/null 2>&1
29          fi
30          if [ -n "$old_classless_routes" ]; then
31                    fill_classless_routes "$old_classless_routes"
32                    set $classless_routes
33                    while [ $# -gt 1 ]; do
34                              route delete "$1" "$2"
35                              shift; shift
36                    done
37                    return 0;
38          fi
39}
40
41add_new_address() {
42          ifconfig $interface \
43                    inet $new_ip_address \
44                    netmask $new_subnet_mask \
45                    broadcast $new_broadcast_address
46
47          # XXX Original TIMEOUT code did not do this unless $new_routers was set?
48          #route add $new_ip_address 127.0.0.1 >/dev/null 2>&1
49}
50
51fill_classless_routes() {
52          set $1
53          while [ $# -ge 5 ]; do
54                    if [ $1 -eq 0 ]; then
55                              route="default"
56                    elif [ $1 -le 8 ]; then
57                              route="$2.0.0.0/$1"
58                              shift
59                    elif [ $1 -le 16 ]; then
60                              route="$2.$3.0.0/$1"
61                              shift; shift
62                    elif [ $1 -le 24 ]; then
63                              route="$2.$3.$4.0/$1"
64                              shift; shift; shift
65                    else
66                              route="$2.$3.$4.$5/$1"
67                              shift; shift; shift; shift
68                    fi
69                    shift
70                    router="$1.$2.$3.$4"
71                    classless_routes="$classless_routes $route $router"
72                    shift; shift; shift; shift
73          done
74}
75
76delete_old_routes() {
77          arp -d -i $interface -an
78}
79
80add_new_routes() {
81          # RFC 3442: If the DHCP server returns both a Classless Static
82          # Routes option and a Router option, the DHCP client MUST ignore
83          # the Router option.
84          #
85          # DHCP clients that support this option (Classless Static Routes)
86          # MUST NOT install the routes specified in the Static Routes
87          # option (option code 33) if both a Static Routes option and the
88          # Classless Static Routes option are provided.
89
90          if [ -n "$new_classless_routes" ]; then
91                    fill_classless_routes "$new_classless_routes"
92                    $LOGGER "New Classless Static Routes ($interface): $classless_routes"
93                    set $classless_routes
94                    while [ $# -gt 1 ]; do
95                              if [ "0.0.0.0" = "$2" ]; then
96                                        route add "$1" -iface "$interface"
97                              else
98                                        route add "$1" "$2"
99                              fi
100                              shift; shift
101                    done
102                    return
103          fi
104
105          for router in $new_routers; do
106                    route -q delete default
107                    if [ "$new_ip_address" = "$router" ]; then
108                              route -q add default -iface $router
109                    else
110                              route -q add default $router
111                    fi
112                    # 2nd and subsequent default routers error out, so explicitly
113                    # stop processing the list after the first one.
114                    break
115          done
116}
117
118add_new_resolv_conf() {
119          # Create resolv.conf when either $new_domain_name_servers or
120          # $new_domain_name are provided. As reported in PR#3135, some ISPs
121          # provide only $new_domain_name_servers.
122
123          local tmpres="/var/run/dhclient-resolv.conf.$interface"
124
125          rm -f "$tmpres"
126
127          if [ -n "$new_domain_name" ]; then
128                    echo "search $new_domain_name" >>"$tmpres"
129          fi
130
131          if [ -n "$new_domain_name_servers" ]; then
132                    for nameserver in $new_domain_name_servers; do
133                              echo "nameserver $nameserver" >>"$tmpres"
134                    done
135          fi
136
137          if [ -f "$tmpres" ]; then
138                    /sbin/resolvconf -a "$interface.dhcp" <"$tmpres"
139                    rm -f "$tmpres"
140          else
141                    /sbin/resolvconf -d "$interface.dhcp" -f
142          fi
143
144          return 0
145}
146
147#
148# Start of active code.
149#
150
151case $reason in
152MEDIUM)
153          # Not called by OpenBSD dhclient(8).
154          ;;
155
156PREINIT)
157          # Not called by OpenBSD dhclient(8).
158          ;;
159
160ARPSEND)
161          # Not called by OpenBSD dhclient(8).
162          exit 1
163          ;;
164
165ARPCHECK)
166          # Not called by OpenBSD dhclient(8).
167          # Always succeed. i.e. accept lease.
168          ;;
169
170BOUND|RENEW|REBIND|REBOOT)
171          if [ -n "$old_ip_address" ]; then
172                    if [ "$old_ip_address" != "$new_ip_address" ]; then
173                              delete_old_address
174                              delete_old_routes
175                    fi
176          fi
177          if [ "$reason" = BOUND ] ||
178             [ "$reason" = REBOOT ] ||
179             [ -z "$old_ip_address" ] ||
180             [ "$old_ip_address" != "$new_ip_address" ]; then
181                    add_new_address
182                    add_new_routes
183          fi
184          add_new_resolv_conf
185          ;;
186
187EXPIRE|FAIL)
188          if [ -n "$old_ip_address" ]; then
189                    delete_old_address
190                    delete_old_routes
191          fi
192          /sbin/resolvconf -d "$interface.dhcp" -f
193          ;;
194
195TIMEOUT)
196          add_new_address
197          sleep 1
198          if [ -n "$new_routers" ]; then
199                    set "$new_routers"
200                    if ping -q -c 1 -w 1 "$1"; then
201                              add_new_routes
202                              if add_new_resolv_conf; then
203                                        exit 0
204                              fi
205                    fi
206          fi
207          ifconfig $interface inet $new_ip_address delete
208          # XXX Why not a delete_old_address as before all other invocations of
209          #     delete_old_routes?
210          delete_old_routes
211          exit 1
212          ;;
213esac
214
215exit 0
216