diff --git a/config/rootfiles/common/dhcp b/config/rootfiles/common/dhcp
index a165ca81a..c2f5aed05 100644
--- a/config/rootfiles/common/dhcp
+++ b/config/rootfiles/common/dhcp
@@ -1,38 +1,39 @@
+#etc/dhclient.conf
etc/dhcpd.conf
-#sbin/dhclient
-#sbin/dhclient-script
#usr/bin/omshell
-#usr/include/dhcpctl.h
+#usr/include/dhcpctl
+#usr/include/dhcpctl/dhcpctl.h
#usr/include/isc-dhcp
-#usr/include/isc-dhcp/boolean.h
#usr/include/isc-dhcp/dst.h
-#usr/include/isc-dhcp/int.h
-#usr/include/isc-dhcp/lang.h
-#usr/include/isc-dhcp/list.h
-#usr/include/isc-dhcp/result.h
-#usr/include/isc-dhcp/types.h
#usr/include/omapip
#usr/include/omapip/alloc.h
#usr/include/omapip/buffer.h
+#usr/include/omapip/convert.h
+#usr/include/omapip/hash.h
+#usr/include/omapip/isclib.h
#usr/include/omapip/omapip.h
+#usr/include/omapip/omapip_p.h
+#usr/include/omapip/result.h
+#usr/include/omapip/trace.h
#usr/lib/libdhcpctl.a
+#usr/lib/libdst.a
#usr/lib/libomapi.a
-#usr/man/man1/omshell.1
-#usr/man/man3/dhcpctl.3
-#usr/man/man3/omapi.3
-#usr/man/man3/omshell.3
-#usr/man/man5/dhclient.conf.5
-#usr/man/man5/dhclient.leases.5
-#usr/man/man5/dhcp-eval.5
-#usr/man/man5/dhcp-options.5
-#usr/man/man5/dhcpd.conf.5
-#usr/man/man5/dhcpd.leases.5
-#usr/man/man8/dhclient-script.8
-#usr/man/man8/dhclient.8
-#usr/man/man8/dhcpd.8
-#usr/man/man8/dhcrelay.8
+#usr/sbin/dhclient
usr/sbin/dhcpd
#usr/sbin/dhcrelay
+#usr/share/man/man1/omshell.1
+#usr/share/man/man3/dhcpctl.3
+#usr/share/man/man3/omapi.3
+#usr/share/man/man5/dhclient.conf.5
+#usr/share/man/man5/dhclient.leases.5
+#usr/share/man/man5/dhcp-eval.5
+#usr/share/man/man5/dhcp-options.5
+#usr/share/man/man5/dhcpd.conf.5
+#usr/share/man/man5/dhcpd.leases.5
+#usr/share/man/man8/dhclient-script.8
+#usr/share/man/man8/dhclient.8
+#usr/share/man/man8/dhcpd.8
+#usr/share/man/man8/dhcrelay.8
#var/state
#var/state/dhcp
var/state/dhcp/dhcpd.leases
diff --git a/config/rootfiles/common/inetutils b/config/rootfiles/common/inetutils
index 426e3757e..3cea63cb3 100644
--- a/config/rootfiles/common/inetutils
+++ b/config/rootfiles/common/inetutils
@@ -4,7 +4,6 @@ bin/ping
#usr/bin/rlogin
#usr/bin/rsh
#usr/bin/talk
-#usr/bin/telnet
#usr/bin/tftp
usr/bin/whois
#usr/sbin/ftpd
@@ -13,7 +12,6 @@ usr/bin/whois
#usr/sbin/rlogind
#usr/sbin/rshd
#usr/sbin/talkd
-#usr/sbin/telnetd
#usr/sbin/tftpd
#usr/sbin/uucpd
#usr/share/info/inetutils.info
diff --git a/config/rootfiles/packages/telnet b/config/rootfiles/packages/telnet
new file mode 100644
index 000000000..75b8d777d
--- /dev/null
+++ b/config/rootfiles/packages/telnet
@@ -0,0 +1,4 @@
+usr/bin/telnet
+#usr/man/man1/telnet.1
+#usr/man/man5/issue.net.5
+#usr/sbin/in.telnetd
diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi
index f91adf1f4..990fe6600 100644
--- a/html/cgi-bin/ovpnmain.cgi
+++ b/html/cgi-bin/ovpnmain.cgi
@@ -356,14 +356,11 @@ sub writeserverconf {
if ($sovpnsettings{CLIENT2CLIENT} eq 'on') {
print CONF "client-to-client\n";
}
- if ($sovpnsettings{'DPROTOCOL'} eq 'udp') {
- if ($sovpnsettings{MSSFIX} eq 'on') {
- print CONF "mssfix\n";
- }
- if ($sovpnsettings{'FRAGMENT'} eq '' || $sovpnsettings{'FRAGMENT'} eq 0) {
- $sovpnsettings{'FRAGMENT'} = '1300';
- }
- print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
+ if ($sovpnsettings{MSSFIX} eq 'on') {
+ print CONF "mssfix\n";
+ }
+ if ($sovpnsettings{FRAGMENT} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
+ print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
}
if ($sovpnsettings{KEEPALIVE_1} > 0 && $sovpnsettings{KEEPALIVE_2} > 0) {
print CONF "keepalive $sovpnsettings{'KEEPALIVE_1'} $sovpnsettings{'KEEPALIVE_2'}\n";
@@ -532,7 +529,7 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) {
}
}
if ($cgiparams{'MSSFIX'} ne 'on') {
- $vpnsettings{'MSSFIX'} = 'off';
+ delete $vpnsettings{'MSSFIX'};
} else {
$vpnsettings{'MSSFIX'} = $cgiparams{'MSSFIX'};
}
@@ -1906,12 +1903,6 @@ ADV_ERROR:
if ($cgiparams{'LOG_VERB'} eq '') {
$cgiparams{'LOG_VERB'} = '3';
}
- if ($cgiparams{'MSSFIX'} eq '') {
- $cgiparams{'MSSFIX'} = 'on';
- }
- if ($cgiparams{'FRAGMENT'} eq '') {
- $cgiparams{'FRAGMENT'} = '1300';
- }
$checked{'CLIENT2CLIENT'}{'off'} = '';
$checked{'CLIENT2CLIENT'}{'on'} = '';
$checked{'CLIENT2CLIENT'}{$cgiparams{'CLIENT2CLIENT'}} = 'CHECKED';
diff --git a/lfs/dhcp b/lfs/dhcp
index 235e82596..317eef4ed 100644
--- a/lfs/dhcp
+++ b/lfs/dhcp
@@ -24,7 +24,7 @@
include Config
-VER = 3.1-ESV-R3
+VER = 4.2.2
THISAPP = dhcp-$(VER)
DL_FILE = $(THISAPP).tar.gz
@@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = af3d8db60f62664f1d5538b81e406459
+$(DL_FILE)_MD5 = bb0f0434cd796f76aa7cead391d71f31
install : $(TARGET)
@@ -70,11 +70,63 @@ $(subst %,%_MD5,$(objects)) :
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
@$(PREBUILD)
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
+
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-3.1_linux3.patch
- cd $(DIR_APP) && ./configure
+
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.2-remove-bind.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-errwarn-message.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.2-options.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-release-by-ifup.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-dhclient-decline-backoff.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-unicast-bootp.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.2-dhclient-usage.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-default-requested-options.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.2-xen-checksum.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.1-manpages.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-paths.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.2-CLOEXEC.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-inherit-leases.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-garbage-chars.patch
+ # ???
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-missing-ipv6-not-fatal.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-add_timeout_when_NULL.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.1-64_bit_lease_parse.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.2-capability.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-logpid.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-UseMulticast.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.1-sendDecline.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.1-retransmission.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.2-rfc3442-classless-static-routes.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-honor-expired.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-noprefixavail.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.2-sharedlib.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.0-PPP.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.2-lpf-ib.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.2-improved-xid.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.2-gpxe-cid.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dhcp-4.2.1-invalid-dhclient-conf.patch
+
+ # Remove bundled BIND stuff.
+ # (requires newer autoconf)
+ #rm -rfv $(DIR_APP)/bind/bind.tar.gz
+ #cd $(DIR_APP) && autoreconf --verbose --force --install
+
+ cd $(DIR_APP) && \
+ ./configure \
+ --prefix=/usr \
+ --sysconfdir=/etc \
+ --with-srv-lease-file=/var/state/dhcp/dhcpd.leases \
+ --disable-static \
+ --enable-paranoia \
+ --enable-early-chroot \
+ --disable-dhcpv6
+
cd $(DIR_APP) && make $(MAKETUNING)
- cd $(DIR_APP) && make LIBDIR=/usr/lib INCDIR=/usr/include install
+ cd $(DIR_APP) && make install
+
+ mkdir -pv /var/state/dhcp
touch /var/state/dhcp/dhcpd.leases
+
ln -sf $(CONFIG_ROOT)/dhcp/dhcpd.conf /etc/dhcpd.conf
@rm -rf $(DIR_APP)
@$(POSTBUILD)
diff --git a/lfs/fireinfo b/lfs/fireinfo
index f7fbbc44a..c2e723893 100644
--- a/lfs/fireinfo
+++ b/lfs/fireinfo
@@ -24,7 +24,7 @@
include Config
-VER = 2.1.5
+VER = 2.1.6
THISAPP = fireinfo-v$(VER)
DL_FILE = $(THISAPP).tar.gz
@@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 7f5350212b6aff44cb361fcabdf991e0
+$(DL_FILE)_MD5 = ff8eb520af49c0bf00722aac167070cd
install : $(TARGET)
diff --git a/lfs/fping b/lfs/fping
index 3b7b97c35..641868644 100644
--- a/lfs/fping
+++ b/lfs/fping
@@ -24,7 +24,7 @@
include Config
-VER = 3.1
+VER = 3.4
THISAPP = fping-$(VER)
DL_FILE = $(THISAPP).tar.gz
@@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE)
DIR_APP = $(DIR_SRC)/$(THISAPP)
TARGET = $(DIR_INFO)/$(THISAPP)
PROG = fping
-PAK_VER = 1
+PAK_VER = 2
DEPS = ""
@@ -44,7 +44,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = a2bbf3316da8c7b47a1a0ffe959d5d9e
+$(DL_FILE)_MD5 = a4bc97804e630dbf26dfac8f28c78091
install : $(TARGET)
diff --git a/lfs/inetutils b/lfs/inetutils
index 87a137eb1..468c2af32 100644
--- a/lfs/inetutils
+++ b/lfs/inetutils
@@ -76,7 +76,7 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
cd $(DIR_APP) && ./configure --prefix=/usr --libexecdir=/usr/sbin \
--sysconfdir=/etc --localstatedir=/var \
--mandir=/usr/share/man --infodir=/usr/share/info \
- --disable-logger --disable-syslogd
+ --disable-logger --disable-syslogd --disable-telnet --disable-telnetd
cd $(DIR_APP) && make $(MAKETUNING)
cd $(DIR_APP) && make install
mv -v /usr/bin/ping /bin
diff --git a/lfs/minidlna b/lfs/minidlna
index 47fe270bd..26ec3dd00 100644
--- a/lfs/minidlna
+++ b/lfs/minidlna
@@ -32,9 +32,9 @@ DL_FROM = $(URL_IPFIRE)
DIR_APP = $(DIR_SRC)/$(THISAPP)
TARGET = $(DIR_INFO)/$(THISAPP)
PROG = minidlna
-PAK_VER = 1
+PAK_VER = 2
-DEPS = "ffmpeg flac libexif libid3tag libogg"
+DEPS = "ffmpeg flac libexif libid3tag libogg sqlite"
###############################################################################
# Top-level Rules
diff --git a/lfs/telnet b/lfs/telnet
new file mode 100644
index 000000000..a43bebab3
--- /dev/null
+++ b/lfs/telnet
@@ -0,0 +1,106 @@
+###############################################################################
+# #
+# IPFire.org - A linux based firewall #
+# Copyright (C) 2007 Michael Tremer & Christian Schmidt #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see . #
+# #
+###############################################################################
+
+###############################################################################
+# Definitions
+###############################################################################
+
+include Config
+
+VER = 0.17
+THISAPP = netkit-telnet-$(VER)
+DL_FILE = $(THISAPP).tar.gz
+DL_FROM = $(URL_IPFIRE)
+DIR_APP = $(DIR_SRC)/$(THISAPP)
+TARGET = $(DIR_INFO)/$(THISAPP)
+PROG = telnet
+PAK_VER = 1
+
+DEPS = ""
+
+###############################################################################
+# Top-level Rules
+###############################################################################
+
+objects = $(DL_FILE) \
+ telnet-client.tar.gz
+
+$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
+telnet-client.tar.gz = $(DL_FROM)/telnet-client.tar.gz
+
+$(DL_FILE)_MD5 = d6beabaaf53fe6e382c42ce3faa05a36
+telnet-client.tar.gz_MD5 = d74983062470c5a3e7ae14f34c489e00
+
+install : $(TARGET)
+
+check : $(patsubst %,$(DIR_CHK)/%,$(objects))
+
+download :$(patsubst %,$(DIR_DL)/%,$(objects))
+
+md5 : $(subst %,%_MD5,$(objects))
+
+dist:
+ @$(PAK)
+
+###############################################################################
+# Downloading, checking, md5sum
+###############################################################################
+
+$(patsubst %,$(DIR_CHK)/%,$(objects)) :
+ @$(CHECK)
+
+$(patsubst %,$(DIR_DL)/%,$(objects)) :
+ @$(LOAD)
+
+$(subst %,%_MD5,$(objects)) :
+ @$(MD5)
+
+###############################################################################
+# Installation Details
+###############################################################################
+
+$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
+ @$(PREBUILD)
+ @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
+ cd ${DIR_APP} && mv telnet telnet-netkit
+ cd ${DIR_APP} && tar zxf $(DIR_DL)/telnet-client.tar.gz
+ cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/telnet-client-cvs.patch0
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-env.patch
+ cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/telnet-0.17-pek.patch0
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-issue.patch
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-sa-01-49.patch
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-8bit.patch
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-argv.patch
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-conf.patch
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-cleanup_race.patch
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-CAN-2005-468_469.patch
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-gethostbyname.patch
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/netkit-telnet-0.17-ipv6.diff
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/netkit-telnet-0.17-nodns.patch
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/telnet-0.17-errno_test_sys_bsd.patch
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/netkit-telnet-0.17-reallynodns.patch
+ cd $(DIR_APP) && ./configure --prefix=/usr
+ cd $(DIR_APP) && make
+ cd $(DIR_APP) && make install
+ rm -f /usr/sbin/telnetd
+ rm -f /usr/man/man8/in.telnetd.8
+ rm -f /usr/man/man8/telnetd.8
+ @rm -rf $(DIR_APP)
+ @$(POSTBUILD)
diff --git a/make.sh b/make.sh
index 1e08be6d3..0e0192c80 100755
--- a/make.sh
+++ b/make.sh
@@ -362,6 +362,7 @@ buildipfire() {
export LOGFILE
ipfiremake configroot
ipfiremake backup
+ ipfiremake bind
ipfiremake dhcp
ipfiremake dhcpcd
ipfiremake libusb
@@ -504,7 +505,6 @@ buildipfire() {
ipfiremake apache2 PASS=C
ipfiremake arping
ipfiremake beep
- ipfiremake bind
ipfiremake dvdrtools
ipfiremake dnsmasq
ipfiremake dosfstools
@@ -760,6 +760,7 @@ buildipfire() {
ipfiremake minidlna
ipfiremake acpid
ipfiremake fping
+ ipfiremake telnet
echo Build on $HOSTNAME > $BASEDIR/build/var/ipfire/firebuild
cat /proc/version >> $BASEDIR/build/var/ipfire/firebuild
echo >> $BASEDIR/build/var/ipfire/firebuild
diff --git a/src/initscripts/init.d/network-vlans b/src/initscripts/init.d/network-vlans
index 88733e6c3..2fdfe9ebb 100755
--- a/src/initscripts/init.d/network-vlans
+++ b/src/initscripts/init.d/network-vlans
@@ -26,7 +26,7 @@ CONFIG_FILE="/var/ipfire/ethernet/vlans"
# Skip immediately if no configuration file has been found.
[ -e "${CONFIG_FILE}" ] || exit 0
-eval $(readhash ${CONFIG_FILE})
+eval $(/usr/local/bin/readhash ${CONFIG_FILE})
# This is start or stop.
action=${1}
@@ -52,21 +52,26 @@ for interface in green0 blue0 orange0; do
case "${action}" in
start)
+ # If no parent device has been configured, we assume
+ # that this interface is not set up for VLANs and
+ # silently go on.
+ [ -z "${PARENT_DEV}" ] && continue
+
# Check if the interface does already exists.
# If so, we skip creating it.
if [ -d "/sys/class/net/${interface}" ]; then
- echo "Interface ${interface} already exists."
+ echo "Interface ${interface} already exists." >&2
continue
fi
# Check if the parent interface exists.
- if [ -z "${PARENT_DEV}" ] || [ ! -d "/sys/class/net/${PARENT_DEV}" ]; then
- echo "${interface}: Parent device is not set or does not exist: ${PARENT_DEV}"
+ if [ ! -d "/sys/class/net/${PARENT_DEV}" ]; then
+ echo "${interface}: Parent device is not set or does not exist: ${PARENT_DEV}" >&2
continue
fi
if [ -z "${VLAN_ID}" ]; then
- echo "${interface}: You did not set the VLAN ID."
+ echo "${interface}: You did not set the VLAN ID." >&2
continue
fi
diff --git a/src/patches/dhcp-4.2.0-PPP.patch b/src/patches/dhcp-4.2.0-PPP.patch
new file mode 100644
index 000000000..bef2be7f0
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-PPP.patch
@@ -0,0 +1,150 @@
+diff -up dhcp-4.2.0-P1/client/dhc6.c.PPP dhcp-4.2.0-P1/client/dhc6.c
+--- dhcp-4.2.0-P1/client/dhc6.c.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/client/dhc6.c 2010-11-09 15:54:12.000000000 +0100
+@@ -129,7 +129,7 @@ extern int stateless;
+ * is not how it is intended. Upcoming rearchitecting the client should
+ * address this "one daemon model."
+ */
+-void
++isc_result_t
+ form_duid(struct data_string *duid, const char *file, int line)
+ {
+ struct interface_info *ip;
+@@ -141,6 +141,15 @@ form_duid(struct data_string *duid, cons
+ if (ip == NULL)
+ log_fatal("Impossible condition at %s:%d.", MDL);
+
++ while (ip && ip->hw_address.hbuf[0] == HTYPE_RESERVED) {
++ /* Try the other interfaces */
++ log_debug("Cannot form default DUID from interface %s.", ip->name);
++ ip = ip->next;
++ }
++ if (ip == NULL) {
++ return ISC_R_UNEXPECTED;
++ }
++
+ if ((ip->hw_address.hlen == 0) ||
+ (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
+ log_fatal("Impossible hardware address length at %s:%d.", MDL);
+@@ -176,6 +185,8 @@ form_duid(struct data_string *duid, cons
+ memcpy(duid->buffer->data + 4, ip->hw_address.hbuf + 1,
+ ip->hw_address.hlen - 1);
+ }
++
++ return ISC_R_SUCCESS;
+ }
+
+ /*
+@@ -5289,7 +5300,8 @@ make_client6_options(struct client_state
+ */
+ if ((oc = lookup_option(&dhcpv6_universe, *op,
+ D6O_CLIENTID)) == NULL) {
+- if (!option_cache(&oc, &default_duid, NULL, clientid_option,
++ if (default_duid.len == 0 ||
++ !option_cache(&oc, &default_duid, NULL, clientid_option,
+ MDL))
+ log_fatal("Failure assembling a DUID.");
+
+diff -up dhcp-4.2.0-P1/client/dhclient.c.PPP dhcp-4.2.0-P1/client/dhclient.c
+--- dhcp-4.2.0-P1/client/dhclient.c.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/client/dhclient.c 2010-11-09 15:37:26.000000000 +0100
+@@ -911,8 +911,8 @@ main(int argc, char **argv) {
+ if (default_duid.buffer != NULL)
+ data_string_forget(&default_duid, MDL);
+
+- form_duid(&default_duid, MDL);
+- write_duid(&default_duid);
++ if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS)
++ write_duid(&default_duid);
+ }
+
+ for (ip = interfaces ; ip != NULL ; ip = ip->next) {
+diff -up dhcp-4.2.0-P1/common/bpf.c.PPP dhcp-4.2.0-P1/common/bpf.c
+--- dhcp-4.2.0-P1/common/bpf.c.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/common/bpf.c 2010-11-09 15:42:42.000000000 +0100
+@@ -599,6 +599,22 @@ get_hw_addr(const char *name, struct har
+ memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
+ break;
+ #endif /* IFT_FDDI */
++#if defined(IFT_PPP)
++ case IFT_PPP:
++ if (local_family != AF_INET6)
++ log_fatal("Unsupported device type %d for \"%s\"",
++ sa->sdl_type, name);
++ hw->hlen = 0;
++ hw->hbuf[0] = HTYPE_RESERVED;
++ /* 0xdeadbeef should never occur on the wire,
++ * and is a signature that something went wrong.
++ */
++ hw->hbuf[1] = 0xde;
++ hw->hbuf[2] = 0xad;
++ hw->hbuf[3] = 0xbe;
++ hw->hbuf[4] = 0xef;
++ break;
++#endif
+ default:
+ log_fatal("Unsupported device type %d for \"%s\"",
+ sa->sdl_type, name);
+diff -up dhcp-4.2.0-P1/common/lpf.c.PPP dhcp-4.2.0-P1/common/lpf.c
+--- dhcp-4.2.0-P1/common/lpf.c.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/common/lpf.c 2010-11-09 15:45:40.000000000 +0100
+@@ -502,6 +502,22 @@ get_hw_addr(const char *name, struct har
+ hw->hbuf[0] = HTYPE_FDDI;
+ memcpy(&hw->hbuf[1], sa->sa_data, 16);
+ break;
++#if defined(ARPHRD_PPP)
++ case ARPHRD_PPP:
++ if (local_family != AF_INET6)
++ log_fatal("Unsupported device type %d for \"%s\"",
++ sa->sa_family, name);
++ hw->hlen = 0;
++ hw->hbuf[0] = HTYPE_RESERVED;
++ /* 0xdeadbeef should never occur on the wire,
++ * and is a signature that something went wrong.
++ */
++ hw->hbuf[1] = 0xde;
++ hw->hbuf[2] = 0xad;
++ hw->hbuf[3] = 0xbe;
++ hw->hbuf[4] = 0xef;
++ break;
++#endif
+ default:
+ log_fatal("Unsupported device type %ld for \"%s\"",
+ (long int)sa->sa_family, name);
+diff -up dhcp-4.2.0-P1/includes/dhcpd.h.PPP dhcp-4.2.0-P1/includes/dhcpd.h
+--- dhcp-4.2.0-P1/includes/dhcpd.h.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/includes/dhcpd.h 2010-11-09 15:46:58.000000000 +0100
+@@ -2733,7 +2733,7 @@ void dhcpv4_client_assignments(void);
+ void dhcpv6_client_assignments(void);
+
+ /* dhc6.c */
+-void form_duid(struct data_string *duid, const char *file, int line);
++isc_result_t form_duid(struct data_string *duid, const char *file, int line);
+ void dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line);
+ void start_init6(struct client_state *client);
+ void start_info_request6(struct client_state *client);
+diff -up dhcp-4.2.0-P1/includes/dhcp.h.PPP dhcp-4.2.0-P1/includes/dhcp.h
+--- dhcp-4.2.0-P1/includes/dhcp.h.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/includes/dhcp.h 2010-11-09 15:48:53.000000000 +0100
+@@ -80,6 +80,8 @@ struct dhcp_packet {
+ #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
+ #define HTYPE_FDDI 8 /* FDDI... */
+
++#define HTYPE_RESERVED 0 /* RFC 5494 */
++
+ /* Magic cookie validating dhcp options field (and bootp vendor
+ extensions field). */
+ #define DHCP_OPTIONS_COOKIE "\143\202\123\143"
+diff -up dhcp-4.2.0-P1/server/dhcpv6.c.PPP dhcp-4.2.0-P1/server/dhcpv6.c
+--- dhcp-4.2.0-P1/server/dhcpv6.c.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/server/dhcpv6.c 2010-11-09 15:50:17.000000000 +0100
+@@ -300,6 +300,9 @@ generate_new_server_duid(void) {
+ if (p->hw_address.hlen > 0) {
+ break;
+ }
++ if (p->next == NULL && p->hw_address.hbuf[0] == HTYPE_RESERVED) {
++ log_error("Can not generate DUID from interfaces which do not have hardware addresses, please configure server-duid!");
++ }
+ }
+ if (p == NULL) {
+ return ISC_R_UNEXPECTED;
diff --git a/src/patches/dhcp-4.2.0-UseMulticast.patch b/src/patches/dhcp-4.2.0-UseMulticast.patch
new file mode 100644
index 000000000..319344aa5
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-UseMulticast.patch
@@ -0,0 +1,229 @@
+diff -up dhcp-4.2.0/server/dhcpv6.c.UseMulticast dhcp-4.2.0/server/dhcpv6.c
+--- dhcp-4.2.0/server/dhcpv6.c.UseMulticast 2010-06-01 19:30:00.000000000 +0200
++++ dhcp-4.2.0/server/dhcpv6.c 2010-07-21 16:17:30.000000000 +0200
+@@ -346,6 +346,48 @@ generate_new_server_duid(void) {
+ }
+
+ /*
++ * Is the D6O_UNICAST option defined in dhcpd.conf ?
++ */
++static isc_boolean_t unicast_option_defined;
++
++/*
++ * Did we already search dhcpd.conf for D6O_UNICAST option ?
++ * We need to store it here to not parse dhcpd.conf repeatedly.
++ */
++static isc_boolean_t unicast_option_parsed = ISC_FALSE;
++
++
++/*
++ * Is the D6O_UNICAST option defined in dhcpd.conf ?
++ */
++isc_boolean_t
++is_unicast_option_defined(void) {
++ struct option_state *opt_state;
++ struct option_cache *oc;
++
++ /*
++ * If we are looking for the unicast option for the first time
++ */
++ if (unicast_option_parsed == ISC_FALSE) {
++ unicast_option_parsed = ISC_TRUE;
++ opt_state = NULL;
++ if (!option_state_allocate(&opt_state, MDL)) {
++ log_fatal("No memory for option state.");
++ }
++
++ execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
++ opt_state, &global_scope, root_group, NULL);
++
++ oc = lookup_option(&dhcpv6_universe, opt_state, D6O_UNICAST);
++ unicast_option_defined = (oc != NULL);
++
++ option_state_dereference(&opt_state, MDL);
++ }
++
++ return (unicast_option_defined);
++}
++
++/*
+ * Get the client identifier from the packet.
+ */
+ isc_result_t
+@@ -1405,6 +1447,56 @@ lease_to_client(struct data_string *repl
+ reply.shared->group);
+ }
+
++ /* reject unicast message, unless we set unicast option */
++ if ((packet->unicast == ISC_TRUE) && !is_unicast_option_defined())
++ /*
++ * RFC3315 section 18.2.1 (Request):
++ *
++ * When the server receives a Request message via unicast from a client
++ * to which the server has not sent a unicast option, the server
++ * discards the Request message and responds with a Reply message
++ * containing a Status Code option with the value UseMulticast, a Server
++ * Identifier option containing the server's DUID, the Client Identifier
++ * option from the client message, and no other options.
++ *
++ * Section 18.2.3 (Renew):
++ *
++ * When the server receives a Renew message via unicast from a client to
++ * which the server has not sent a unicast option, the server discards
++ * the Renew message and responds with a Reply message containing a
++ * Status Code option with the value UseMulticast, a Server Identifier
++ * option containing the server's DUID, the Client Identifier option
++ * from the client message, and no other options.
++ */
++ {
++ /* Set the UseMulticast status code. */
++ if (!set_status_code(STATUS_UseMulticast,
++ "Unicast not allowed by server.",
++ reply.opt_state)) {
++ log_error("lease_to_client: Unable to set "
++ "UseMulticast status code.");
++ goto exit;
++ }
++
++ /* Rewind the cursor to the start. */
++ reply.cursor = REPLY_OPTIONS_INDEX;
++
++ /*
++ * Produce an reply that includes only:
++ *
++ * Status code.
++ * Server DUID.
++ * Client DUID.
++ */
++ reply.cursor += store_options6((char *)reply.buf.data +
++ reply.cursor,
++ sizeof(reply.buf) -
++ reply.cursor,
++ reply.opt_state, reply.packet,
++ required_opts_NAA,
++ NULL);
++ } else if (no_resources_avail && (reply.ia_count != 0) &&
++ (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT))
+ /*
+ * RFC3315 section 17.2.2 (Solicit):
+ *
+@@ -1429,8 +1521,6 @@ lease_to_client(struct data_string *repl
+ * the server.
+ * Sends a Renew/Rebind if the IA is not in the Reply message.
+ */
+- if (no_resources_avail && (reply.ia_count != 0) &&
+- (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT))
+ {
+ /* Set the NoAddrsAvail status code. */
+ if (!set_status_code(STATUS_NoAddrsAvail,
+@@ -4128,7 +4218,6 @@ dhcpv6_solicit(struct data_string *reply
+ * Very similar to Solicit handling, except the server DUID is required.
+ */
+
+-/* TODO: reject unicast messages, unless we set unicast option */
+ static void
+ dhcpv6_request(struct data_string *reply_ret, struct packet *packet) {
+ struct data_string client_id;
+@@ -4443,7 +4532,6 @@ exit:
+ * except for the error code of when addresses don't match.
+ */
+
+-/* TODO: reject unicast messages, unless we set unicast option */
+ static void
+ dhcpv6_renew(struct data_string *reply, struct packet *packet) {
+ struct data_string client_id;
+@@ -4688,18 +4776,60 @@ iterate_over_ia_na(struct data_string *r
+ goto exit;
+ }
+
+- snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
+- if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
+- goto exit;
+- }
++ /* reject unicast message, unless we set unicast option */
++ if ((packet->unicast == ISC_TRUE) && !is_unicast_option_defined()) {
++ /*
++ * RFC3315 section 18.2.6 (Release):
++ *
++ * When the server receives a Release message via unicast from a client
++ * to which the server has not sent a unicast option, the server
++ * discards the Release message and responds with a Reply message
++ * containing a Status Code option with value UseMulticast, a Server
++ * Identifier option containing the server's DUID, the Client Identifier
++ * option from the client message, and no other options.
++ *
++ * Section 18.2.7 (Decline):
++ *
++ * When the server receives a Decline message via unicast from a client
++ * to which the server has not sent a unicast option, the server
++ * discards the Decline message and responds with a Reply message
++ * containing a Status Code option with the value UseMulticast, a Server
++ * Identifier option containing the server's DUID, the Client Identifier
++ * option from the client message, and no other options.
++ */
++ snprintf(status_msg, sizeof(status_msg),
++ "%s received unicast.", packet_type);
++ if (!set_status_code(STATUS_UseMulticast, status_msg, opt_state)) {
++ goto exit;
++ }
+
+- /*
+- * Add our options that are not associated with any IA_NA or IA_TA.
+- */
+- reply_ofs += store_options6(reply_data+reply_ofs,
+- sizeof(reply_data)-reply_ofs,
++ /*
++ * Produce an reply that includes only:
++ *
++ * Status code.
++ * Server DUID.
++ * Client DUID.
++ */
++ reply_ofs += store_options6(reply_data+reply_ofs,
++ sizeof(reply_data)-reply_ofs,
+ opt_state, packet,
+- required_opts, NULL);
++ required_opts_NAA, NULL);
++
++ goto return_reply;
++ } else {
++ snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
++ if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
++ goto exit;
++ }
++
++ /*
++ * Add our options that are not associated with any IA_NA or IA_TA.
++ */
++ reply_ofs += store_options6(reply_data+reply_ofs,
++ sizeof(reply_data)-reply_ofs,
++ opt_state, packet,
++ required_opts, NULL);
++ }
+
+ /*
+ * Loop through the IA_NA reported by the client, and deal with
+@@ -4838,6 +4968,7 @@ iterate_over_ia_na(struct data_string *r
+ /*
+ * Return our reply to the caller.
+ */
++return_reply:
+ reply_ret->len = reply_ofs;
+ reply_ret->buffer = NULL;
+ if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
+@@ -4883,7 +5014,6 @@ exit:
+ * we still need to be aware of this possibility.
+ */
+
+-/* TODO: reject unicast messages, unless we set unicast option */
+ /* TODO: IA_TA */
+ static void
+ dhcpv6_decline(struct data_string *reply, struct packet *packet) {
+@@ -5355,7 +5485,6 @@ exit:
+ * Release means a client is done with the leases.
+ */
+
+-/* TODO: reject unicast messages, unless we set unicast option */
+ static void
+ dhcpv6_release(struct data_string *reply, struct packet *packet) {
+ struct data_string client_id;
diff --git a/src/patches/dhcp-4.2.0-add_timeout_when_NULL.patch b/src/patches/dhcp-4.2.0-add_timeout_when_NULL.patch
new file mode 100644
index 000000000..4784d5a68
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-add_timeout_when_NULL.patch
@@ -0,0 +1,14 @@
+diff -up dhcp-4.2.0/common/dispatch.c.dracut dhcp-4.2.0/common/dispatch.c
+--- dhcp-4.2.0/common/dispatch.c.dracut 2010-06-01 19:29:59.000000000 +0200
++++ dhcp-4.2.0/common/dispatch.c 2010-07-21 16:10:09.000000000 +0200
+@@ -189,6 +189,10 @@ void add_timeout (when, where, what, ref
+ isc_interval_t interval;
+ isc_time_t expires;
+
++ if (when == NULL) {
++ return;
++ }
++
+ /* See if this timeout supersedes an existing timeout. */
+ t = (struct timeout *)0;
+ for (q = timeouts; q; q = q->next) {
diff --git a/src/patches/dhcp-4.2.0-default-requested-options.patch b/src/patches/dhcp-4.2.0-default-requested-options.patch
new file mode 100644
index 000000000..fea8a4b99
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-default-requested-options.patch
@@ -0,0 +1,44 @@
+diff -up dhcp-4.2.0/client/clparse.c.requested dhcp-4.2.0/client/clparse.c
+--- dhcp-4.2.0/client/clparse.c.requested 2010-07-21 13:29:05.000000000 +0200
++++ dhcp-4.2.0/client/clparse.c 2010-07-21 13:50:29.000000000 +0200
+@@ -37,7 +37,7 @@
+
+ struct client_config top_level_config;
+
+-#define NUM_DEFAULT_REQUESTED_OPTS 9
++#define NUM_DEFAULT_REQUESTED_OPTS 14
+ struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 1];
+
+ static void parse_client_default_duid(struct parse *cfile);
+@@ -111,6 +111,31 @@ isc_result_t read_client_conf ()
+ option_code_hash_lookup(&default_requested_options[8],
+ dhcpv6_universe.code_hash, &code, 0, MDL);
+
++ /* 10 */
++ code = DHO_NIS_DOMAIN;
++ option_code_hash_lookup(&default_requested_options[9],
++ dhcp_universe.code_hash, &code, 0, MDL);
++
++ /* 11 */
++ code = DHO_NIS_SERVERS;
++ option_code_hash_lookup(&default_requested_options[10],
++ dhcp_universe.code_hash, &code, 0, MDL);
++
++ /* 12 */
++ code = DHO_NTP_SERVERS;
++ option_code_hash_lookup(&default_requested_options[11],
++ dhcp_universe.code_hash, &code, 0, MDL);
++
++ /* 13 */
++ code = DHO_INTERFACE_MTU;
++ option_code_hash_lookup(&default_requested_options[12],
++ dhcp_universe.code_hash, &code, 0, MDL);
++
++ /* 14 */
++ code = DHO_DOMAIN_SEARCH;
++ option_code_hash_lookup(&default_requested_options[13],
++ dhcp_universe.code_hash, &code, 0, MDL);
++
+ for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) {
+ if (default_requested_options[code] == NULL)
+ log_fatal("Unable to find option definition for "
diff --git a/src/patches/dhcp-4.2.0-dhclient-decline-backoff.patch b/src/patches/dhcp-4.2.0-dhclient-decline-backoff.patch
new file mode 100644
index 000000000..81bec7bd4
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-dhclient-decline-backoff.patch
@@ -0,0 +1,63 @@
+diff -up dhcp-4.2.0/client/dhclient.c.backoff dhcp-4.2.0/client/dhclient.c
+--- dhcp-4.2.0/client/dhclient.c.backoff 2010-07-21 13:37:03.000000000 +0200
++++ dhcp-4.2.0/client/dhclient.c 2010-07-21 13:38:31.000000000 +0200
+@@ -1208,6 +1208,8 @@ void state_init (cpp)
+ void *cpp;
+ {
+ struct client_state *client = cpp;
++ enum dhcp_state init_state = client->state;
++ struct timeval tv;
+
+ ASSERT_STATE(state, S_INIT);
+
+@@ -1220,9 +1222,18 @@ void state_init (cpp)
+ client -> first_sending = cur_time;
+ client -> interval = client -> config -> initial_interval;
+
+- /* Add an immediate timeout to cause the first DHCPDISCOVER packet
+- to go out. */
+- send_discover (client);
++ if (init_state != S_DECLINED) {
++ /* Add an immediate timeout to cause the first DHCPDISCOVER packet
++ to go out. */
++ send_discover(client);
++ } else {
++ /* We've received an OFFER and it has been DECLINEd by dhclient-script.
++ * wait for a random time between 1 and backoff_cutoff seconds before
++ * trying again. */
++ tv . tv_sec = cur_time + ((1 + (random() >> 2)) % client->config->backoff_cutoff);
++ tv . tv_usec = 0;
++ add_timeout(&tv, send_discover, client, 0, 0);
++ }
+ }
+
+ /*
+@@ -1501,6 +1512,7 @@ void bind_lease (client)
+ send_decline (client);
+ destroy_client_lease (client -> new);
+ client -> new = (struct client_lease *)0;
++ client -> state = S_DECLINED;
+ state_init (client);
+ return;
+ }
+@@ -3711,6 +3723,7 @@ void client_location_changed ()
+ case S_INIT:
+ case S_REBINDING:
+ case S_STOPPED:
++ case S_DECLINED:
+ break;
+ }
+ client -> state = S_INIT;
+diff -up dhcp-4.2.0/includes/dhcpd.h.backoff dhcp-4.2.0/includes/dhcpd.h
+--- dhcp-4.2.0/includes/dhcpd.h.backoff 2010-07-21 13:29:05.000000000 +0200
++++ dhcp-4.2.0/includes/dhcpd.h 2010-07-21 13:38:31.000000000 +0200
+@@ -1056,7 +1056,8 @@ enum dhcp_state {
+ S_BOUND = 5,
+ S_RENEWING = 6,
+ S_REBINDING = 7,
+- S_STOPPED = 8
++ S_STOPPED = 8,
++ S_DECLINED = 9
+ };
+
+ /* Authentication and BOOTP policy possibilities (not all values work
diff --git a/src/patches/dhcp-4.2.0-errwarn-message.patch b/src/patches/dhcp-4.2.0-errwarn-message.patch
new file mode 100644
index 000000000..a0f70cd04
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-errwarn-message.patch
@@ -0,0 +1,30 @@
+diff -up dhcp-4.2.0/omapip/errwarn.c.errwarn dhcp-4.2.0/omapip/errwarn.c
+--- dhcp-4.2.0/omapip/errwarn.c.errwarn 2009-07-23 20:52:21.000000000 +0200
++++ dhcp-4.2.0/omapip/errwarn.c 2010-07-21 13:23:47.000000000 +0200
+@@ -76,20 +76,13 @@ void log_fatal (const char * fmt, ... )
+
+ #if !defined (NOMINUM)
+ log_error ("%s", "");
+- log_error ("If you did not get this software from ftp.isc.org, please");
+- log_error ("get the latest from ftp.isc.org and install that before");
+- log_error ("requesting help.");
++ log_error ("This version of ISC DHCP is based on the release available");
++ log_error ("on ftp.isc.org. Features have been added and other changes");
++ log_error ("have been made to the base software release in order to make");
++ log_error ("it work better with this distribution.");
+ log_error ("%s", "");
+- log_error ("If you did get this software from ftp.isc.org and have not");
+- log_error ("yet read the README, please read it before requesting help.");
+- log_error ("If you intend to request help from the dhcp-server@isc.org");
+- log_error ("mailing list, please read the section on the README about");
+- log_error ("submitting bug reports and requests for help.");
+- log_error ("%s", "");
+- log_error ("Please do not under any circumstances send requests for");
+- log_error ("help directly to the authors of this software - please");
+- log_error ("send them to the appropriate mailing list as described in");
+- log_error ("the README file.");
++ log_error ("Please report for this software via the Red Hat Bugzilla site:");
++ log_error (" http://bugzilla.redhat.com");
+ log_error ("%s", "");
+ log_error ("exiting.");
+ #endif
diff --git a/src/patches/dhcp-4.2.0-garbage-chars.patch b/src/patches/dhcp-4.2.0-garbage-chars.patch
new file mode 100644
index 000000000..118ff3fc1
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-garbage-chars.patch
@@ -0,0 +1,12 @@
+diff -up dhcp-4.2.0/common/tables.c.garbage dhcp-4.2.0/common/tables.c
+--- dhcp-4.2.0/common/tables.c.garbage 2009-11-20 02:49:01.000000000 +0100
++++ dhcp-4.2.0/common/tables.c 2010-07-21 14:40:56.000000000 +0200
+@@ -207,7 +207,7 @@ static struct option dhcp_options[] = {
+ { "netinfo-server-tag", "t", &dhcp_universe, 113, 1 },
+ { "default-url", "t", &dhcp_universe, 114, 1 },
+ { "subnet-selection", "I", &dhcp_universe, 118, 1 },
+- { "domain-search", "Dc", &dhcp_universe, 119, 1 },
++ { "domain-search", "D", &dhcp_universe, 119, 1 },
+ { "vivco", "Evendor-class.", &dhcp_universe, 124, 1 },
+ { "vivso", "Evendor.", &dhcp_universe, 125, 1 },
+ #if 0
diff --git a/src/patches/dhcp-4.2.0-honor-expired.patch b/src/patches/dhcp-4.2.0-honor-expired.patch
new file mode 100644
index 000000000..0ae912848
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-honor-expired.patch
@@ -0,0 +1,49 @@
+diff -up dhcp-4.2.0/client/dhc6.c.honor-expired dhcp-4.2.0/client/dhc6.c
+--- dhcp-4.2.0/client/dhc6.c.honor-expired 2010-10-07 12:55:37.000000000 +0200
++++ dhcp-4.2.0/client/dhc6.c 2010-10-07 12:56:43.000000000 +0200
+@@ -1405,6 +1405,32 @@ start_info_request6(struct client_state
+ go_daemon();
+ }
+
++/* Run through the addresses in lease and return true if there's any unexpired.
++ * Return false otherwise.
++ */
++isc_boolean_t
++unexpired_address_in_lease(struct dhc6_lease *lease)
++{
++ struct dhc6_ia *ia;
++ struct dhc6_addr *addr;
++
++ for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
++ for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
++ if (addr->flags & DHC6_ADDR_EXPIRED)
++ continue;
++
++ if (addr->starts + addr->max_life > cur_time) {
++ return ISC_TRUE;
++ }
++ }
++ }
++
++ log_info("PRC: Previous lease is devoid of active addresses."
++ " Re-initializing.");
++
++ return ISC_FALSE;
++}
++
+ /*
+ * start_confirm6() kicks off an "init-reboot" version of the process, at
+ * startup to find out if old bindings are 'fair' and at runtime whenever
+@@ -1417,8 +1446,10 @@ start_confirm6(struct client_state *clie
+
+ /* If there is no active lease, there is nothing to check. */
+ if ((client->active_lease == NULL) ||
+- !active_prefix(client) ||
+- client->active_lease->released) {
++ !active_prefix(client) ||
++ client->active_lease->released ||
++ !unexpired_address_in_lease(client->active_lease)) {
++ dhc6_lease_destroy(&client->active_lease, MDL);
+ start_init6(client);
+ return;
+ }
diff --git a/src/patches/dhcp-4.2.0-inherit-leases.patch b/src/patches/dhcp-4.2.0-inherit-leases.patch
new file mode 100644
index 000000000..052f64259
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-inherit-leases.patch
@@ -0,0 +1,34 @@
+diff -up dhcp-4.2.0/client/dhclient.c.inherit dhcp-4.2.0/client/dhclient.c
+--- dhcp-4.2.0/client/dhclient.c.inherit 2010-07-21 14:33:44.000000000 +0200
++++ dhcp-4.2.0/client/dhclient.c 2010-07-21 14:40:05.000000000 +0200
+@@ -2322,6 +2322,7 @@ void send_request (cpp)
+ {
+ struct client_state *client = cpp;
+
++ int i;
+ int result;
+ int interval;
+ struct sockaddr_in destination;
+@@ -2381,6 +2382,22 @@ void send_request (cpp)
+ /* Now do a preinit on the interface so that we can
+ discover a new address. */
+ script_init (client, "PREINIT", (struct string_list *)0);
++
++ /* Has an active lease */
++ if (client -> interface -> addresses != NULL) {
++ for (i = 0; i < client -> interface -> address_count; i++) {
++ if (client -> active &&
++ client -> active -> is_bootp &&
++ client -> active -> expiry > cur_time &&
++ client -> interface -> addresses[i].s_addr != 0 &&
++ client -> active -> address.len == 4 &&
++ memcpy (client -> active -> address.iabuf, &(client -> interface -> addresses[i]), 4) == 0) {
++ client_envadd (client, "", "keep_old_ip", "%s", "yes");
++ break;
++ }
++ }
++ }
++
+ if (client -> alias)
+ script_write_params (client, "alias_",
+ client -> alias);
diff --git a/src/patches/dhcp-4.2.0-logpid.patch b/src/patches/dhcp-4.2.0-logpid.patch
new file mode 100644
index 000000000..c24adb14a
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-logpid.patch
@@ -0,0 +1,12 @@
+diff -up dhcp-4.2.0/client/dhclient.c.logpid dhcp-4.2.0/client/dhclient.c
+--- dhcp-4.2.0/client/dhclient.c.logpid 2010-07-21 16:13:52.000000000 +0200
++++ dhcp-4.2.0/client/dhclient.c 2010-07-21 16:16:51.000000000 +0200
+@@ -154,7 +154,7 @@ main(int argc, char **argv) {
+ else if (fd != -1)
+ close(fd);
+
+- openlog("dhclient", LOG_NDELAY, LOG_DAEMON);
++ openlog("dhclient", LOG_NDELAY | LOG_PID, LOG_DAEMON);
+
+ #if !(defined(DEBUG) || defined(__CYGWIN32__))
+ setlogmask(LOG_UPTO(LOG_INFO));
diff --git a/src/patches/dhcp-4.2.0-missing-ipv6-not-fatal.patch b/src/patches/dhcp-4.2.0-missing-ipv6-not-fatal.patch
new file mode 100644
index 000000000..b60411545
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-missing-ipv6-not-fatal.patch
@@ -0,0 +1,40 @@
+diff -up dhcp-4.2.0/common/discover.c.noipv6 dhcp-4.2.0/common/discover.c
+--- dhcp-4.2.0/common/discover.c.noipv6 2010-07-21 14:31:13.000000000 +0200
++++ dhcp-4.2.0/common/discover.c 2010-07-21 16:04:57.000000000 +0200
+@@ -443,7 +443,7 @@ begin_iface_scan(struct iface_conf_list
+ }
+
+ #ifdef DHCPv6
+- if (local_family == AF_INET6) {
++ if ((local_family == AF_INET6) && !access("/proc/net/if_inet6", R_OK)) {
+ ifaces->fp6 = fopen("/proc/net/if_inet6", "re");
+ if (ifaces->fp6 == NULL) {
+ log_error("Error opening '/proc/net/if_inet6' to "
+@@ -454,6 +454,8 @@ begin_iface_scan(struct iface_conf_list
+ ifaces->fp = NULL;
+ return 0;
+ }
++ } else {
++ ifaces->fp6 = NULL;
+ }
+ #endif
+
+@@ -721,7 +723,7 @@ next_iface(struct iface_info *info, int
+ return 1;
+ }
+ #ifdef DHCPv6
+- if (!(*err)) {
++ if (!(*err) && ifaces->fp6) {
+ if (local_family == AF_INET6)
+ return next_iface6(info, err, ifaces);
+ }
+@@ -740,7 +742,8 @@ end_iface_scan(struct iface_conf_list *i
+ ifaces->sock = -1;
+ #ifdef DHCPv6
+ if (local_family == AF_INET6) {
+- fclose(ifaces->fp6);
++ if (ifaces->fp6)
++ fclose(ifaces->fp6);
+ ifaces->fp6 = NULL;
+ }
+ #endif
diff --git a/src/patches/dhcp-4.2.0-noprefixavail.patch b/src/patches/dhcp-4.2.0-noprefixavail.patch
new file mode 100644
index 000000000..729a1726a
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-noprefixavail.patch
@@ -0,0 +1,140 @@
+diff -up dhcp-4.2.0/server/dhcpv6.c.noprefixavail dhcp-4.2.0/server/dhcpv6.c
+--- dhcp-4.2.0/server/dhcpv6.c.noprefixavail 2010-10-07 13:48:45.000000000 +0200
++++ dhcp-4.2.0/server/dhcpv6.c 2010-10-13 11:00:25.000000000 +0200
+@@ -1134,7 +1134,7 @@ try_client_v6_prefix(struct iasubopt **p
+ return DHCP_R_INVALIDARG;
+ }
+ tmp_plen = (int) requested_pref->data[0];
+- if ((tmp_plen < 3) || (tmp_plen > 128)) {
++ if ((tmp_plen < 3) || (tmp_plen > 128) ||((int)tmp_plen != pool->units)) {
+ return ISC_R_FAILURE;
+ }
+ memcpy(&tmp_pref, requested_pref->data + 1, sizeof(tmp_pref));
+@@ -1147,9 +1147,8 @@ try_client_v6_prefix(struct iasubopt **p
+ return ISC_R_FAILURE;
+ }
+
+- if (((int)tmp_plen != pool->units) ||
+- !ipv6_in_pool(&tmp_pref, pool)) {
+- return ISC_R_FAILURE;
++ if (!ipv6_in_pool(&tmp_pref, pool)) {
++ return ISC_R_ADDRNOTAVAIL;
+ }
+
+ if (prefix6_exists(pool, &tmp_pref, tmp_plen)) {
+@@ -1409,13 +1408,6 @@ lease_to_client(struct data_string *repl
+ if ((status != ISC_R_SUCCESS) &&
+ (status != ISC_R_NORESOURCES))
+ goto exit;
+-
+- /*
+- * If any prefix cannot be given to any IA_PD, then
+- * set the NoPrefixAvail status code.
+- */
+- if (reply.client_resources == 0)
+- no_resources_avail = ISC_TRUE;
+ }
+
+ /*
+@@ -1549,36 +1541,6 @@ lease_to_client(struct data_string *repl
+ reply.opt_state, reply.packet,
+ required_opts_NAA,
+ NULL);
+- } else if (no_resources_avail && (reply.ia_count == 0) &&
+- (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT))
+- {
+- /* Set the NoPrefixAvail status code. */
+- if (!set_status_code(STATUS_NoPrefixAvail,
+- "No prefixes available for this "
+- "interface.", reply.opt_state)) {
+- log_error("lease_to_client: Unable to set "
+- "NoPrefixAvail status code.");
+- goto exit;
+- }
+-
+- /* Rewind the cursor to the start. */
+- reply.cursor = REPLY_OPTIONS_INDEX;
+-
+- /*
+- * Produce an advertise that includes only:
+- *
+- * Status code.
+- * Server DUID.
+- * Client DUID.
+- */
+- reply.buf.reply.msg_type = DHCPV6_ADVERTISE;
+- reply.cursor += store_options6((char *)reply.buf.data +
+- reply.cursor,
+- sizeof(reply.buf) -
+- reply.cursor,
+- reply.opt_state, reply.packet,
+- required_opts_NAA,
+- NULL);
+ } else {
+ /*
+ * Having stored the client's IA's, store any options that
+@@ -2793,16 +2755,18 @@ find_client_temporaries(struct reply_sta
+ */
+ static isc_result_t
+ reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) {
+- isc_result_t status = ISC_R_NORESOURCES;
++ isc_result_t status = ISC_R_ADDRNOTAVAIL;
+ struct ipv6_pool *pool;
+ int i;
+ struct data_string data_addr;
+
+ if ((reply == NULL) || (reply->shared == NULL) ||
+- (reply->shared->ipv6_pools == NULL) || (addr == NULL) ||
+- (reply->lease != NULL))
++ (addr == NULL) || (reply->lease != NULL))
+ return DHCP_R_INVALIDARG;
+
++ if (reply->shared->ipv6_pools == NULL)
++ return ISC_R_ADDRNOTAVAIL;
++
+ memset(&data_addr, 0, sizeof(data_addr));
+ data_addr.len = addr->len;
+ data_addr.data = addr->iabuf;
+@@ -3314,7 +3278,9 @@ reply_process_ia_pd(struct reply_state *
+ if (status == ISC_R_CANCELED)
+ break;
+
+- if ((status != ISC_R_SUCCESS) && (status != ISC_R_ADDRINUSE))
++ if ((status != ISC_R_SUCCESS) &&
++ (status != ISC_R_ADDRINUSE) &&
++ (status != ISC_R_ADDRNOTAVAIL))
+ goto cleanup;
+ }
+
+@@ -3594,7 +3560,8 @@ reply_process_prefix(struct reply_state
+
+ /* Either error out or skip this prefix. */
+ if ((status != ISC_R_SUCCESS) &&
+- (status != ISC_R_ADDRINUSE))
++ (status != ISC_R_ADDRINUSE) &&
++ (status != ISC_R_ADDRNOTAVAIL))
+ goto cleanup;
+
+ if (reply->lease == NULL) {
+@@ -3773,16 +3740,18 @@ prefix_is_owned(struct reply_state *repl
+ static isc_result_t
+ reply_process_try_prefix(struct reply_state *reply,
+ struct iaddrcidrnet *pref) {
+- isc_result_t status = ISC_R_NORESOURCES;
++ isc_result_t status = ISC_R_ADDRNOTAVAIL;
+ struct ipv6_pool *pool;
+ int i;
+ struct data_string data_pref;
+
+ if ((reply == NULL) || (reply->shared == NULL) ||
+- (reply->shared->ipv6_pools == NULL) || (pref == NULL) ||
+- (reply->lease != NULL))
++ (pref == NULL) || (reply->lease != NULL))
+ return DHCP_R_INVALIDARG;
+
++ if (reply->shared->ipv6_pools == NULL)
++ return ISC_R_ADDRNOTAVAIL;
++
+ memset(&data_pref, 0, sizeof(data_pref));
+ data_pref.len = 17;
+ if (!buffer_allocate(&data_pref.buffer, data_pref.len, MDL)) {
diff --git a/src/patches/dhcp-4.2.0-paths.patch b/src/patches/dhcp-4.2.0-paths.patch
new file mode 100644
index 000000000..54c7aba8e
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-paths.patch
@@ -0,0 +1,45 @@
+diff -up dhcp-4.2.0/includes/dhcpd.h.paths dhcp-4.2.0/includes/dhcpd.h
+--- dhcp-4.2.0/includes/dhcpd.h.paths 2010-07-21 13:55:42.000000000 +0200
++++ dhcp-4.2.0/includes/dhcpd.h 2010-07-21 14:29:57.000000000 +0200
+@@ -1390,15 +1390,15 @@ typedef unsigned char option_mask [16];
+ #else /* !DEBUG */
+
+ #ifndef _PATH_DHCPD_CONF
+-#define _PATH_DHCPD_CONF "/etc/dhcpd.conf"
++#define _PATH_DHCPD_CONF "/etc/dhcp/dhcpd.conf"
+ #endif /* DEBUG */
+
+ #ifndef _PATH_DHCPD_DB
+-#define _PATH_DHCPD_DB LOCALSTATEDIR"/db/dhcpd.leases"
++#define _PATH_DHCPD_DB LOCALSTATEDIR"/dhcpd/dhcpd.leases"
+ #endif
+
+ #ifndef _PATH_DHCPD6_DB
+-#define _PATH_DHCPD6_DB LOCALSTATEDIR"/db/dhcpd6.leases"
++#define _PATH_DHCPD6_DB LOCALSTATEDIR"/dhcpd/dhcpd6.leases"
+ #endif
+
+ #ifndef _PATH_DHCPD_PID
+@@ -1412,7 +1412,7 @@ typedef unsigned char option_mask [16];
+ #endif /* DEBUG */
+
+ #ifndef _PATH_DHCLIENT_CONF
+-#define _PATH_DHCLIENT_CONF "/etc/dhclient.conf"
++#define _PATH_DHCLIENT_CONF "/etc/dhcp/dhclient.conf"
+ #endif
+
+ #ifndef _PATH_DHCLIENT_SCRIPT
+@@ -1428,11 +1428,11 @@ typedef unsigned char option_mask [16];
+ #endif
+
+ #ifndef _PATH_DHCLIENT_DB
+-#define _PATH_DHCLIENT_DB LOCALSTATEDIR"/db/dhclient.leases"
++#define _PATH_DHCLIENT_DB LOCALSTATEDIR"/dhclient/dhclient.leases"
+ #endif
+
+ #ifndef _PATH_DHCLIENT6_DB
+-#define _PATH_DHCLIENT6_DB LOCALSTATEDIR"/db/dhclient6.leases"
++#define _PATH_DHCLIENT6_DB LOCALSTATEDIR"/dhclient/dhclient6.leases"
+ #endif
+
+ #ifndef _PATH_RESOLV_CONF
diff --git a/src/patches/dhcp-4.2.0-release-by-ifup.patch b/src/patches/dhcp-4.2.0-release-by-ifup.patch
new file mode 100644
index 000000000..300c5f334
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-release-by-ifup.patch
@@ -0,0 +1,85 @@
+diff -up dhcp-4.2.0/client/dhclient.c.ifup dhcp-4.2.0/client/dhclient.c
+--- dhcp-4.2.0/client/dhclient.c.ifup 2010-07-21 13:30:10.000000000 +0200
++++ dhcp-4.2.0/client/dhclient.c 2010-07-21 13:37:03.000000000 +0200
+@@ -497,9 +497,81 @@ main(int argc, char **argv) {
+ kill(oldpid, SIGTERM);
+ }
+ fclose(pidfd);
++ } else {
++ /* handle release for interfaces requested with Red Hat
++ * /sbin/ifup - pidfile will be /var/run/dhclient-$interface.pid
++ */
++
++ if ((path_dhclient_pid == NULL) || (*path_dhclient_pid == '\0'))
++ path_dhclient_pid = "/var/run/dhclient.pid";
++
++ char *new_path_dhclient_pid;
++ struct interface_info *ip;
++ int pdp_len = strlen(path_dhclient_pid), pfx, dpfx;
++
++ /* find append point: beginning of any trailing '.pid'
++ * or '-$IF.pid' */
++ for (pfx=pdp_len; (pfx >= 0) && (path_dhclient_pid[pfx] != '.') && (path_dhclient_pid[pfx] != '/'); pfx--);
++ if (pfx == -1)
++ pfx = pdp_len;
++
++ if (path_dhclient_pid[pfx] == '/')
++ pfx += 1;
++
++ for (dpfx=pfx; (dpfx >= 0) && (path_dhclient_pid[dpfx] != '-') && (path_dhclient_pid[dpfx] != '/'); dpfx--);
++ if ((dpfx > -1) && (path_dhclient_pid[dpfx] != '/'))
++ pfx = dpfx;
++
++ for (ip = interfaces; ip; ip = ip->next) {
++ if (interfaces_requested && (ip->flags & (INTERFACE_REQUESTED))) {
++ int n_len = strlen(ip->name);
++
++ new_path_dhclient_pid = (char*) malloc(pfx + n_len + 6);
++ strncpy(new_path_dhclient_pid, path_dhclient_pid, pfx);
++ sprintf(new_path_dhclient_pid + pfx, "-%s.pid", ip->name);
++
++ if ((pidfd = fopen(new_path_dhclient_pid, "r")) != NULL) {
++ e = fscanf(pidfd, "%ld\n", &temp);
++ oldpid = (pid_t)temp;
++
++ if (e != 0 && e != EOF) {
++ if (oldpid) {
++ if (kill(oldpid, SIGTERM) == 0)
++ unlink(path_dhclient_pid);
++ }
++ }
++
++ fclose(pidfd);
++ }
++
++ free(new_path_dhclient_pid);
++ }
++ }
++ }
++ } else {
++ FILE *pidfp = NULL;
++ long temp = 0;
++ pid_t dhcpid = 0;
++ int dhc_running = 0;
++ char procfn[256] = "";
++
++ if ((pidfp = fopen(path_dhclient_pid, "r")) != NULL) {
++ if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
++ snprintf(procfn,256,"/proc/%u",dhcpid);
++ dhc_running = (access(procfn, F_OK) == 0);
++ }
++
++ fclose(pidfp);
++ }
++
++ if (dhc_running) {
++ log_fatal("dhclient(%u) is already running - exiting. ", dhcpid);
++ return(1);
+ }
+ }
+
++ write_client_pid_file();
++
+ if (!quiet) {
+ log_info("%s %s", message, PACKAGE_VERSION);
+ log_info(copyright);
diff --git a/src/patches/dhcp-4.2.0-unicast-bootp.patch b/src/patches/dhcp-4.2.0-unicast-bootp.patch
new file mode 100644
index 000000000..78bc078dc
--- /dev/null
+++ b/src/patches/dhcp-4.2.0-unicast-bootp.patch
@@ -0,0 +1,99 @@
+diff -up dhcp-4.2.0/server/bootp.c.unicast dhcp-4.2.0/server/bootp.c
+--- dhcp-4.2.0/server/bootp.c.unicast 2009-11-20 02:49:03.000000000 +0100
++++ dhcp-4.2.0/server/bootp.c 2010-07-21 13:40:25.000000000 +0200
+@@ -58,6 +58,7 @@ void bootp (packet)
+ char msgbuf [1024];
+ int ignorep;
+ int peer_has_leases = 0;
++ int norelay = 0;
+
+ if (packet -> raw -> op != BOOTREQUEST)
+ return;
+@@ -73,7 +74,7 @@ void bootp (packet)
+ ? inet_ntoa (packet -> raw -> giaddr)
+ : packet -> interface -> name);
+
+- if (!locate_network (packet)) {
++ if ((norelay = locate_network (packet)) == 0) {
+ log_info ("%s: network unknown", msgbuf);
+ return;
+ }
+@@ -390,6 +391,13 @@ void bootp (packet)
+ from, &to, &hto);
+ goto out;
+ }
++ } else if (norelay == 2) {
++ to.sin_addr = raw.ciaddr;
++ to.sin_port = remote_port;
++ if (fallback_interface) {
++ result = send_packet (fallback_interface, (struct packet *)0, &raw, outgoing.packet_length, from, &to, &hto);
++ goto out;
++ }
+
+ /* If it comes from a client that already knows its address
+ and is not requesting a broadcast response, and we can
+diff -up dhcp-4.2.0/server/dhcp.c.unicast dhcp-4.2.0/server/dhcp.c
+--- dhcp-4.2.0/server/dhcp.c.unicast 2010-06-01 19:29:59.000000000 +0200
++++ dhcp-4.2.0/server/dhcp.c 2010-07-21 13:40:25.000000000 +0200
+@@ -4185,6 +4185,7 @@ int locate_network (packet)
+ struct data_string data;
+ struct subnet *subnet = (struct subnet *)0;
+ struct option_cache *oc;
++ int norelay = 0;
+
+ /* See if there's a Relay Agent Link Selection Option, or a
+ * Subnet Selection Option. The Link-Select and Subnet-Select
+@@ -4200,12 +4201,24 @@ int locate_network (packet)
+ from the interface, if there is one. If not, fail. */
+ if (!oc && !packet -> raw -> giaddr.s_addr) {
+ if (packet -> interface -> shared_network) {
+- shared_network_reference
+- (&packet -> shared_network,
+- packet -> interface -> shared_network, MDL);
+- return 1;
++ struct in_addr any_addr;
++ any_addr.s_addr = INADDR_ANY;
++
++ if (!packet -> packet_type && memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) {
++ struct iaddr cip;
++ memcpy(cip.iabuf, &packet -> raw -> ciaddr, 4);
++ cip.len = 4;
++ if (!find_grouped_subnet(&subnet, packet->interface->shared_network, cip, MDL))
++ norelay = 2;
++ }
++
++ if (!norelay) {
++ shared_network_reference(&packet -> shared_network, packet -> interface -> shared_network, MDL);
++ return 1;
++ }
++ } else {
++ return 0;
+ }
+- return 0;
+ }
+
+ /* If there's an option indicating link connection, and it's valid,
+@@ -4228,7 +4241,10 @@ int locate_network (packet)
+ data_string_forget (&data, MDL);
+ } else {
+ ia.len = 4;
+- memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
++ if (norelay)
++ memcpy (ia.iabuf, &packet->raw->ciaddr, 4);
++ else
++ memcpy (ia.iabuf, &packet->raw->giaddr, 4);
+ }
+
+ /* If we know the subnet on which the IP address lives, use it. */
+@@ -4236,7 +4252,10 @@ int locate_network (packet)
+ shared_network_reference (&packet -> shared_network,
+ subnet -> shared_network, MDL);
+ subnet_dereference (&subnet, MDL);
+- return 1;
++ if (norelay)
++ return norelay;
++ else
++ return 1;
+ }
+
+ /* Otherwise, fail. */
diff --git a/src/patches/dhcp-4.2.1-64_bit_lease_parse.patch b/src/patches/dhcp-4.2.1-64_bit_lease_parse.patch
new file mode 100644
index 000000000..a540bc19f
--- /dev/null
+++ b/src/patches/dhcp-4.2.1-64_bit_lease_parse.patch
@@ -0,0 +1,94 @@
+diff -up dhcp-4.2.1b1/common/dispatch.c.64-bit_lease_parse dhcp-4.2.1b1/common/dispatch.c
+diff -up dhcp-4.2.1b1/common/parse.c.64-bit_lease_parse dhcp-4.2.1b1/common/parse.c
+--- dhcp-4.2.1b1/common/parse.c.64-bit_lease_parse 2010-12-30 00:01:42.000000000 +0100
++++ dhcp-4.2.1b1/common/parse.c 2011-01-28 08:01:10.000000000 +0100
+@@ -909,8 +909,8 @@ TIME
+ parse_date_core(cfile)
+ struct parse *cfile;
+ {
+- int guess;
+- int tzoff, wday, year, mon, mday, hour, min, sec;
++ TIME guess;
++ long int tzoff, wday, year, mon, mday, hour, min, sec;
+ const char *val;
+ enum dhcp_token token;
+ static int months[11] = { 31, 59, 90, 120, 151, 181,
+@@ -936,7 +936,7 @@ parse_date_core(cfile)
+ }
+
+ token = next_token(&val, NULL, cfile); /* consume number */
+- guess = atoi(val);
++ guess = atol(val);
+
+ return((TIME)guess);
+ }
+@@ -948,7 +948,7 @@ parse_date_core(cfile)
+ return((TIME)0);
+ }
+ token = next_token(&val, NULL, cfile); /* consume day of week */
+- wday = atoi(val);
++ wday = atol(val);
+
+ /* Year... */
+ token = peek_token(&val, NULL, cfile);
+@@ -964,7 +964,7 @@ parse_date_core(cfile)
+ somebody invents a time machine, I think we can safely disregard
+ it. This actually works around a stupid Y2K bug that was present
+ in a very early beta release of dhcpd. */
+- year = atoi(val);
++ year = atol(val);
+ if (year > 1900)
+ year -= 1900;
+
+@@ -988,7 +988,7 @@ parse_date_core(cfile)
+ return((TIME)0);
+ }
+ token = next_token(&val, NULL, cfile); /* consume month */
+- mon = atoi(val) - 1;
++ mon = atol(val) - 1;
+
+ /* Slash separating month from day... */
+ token = peek_token(&val, NULL, cfile);
+@@ -1010,7 +1010,7 @@ parse_date_core(cfile)
+ return((TIME)0);
+ }
+ token = next_token(&val, NULL, cfile); /* consume day of month */
+- mday = atoi(val);
++ mday = atol(val);
+
+ /* Hour... */
+ token = peek_token(&val, NULL, cfile);
+@@ -1021,7 +1021,7 @@ parse_date_core(cfile)
+ return((TIME)0);
+ }
+ token = next_token(&val, NULL, cfile); /* consume hour */
+- hour = atoi(val);
++ hour = atol(val);
+
+ /* Colon separating hour from minute... */
+ token = peek_token(&val, NULL, cfile);
+@@ -1043,7 +1043,7 @@ parse_date_core(cfile)
+ return((TIME)0);
+ }
+ token = next_token(&val, NULL, cfile); /* consume minute */
+- min = atoi(val);
++ min = atol(val);
+
+ /* Colon separating minute from second... */
+ token = peek_token(&val, NULL, cfile);
+@@ -1065,13 +1065,13 @@ parse_date_core(cfile)
+ return((TIME)0);
+ }
+ token = next_token(&val, NULL, cfile); /* consume second */
+- sec = atoi(val);
++ sec = atol(val);
+
+ tzoff = 0;
+ token = peek_token(&val, NULL, cfile);
+ if (token == NUMBER) {
+ token = next_token(&val, NULL, cfile); /* consume tzoff */
+- tzoff = atoi(val);
++ tzoff = atol(val);
+ } else if (token != SEMI) {
+ token = next_token(&val, NULL, cfile);
+ parse_warn(cfile,
diff --git a/src/patches/dhcp-4.2.1-invalid-dhclient-conf.patch b/src/patches/dhcp-4.2.1-invalid-dhclient-conf.patch
new file mode 100644
index 000000000..eeeea84fd
--- /dev/null
+++ b/src/patches/dhcp-4.2.1-invalid-dhclient-conf.patch
@@ -0,0 +1,12 @@
+diff -up dhcp-4.2.1b1/client/dhclient.conf.supersede dhcp-4.2.1b1/client/dhclient.conf
+--- dhcp-4.2.1b1/client/dhclient.conf.supersede 2010-09-15 01:03:56.000000000 +0200
++++ dhcp-4.2.1b1/client/dhclient.conf 2011-01-27 18:38:28.000000000 +0100
+@@ -4,7 +4,7 @@ send dhcp-lease-time 3600;
+ supersede domain-search "fugue.com", "home.vix.com";
+ prepend domain-name-servers 127.0.0.1;
+ request subnet-mask, broadcast-address, time-offset, routers,
+- domain-name, domain-name-servers, host-name;
++ domain-search, domain-name-servers, host-name;
+ require subnet-mask, domain-name-servers;
+ timeout 60;
+ retry 60;
diff --git a/src/patches/dhcp-4.2.1-manpages.patch b/src/patches/dhcp-4.2.1-manpages.patch
new file mode 100644
index 000000000..9a42b7fc7
--- /dev/null
+++ b/src/patches/dhcp-4.2.1-manpages.patch
@@ -0,0 +1,264 @@
+diff -up dhcp-4.2.1b1/client/dhclient.8.man dhcp-4.2.1b1/client/dhclient.8
+--- dhcp-4.2.1b1/client/dhclient.8.man 2010-07-14 22:09:34.000000000 +0200
++++ dhcp-4.2.1b1/client/dhclient.8 2011-01-27 18:19:07.000000000 +0100
+@@ -115,6 +115,33 @@ dhclient - Dynamic Host Configuration Pr
+ .B -w
+ ]
+ [
++.B -B
++]
++[
++.B -I
++.I dhcp-client-identifier
++]
++[
++.B -H
++.I host-name
++]
++[
++.B -F
++.I fqdn.fqdn
++]
++[
++.B -V
++.I vendor-class-identifier
++]
++[
++.B -R
++.I request-option-list
++]
++[
++.B -timeout
++.I timeout
++]
++[
+ .B -v
+ ]
+ [
+@@ -264,6 +291,69 @@ not to exit when it doesn't find any suc
+ program can then be used to notify the client when a network interface
+ has been added or removed, so that the client can attempt to configure an IP
+ address on that interface.
++
++.TP
++.BI \-B
++Set the BOOTP broadcast flag in request packets so servers will always
++broadcast replies.
++
++.TP
++.BI \-I\
++Specify the dhcp-client-identifier option to send to the DHCP server.
++
++.TP
++.BI \-H\
++Specify the host-name option to send to the DHCP server. The host-name
++string only contains the client's hostname prefix, to which the server will
++append the ddns-domainname or domain-name options, if any, to derive the
++fully qualified domain name of the client. The
++.B -H
++option cannot be used with the
++.B -F
++option.
++
++.TP
++.BI \-F\
++Specify the fqdn.fqdn option to send to the DHCP server. This option cannot
++be used with the
++.B -H
++option. The fqdn.fqdn option must specify the complete domain name of the
++client host, which the server may use for dynamic DNS updates.
++
++.TP
++.BI \-V\
++Specify the vendor-class-identifier option to send to the DHCP server.
++
++.TP
++.BI \-R\