2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-24 19:08:08 +00:00
Thomas Markwalder 7d9dd30689 [master] Squashed commit of the following:
commit d911f58de00fd97f0e041cd12bd6b43804c32f4b
Author: Shawn Routhier <sar@isc.org>
Date:   Mon Jul 7 19:20:13 2014 -0700

    [rt36102] Add release note

commit 9dd4630b0653e7f7405a633e7f0163c163d3cb9a
Author: Thomas Markwalder <tmark@isc.org>
Date:   Mon Jul 7 09:11:35 2014 -0400

    [master] Patched client scripts for linux and openwrt

    36102 - Client scripts were not updatig resolv.conf when reason is
    RENEW6 or REBIND6 and mode is stateless.  Note this only affects
    the linux and openwrt scripts as only these two flush the interface
    of "stale" addresses in PREINIT6
2014-07-08 13:14:19 -04:00

317 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
${ip} -f inet6 addr add ${new_ip6_address}/${new_ip6_prefixlen} \
dev ${interface} scope global
fi
# 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