netbsd revision 1.1.1.1
1#!/bin/sh
2
3make_resolv_conf() {
4  if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
5    cat /dev/null > /etc/resolv.conf.dhclient
6    if [ "x$new_domain_search" != x ]; then
7      echo search $new_domain_search >> /etc/resolv.conf.dhclient
8    elif [ "x$new_domain_name" != x ]; then
9      # Note that the DHCP 'Domain Name Option' is really just a domain
10      # name, and that this practice of using the domain name option as
11      # a search path is both nonstandard and deprecated.
12      echo search $new_domain_name >> /etc/resolv.conf.dhclient
13    fi
14    for nameserver in $new_domain_name_servers; do
15      echo nameserver $nameserver >>/etc/resolv.conf.dhclient
16    done
17
18    mv /etc/resolv.conf.dhclient /etc/resolv.conf
19  elif [ "x${new_dhcp6_name_servers}" != x ] ; then
20    cat /dev/null > /etc/resolv.conf.dhclient6
21    chmod 644 /etc/resolv.conf.dhclient6
22
23    if [ "x${new_dhcp6_domain_search}" != x ] ; then
24      echo search ${new_dhcp6_domain_search} >> /etc/resolv.conf.dhclient6
25    fi
26    for nameserver in ${new_dhcp6_name_servers} ; do
27      # If the nameserver has a link-local address
28      # add a <zone_id> (interface name) to it.
29      case $nameserver in
30	fe80:*) zone_id="%$interface";;
31	FE80:*) zone_id="%$interface";;
32	*)      zone_id="";;
33      esac
34      echo nameserver ${nameserver}$zone_id >> /etc/resolv.conf.dhclient6
35    done
36
37    mv /etc/resolv.conf.dhclient6 /etc/resolv.conf
38  fi
39}
40
41# Must be used on exit.   Invokes the local dhcp client exit hooks, if any.
42exit_with_hooks() {
43  exit_status=$1
44  if [ -f /etc/dhclient-exit-hooks ]; then
45    . /etc/dhclient-exit-hooks
46  fi
47# probably should do something with exit status of the local script
48  exit $exit_status
49}
50
51# This function was largely borrowed from dhclient-script that
52# ships with Centos, authored by Jiri Popelka and David Cantrell
53# of Redhat. Thanks guys.
54add_ipv6_addr_with_DAD() {
55    ifconfig ${interface} inet6 ${new_ip6_address}/${new_ip6_prefixlen} alias
56
57    if [ ${dad_wait_time} -le 0 ]
58    then
59        # if we're not waiting for DAD, assume we're good
60        return 0
61    fi
62
63    # Repeatedly test whether newly added address passed
64    # duplicate address detection (DAD)
65    for i in $(seq 1 ${dad_wait_time}); do
66        sleep 1 # give the DAD some time
67
68        addr=$(ifconfig ${interface} \
69            | grep "${new_ip6_address} prefixlen ${new_ip6_prefixlen}")
70
71        # tentative flag == DAD is still not complete
72        tentative=$(echo "${addr}" | grep tentative)
73        # dadfailed flag == address is already in use somewhere else
74        dadfailed=$(echo "${addr}" | grep duplicated)
75
76        if [ -n "${dadfailed}" ] ; then
77            # dad failed, remove the address
78            ifconfig ${interface} inet6 ${new_ip6_address}/${new_ip6_prefixlen} -alias
79            exit_with_hooks 3
80        fi
81
82        if [ -z "${tentative}" ] ; then
83            if [ -n "${addr}" ]; then
84                # DAD is over
85                return 0
86            else
87                # address was auto-removed (or not added at all)
88                exit_with_hooks 3
89            fi
90        fi
91    done
92
93    return 0
94}
95
96# Invoke the local dhcp client enter hooks, if they exist.
97if [ -f /etc/dhclient-enter-hooks ]; then
98  exit_status=0
99  . /etc/dhclient-enter-hooks
100  # allow the local script to abort processing of this state
101  # local script must set exit_status variable to nonzero.
102  if [ $exit_status -ne 0 ]; then
103    exit $exit_status
104  fi
105fi
106
107if [ x$new_network_number != x ]; then
108   echo New Network Number: $new_network_number
109fi
110
111if [ x$new_broadcast_address != x ]; then
112 echo New Broadcast Address: $new_broadcast_address
113  new_broadcast_arg="broadcast $new_broadcast_address"
114fi
115if [ x$old_broadcast_address != x ]; then
116  old_broadcast_arg="broadcast $old_broadcast_address"
117fi
118if [ x$new_subnet_mask != x ]; then
119  new_netmask_arg="netmask $new_subnet_mask"
120fi
121if [ x$old_subnet_mask != x ]; then
122  old_netmask_arg="netmask $old_subnet_mask"
123fi
124if [ x$alias_subnet_mask != x ]; then
125  alias_subnet_arg="netmask $alias_subnet_mask"
126fi
127 if [ x$new_interface_mtu != x ]; then
128   mtu_arg="mtu $new_interface_mtu"
129 fi
130if [ x$IF_METRIC != x ]; then
131  metric_arg="metric $IF_METRIC"
132fi
133
134if [ x$reason = xMEDIUM ]; then
135  eval "ifconfig $interface $medium"
136  eval "ifconfig $interface inet -alias 0.0.0.0 $medium" >/dev/null 2>&1
137  sleep 1
138  exit_with_hooks 0
139fi
140
141###
142### DHCPv4 Handlers
143###
144
145if [ x$reason = xPREINIT ]; then
146  if [ x$alias_ip_address != x ]; then
147    ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
148    route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
149  fi
150  ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 \
151		broadcast 255.255.255.255 up
152  exit_with_hooks 0
153fi
154
155if [ x$reason = xARPCHECK ] || [ x$reason = xARPSEND ]; then
156  exit_with_hooks 0
157fi
158  
159if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
160   [ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then
161  current_hostname=`hostname`
162  if [ x$current_hostname = x ] || \
163     [ x$current_hostname = x$old_host_name ]; then
164    if [ x$current_hostname = x ] || \
165       [ x$new_host_name != x$old_host_name ]; then
166      hostname $new_host_name
167    fi
168  fi
169    
170  if [ x$old_ip_address != x ] && [ x$alias_ip_address != x ] && \
171		[ x$alias_ip_address != x$old_ip_address ]; then
172    ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
173    route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
174  fi
175  if [ x$old_ip_address != x ] && [ x$old_ip_address != x$new_ip_address ]
176   then
177    eval "ifconfig $interface inet -alias $old_ip_address $medium"
178    route delete $old_ip_address 127.1 >/dev/null 2>&1
179    for router in $old_routers; do
180      route delete default $router >/dev/null 2>&1
181    done
182    if [ "$old_static_routes" != "" ]; then
183      set $old_static_routes
184      while [ $# -gt 1 ]; do
185	route delete $1 $2
186	shift; shift
187      done
188    fi
189    arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' |sh
190  fi
191  if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \
192     [ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
193    eval "ifconfig $interface inet $new_ip_address $new_netmask_arg \
194			$new_broadcast_arg $mtu_arg $metric_arg $medium"
195    route add $new_ip_address 127.1 >/dev/null 2>&1
196    for router in $new_routers; do
197      route add default $router >/dev/null 2>&1
198    done
199    if [ "$new_static_routes" != "" ]; then
200      set $new_static_routes
201      while [ $# -gt 1 ]; do
202	route add $1 $2
203	shift; shift
204      done
205    fi
206  else                                                                        
207    # we haven't changed the address, have we changed other options           
208    # that we wish to update?
209    if [ x$new_routers != x ] && [ x$new_routers != x$old_routers ] ; then
210      # if we've changed routers delete the old and add the new.
211      $LOGGER "New Routers: $new_routers"
212      for router in $old_routers; do
213        route delete default $router >/dev/null 2>&1
214      done
215      for router in $new_routers; do
216        route add default $router >/dev/null 2>&1
217      done
218    fi
219  fi
220  if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
221   then
222    ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
223    route add $alias_ip_address 127.0.0.1
224  fi
225  make_resolv_conf
226  exit_with_hooks 0
227fi
228
229if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
230   || [ x$reason = xSTOP ]; then
231  if [ x$alias_ip_address != x ]; then
232    ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
233    route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
234  fi
235  if [ x$old_ip_address != x ]; then
236    eval "ifconfig $interface inet -alias $old_ip_address $medium"
237    route delete $old_ip_address 127.1 >/dev/null 2>&1
238    for router in $old_routers; do
239      route delete default $router >/dev/null 2>&1
240    done
241    if [ "$old_static_routes" != "" ]; then
242      set $old_static_routes
243      while [ $# -gt 1 ]; do
244	route delete $1 $2
245	shift; shift
246      done
247    fi
248    arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' \
249						|sh >/dev/null 2>&1
250  fi
251  if [ x$alias_ip_address != x ]; then
252    ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
253    route add $alias_ip_address 127.0.0.1
254  fi
255  exit_with_hooks 0
256fi
257
258if [ x$reason = xTIMEOUT ]; then
259  if [ x$alias_ip_address != x ]; then
260    ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
261    route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
262  fi
263  eval "ifconfig $interface inet $new_ip_address $new_netmask_arg \
264			$new_broadcast_arg $mtu_arg $metric_arg $medium"
265  sleep 1
266  if [ "$new_routers" != "" ]; then
267    set $new_routers
268    if ping -q -c 1 -w 1 $1; then
269      if [ x$new_ip_address != x$alias_ip_address ] && \
270			[ x$alias_ip_address != x ]; then
271	ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
272	route add $alias_ip_address 127.0.0.1
273      fi
274      route add $new_ip_address 127.1 >/dev/null 2>&1
275      for router in $new_routers; do
276	route add default $router >/dev/null 2>&1
277      done
278      set $new_static_routes
279      while [ $# -gt 1 ]; do
280	route add $0 $1
281	shift; shift
282      done
283      make_resolv_conf
284      exit_with_hooks 0
285    fi
286  fi
287  eval "ifconfig $interface inet -alias $new_ip_address $medium"
288  for router in $old_routers; do
289    route delete default $router >/dev/null 2>&1
290  done
291  if [ "$old_static_routes" != "" ]; then
292    set $old_static_routes
293    while [ $# -gt 1 ]; do
294      route delete $1 $2
295      shift; shift
296    done
297  fi
298  arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' \
299							|sh >/dev/null 2>&1
300  exit_with_hooks 1
301fi
302
303###
304### DHCPv6 Handlers
305###
306
307if [ ${reason} = PREINIT6 ] ; then
308  # Ensure interface is up.
309  ifconfig ${interface} up
310
311  # XXX: Remove any stale addresses from aborted clients.
312
313  # We need to give the kernel some time to active interface
314  interface_up_wait_time=5
315  for i in $(seq 0 ${interface_up_wait_time})
316  do
317      ifconfig ${interface} | grep inactive >/dev/null 2>&1
318      if [ $? -ne 0 ]; then
319          break;
320      fi
321      sleep 1
322  done
323
324  # Wait for duplicate address detection for this interface if the
325  # --dad-wait-time parameter has been specified and is greater than
326  # zero.
327  if [ ${dad_wait_time} -gt 0 ]; then
328      # Check if any IPv6 address on this interface is marked as
329      # tentative.
330      ifconfig ${interface} | grep inet6 | grep tentative \
331          >/dev/null 2>&1
332      if [ $? -eq 0 ]; then
333          # Wait for duplicate address detection to complete or for
334          # the timeout specified as --dad-wait-time.
335          for i in $(seq 0 $dad_wait_time)
336          do
337              # We're going to poll for the tentative flag every second.
338              sleep 1
339              ifconfig ${interface} | grep inet6 | grep tentative \
340                  >/dev/null 2>&1
341              if [ $? -ne 0 ]; then
342                  break;
343              fi
344          done
345      fi
346  fi
347
348  exit_with_hooks 0
349fi
350
351if [ x${old_ip6_prefix} != x ] || [ x${new_ip6_prefix} != x ] ; then
352    echo Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix}
353
354    exit_with_hooks 0
355fi
356
357if [ ${reason} = BOUND6 ] ; then
358  if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
359    exit_with_hooks 2;
360  fi
361
362  # Add address to interface, check for DAD if dad_wait_time > 0
363  add_ipv6_addr_with_DAD
364
365  # Check for nameserver options.
366  make_resolv_conf
367
368  exit_with_hooks 0
369fi
370
371if [ ${reason} = RENEW6 ] || [ ${reason} = REBIND6 ] ; then
372  # Make sure nothing has moved around on us.
373
374  # Nameservers/domains/etc.
375  if [ "x${new_dhcp6_name_servers}" != "x${old_dhcp6_name_servers}" ] ||
376     [ "x${new_dhcp6_domain_search}" != "x${old_dhcp6_domain_search}" ] ; then
377    make_resolv_conf
378  fi
379
380  exit_with_hooks 0
381fi
382
383if [ ${reason} = DEPREF6 ] ; then
384  if [ x${new_ip6_prefixlen} = x ] ; then
385    exit_with_hooks 2;
386  fi
387
388  # XXX:
389  # There doesn't appear to be a way to update an addr to indicate
390  # preference.
391
392  exit_with_hooks 0
393fi
394
395if [ ${reason} = EXPIRE6 -o ${reason} = RELEASE6 -o ${reason} = STOP6 ] ; then
396  if [ x${old_ip6_address} = x ] || [ x${old_ip6_prefixlen} = x ] ; then
397    exit_with_hooks 2;
398  fi
399
400  ifconfig ${interface} inet6 -alias ${old_ip6_address}/${old_ip6_prefixlen}
401
402  exit_with_hooks 0
403fi
404
405exit_with_hooks 0
406