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