mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-29 05:17:57 +00:00
[ISC-Bugs #23045] Typos in client/scripts/openbsd [ISC-Bugs #23565] In the client scripts add a zone id (interface id) if the domain search address is link local. [ISC-Bugs #1277] In some of the client scripts add code to handle the case of the default router information being changed without the address being changed.
393 lines
12 KiB
Bash
Executable File
393 lines
12 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# $Id: freebsd,v 1.24 2011/05/18 19:55:44 sar Exp $
|
|
#
|
|
# $FreeBSD$
|
|
|
|
if [ -x /usr/bin/logger ]; then
|
|
LOGGER="/usr/bin/logger -s -p user.notice -t dhclient"
|
|
else
|
|
LOGGER=echo
|
|
fi
|
|
|
|
make_resolv_conf() {
|
|
if [ x"$new_domain_name_servers" != x ]; then
|
|
( cat /dev/null > /etc/resolv.conf.dhclient )
|
|
exit_status=$?
|
|
if [ $exit_status -ne 0 ]; then
|
|
$LOGGER "Unable to create /etc/resolv.conf.dhclient: Error $exit_status"
|
|
else
|
|
if [ "x$new_domain_search" != x ]; then
|
|
( echo search $new_domain_search >> /etc/resolv.conf.dhclient )
|
|
exit_status=$?
|
|
elif [ "x$new_domain_name" != x ]; then
|
|
# Note that the DHCP 'Domain Name Option' is really just a domain
|
|
# name, and that this practice of using the domain name option as
|
|
# a search path is both nonstandard and deprecated.
|
|
( echo search $new_domain_name >> /etc/resolv.conf.dhclient )
|
|
exit_status=$?
|
|
fi
|
|
for nameserver in $new_domain_name_servers; do
|
|
if [ $exit_status -ne 0 ]; then
|
|
break
|
|
fi
|
|
( echo nameserver $nameserver >>/etc/resolv.conf.dhclient )
|
|
exit_status=$?
|
|
done
|
|
|
|
# If there were no errors, attempt to mv the new file into place.
|
|
if [ $exit_status -eq 0 ]; then
|
|
( mv /etc/resolv.conf.dhclient /etc/resolv.conf )
|
|
exit_status=$?
|
|
fi
|
|
|
|
if [ $exit_status -ne 0 ]; then
|
|
$LOGGER "Error while writing new /etc/resolv.conf."
|
|
fi
|
|
fi
|
|
elif [ "x${new_dhcp6_name_servers}" != x ] ; then
|
|
( cat /dev/null > /etc/resolv.conf.dhclient6 )
|
|
exit_status=$?
|
|
if [ $exit_status -ne 0 ] ; then
|
|
$LOGGER "Unable to create /etc/resolv.conf.dhclient6: Error $exit_status"
|
|
else
|
|
if [ "x${new_dhcp6_domain_search}" != x ] ; then
|
|
( echo search ${new_dhcp6_domain_search} >> /etc/resolv.conf.dhclient6 )
|
|
exit_status=$?
|
|
fi
|
|
for nameserver in ${new_dhcp6_name_servers} ; do
|
|
if [ $exit_status -ne 0 ] ; then
|
|
break
|
|
fi
|
|
# If the nameserver has a link-local address
|
|
# add a <zone_id> (interface name) to it.
|
|
case $nameserver in
|
|
fe80:*) zone_id="%$interface";;
|
|
FE80:*) zone_id="%$interface";;
|
|
*) zone_id='';;
|
|
esac
|
|
( echo nameserver ${nameserver}$zone_id >> /etc/resolv.conf.dhclient6 )
|
|
exit_status=$?
|
|
done
|
|
|
|
if [ $exit_status -eq 0 ] ; then
|
|
( mv /etc/resolv.conf.dhclient6 /etc/resolv.conf )
|
|
exit_status=$?
|
|
fi
|
|
|
|
if [ $exit_status -ne 0 ] ; then
|
|
$LOGGER "Error while writing new /etc/resolv.conf."
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Must be used on exit. Invokes the local dhcp client exit hooks, if any.
|
|
exit_with_hooks() {
|
|
exit_status=$1
|
|
if [ -f /etc/dhclient-exit-hooks ]; then
|
|
. /etc/dhclient-exit-hooks
|
|
fi
|
|
# probably should do something with exit status of the local script
|
|
exit $exit_status
|
|
}
|
|
|
|
# Invoke the local dhcp client enter hooks, if they exist.
|
|
if [ -f /etc/dhclient-enter-hooks ]; then
|
|
exit_status=0
|
|
. /etc/dhclient-enter-hooks
|
|
# allow the local script to abort processing of this state
|
|
# local script must set exit_status variable to nonzero.
|
|
if [ $exit_status -ne 0 ]; then
|
|
exit $exit_status
|
|
fi
|
|
fi
|
|
|
|
if [ x$new_network_number != x ]; then
|
|
$LOGGER New Network Number: $new_network_number
|
|
fi
|
|
|
|
if [ x$new_broadcast_address != x ]; then
|
|
$LOGGER New Broadcast Address: $new_broadcast_address
|
|
new_broadcast_arg="broadcast $new_broadcast_address"
|
|
fi
|
|
if [ x$old_broadcast_address != x ]; then
|
|
old_broadcast_arg="broadcast $old_broadcast_address"
|
|
fi
|
|
if [ x$new_subnet_mask != x ]; then
|
|
new_netmask_arg="netmask $new_subnet_mask"
|
|
fi
|
|
if [ x$old_subnet_mask != x ]; then
|
|
old_netmask_arg="netmask $old_subnet_mask"
|
|
fi
|
|
if [ x$alias_subnet_mask != x ]; then
|
|
alias_subnet_arg="netmask $alias_subnet_mask"
|
|
fi
|
|
if [ x$new_interface_mtu != x ]; then
|
|
mtu_arg="mtu $new_interface_mtu"
|
|
fi
|
|
if [ x$IF_METRIC != x ]; then
|
|
metric_arg="metric $IF_METRIC"
|
|
fi
|
|
|
|
if [ x$reason = xMEDIUM ]; then
|
|
eval "ifconfig $interface $medium"
|
|
eval "ifconfig $interface inet -alias 0.0.0.0 $medium" >/dev/null 2>&1
|
|
sleep 1
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
###
|
|
### DHCPv4 Handlers
|
|
###
|
|
|
|
if [ x$reason = xPREINIT ]; then
|
|
if [ x$alias_ip_address != x ]; then
|
|
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
|
|
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
|
|
fi
|
|
ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 \
|
|
broadcast 255.255.255.255 up
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ x$reason = xARPCHECK ] || [ x$reason = xARPSEND ]; then
|
|
exit_with_hooks 0;
|
|
fi
|
|
|
|
if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
|
|
[ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then
|
|
current_hostname=`/bin/hostname`
|
|
if [ x$current_hostname = x ] || \
|
|
[ x$current_hostname = x$old_host_name ]; then
|
|
if [ x$current_hostname = x ] || \
|
|
[ x$new_host_name != x$old_host_name ]; then
|
|
$LOGGER "New Hostname: $new_host_name"
|
|
hostname $new_host_name
|
|
fi
|
|
fi
|
|
if [ x$old_ip_address != x ] && [ x$alias_ip_address != x ] && \
|
|
[ x$alias_ip_address != x$old_ip_address ]; then
|
|
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
|
|
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
|
|
fi
|
|
if [ x$old_ip_address != x ] && [ x$old_ip_address != x$new_ip_address ]
|
|
then
|
|
eval "ifconfig $interface inet -alias $old_ip_address $medium"
|
|
route delete $old_ip_address 127.1 >/dev/null 2>&1
|
|
for router in $old_routers; do
|
|
route delete default $router >/dev/null 2>&1
|
|
done
|
|
if [ -n "$old_static_routes" ]; then
|
|
set -- $old_static_routes
|
|
while [ $# -gt 1 ]; do
|
|
route delete $1 $2
|
|
shift; shift
|
|
done
|
|
fi
|
|
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -d \1/p' |sh
|
|
fi
|
|
if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \
|
|
[ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
|
|
eval "ifconfig $interface inet $new_ip_address $new_netmask_arg \
|
|
$new_broadcast_arg $mtu_arg $metric_arg $medium"
|
|
$LOGGER "New IP Address ($interface): $new_ip_address"
|
|
$LOGGER "New Subnet Mask ($interface): $new_subnet_mask"
|
|
$LOGGER "New Broadcast Address ($interface): $new_broadcast_address"
|
|
if [ -n "$new_routers" ]; then
|
|
$LOGGER "New Routers: $new_routers"
|
|
fi
|
|
route add $new_ip_address 127.1 >/dev/null 2>&1
|
|
for router in $new_routers; do
|
|
# If the subnet is captive, eg the netmask is /32 but the default
|
|
# gateway is (obviously) outside of this, then we need to produce a
|
|
# host route to reach the gateway.
|
|
if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
|
|
route add -host $router -interface $interface
|
|
fi
|
|
route add default $router >/dev/null 2>&1
|
|
done
|
|
if [ -n "$new_static_routes" ]; then
|
|
$LOGGER "New Static Routes: $new_static_routes"
|
|
set -- $new_static_routes
|
|
while [ $# -gt 1 ]; do
|
|
route add $1 $2
|
|
shift; shift
|
|
done
|
|
fi
|
|
else
|
|
# we haven't changed the address, have we changed other options
|
|
# that we wish to update?
|
|
if [ x$new_routers != x ] && [ x$new_routers != x$old_routers ] ; then
|
|
# if we've changed routers delete the old and add the new.
|
|
$LOGGER "New Routers: $new_routers"
|
|
for router in $old_routers; do
|
|
route delete default $router >/dev/null 2>&1
|
|
done
|
|
for router in $new_routers; do
|
|
# If the subnet is captive, eg the netmask is /32 but the default
|
|
# gateway is (obviously) outside of this, then we need to produce a
|
|
# host route to reach the gateway.
|
|
if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
|
|
route add -host $router -interface $interface
|
|
fi
|
|
route add default $router >/dev/null 2>&1
|
|
done
|
|
fi
|
|
fi
|
|
if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
|
|
then
|
|
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
|
|
route add $alias_ip_address 127.0.0.1
|
|
fi
|
|
make_resolv_conf
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
|
|
|| [ x$reason = xSTOP ]; then
|
|
if [ x$alias_ip_address != x ]; then
|
|
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
|
|
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
|
|
fi
|
|
if [ x$old_ip_address != x ]; then
|
|
eval "ifconfig $interface inet -alias $old_ip_address $medium"
|
|
route delete $old_ip_address 127.1 >/dev/null 2>&1
|
|
for router in $old_routers; do
|
|
route delete default $router >/dev/null 2>&1
|
|
done
|
|
if [ -n "$old_static_routes" ]; then
|
|
set -- $old_static_routes
|
|
while [ $# -gt 1 ]; do
|
|
route delete $1 $2
|
|
shift; shift
|
|
done
|
|
fi
|
|
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -d \1/p' \
|
|
|sh >/dev/null 2>&1
|
|
fi
|
|
if [ x$alias_ip_address != x ]; then
|
|
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
|
|
route add $alias_ip_address 127.0.0.1
|
|
fi
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ x$reason = xTIMEOUT ]; then
|
|
if [ x$alias_ip_address != x ]; then
|
|
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
|
|
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
|
|
fi
|
|
eval "ifconfig $interface inet $new_ip_address $new_netmask_arg \
|
|
$new_broadcast_arg $mtu_arg $metric_arg $medium"
|
|
$LOGGER "New IP Address ($interface): $new_ip_address"
|
|
$LOGGER "New Subnet Mask ($interface): $new_subnet_mask"
|
|
$LOGGER "New Broadcast Address ($interface): $new_broadcast_address"
|
|
sleep 1
|
|
if [ -n "$new_routers" ]; then
|
|
$LOGGER "New Routers: $new_routers"
|
|
set -- $new_routers
|
|
if ping -q -c 1 $1; then
|
|
if [ x$new_ip_address != x$alias_ip_address ] && \
|
|
[ x$alias_ip_address != x ]; then
|
|
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
|
|
route add $alias_ip_address 127.0.0.1
|
|
fi
|
|
route add $new_ip_address 127.1 >/dev/null 2>&1
|
|
for router in $new_routers; do
|
|
if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
|
|
route add -host $router -interface $interface
|
|
fi
|
|
route add default $router >/dev/null 2>&1
|
|
done
|
|
set -- $new_static_routes
|
|
while [ $# -gt 1 ]; do
|
|
route add $1 $2
|
|
shift; shift
|
|
done
|
|
make_resolv_conf
|
|
exit_with_hooks 0
|
|
fi
|
|
fi
|
|
eval "ifconfig $interface inet -alias $new_ip_address $medium"
|
|
for router in $old_routers; do
|
|
route delete default $router >/dev/null 2>&1
|
|
done
|
|
if [ -n "$old_static_routes" ]; then
|
|
set -- $old_static_routes
|
|
while [ $# -gt 1 ]; do
|
|
route delete $1 $2
|
|
shift; shift
|
|
done
|
|
fi
|
|
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -d \1/p' \
|
|
|sh >/dev/null 2>&1
|
|
exit_with_hooks 1
|
|
fi
|
|
|
|
###
|
|
### DHCPv6 Handlers
|
|
###
|
|
|
|
if [ ${reason} = PREINIT6 ] ; then
|
|
# Ensure interface is up.
|
|
ifconfig ${interface} up
|
|
|
|
# XXX: Remove any stale addresses from aborted clients.
|
|
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ x${old_ip6_prefix} != x ] || [ x${new_ip6_prefix} != x ] ; then
|
|
echo Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix}
|
|
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ ${reason} = BOUND6 ] ; then
|
|
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
|
|
exit_with_hooks 2;
|
|
fi
|
|
|
|
ifconfig ${interface} inet6 ${new_ip6_address}/${new_ip6_prefixlen} alias
|
|
|
|
# Check for nameserver options.
|
|
make_resolv_conf
|
|
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ ${reason} = RENEW6 ] || [ ${reason} = REBIND6 ] ; then
|
|
# Make sure nothing has moved around on us.
|
|
|
|
# Nameservers/domains/etc.
|
|
if [ "x${new_dhcp6_name_servers}" != "x${old_dhcp6_name_servers}" ] ||
|
|
[ "x${new_dhcp6_domain_search}" != "x${old_dhcp6_domain_search}" ] ; then
|
|
make_resolv_conf
|
|
fi
|
|
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ ${reason} = DEPREF6 ] ; then
|
|
if [ x${new_ip6_address} = x ] ; then
|
|
exit_with_hooks 2;
|
|
fi
|
|
|
|
ifconfig ${interface} inet6 ${new_ip6_address} deprecated
|
|
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ ${reason} = EXPIRE6 -o ${reason} = RELEASE6 -o ${reason} = STOP6 ] ; then
|
|
if [ x${old_ip6_address} = x ] || [ x${old_ip6_prefixlen} = x ] ; then
|
|
exit_with_hooks 2;
|
|
fi
|
|
|
|
ifconfig ${interface} inet6 ${old_ip6_address}/${old_ip6_prefixlen} -alias
|
|
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
exit_with_hooks 0
|