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