Home | History | Annotate | Line # | Download | only in scripts
      1 #!/bin/sh
      2 
      3 # 'ip' just looks too weird.  /sbin/ip looks less weird.
      4 ip=/usr/sbin/ip
      5 
      6 make_resolv_conf() {
      7   if [ x"$new_domain_name_servers" != x ]; then
      8     cat /dev/null > /etc/resolv.conf.dhclient
      9     chmod 644 /etc/resolv.conf.dhclient
     10     if [ x"$new_domain_search" != x ]; then
     11       echo search $new_domain_search >> /etc/resolv.conf.dhclient
     12     elif [ x"$new_domain_name" != x ]; then
     13       # Note that the DHCP 'Domain Name Option' is really just a domain
     14       # name, and that this practice of using the domain name option as
     15       # a search path is both nonstandard and deprecated.
     16       echo search $new_domain_name >> /etc/resolv.conf.dhclient
     17     fi
     18     for nameserver in $new_domain_name_servers; do
     19       echo nameserver $nameserver >>/etc/resolv.conf.dhclient
     20     done
     21 
     22     mv /etc/resolv.conf.dhclient /etc/resolv.conf
     23   elif [ "x${new_dhcp6_name_servers}" != x ] ; then
     24     cat /dev/null > /etc/resolv.conf.dhclient6
     25     chmod 644 /etc/resolv.conf.dhclient6
     26 
     27     if [ "x${new_dhcp6_domain_search}" != x ] ; then
     28       echo search ${new_dhcp6_domain_search} >> /etc/resolv.conf.dhclient6
     29     fi
     30     for nameserver in ${new_dhcp6_name_servers} ; do
     31       # If the nameserver has a link-local address
     32       # add a <zone_id> (interface name) to it.
     33       case $nameserver in
     34 	fe80:*) zone_id="%$interface";;
     35 	FE80:*) zone_id="%$interface";;
     36 	*)      zone_id="";;
     37       esac
     38       echo nameserver ${nameserver}$zone_id >> /etc/resolv.conf.dhclient6
     39     done
     40 
     41     mv /etc/resolv.conf.dhclient6 /etc/resolv.conf
     42   fi
     43 }
     44 
     45 # Must be used on exit. Invokes the local dhcp client exit hooks, if any.
     46 exit_with_hooks() {
     47   exit_status=$1
     48   if [ -f /etc/dhclient-exit-hooks ]; then
     49     . /etc/dhclient-exit-hooks
     50   fi
     51 # probably should do something with exit status of the local script
     52   exit $exit_status
     53 }
     54 
     55 # Invoke the local dhcp client enter hooks, if they exist.
     56 if [ -f /etc/dhclient-enter-hooks ]; then
     57   exit_status=0
     58   . /etc/dhclient-enter-hooks
     59   # allow the local script to abort processing of this state
     60   # local script must set exit_status variable to nonzero.
     61   if [ $exit_status -ne 0 ]; then
     62     exit $exit_status
     63   fi
     64 fi
     65 
     66 ###
     67 ### DHCPv4 Handlers
     68 ###
     69 
     70 if [ x$new_broadcast_address != x ]; then
     71   new_broadcast_arg="broadcast $new_broadcast_address"
     72 fi
     73 if [ x$new_subnet_mask != x ]; then
     74   new_subnet_arg="netmask $new_subnet_mask"
     75 fi
     76 if [ x$alias_subnet_mask != x ]; then
     77   alias_subnet_arg="netmask $alias_subnet_mask"
     78 fi
     79 if [ x$new_interface_mtu != x ]; then
     80   mtu_arg="mtu $new_interface_mtu"
     81 fi
     82 if [ x$IF_METRIC != x ]; then
     83   metric_arg="metric $IF_METRIC"
     84 fi
     85 
     86 if [ x$reason = xMEDIUM ]; then
     87   # Linux doesn't do mediums (ok, ok, media).
     88   exit_with_hooks 0
     89 fi
     90 
     91 if [ x$reason = xPREINIT ]; then
     92   if [ x$alias_ip_address != x ]; then
     93     # Bring down alias interface. Its routes will disappear too.
     94     ifconfig $interface:0- 0.0.0.0
     95   fi
     96   ifconfig $interface 0.0.0.0 up
     97 
     98   # We need to give the kernel some time to get the interface up.
     99   sleep 1
    100 
    101   exit_with_hooks 0
    102 fi
    103 
    104 if [ x$reason = xARPCHECK ] || [ x$reason = xARPSEND ]; then
    105   exit_with_hooks 0
    106 fi
    107 
    108 if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
    109    [ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then
    110   current_hostname=`hostname`
    111   if [ x$current_hostname = x ] || \
    112      [ x$current_hostname = x$old_host_name ]; then
    113     if [ x$current_hostname = x ] || \
    114        [ x$new_host_name != x$old_host_name ]; then
    115       hostname $new_host_name
    116     fi
    117   fi
    118 
    119   if [ x$old_ip_address != x ] && [ x$alias_ip_address != x ] && \
    120 		[ x$alias_ip_address != x$old_ip_address ]; then
    121     # Possible new alias. Remove old alias.
    122     ifconfig $interface:0- 0.0.0.0
    123   fi
    124   if [ x$old_ip_address != x ] && \
    125 		[ x$old_ip_address != x$new_ip_address ]; then
    126     # IP address changed. Bringing down the interface will delete all routes,
    127     # and clear the ARP cache.
    128     ifconfig $interface 0.0.0.0 down
    129 
    130   fi
    131   if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \
    132      [ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
    133 
    134     ifconfig $interface $new_ip_address $new_subnet_arg \
    135 					$new_broadcast_arg $mtu_arg
    136     for router in $new_routers; do
    137       if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
    138 	route add -host $router dev $interface
    139       fi
    140       route add default gw $router $metric_arg dev $interface
    141     done
    142   else
    143     # we haven't changed the address, have we changed other options
    144     # that we wish to update?
    145     if [ x$new_routers != x ] && [ x$new_routers != x$old_routers ] ; then
    146       # if we've changed routers delete the old and add the new.
    147       $LOGGER "New Routers: $new_routers"
    148       for router in $old_routers; do
    149 	route del default gw $router
    150       done
    151       for router in $new_routers; do
    152 	if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
    153 	  route add -host $router dev $interface
    154 	fi
    155 	route add default gw $router $metric_arg dev $interface
    156       done
    157     fi
    158   fi
    159   if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
    160    then
    161     ifconfig $interface:0- 0.0.0.0
    162     ifconfig $interface:0 $alias_ip_address $alias_subnet_arg
    163     route add -host $alias_ip_address $interface:0
    164   fi
    165   make_resolv_conf
    166   exit_with_hooks 0
    167 fi
    168 
    169 if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
    170    || [ x$reason = xSTOP ]; then
    171   if [ x$alias_ip_address != x ]; then
    172     # Turn off alias interface.
    173     ifconfig $interface:0- 0.0.0.0
    174   fi
    175   if [ x$old_ip_address != x ]; then
    176     # Shut down interface, which will delete routes and clear arp cache.
    177     ifconfig $interface 0.0.0.0 down
    178   fi
    179   if [ x$alias_ip_address != x ]; then
    180     ifconfig $interface:0 $alias_ip_address $alias_subnet_arg
    181     route add -host $alias_ip_address $interface:0
    182   fi
    183   exit_with_hooks 0
    184 fi
    185 
    186 if [ x$reason = xTIMEOUT ]; then
    187   if [ x$alias_ip_address != x ]; then
    188     ifconfig $interface:0- 0.0.0.0
    189   fi
    190   ifconfig $interface $new_ip_address $new_subnet_arg \
    191 					$new_broadcast_arg $mtu_arg
    192   set $new_routers
    193   if ping -q -c 1 $1; then
    194     if [ x$new_ip_address != x$alias_ip_address ] && \
    195 			[ x$alias_ip_address != x ]; then
    196       ifconfig $interface:0 $alias_ip_address $alias_subnet_arg
    197       route add -host $alias_ip_address dev $interface:0
    198     fi
    199     for router in $new_routers; do
    200       if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
    201 	route add -host $router dev $interface
    202       fi
    203       route add default gw $router $metric_arg dev $interface
    204     done
    205     make_resolv_conf
    206     exit_with_hooks 0
    207   fi
    208   ifconfig $interface 0.0.0.0 down
    209   exit_with_hooks 1
    210 fi
    211 
    212 ###
    213 ### DHCPv6 Handlers
    214 ###
    215 
    216 if [ x$reason = xPREINIT6 ]; then
    217   # Ensure interface is up.
    218   ${ip} link set ${interface} up
    219 
    220   # Remove any stale addresses from aborted clients.
    221   ${ip} -f inet6 addr flush dev ${interface} scope global permanent
    222 
    223   exit_with_hooks 0
    224 fi
    225 
    226 if [ x${old_ip6_prefix} != x ] || [ x${new_ip6_prefix} != x ] ; then
    227     echo Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix}
    228 
    229     exit_with_hooks 0
    230 fi
    231 
    232 if [ x$reason = xBOUND6 ]; then
    233   if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
    234     exit_with_hooks 2;
    235   fi
    236 
    237   ${ip} -f inet6 addr add ${new_ip6_address}/${new_ip6_prefixlen} \
    238 	dev ${interface} scope global
    239 
    240   # Check for nameserver options.
    241   make_resolv_conf
    242 
    243   exit_with_hooks 0
    244 fi
    245 
    246 if [ x$reason = xRENEW6 ] || [ x$reason = xREBIND6 ]; then
    247   if [ x${new_ip6_address} != x ] && [ x${new_ip6_prefixlen} != x ] ; then
    248     ${ip} -f inet6 addr add ${new_ip6_address}/${new_ip6_prefixlen} \
    249 	   dev ${interface} scope global
    250   fi
    251 
    252   # Make sure nothing has moved around on us.
    253 
    254   # Nameservers/domains/etc.
    255   if [ "x${new_dhcp6_name_servers}" != "x${old_dhcp6_name_servers}" ] ||
    256      [ "x${new_dhcp6_domain_search}" != "x${old_dhcp6_domain_search}" ] ; then
    257     make_resolv_conf
    258   fi
    259 
    260   exit_with_hooks 0
    261 fi
    262 
    263 if [ x$reason = xDEPREF6 ]; then
    264   if [ x${new_ip6_prefixlen} = x ] ; then
    265     exit_with_hooks 2;
    266   fi
    267 
    268   ${ip} -f inet6 addr change ${new_ip6_address}/${new_ip6_prefixlen} \
    269 	dev ${interface} scope global preferred_lft 0
    270 
    271   exit_with_hooks 0
    272 fi
    273 
    274 if [ x$reason = xEXPIRE6 -o x$reason = xRELEASE6 -o x$reason = xSTOP6 ]; then
    275   if [ x${old_ip6_address} = x ] || [ x${old_ip6_prefixlen} = x ] ; then
    276     exit_with_hooks 2;
    277   fi
    278 
    279   ${ip} -f inet6 addr del ${old_ip6_address}/${old_ip6_prefixlen} \
    280 	dev ${interface}
    281 
    282   exit_with_hooks 0
    283 fi
    284 
    285 exit_with_hooks 0
    286