mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-23 02:17:31 +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.
319 lines
9.4 KiB
Bash
Executable File
319 lines
9.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# dhclient-script for Linux. Dan Halbert, March, 1997.
|
|
# Updated for Linux 2.[12] by Brian J. Murrell, January 1999.
|
|
# No guarantees about this. I'm a novice at the details of Linux
|
|
# networking.
|
|
|
|
# Notes:
|
|
|
|
# 0. This script is based on the netbsd script supplied with dhcp-970306.
|
|
|
|
# 1. ifconfig down apparently deletes all relevant routes and flushes
|
|
# the arp cache, so this doesn't need to be done explicitly.
|
|
|
|
# 2. The alias address handling here has not been tested AT ALL.
|
|
# I'm just going by the doc of modern Linux ip aliasing, which uses
|
|
# notations like eth0:0, eth0:1, for each alias.
|
|
|
|
# 3. I have to calculate the network address, and calculate the broadcast
|
|
# address if it is not supplied. This might be much more easily done
|
|
# by the dhclient C code, and passed on.
|
|
|
|
# 4. TIMEOUT not tested. ping has a flag I don't know, and I'm suspicious
|
|
# of the $1 in its args.
|
|
|
|
# 'ip' just looks too weird. /sbin/ip looks less weird.
|
|
ip=/sbin/ip
|
|
|
|
make_resolv_conf() {
|
|
if [ x"$new_domain_name_servers" != x ]; then
|
|
cat /dev/null > /etc/resolv.conf.dhclient
|
|
chmod 644 /etc/resolv.conf.dhclient
|
|
if [ x"$new_domain_search" != x ]; then
|
|
echo search $new_domain_search >> /etc/resolv.conf.dhclient
|
|
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
|
|
fi
|
|
for nameserver in $new_domain_name_servers; do
|
|
echo nameserver $nameserver >>/etc/resolv.conf.dhclient
|
|
done
|
|
|
|
mv /etc/resolv.conf.dhclient /etc/resolv.conf
|
|
elif [ "x${new_dhcp6_name_servers}" != x ] ; then
|
|
cat /dev/null > /etc/resolv.conf.dhclient6
|
|
chmod 644 /etc/resolv.conf.dhclient6
|
|
|
|
if [ "x${new_dhcp6_domain_search}" != x ] ; then
|
|
echo search ${new_dhcp6_domain_search} >> /etc/resolv.conf.dhclient6
|
|
fi
|
|
shopt -s nocasematch
|
|
for nameserver in ${new_dhcp6_name_servers} ; do
|
|
# If the nameserver has a link-local address
|
|
# add a <zone_id> (interface name) to it.
|
|
if [[ "$nameserver" =~ ^fe80:: ]]
|
|
then
|
|
zone_id="%$interface"
|
|
else
|
|
zone_id=
|
|
fi
|
|
echo nameserver ${nameserver}$zone_id >> /etc/resolv.conf.dhclient6
|
|
done
|
|
shopt -u nocasematch
|
|
|
|
mv /etc/resolv.conf.dhclient6 /etc/resolv.conf
|
|
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
|
|
|
|
###
|
|
### DHCPv4 Handlers
|
|
###
|
|
|
|
if [ x$new_broadcast_address != x ]; then
|
|
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_subnet_arg="netmask $new_subnet_mask"
|
|
fi
|
|
if [ x$old_subnet_mask != x ]; then
|
|
old_subnet_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
|
|
# Linux doesn't do mediums (ok, ok, media).
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ x$reason = xPREINIT ]; then
|
|
if [ x$alias_ip_address != x ]; then
|
|
# Bring down alias interface. Its routes will disappear too.
|
|
ifconfig $interface:0- inet 0
|
|
fi
|
|
ifconfig $interface 0 up
|
|
|
|
# We need to give the kernel some time to get the interface up.
|
|
sleep 1
|
|
|
|
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=`hostname`
|
|
if [ x$current_hostname = x ] || \
|
|
[ x$current_hostname = "x(none)" ] || \
|
|
[ x$current_hostname = xlocalhost ] || \
|
|
[ x$current_hostname = x$old_host_name ]; then
|
|
if [ x$new_host_name != x$old_host_name ]; then
|
|
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
|
|
# Possible new alias. Remove old alias.
|
|
ifconfig $interface:0- inet 0
|
|
fi
|
|
if [ x$old_ip_address != x ] && [ x$old_ip_address != x$new_ip_address ]; then
|
|
# IP address changed. Bringing down the interface will delete all routes,
|
|
# and clear the ARP cache.
|
|
ifconfig $interface inet 0 down
|
|
|
|
fi
|
|
if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \
|
|
[ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
|
|
|
|
ifconfig $interface inet $new_ip_address $new_subnet_arg \
|
|
$new_broadcast_arg $mtu_arg
|
|
# Add a network route to the computed network address.
|
|
for router in $new_routers; do
|
|
if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
|
|
route add -host $router dev $interface
|
|
fi
|
|
route add default gw $router $metric_arg dev $interface
|
|
done
|
|
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.
|
|
for router in $old_routers; do
|
|
route del default gw $router
|
|
done
|
|
for router in $new_routers; do
|
|
if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
|
|
route add -host $router dev $interface
|
|
fi
|
|
route add default gw $router $metric_arg dev $interface
|
|
done
|
|
fi
|
|
fi
|
|
if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
|
|
then
|
|
ifconfig $interface:0- inet 0
|
|
ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg
|
|
route add -host $alias_ip_address $interface:0
|
|
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
|
|
# Turn off alias interface.
|
|
ifconfig $interface:0- inet 0
|
|
fi
|
|
if [ x$old_ip_address != x ]; then
|
|
# Shut down interface, which will delete routes and clear arp cache.
|
|
ifconfig $interface inet 0 down
|
|
fi
|
|
if [ x$alias_ip_address != x ]; then
|
|
ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg
|
|
route add -host $alias_ip_address $interface:0
|
|
fi
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ x$reason = xTIMEOUT ]; then
|
|
if [ x$alias_ip_address != x ]; then
|
|
ifconfig $interface:0- inet 0
|
|
fi
|
|
ifconfig $interface inet $new_ip_address $new_subnet_arg \
|
|
$new_broadcast_arg $mtu_arg
|
|
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:0 inet $alias_ip_address $alias_subnet_arg
|
|
route add -host $alias_ip_address dev $interface:0
|
|
fi
|
|
for router in $new_routers; do
|
|
if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
|
|
route add -host $router dev $interface
|
|
fi
|
|
route add default gw $router $metric_arg dev $interface
|
|
done
|
|
make_resolv_conf
|
|
exit_with_hooks 0
|
|
fi
|
|
ifconfig $interface inet 0 down
|
|
exit_with_hooks 1
|
|
fi
|
|
|
|
###
|
|
### DHCPv6 Handlers
|
|
###
|
|
|
|
if [ x$reason = xPREINIT6 ] ; then
|
|
# Ensure interface is up.
|
|
${ip} link set ${interface} up
|
|
|
|
# Remove any stale addresses from aborted clients.
|
|
${ip} -f inet6 addr flush dev ${interface} scope global permanent
|
|
|
|
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 [ x$reason = xBOUND6 ] ; then
|
|
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
|
|
exit_with_hooks 2;
|
|
fi
|
|
|
|
${ip} -f inet6 addr add ${new_ip6_address}/${new_ip6_prefixlen} \
|
|
dev ${interface} scope global
|
|
|
|
# Check for nameserver options.
|
|
make_resolv_conf
|
|
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ x$reason = xRENEW6 ] || [ x$reason = xREBIND6 ] ; then
|
|
if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
|
|
exit_with_hooks 2;
|
|
fi
|
|
|
|
${ip} -f inet6 addr add ${new_ip6_address}/${new_ip6_prefixlen} \
|
|
dev ${interface} scope global
|
|
|
|
# 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 [ x$reason = xDEPREF6 ] ; then
|
|
if [ x${new_ip6_prefixlen} = x ] ; then
|
|
exit_with_hooks 2;
|
|
fi
|
|
|
|
${ip} -f inet6 addr change ${new_ip6_address}/${new_ip6_prefixlen} \
|
|
dev ${interface} scope global preferred_lft 0
|
|
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
if [ x$reason = xEXPIRE6 -o x$reason = xRELEASE6 -o x$reason = xSTOP6 ] ; then
|
|
if [ x${old_ip6_address} = x ] || [ x${old_ip6_prefixlen} = x ] ; then
|
|
exit_with_hooks 2;
|
|
fi
|
|
|
|
${ip} -f inet6 addr del ${old_ip6_address}/${old_ip6_prefixlen} \
|
|
dev ${interface}
|
|
|
|
exit_with_hooks 0
|
|
fi
|
|
|
|
exit_with_hooks 0
|