From 651018775c78e38045966825b920b641a0302b43 Mon Sep 17 00:00:00 2001 From: smos Date: Fri, 12 Oct 2012 12:20:43 +0200 Subject: Merge changes required for using the ISC dhclient in pfSense with prefix delegation. This should hopefully be a bit more reliable in the long run. The dhclient6-script could be merged with dhclient-script in the future. Still need to cleanup old adresses and prefixes, as well as LAN prefixes when a old prefix dissapears. This needs some thought and clue to strap together. --- sbin/dhclient6-script | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100755 sbin/dhclient6-script (limited to 'sbin') diff --git a/sbin/dhclient6-script b/sbin/dhclient6-script new file mode 100755 index 0000000..f0f2ffa --- /dev/null +++ b/sbin/dhclient6-script @@ -0,0 +1,244 @@ +#!/bin/sh +# $Id$ +# $OpenBSD: dhclient-script,v 1.6 2004/05/06 18:22:41 claudio Exp $ +# $FreeBSD: src/sbin/dhclient/dhclient-script,v 1.4 2005/06/10 03:41:18 brooks Exp $ +# +# Copyright (c) 2003 Kenneth R Westerback +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +NETSTAT=/usr/bin/netstat +GREP=/usr/bin/grep +AWK=/usr/bin/awk +HOSTNAME=/bin/hostname +GREP=/usr/bin/grep +ROUTE=/sbin/route +SED=/usr/bin/sed +ARP=/usr/sbin/arp +IFCONFIG=/sbin/ifconfig + +LOCALHOST=::1 + +if [ -x /usr/bin/logger ]; then + LOGGER="/usr/bin/logger -s -p user.notice -t dhclient6" +else + LOGGER=echo +fi + +# +# Helper functions that implement common actions. +# + +check_hostname() { + current_hostname=`$HOSTNAME` + if [ -z "$current_hostname" ]; then + $LOGGER "New Hostname ($interface): $new_host_name" + $HOSTNAME $new_host_name + elif [ "$current_hostname" = "$old_host_name" -a \ + "$new_host_name" != "$old_host_name" ]; then + $LOGGER "New Hostname ($interface): $new_host_name" + $HOSTNAME $new_host_name + fi +} + +delete_old_states() { + $LOGGER "Starting delete_old_states()" + # If the IP changed, remove states from the old one + if [ -f /var/db/${interface}_ipv6 ]; then + OLD_IPv6 = `cat /var/db/${interface}_ipv6` + $LOGGER "Comparing IPv6s: Old: ${OLD_IPv6} New: ${new_ip6_address}" + if [ -n "${OLD_IPv6}" ] && [ "${OLD_IPv6}" != "${new_ip6_address}" ]; then + $LOGGER "Removing states from old IPv6 '${OLD_IPv6}' (new IP '${new_ip6_address}')" + /sbin/pfctl -k :: -k ${OLD_IPv6}/128 + /sbin/pfctl -k ${OLD_IPv6}/128 + pfctl -K ${OLD_IPv6}/128 + fi + fi + # Delete states through old gateway if it's not the same + # FIXME: dhcp6 doesn't know about routers. Needs fixing elsewhere. +} + +delete_old_address() { + /bin/rm -f /var/db/${interface}_ipv6 + $IFCONFIG $interface inet6 -alias $old_ip6_address +} + +add_new_address() { + if [ -z $new_ip6_address ]; then + return; + fi + + $LOGGER "Starting add_new_address()" + $LOGGER "ifconfig $interface inet6 $new_ip6_address prefixlen $new_ip6_prefixlen" + $IFCONFIG $interface \ + inet6 $new_ip6_address \ + prefixlen $new_ip6_prefixlen + + $LOGGER "New IPv6 Address ($interface): $new_ip6_address" + $LOGGER "New Prefix Length ($interface): $new_ip6_prefixlen" + + echo $new_ip6_address > /var/db/${interface}_ipv6 +} + +add_new_prefix() { + if [ -z $new_ip6_prefix ]; then + return + fi + $LOGGER "Starting add_new_prefix()" + echo $new_ip6_prefix > /var/db/${interface}_pd_ipv6 +} + +delete_old_prefix() { + if [ -z $old_ip6_prefix ]; then + return + fi + $LOGGER "Starting delete_old_prefix()" + rm -f /var/db/${interface}_pd_ipv6 +} + +delete_old_alias() { + if [ -n "$alias_ip6_address" ]; then + $IFCONFIG $interface inet6 -alias $alias_ip6_address > /dev/null 2>&1 + $ROUTE delete -inet6 $alias_ip6_address $LOCALHOST > /dev/null 2>&1 + fi +} + +add_new_alias() { + if [ -n "$alias_ip6_address" ]; then + $IFCONFIG $interface inet6 alias $alias_ip6_address prefixlen $new_ip6_prefixlen + $ROUTE add -inet6 $alias_ip6_address $LOCALHOST + fi +} + +add_new_resolv_conf() { + $LOGGER "Creating resolv.conf" + if [ -f "/var/etc/nameserver_v6$interface" ]; then + # Remove old entries + for nameserver in `cat /var/etc/nameserver_v6$interface`; do + $ROUTE delete -inet6 $nameserver >/dev/null 2>&1 + done + fi + if [ -n "$new_dhcp6_name_servers" ]; then + /bin/rm -f /var/etc/nameserver_v6$interface + ALLOWOVERRIDE=`/usr/bin/grep dnsallowoverride /conf/config.xml | /usr/bin/wc -l` + for nameserver in $new_dhcp6_name_servers; do + # Add a route to the nameserver out the correct interface + # so that mulitple wans work correctly with multiple dns + # also backup the nameserver for later route removal + if [ $ALLOWOVERRIDE -gt 0 ]; then + echo $nameserver >>/var/etc/nameserver_v6$interface + $ROUTE add -inet6 $nameserver -iface $interface + fi + done + echo $new_dhcp6_domain_search >/var/etc/searchdomain_v6$interface + fi + + return 0 +} + +# Notify rc.newwanip of changes to an interface +notify_rc_newwanipv6() { + /etc/rc.newwanipv6 $interface + # /usr/local/sbin/pfSctl -c "interface newipv6 $interface" +} + +# +# Start of active code. +# + +# Invoke the local dhcp client enter hooks, if they exist. +if [ -f /etc/dhclient-enter-hooks ]; then + $LOGGER "dhclient-enter-hooks" + 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 + +$LOGGER $reason +case $reason in +PREINIT6) + delete_old_alias + delete_old_prefix + $IFCONFIG $interface inet6 up + delete_old_states + ;; + +BOUND6|RENEW6|REBIND6|REBOOT6) + + set + check_hostname + changes="no" + if [ "$old_ip6_address" != "$new_ip6_address" ]; then + delete_old_states + fi + if [ -n "$old_ip6_address" ]; then + if [ "$old_ip6_address" != "$alias_ip6_address" ]; then + delete_old_alias + changes="yes" + fi + fi + if [ "$old_ip6_prefix" != "$new_ip6_prefix" ]; then + delete_old_prefix + changes="yes" + fi + if [ "$reason" = BOUND6 ] || \ + [ "$reason" = REBOOT6 ] || \ + [ "$reason" = REBIND6 ] || \ + [ -z "$old_ip6_address" ] || \ + [ "$old_ip6_address" || "$new_ip6_address" ]; then + add_new_address + add_new_prefix + changes="yes" + fi + if [ -n "$alias_ip6_address" ] && \ + [ "$new_ip6_address" != "$alias_ip6_address" ]; then + add_new_alias + changes="yes" + fi + add_new_resolv_conf + if [ "$changes" = "yes" ] ; then + notify_rc_newwanipv6 + fi + ;; + +EXPIRE6|FAIL6) + delete_old_alias + delete_old_states + if [ -n "$old_ip6_address" ]; then + delete_old_address + fi + ;; + +TIMEOUT6) + delete_old_alias + add_new_address + /bin/sleep 1 + $IFCONFIG $interface inet6 -alias $new_ip6_address $medium + delete_old_states + ;; +esac + +# Invoke the local dhcp client exit hooks, if they exist. +if [ -f /etc/dhclient-exit-hooks ]; then + $LOGGER "dhclient-exit-hooks" + exit_status=0 + . /etc/dhclient-exit-hooks + # allow the local script to abort processing of this state + # local script must set exit_status variable to nonzero. + exit $exit_status +fi -- cgit v1.1