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