Remove dhcp-3.0 from base and import dhclient from OpenBSD. Porting work
authorHasso Tepper <hasso@dragonflybsd.org>
Sat, 30 Aug 2008 16:07:59 +0000 (16:07 +0000)
committerHasso Tepper <hasso@dragonflybsd.org>
Sat, 30 Aug 2008 16:07:59 +0000 (16:07 +0000)
done by Matthias Schmidt and Andras Voroskoi.

210 files changed:
contrib/dhcp-3.0/LICENSE [deleted file]
contrib/dhcp-3.0/README [deleted file]
contrib/dhcp-3.0/README.DELETED [deleted file]
contrib/dhcp-3.0/README.DRAGONFLY [deleted file]
contrib/dhcp-3.0/RELNOTES [deleted file]
contrib/dhcp-3.0/client/clparse.c [deleted file]
contrib/dhcp-3.0/client/dhclient-script.8 [deleted file]
contrib/dhcp-3.0/client/dhclient.8 [deleted file]
contrib/dhcp-3.0/client/dhclient.c [deleted file]
contrib/dhcp-3.0/client/dhclient.conf [deleted file]
contrib/dhcp-3.0/client/dhclient.conf.5 [deleted file]
contrib/dhcp-3.0/client/dhclient.leases.5 [deleted file]
contrib/dhcp-3.0/client/scripts/freebsd [deleted file]
contrib/dhcp-3.0/common/alloc.c [deleted file]
contrib/dhcp-3.0/common/bpf.c [deleted file]
contrib/dhcp-3.0/common/comapi.c [deleted file]
contrib/dhcp-3.0/common/conflex.c [deleted file]
contrib/dhcp-3.0/common/ctrace.c [deleted file]
contrib/dhcp-3.0/common/dhcp-eval.5 [deleted file]
contrib/dhcp-3.0/common/dhcp-options.5 [deleted file]
contrib/dhcp-3.0/common/discover.c [deleted file]
contrib/dhcp-3.0/common/dispatch.c [deleted file]
contrib/dhcp-3.0/common/dlpi.c [deleted file]
contrib/dhcp-3.0/common/dns.c [deleted file]
contrib/dhcp-3.0/common/ethernet.c [deleted file]
contrib/dhcp-3.0/common/execute.c [deleted file]
contrib/dhcp-3.0/common/fddi.c [deleted file]
contrib/dhcp-3.0/common/icmp.c [deleted file]
contrib/dhcp-3.0/common/inet.c [deleted file]
contrib/dhcp-3.0/common/lpf.c [deleted file]
contrib/dhcp-3.0/common/memory.c [deleted file]
contrib/dhcp-3.0/common/nit.c [deleted file]
contrib/dhcp-3.0/common/options.c [deleted file]
contrib/dhcp-3.0/common/packet.c [deleted file]
contrib/dhcp-3.0/common/parse.c [deleted file]
contrib/dhcp-3.0/common/print.c [deleted file]
contrib/dhcp-3.0/common/raw.c [deleted file]
contrib/dhcp-3.0/common/resolv.c [deleted file]
contrib/dhcp-3.0/common/socket.c [deleted file]
contrib/dhcp-3.0/common/tables.c [deleted file]
contrib/dhcp-3.0/common/tr.c [deleted file]
contrib/dhcp-3.0/common/tree.c [deleted file]
contrib/dhcp-3.0/common/upf.c [deleted file]
contrib/dhcp-3.0/dhcpctl/callback.c [deleted file]
contrib/dhcp-3.0/dhcpctl/dhcpctl.3 [deleted file]
contrib/dhcp-3.0/dhcpctl/dhcpctl.c [deleted file]
contrib/dhcp-3.0/dhcpctl/dhcpctl.h [deleted file]
contrib/dhcp-3.0/dhcpctl/omshell.1 [deleted file]
contrib/dhcp-3.0/dhcpctl/omshell.c [deleted file]
contrib/dhcp-3.0/dhcpctl/remote.c [deleted file]
contrib/dhcp-3.0/dst/base64.c [deleted file]
contrib/dhcp-3.0/dst/dst_api.c [deleted file]
contrib/dhcp-3.0/dst/dst_internal.h [deleted file]
contrib/dhcp-3.0/dst/dst_support.c [deleted file]
contrib/dhcp-3.0/dst/hmac_link.c [deleted file]
contrib/dhcp-3.0/dst/md5.h [deleted file]
contrib/dhcp-3.0/dst/md5_dgst.c [deleted file]
contrib/dhcp-3.0/dst/md5_locl.h [deleted file]
contrib/dhcp-3.0/dst/prandom.c [deleted file]
contrib/dhcp-3.0/includes/arpa/nameser.h [deleted file]
contrib/dhcp-3.0/includes/arpa/nameser_compat.h [deleted file]
contrib/dhcp-3.0/includes/cdefs.h [deleted file]
contrib/dhcp-3.0/includes/cf/freebsd.h [deleted file]
contrib/dhcp-3.0/includes/ctrace.h [deleted file]
contrib/dhcp-3.0/includes/dhcp.h [deleted file]
contrib/dhcp-3.0/includes/dhcpd.h [deleted file]
contrib/dhcp-3.0/includes/dhctoken.h [deleted file]
contrib/dhcp-3.0/includes/failover.h [deleted file]
contrib/dhcp-3.0/includes/inet.h [deleted file]
contrib/dhcp-3.0/includes/isc-dhcp/boolean.h [deleted file]
contrib/dhcp-3.0/includes/isc-dhcp/dst.h [deleted file]
contrib/dhcp-3.0/includes/isc-dhcp/int.h [deleted file]
contrib/dhcp-3.0/includes/isc-dhcp/lang.h [deleted file]
contrib/dhcp-3.0/includes/isc-dhcp/list.h [deleted file]
contrib/dhcp-3.0/includes/isc-dhcp/result.h [deleted file]
contrib/dhcp-3.0/includes/isc-dhcp/types.h [deleted file]
contrib/dhcp-3.0/includes/minires/minires.h [deleted file]
contrib/dhcp-3.0/includes/minires/res_update.h [deleted file]
contrib/dhcp-3.0/includes/minires/resolv.h [deleted file]
contrib/dhcp-3.0/includes/netinet/if_ether.h [deleted file]
contrib/dhcp-3.0/includes/netinet/ip.h [deleted file]
contrib/dhcp-3.0/includes/netinet/ip_icmp.h [deleted file]
contrib/dhcp-3.0/includes/netinet/udp.h [deleted file]
contrib/dhcp-3.0/includes/omapip/alloc.h [deleted file]
contrib/dhcp-3.0/includes/omapip/buffer.h [deleted file]
contrib/dhcp-3.0/includes/omapip/convert.h [deleted file]
contrib/dhcp-3.0/includes/omapip/hash.h [deleted file]
contrib/dhcp-3.0/includes/omapip/omapip.h [deleted file]
contrib/dhcp-3.0/includes/omapip/omapip_p.h [deleted file]
contrib/dhcp-3.0/includes/omapip/trace.h [deleted file]
contrib/dhcp-3.0/includes/osdep.h [deleted file]
contrib/dhcp-3.0/includes/site.h [deleted file]
contrib/dhcp-3.0/includes/statement.h [deleted file]
contrib/dhcp-3.0/includes/tree.h [deleted file]
contrib/dhcp-3.0/includes/version.h [deleted file]
contrib/dhcp-3.0/minires/ns_date.c [deleted file]
contrib/dhcp-3.0/minires/ns_name.c [deleted file]
contrib/dhcp-3.0/minires/ns_parse.c [deleted file]
contrib/dhcp-3.0/minires/ns_samedomain.c [deleted file]
contrib/dhcp-3.0/minires/ns_sign.c [deleted file]
contrib/dhcp-3.0/minires/ns_verify.c [deleted file]
contrib/dhcp-3.0/minires/res_comp.c [deleted file]
contrib/dhcp-3.0/minires/res_findzonecut.c [deleted file]
contrib/dhcp-3.0/minires/res_init.c [deleted file]
contrib/dhcp-3.0/minires/res_mkquery.c [deleted file]
contrib/dhcp-3.0/minires/res_mkupdate.c [deleted file]
contrib/dhcp-3.0/minires/res_query.c [deleted file]
contrib/dhcp-3.0/minires/res_send.c [deleted file]
contrib/dhcp-3.0/minires/res_sendsigned.c [deleted file]
contrib/dhcp-3.0/minires/res_update.c [deleted file]
contrib/dhcp-3.0/omapip/alloc.c [deleted file]
contrib/dhcp-3.0/omapip/array.c [deleted file]
contrib/dhcp-3.0/omapip/auth.c [deleted file]
contrib/dhcp-3.0/omapip/buffer.c [deleted file]
contrib/dhcp-3.0/omapip/connection.c [deleted file]
contrib/dhcp-3.0/omapip/convert.c [deleted file]
contrib/dhcp-3.0/omapip/dispatch.c [deleted file]
contrib/dhcp-3.0/omapip/errwarn.c [deleted file]
contrib/dhcp-3.0/omapip/generic.c [deleted file]
contrib/dhcp-3.0/omapip/handle.c [deleted file]
contrib/dhcp-3.0/omapip/hash.c [deleted file]
contrib/dhcp-3.0/omapip/inet_addr.c [deleted file]
contrib/dhcp-3.0/omapip/iscprint.c [deleted file]
contrib/dhcp-3.0/omapip/listener.c [deleted file]
contrib/dhcp-3.0/omapip/message.c [deleted file]
contrib/dhcp-3.0/omapip/mrtrace.c [deleted file]
contrib/dhcp-3.0/omapip/omapi.3 [deleted file]
contrib/dhcp-3.0/omapip/protocol.c [deleted file]
contrib/dhcp-3.0/omapip/result.c [deleted file]
contrib/dhcp-3.0/omapip/support.c [deleted file]
contrib/dhcp-3.0/omapip/toisc.c [deleted file]
contrib/dhcp-3.0/omapip/trace.c [deleted file]
contrib/dhcp-3.0/relay/dhcrelay.8 [deleted file]
contrib/dhcp-3.0/relay/dhcrelay.c [deleted file]
contrib/dhcp-3.0/server/bootp.c [deleted file]
contrib/dhcp-3.0/server/class.c [deleted file]
contrib/dhcp-3.0/server/confpars.c [deleted file]
contrib/dhcp-3.0/server/db.c [deleted file]
contrib/dhcp-3.0/server/ddns.c [deleted file]
contrib/dhcp-3.0/server/dhcp.c [deleted file]
contrib/dhcp-3.0/server/dhcpd.8 [deleted file]
contrib/dhcp-3.0/server/dhcpd.c [deleted file]
contrib/dhcp-3.0/server/dhcpd.conf [deleted file]
contrib/dhcp-3.0/server/dhcpd.conf.5 [deleted file]
contrib/dhcp-3.0/server/dhcpd.leases.5 [deleted file]
contrib/dhcp-3.0/server/failover.c [deleted file]
contrib/dhcp-3.0/server/mdb.c [deleted file]
contrib/dhcp-3.0/server/omapi.c [deleted file]
contrib/dhcp-3.0/server/salloc.c [deleted file]
contrib/dhcp-3.0/server/stables.c [deleted file]
etc/ftpusers
etc/group
etc/mail/aliases
etc/master.passwd
include/paths.h
sbin/dhclient/Makefile
sbin/dhclient/Makefile.common [deleted file]
sbin/dhclient/Makefile.inc [deleted file]
sbin/dhclient/bpf.c [new file with mode: 0644]
sbin/dhclient/client/Makefile [deleted file]
sbin/dhclient/client/clparse.c.patch [deleted file]
sbin/dhclient/client/dhclient.8.no_obj.patch [deleted file]
sbin/dhclient/client/dhclient.c.patch [deleted file]
sbin/dhclient/client/scripts,freebsd.no_obj.patch [deleted file]
sbin/dhclient/clparse.c [new file with mode: 0644]
sbin/dhclient/common/Makefile [deleted file]
sbin/dhclient/common/ctrace.c.patch [deleted file]
sbin/dhclient/common/dhcp-options.5.no_obj.patch [deleted file]
sbin/dhclient/common/discover.c.patch [deleted file]
sbin/dhclient/common/dispatch.c.patch [deleted file]
sbin/dhclient/common/icmp.c.patch [deleted file]
sbin/dhclient/common/parse.c.patch [deleted file]
sbin/dhclient/conflex.c [new file with mode: 0644]
sbin/dhclient/convert.c [new file with mode: 0644]
sbin/dhclient/dhclient-script [new file with mode: 0644]
sbin/dhclient/dhclient-script.8 [new file with mode: 0644]
sbin/dhclient/dhclient.8 [new file with mode: 0644]
sbin/dhclient/dhclient.c [new file with mode: 0644]
sbin/dhclient/dhclient.conf.5 [new file with mode: 0644]
sbin/dhclient/dhclient.leases.5 [new file with mode: 0644]
sbin/dhclient/dhcp-options.5 [new file with mode: 0644]
sbin/dhclient/dhcp.h [new file with mode: 0644]
sbin/dhclient/dhcpd.h [new file with mode: 0644]
sbin/dhclient/dhctoken.h [new file with mode: 0644]
sbin/dhclient/dispatch.c [new file with mode: 0644]
sbin/dhclient/dst/Makefile [deleted file]
sbin/dhclient/errwarn.c [new file with mode: 0644]
sbin/dhclient/includes/Makefile [deleted file]
sbin/dhclient/includes/dhcpd.h.patch [deleted file]
sbin/dhclient/includes/osdep.h.patch [deleted file]
sbin/dhclient/inet.c [new file with mode: 0644]
sbin/dhclient/minires/Makefile [deleted file]
sbin/dhclient/omapip/Makefile [deleted file]
sbin/dhclient/options.c [new file with mode: 0644]
sbin/dhclient/packet.c [new file with mode: 0644]
sbin/dhclient/parse.c [new file with mode: 0644]
sbin/dhclient/privsep.c [new file with mode: 0644]
sbin/dhclient/privsep.h [new file with mode: 0644]
sbin/dhclient/tables.c [new file with mode: 0644]
sys/net/if.h
usr.sbin/Makefile
usr.sbin/dhcp/Makefile [deleted file]
usr.sbin/dhcp/Makefile.common [deleted file]
usr.sbin/dhcp/Makefile.inc [deleted file]
usr.sbin/dhcp/dhcpctl/Makefile [deleted file]
usr.sbin/dhcp/dhcpctl/Makefile.bin [deleted file]
usr.sbin/dhcp/dhcpctl/Makefile.lib [deleted file]
usr.sbin/dhcp/dhcpctl/omshell.1.no_obj.patch [deleted file]
usr.sbin/dhcp/relay/Makefile [deleted file]
usr.sbin/dhcp/server/Makefile [deleted file]

diff --git a/contrib/dhcp-3.0/LICENSE b/contrib/dhcp-3.0/LICENSE
deleted file mode 100644 (file)
index ef2536b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-# Copyright (c) 1995-2003 by Internet Software Consortium
-#
-# 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 ISC DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC 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.
-#
-#   Internet Systems Consortium, Inc.
-#   950 Charter Street
-#   Redwood City, CA 94063
-#   <info@isc.org>
-#   http://www.isc.org/
diff --git a/contrib/dhcp-3.0/README b/contrib/dhcp-3.0/README
deleted file mode 100644 (file)
index a487a2c..0000000
+++ /dev/null
@@ -1,656 +0,0 @@
-              Internet Systems Consortium DHCP Distribution
-                            Version 3.0.2rc3
-                           December  3, 2004
-
-                             README FILE
-
-You should read this file carefully before trying to install or use
-the ISC DHCP Distribution.
-
-                         TABLE OF CONTENTS
-
-       1       WHERE TO FIND DOCUMENTATION
-       2       RELEASE STATUS
-       3       BUILDING THE DHCP DISTRIBUTION
-        3.1     UNPACKING IT
-        3.2     CONFIGURING IT
-         3.2.1   DYNAMIC DNS UPDATES
-         3.2.2   LOCALLY DEFINED OPTIONS
-        3.3     BUILDING IT
-       4       INSTALLING THE DHCP DISTRIBUTION
-       5       USING THE DHCP DISTRIBUTION
-        5.1      FIREWALL RULES
-        5.2     LINUX
-         5.2.1   IF_TR.H NOT FOUND
-         5.2.2   SO_ATTACH_FILTER UNDECLARED
-         5.2.3   PROTOCOL NOT CONFIGURED
-         5.2.4   BROADCAST
-         5.2.6   IP BOOTP AGENT
-         5.2.7   MULTIPLE INTERFACES
-        5.3     SCO
-        5.4     HP-UX
-        5.5     ULTRIX
-        5.6     FreeBSD
-        5.7     NeXTSTEP
-        5.8     SOLARIS
-       6       SUPPORT
-        6.1     HOW TO REPORT BUGS
-
-                     WHERE TO FIND DOCUMENTATION
-
-Documentation for this software includes this README file, the
-RELNOTES file, and the manual pages, which are in the server, common,
-client and relay subdirectories.  The README file (this file) includes
-late-breaking operational and system-specific information that you
-should read even if you don't want to read the manual pages, and that
-you should *certainly* read if you run into trouble.  Internet
-standards relating to the DHCP protocol are stored in the doc
-subdirectory.  You will have the best luck reading the manual pages if
-you build this software and then install it, although you can read
-them directly out of the distribution if you need to.
-
-DHCP server documentation is in the dhcpd man page.  Information about
-the DHCP server lease database is in the dhcpd.leases man page.
-Server configuration documentation is in the dhcpd.conf man page as
-well as the dhcp-options man page.   A sample DHCP server
-configuration is in the file server/dhcpd.conf.   The source for the
-dhcpd, dhcpd.leases and dhcpd.conf man pages is in the server/ sub-
-directory in the distribution.   The source for the dhcp-options.5
-man page is in the common/ subdirectory.
-
-DHCP Client documentation is in the dhclient man page.  DHCP client
-configuration documentation is in the dhclient.conf man page and the
-dhcp-options man page.  The DHCP client configuration script is
-documented in the dhclient-script man page.   The format of the DHCP
-client lease database is documented in the dhclient.leases man page.
-The source for all these man pages is in the client/ subdirectory in
-the distribution.   In addition, the dhcp-options man page should be
-referred to for information about DHCP options.
-
-DHCP relay agent documentation is in the dhcrelay man page, the source
-for which is distributed in the relay/ subdirectory.
-
-To read installed manual pages, use the man command.  Type "man page"
-where page is the name of the manual page.   This will only work if
-you have installed the ISC DHCP distribution using the ``make install''
-command (described later).
-
-If you want to read manual pages that aren't installed, you can type
-``nroff -man page |more'' where page is the filename of the
-unformatted manual page.  The filename of an unformatted manual page
-is the name of the manual page, followed by '.', followed by some
-number - 5 for documentation about files, and 8 for documentation
-about programs.   For example, to read the dhcp-options man page,
-you would type ``nroff -man common/dhcp-options.5 |more'', assuming
-your current working directory is the top level directory of the ISC
-DHCP Distribution.
-
-If you do not have the nroff command, you can type ``more catpage''
-where catpage is the filename of the catted man page.  Catted man
-pages names are the name of the manual page followed by ".cat"
-followed by 5 or 8, as with unformatted manual pages.
-
-Please note that until you install the manual pages, the pathnames of
-files to which they refer will not be correct for your operating
-system.
-
-                           RELEASE STATUS
-
-This is the second release candidate of ISC DHCP 3.0.2.  This is a
-maintenance release which seeks only to fix bugs present in versions
-3.0.1 and earlier.  No new features have or will be added in subsequent
-release candidates of this release.
-
-In this release, the server and relay agent are currently fully
-functional on NetBSD, Linux systems with kernel version 2.2 or later,
-FreeBSD, OpenBSD, BSD/OS, Digital Tru64 Unix and Solaris.  The software
-will also run on AIX and HP-UX, but only supports a single network
-interface.  Ports also exist for QNX, SCO, NeXTStep, and MacOS X, but
-are not in wide use, with all that implies.   We are not aware of an
-easy way to get this software running on HP-UX.
-
-The DHCP client currently only knows how to configure the network on
-NetBSD, FreeBSD, OpenBSD, BSD/os, Linux, Solaris and NextStep.  The
-client depends on a system-dependent shell script to do network
-configuration - support for other operating systems is simply a matter
-of porting this shell script to the new platform.
-
-If you are running the DHCP distribution on a machine which is a
-firewall, or if there is a firewall between your DHCP server(s) and
-DHCP clients, please read the section on firewalls which appears later
-in this document.
-
-If you wish to run the DHCP Distribution on Linux, please see the
-Linux-specific notes later in this document.  If you wish to run on an
-SCO release, please see the SCO-specific notes later in this document.
-You particularly need to read these notes if you intend to support
-Windows 95 clients.  If you are running a version of FreeBSD prior to
-2.2, please read the note on FreeBSD.  If you are running HP-UX or
-Ultrix, please read the notes for those operating systems below.  If
-you are running NeXTSTEP, please see the notes on NeXTSTEP below.
-
-If you start dhcpd and get a message, "no free bpf", that means you
-need to configure the Berkeley Packet Filter into your operating
-system kernel.   On NetBSD, FreeBSD and BSD/os, type ``man bpf'' for
-information.   On Digital Unix, type ``man pfilt''.
-
-
-                   BUILDING THE DHCP DISTRIBUTION
-
-                            UNPACKING IT
-
-To build the DHCP Distribution, unpack the compressed tar file using
-the tar utility and the gzip command - type something like:
-
-       zcat dhcp-3.0.2rc3.tar.gz |tar xvf -
-
-On BSD/OS, you have to type gzcat, not zcat, and you may run into
-similar problems on other operating systems.
-
-                           CONFIGURING IT
-
-Now, cd to the dhcp-3.0.2rc3 subdirectory that you've just created and
-configure the source tree by typing:
-
-       ./configure
-
-If the configure utility can figure out what sort of system you're
-running on, it will create a custom Makefile for you for that
-system; otherwise, it will complain.  If it can't figure out what
-system you are using, that system is not supported - you are on
-your own.
-
-                        DYNAMIC DNS UPDATES
-
-A fully-featured implementation of dynamic DNS updates is included in
-this release.   There are no build dependencies with any BIND version
-- this version can and should just use the resolver in your C library.
-
-There is documentation for the DDNS support in the dhcpd.conf manual
-page - see the beginning of this document for information on finding
-manual pages.
-
-                      LOCALLY DEFINED OPTIONS
-
-In previous versions of the DHCP server there was a mechanism whereby
-options that were not known by the server could be configured using
-a name made up of the option code number and an identifier:
-"option-nnn"   This is no longer supported, because it is not future-
-proof.   Instead, if you want to use an option that the server doesn't
-know about, you must explicitly define it using the method described
-in the dhcp-options man page under the DEFINING NEW OPTIONS heading.
-
-                            BUILDING IT
-
-Once you've run configure, just type ``make'', and after a while
-you should have a dhcp server.  If you get compile errors on one
-of the supported systems mentioned earlier, please let us know.
-If you get warnings, it's not likely to be a problem - the DHCP
-server compiles completely warning-free on as many architectures
-as we can manage, but there are a few for which this is difficult.
-If you get errors on a system not mentioned above, you will need
-to do some programming or debugging on your own to get the DHCP
-Distribution working.
-
-                  INSTALLING THE DHCP DISTRIBUTION
-
-Once you have successfully gotten the DHCP Distribution to build, you
-can install it by typing ``make install''.   If you already have an old
-version of the DHCP Distribution installed, you may want to save it
-before typing ``make install''.
-
-                    USING THE DHCP DISTRIBUTION
-
-                           FIREWALL RULES
-
-If you are running the DHCP server or client on a computer that's also
-acting as a firewall, you must be sure to allow DHCP packets through
-the firewall.  In particular, your firewall rules _must_ allow packets
-from IP address 0.0.0.0 to IP address 255.255.255.255 from UDP port 68
-to UDP port 67 through.  They must also allow packets from your local
-firewall's IP address and UDP port 67 through to any address your DHCP
-server might serve on UDP port 68.  Finally, packets from relay agents
-on port 67 to the DHCP server on port 67, and vice versa, must be
-permitted.
-
-We have noticed that on some systems where we are using a packet
-filter, if you set up a firewall that blocks UDP port 67 and 68
-entirely, packets sent through the packet filter will not be blocked.
-However, unicast packets will be blocked.   This can result in strange
-behaviour, particularly on DHCP clients, where the initial packet
-exchange is broadcast, but renewals are unicast - the client will
-appear to be unable to renew until it starts broadcasting its
-renewals, and then suddenly it'll work.   The fix is to fix the
-firewall rules as described above.
-
-                          PARTIAL SERVERS
-
-If you have a server that is connected to two networks, and you only
-want to provide DHCP service on one of those networks (e.g., you are
-using a cable modem and have set up a NAT router), if you don't write
-any subnet declaration for the network you aren't supporting, the DHCP
-server will ignore input on that network interface if it can.  If it
-can't, it will refuse to run - some operating systems do not have the
-capability of supporting DHCP on machines with more than one
-interface, and ironically this is the case even if you don't want to
-provide DHCP service on one of those interfaces.
-
-                               LINUX
-
-There are three big LINUX issues: the all-ones broadcast address,
-Linux 2.1 ip_bootp_agent enabling, and operations with more than one
-network interface.   There are also two potential compilation/runtime
-problems for Linux 2.1/2.2: the "SO_ATTACH_FILTER undeclared" problem
-and the "protocol not configured" problem.
-
-                 LINUX: SO_ATTACH_FILTER UNDECLARED
-
-In addition, there is a minor issue that we will mention here because
-this release is so close on the heels of the Linux 2.2 release: there
-is a symlink in /usr/include that points at the linux asm headers.  It
-appears to be not uncommon that this link won't be updated correctly,
-in which case you'll get the following error when you try to build:
-
-   lpf.c: In function `if_register_receive':
-   lpf.c:152: `SO_ATTACH_FILTER' undeclared (first use this function)
-   lpf.c:152: (Each undeclared identifier is reported only once
-   lpf.c:152: for each function it appears in.)
-
-The line numbers may be different, of course.   If you see this
-header, your linux asm header link is probably bad, and you should
-make sure it's pointing to correct linux source directory.
-
-                   LINUX: PROTOCOL NOT CONFIGURED
-
-One additional Linux 2.1/2.2 issue: if you get the following message,
-it's because your kernel doesn't have the linux packetfilter or raw
-packet socket configured:
-
- Make sure CONFIG_PACKET (Packet socket) and CONFIG_FILTER (Socket
- Filtering) are enabled in your kernel configuration
-
-If this happens, you need to configure your Linux kernel to support
-Socket Filtering and the Packet socket.  You can do this by typing
-``make config'', ``make menuconfig'' or ``make xconfig'', and then
-enabling the Packet socket and Socket Filtering options that you'll
-see displayed on the menu or in the questionnaire.  You can also edit
-your linux kernel .config file directly: set CONFIG_FILTER=y and
-CONFIG_PACKET=y.  If you do this, make sure you run ``make oldconfig''
-afterwards, so that the changes you've made are propogated to the
-kernel header files.   After you've reconfigured, you need to type
-``make'' to build a new Linux kernel, and then install it in the
-appropriate place (probably /linux).  Make sure to save a copy of your
-old /linux.
-
-If the preceding paragraph made no sense to you, ask your Linux
-vendor/guru for help - please don't ask us.
-
-If you set CONFIG_PACKET=m or CONFIG_FILTER=m, then you must tell the
-kernel module loader to load the appropriate modules.  If this doesn't
-make sense to you, don't use CONFIG_whatever=m - use CONFIG_whatever=y.  
-Don't ask for help with this on the DHCP mailing list - it's a Linux
-kernel issue.   This is probably not a problem with the most recent
-Linux 2.2.x kernels.
-
-                          LINUX: BROADCAST
-
-If you are running a recent version of Linux, this won't be a problem,
-but on older versions of Linux (kernel versions prior to 2.2), there
-is a potential problem with the broadcast address being sent
-incorrectly.
-
-In order for dhcpd to work correctly with picky DHCP clients (e.g.,
-Windows 95), it must be able to send packets with an IP destination
-address of 255.255.255.255.  Unfortunately, Linux changes an IP
-destination of 255.255.255.255 into the local subnet broadcast address
-(here, that's 192.5.5.223).
-
-This isn't generally a problem on Linux 2.2 and later kernels, since
-we completely bypass the Linux IP stack, but on old versions of Linux
-2.1 and all versions of Linux prior to 2.1, it is a problem - pickier
-DHCP clients connected to the same network as the ISC DHCP server or
-ISC relay agent will not see messages from the DHCP server.   It *is*
-possible to run into trouble with this on Linux 2.2 and later if you
-are running a verson of the DHCP server that was compiled on a Linux
-2.0 system, though.
-
-It is possible to work around this problem on some versions of Linux
-by creating a host route from your network interface address to
-255.255.255.255.   The command you need to use to do this on Linux
-varies from version to version.   The easiest version is:
-
-       route add -host 255.255.255.255 dev eth0
-
-On some older Linux systems, you will get an error if you try to do
-this.   On those systems, try adding the following entry to your
-/etc/hosts file:
-
-255.255.255.255        all-ones
-
-Then, try:
-
-       route add -host all-ones dev eth0
-
-Another route that has worked for some users is:
-
-       route add -net 255.255.255.0 dev eth0
-
-If you are not using eth0 as your network interface, you should
-specify the network interface you *are* using in your route command.
-
-                       LINUX: IP BOOTP AGENT
-
-Some versions of the Linux 2.1 kernel apparently prevent dhcpd from
-working unless you enable it by doing the following:
-
-             echo 1 >/proc/sys/net/ipv4/ip_bootp_agent
-
-
-                     LINUX: MULTIPLE INTERFACES
-
-Very old versions of the Linux kernel do not provide a networking API
-that allows dhcpd to operate correctly if the system has more than one
-broadcast network interface.  However, Linux 2.0 kernels with version
-numbers greater than or equal to 2.0.31 add an API feature: the
-SO_BINDTODEVICE socket option.  If SO_BINDTODEVICE is present, it is
-possible for dhcpd to operate on Linux with more than one network
-interface.  In order to take advantage of this, you must be running a
-2.0.31 or greater kernel, and you must have 2.0.31 or later system
-headers installed *before* you build the DHCP Distribution.
-
-We have heard reports that you must still add routes to 255.255.255.255
-in order for the all-ones broadcast to work, even on 2.0.31 kernels.
-In fact, you now need to add a route for each interface.   Hopefully
-the Linux kernel gurus will get this straight eventually.
-
-Linux 2.1 and later kernels do not use SO_BINDTODEVICE or require the
-broadcast address hack, but do support multiple interfaces, using the
-Linux Packet Filter.
-
-                                SCO
-
-SCO has the same problem as Linux (described earlier).  The thing is,
-SCO *really* doesn't want to let you add a host route to the all-ones
-broadcast address.
-
-On more recent versions of SCO, you can do this:
-
-  ifconfig net0 xxx.xxx.xxx.xxx netmask 0xNNNNNNNN broadcast 255.255.255.255
-
-If this doesn't work, you can also try the following strange hack:
-
-  ifconfig net0 alias 10.1.1.1 netmask 8.0.0.0
-
-Apparently this works because of an interaction between SCO's support
-for network classes and the weird netmask.  The 10.* network is just a
-dummy that can generally be assumed to be safe.   Don't ask why this
-works.   Just try it.   If it works for you, great.   SCO has added
-support for doing DHCP in a more sensible way, but I have not had the
-time or cause to implement them.   If you are interested in this, and
-are able to hack your way out of a wet paper back without assistance,
-we'd appreciate it if you'd give it a try, but don't expect too much
-support from us (sorry!).
-
-                               HP-UX
-
-HP-UX has the same problem with the all-ones broadcast address that
-SCO and Linux have.   One user reported that adding the following to
-/etc/rc.config.d/netconf helped (you may have to modify this to suit
-your local configuration):
-
-INTERFACE_NAME[0]=lan0
-IP_ADDRESS[0]=1.1.1.1
-SUBNET_MASK[0]=255.255.255.0
-BROADCAST_ADDRESS[0]="255.255.255.255"
-LANCONFIG_ARGS[0]="ether"
-DHCP_ENABLE[0]=0
-
-                               ULTRIX
-
-Now that we have Ultrix packet filter support, the DHCP Distribution
-on Ultrix should be pretty trouble-free.  However, one thing you do
-need to be aware of is that it now requires that the pfilt device be
-configured into your kernel and present in /dev.  If you type ``man
-packetfilter'', you will get some information on how to configure your
-kernel for the packet filter (if it isn't already) and how to make an
-entry for it in /dev.
-
-                              FreeBSD
-
-Versions of FreeBSD prior to 2.2 have a bug in BPF support in that the
-ethernet driver swaps the ethertype field in the ethernet header
-downstream from BPF, which corrupts the output packet.   If you are
-running a version of FreeBSD prior to 2.2, and you find that dhcpd
-can't communicate with its clients, you should #define BROKEN_FREEBSD_BPF 
-in site.h and recompile.
-
-Modern versions of FreeBSD include the ISC DHCP 3.0 client as part of
-the base system, and the full distribution (for the DHCP server and
-relay agent) is available from the Ports Collection in
-/usr/ports/net/isc-dhcp3, or as a package on FreeBSD installation
-CDROMs.
-
-                              NeXTSTEP
-
-The NeXTSTEP support uses the NeXTSTEP Berkeley Packet Filter
-extension, which is not included in the base NextStep system.  You
-must install this extension in order to get dhcpd or dhclient to work.
-
-                              SOLARIS
-
-One problem which has been observed and is not fixed in this
-patchlevel has to do with using DLPI on Solaris machines.  The symptom
-of this problem is that the DHCP server never receives any requests.
-This has been observed with Solaris 2.6 and Solaris 7 on Intel x86
-systems, although it may occur with other systems as well.  If you
-encounter this symptom, and you are running the DHCP server on a
-machine with a single broadcast network interface, you may wish to
-edit the includes/site.h file and uncomment the #define USE_SOCKETS
-line.  Then type ``make clean; make''.
-
-The DHCP client on Solaris will only work with DLPI.  If you run it
-and it just keeps saying it's sending DHCPREQUEST packets, but never
-gets a response, you may be having DLPI trouble as described above.
-If so, we have no solution to offer at this time.  Also, because
-Solaris requires you to "plumb" an interface before it can be detected
-by the DHCP client, you must either specify the name(s) of the
-interface(s) you want to configure on the command line, or must plumb
-the interfaces prior to invoking the DHCP client.  This can be done
-with ``ifconfig iface plumb'', where iface is the name of the
-interface (e.g., ``ifconfig hme0 plumb'').
-
-It should be noted that Solaris versions from 2.6 onward include a
-DHCP client that you can run with ``/sbin/ifconfig iface dhcp start''
-rather than using the ISC DHCP client.  The feature set of the Solaris
-client is different (not necessarily better or worse) than that of the
-ISC client, but in most cases it will be a lot easier for you to just
-use that.  Please do not ask for help in using the Solaris DHCP client
-on Internet Systems Consortium mailing lists - that's why you're
-paying Sun the big bucks.   If you're having a problem with the
-Solaris client interoperating with the ISC dhcp server, that's another
-matter, but please check with Sun first.
-
-                               AIX
-
-The AIX support uses the BSD socket API, which cannot differentiate on
-which network interface a broadcast packet was received; thus the DHCP
-server and relay will work only on a single interface.  (They do work
-on multi-interface machines if configured to listen on only one of the
-interfaces.)
-
-The ISC DHCP distribution does not include a dhclient-script for AIX--
-AIX comes with a DHCP client.  Contribution of a working dhclient-script
-for AIX would be welcome.
-
-                              SUPPORT
-
-The Internet Systems Consortium DHCP server is not a commercial
-product, and is not supported by the ISC.  However, it has attracted a
-fairly sizable following on the Internet, which means that there are a
-lot of knowledgable users who may be able to help you if you get
-stuck.  These people generally read the dhcp-server@isc.org mailing
-list.
-
-If you are going to use dhcpd, you should probably subscribe to the
-dhcp-server and dhcp-announce mailing lists.  If you will be using
-dhclient, you should subscribe to the dhcp-client mailing list.
-
-If you need help, you should ask on the dhcp-server or dhcp-client
-mailing list - whichever is appropriate to your application.  Support
-requests for the ISC DHCP client should go to dhcp-client@isc.org.
-Support requests for the DHCP server should go to dhcp-server@isc.org.
-If you are having trouble with a combination of the client and server,
-send the request to dhcp-server@isc.org.  Please do not cross-post to
-both lists under any circumstances.
-
-WHERE TO REPORT BUGS: If you want the act of sending in a bug report
-to result in you getting help in the form of a fixed piece of
-software, you are asking for help.  Your bug report is helpful to us,
-but fundamentally you are making a support request, so please use the
-addresses described in the previous paragraphs.  If you are _sure_ that
-your problem is a bug, and not user error, or if your bug report
-includes a patch, you can send it to dhcp-bugs@isc.org without
-subscribing.   This mailing list goes into a bug tracking system, so
-you don't need to check periodically to see if we still remember the
-bug - if you haven't been notified that the bug has been closed, we
-still consider it a bug, and still have it in the system.
-
-PLEASE DO NOT REPORT BUGS IN OLD SOFTWARE RELEASES!  Fetch the latest
-release and see if the bug is still in that version of the software,
-and if it's not, _then_ report it.  It's okay to report bugs in the
-latest patchlevel of a major version that's not the most recent major
-version, though - for example, if you're running 3.0.1, you don't have
-to upgrade to a 3.0.2rc (release candidate) before you can report bugs.
-
-PLEASE DO NOT REPORT BUGS IF YOU ARE RUNNING A VERSION OF THE ISC
-DHCP DISTRIBUTION THAT YOU DIDN'T GET FROM THE ISC!   Free operating
-system distributions are notorious for including outdated versions of
-software, and also versions of software that were not compiled on your
-particular version of the operating system.   These versions
-frequently do not work.   Getting a source distribution from the ISC
-and installing it frequently *does* work.   Please try this *before*
-asking for help.
-
-PLEASE READ THIS README FILE CAREFULLY BEFORE REPORTING BUGS,
-PARTICULARLY THE SECTION BELOW ON WHAT TO INCLUDE IN A BUG REPORT OR
-HELP REQUEST.
-
-PLEASE DO NOT SEND REQUESTS FOR SUPPORT DIRECTLY TO THE ENGINEERS WHO
-WORK ON THE ISC DHCP DISTRIBUTION!  *PARTICULARLY*, DO NOT SEND MAIL
-TO THE ENGINEERS BECAUSE YOU AREN'T SURE TO WHOM YOU SHOULD SEND MAIL
-- if you aren't sure, *ask* on the dhcp-server@isc.org or
-dhcp-client@isc.org mailing list.
-
-The number of people using the DHCP Distribution is sufficiently large
-that if we take interrupts every time any one of those people runs
-into trouble, we will never get any more coding done.  If you send a
-support request directly to any ISC or Nominum engineer, we will
-forward it to the mailing list, or possibly ignore it, depending on
-how much stress we are under at the time.
-
-Please do not Cc: us on mail you send to these lists - we read both
-mailing lists, so this just means we get two copies!
-
-If your question can only be answered by one of the engineers, send it
-to the appropriate public mailing list anyway - we will answer it
-there.  When we have time.
-
-Please do not think "Oh, I don't want to bother the whole mailing list
-with this question."  If you are too embarrassed to ask publically,
-get a support contract.
-
-If you are concerned about bothering everybody on the list, that's
-great, but that's what the list is there for.  When you send mail to
-one of the engineers, you are taking resources away from everybody on
-the mailing list *anyway* - they just don't know it.
-
-We're not writing this because we don't respect you - we really do
-want to help you, and we appreciate your bug reports and comments.
-But please use the mechanisms we have in place to provide you with
-help, because otherwise you are almost certainly depriving someone
-else of our help.
-
-PLEASE DO NOT CALL US ON THE PHONE FOR HELP!  Answering the phone
-takes a lot more of our time and attention than answering email.  If
-you do call us on the phone, we will tell you to send email to the
-mailing list or buy a support contract, so please don't waste your
-time or ours.  If you have a support contract, please use the support
-channel mentioned in the support contract - otherwise you probably
-won't get timely support unless you happen to ask an interesting
-question and we happen to have some time to kill, because we can't
-tell you're a support customer if you send mail to the public mailing
-lists.
-
-               HOW TO REPORT BUGS OR REQUEST HELP
-
-When you report bugs or ask for help, please provide us complete
-information.  A list of information we need follows.  Please read it
-carefully, and put all the information you can into your initial bug
-report, so that we don't have to ask you any questions in order to
-figure out your problem.   If you need handholding support, please
-consider contacting a commercial provider of the ISC DHCP
-Distribution.
-
-      1.  The specific operating system name and version of the
-          machine on which the DHCP server or client is running.
-      2.  The specific operating system name and version of the
-          machine on which the client is running, if you are having
-          trouble getting a client working with the server.
-      3.  If you're running Linux, the version number we care about is
-          the kernel version and maybe the library version, not the
-          distribution version - e.g., while we don't mind knowing
-          that you're running Redhat version mumble.foo, we must know
-          what kernel version you're running, and it helps if you can
-          tell us what version of the C library you're running,
-          although if you don't know that off the top of your head it
-          may be hard for you to figure it out, so don't go crazy
-          trying.
-      4.  The specific version of the DHCP distribution you're
-          running, for example "2.0b1pl19", not "2.0".
-      5.  Please explain the problem carefully, thinking through what
-          you're saying to ensure that you don't assume we know
-          something about your situation that we don't know.
-      6.  Include your dhcpd.conf and dhcpd.leases file if they're not
-          huge (if they are huge, we may need them anyway, but don't
-          send them until you're asked).   Huge means more than 100
-          kilobytes each.
-      7.  Include a log of your server or client running until it
-          encounters the problem - for example, if you are having
-          trouble getting some client to get an address, restart the
-          server with the -d flag and then restart the client, and
-          send us what the server prints.   Likewise, with the client,
-          include the output of the client as it fails to get an
-          address or otherwise does the wrong thing.   Do not leave
-          out parts of the output that you think aren't interesting.
-      8.  If the client or server is dumping core, please run the
-          debugger and get a stack trace, and include that in your
-          bug report.   For example, if your debugger is gdb, do the
-          following:
-
-               gdb dhcpd dhcpd.core
-               (gdb) where
-                     [...]
-               (gdb) quit
-
-         This assumes that it's the dhcp server you're debugging, and
-         that the core file is in dhcpd.core.
-      9.  If you know that the problem is an actual bug, and you can
-         reproduce the bug, you can skip steps 6 through 8 and instead
-         capture a trace file using the -tf flag (see the man page for
-         details).   If you do this, and there is anything in your
-         dhcp configuration that you are not willing to make public,
-         please send the trace file to dhcp-bugs@isc.org and NOT to
-         dhcp-server@isc.org, because the tracefile contains your entire
-         dhcp configuration.
-
-PLEASE DO NOT send queries about non-isc clients to the dhcp-client
-mailing list.   If you're asking about them on an ISC mailing list,
-it's probably because you're using the ISC DHCP server, so ask there.
-If you are having problems with a client whose executable is called
-dhcpcd, this is _not_ the ISC DHCP client, and we probably can't help
-you with it.
-
-Please see http://www.isc.org/sw/dhcp/ for details on how to subscribe
-to the ISC DHCP mailing lists.
-
-
diff --git a/contrib/dhcp-3.0/README.DELETED b/contrib/dhcp-3.0/README.DELETED
deleted file mode 100644 (file)
index 786887d..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-Makefile
-Makefile.conf
-Makefile.dist
-client/Makefile.dist
-client/scripts/bsdos
-client/scripts/linux
-client/scripts/netbsd
-client/scripts/nextstep
-client/scripts/openbsd
-client/scripts/solaris
-common/Makefile.dist
-configure
-contrib
-dhcpctl/Makefile.dist
-dhcpctl/cltest.c
-doc
-dst/Makefile.dist
-includes/cf/aix.h
-includes/cf/alphaosf.h
-includes/cf/bsdos.h
-includes/cf/cygwin32.h
-includes/cf/hpux.h
-includes/cf/irix.h
-includes/cf/linux.h
-includes/cf/netbsd.h
-includes/cf/nextstep.h
-includes/cf/openbsd.h
-includes/cf/qnx.h
-includes/cf/rhapsody.h
-includes/cf/sample.h
-includes/cf/sco.h
-includes/cf/sunos4.h
-includes/cf/sunos5-5.h
-includes/cf/ultrix.h
-minires/Makefile.dist
-omapip/Makefile.dist
-omapip/test.c
-relay/Makefile.dist
-server/Makefile.dist
-site.conf
-tests
diff --git a/contrib/dhcp-3.0/README.DRAGONFLY b/contrib/dhcp-3.0/README.DRAGONFLY
deleted file mode 100644 (file)
index f02023b..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Original Source can be downloaded from:
-ftp://ftp.isc.org/isc/dhcp/dhcp-3.0.2rc3.tar.gz
-MD5 (dhcp-3.0.2rc3.tar.gz) = 7c5dd4587d0236275ddf026750513131
-
-A list of files and directories removed is in README.DELETED.
diff --git a/contrib/dhcp-3.0/RELNOTES b/contrib/dhcp-3.0/RELNOTES
deleted file mode 100644 (file)
index 2200102..0000000
+++ /dev/null
@@ -1,1441 +0,0 @@
-             Internet Systems Consortium DHCP Distribution
-                            Version 3.0.2rc3
-                           December  3, 2004
-
-                            Release Notes
-
-                            NEW FEATURES
-
-Version 3 of the ISC DHCP Distribution includes the following features
-that are new since version 2.0:
-
-     - DHCP Failover Protocol support
-     - OMAPI, an API for accessing and modifying the DHCP server and
-       client state.
-     - Conditional behaviour
-     - Storing arbitrary information on leases
-     - Address pools with access control
-     - Client classing
-     - Address allocation restriction by class
-     - Relay agent information option support 
-     - Dynamic DNS updates
-     - Many bug fixes, performance enhancements, and minor new DHCP
-       protocol features. 
-
-The main bug fixed here is a bug in the subclass allocation code that
-could result in a memory smash.   Any users of the ISC DHCP server who
-are using subclasses should seriously consider upgrading to 3.0.1.
-
-If you are running 3.0 beta 1 and are doing dynamic DNS updates, the
-lease file is no longer forward-compatible to 3.0 final.   A script
-has been provided to convert 3.0b1 lease files.   This is in
-contrib/3.0b1-lease-convert.
-
-For information on how to install, configure and run this software,
-as well as how to find documentation and report bugs, please consult
-the README file.
-
-The Dynamic DNS Update support is a descendent of an implementation
-done by Lans Carstensen and Brian Dols at Rose-Hulman Institute of
-Technology, Jim Watt at Applied Biosystems, Irina Goble at Integrated
-Measurement Systems, Igor Sharfmesser at Kazakh Telecom, and Brian
-Murrell at BC Tel Advanced Communications.  I'd like to express my
-thanks to all of these good people here, both for working on the code
-and for prodding me into improving it.
-
-                       Changes since 3.0.2rc2
-
-- Two varaibles introduced in 3.0.2b1 were used without being initialized
-  in the case where neither the FILE nor SNAME fields were available for
-  overloading.  This was repaired.
-
-- A heretofore believed to be impossible corner case of the option
-  overloading implementation turned out to be possible ("Unable to sort
-  overloaded options after 10 tries.").  The implementation was reworked
-  to consider the case of an option so large it would require more than
-  three chunks to fit.
-
-- Many other instances of variables being used without being initialized
-  were repaired.
-
-- An uninitialized variable in omapi_io_destroy() led to the discovery
-  that this function may result in orphaned pointers (and hence, a memory
-  leak).
-
-                       Changes since 3.0.2rc1
-
-- allocate_lease() was rewritten to repair a bug in which the server would
-  try to allocate an ABANDONED lease when FREE leases were available.
-
-                       Changes since 3.0.2b1
-
-- Some dhcp-eval.5 manpage formatting was repaired.
-
-                       Changes since 3.0.1
-
-- A bug was fixed in the server's 'option overloading' implementation,
-  where options loaded into the 'file' and 'sname' packet fields were
-  not aligned precisely as rfc2131 dictates.
-
-- The FreeBSD client script was changed to support the case where a domain
-  name was not provided by the server.
-
-- A memory leak in 'omshell' per each command line parsed was
-  repaired, thanks to a patch from Jarkko Torppa.
-
-- Log functions writing to stderr were adjusted to use the STDERR_FILENO
-  system definition rather than '2'.  This is a no-op for 90% of platforms.
-
-- One call to trace_write_packet_iov() counted the number of io vectors
-  incorrectly, causing inconsistent tracefiles.  This was fixed.
-
-- Some expression parse failure memory leaks were closed.
-
-- A host byte order problem in tracefiles was repaired.
-
-- Pools configured in DHCPD for failover possessing permission lists that
-  previously were assumed to not include dyanmic bootp clients are now
-  a little more pessimistic.  The result is, dhcpd will nag you about just
-  about most pools that possess a 'allow' statement with no 'deny' that
-  would definitely match a dynamic bootp client.
-
-- The 'ddns-update-style' configuration warning bit now insists that
-  the configuration be globally scoped.
-
-- Two memory leaks in dhclient were closed thanks to a patch from Felix
-  Farkas.
-
-- Some minor but excellently pedantic documentation errors were fixed
-  thanks to a patch from Thomas Klausner.
-
-- Bugs in operator precedence in executable statements have been repaired
-  once again.  More legal syntaxes should be parsed legally.
-
-- Failing to initialize a tracefile for any reason if a tracefile was
-  specified is now a fatal error.  Thanks to a patch from Albert Herranz.
-
-- Corrected a bug in which the number of leases transferred as calculated
-  by the failover primary and sent to peers in POOLRESP responses may be
-  incorrect.  This value is not believed to be used by other failover
-  implementations, excepting perhaps as logged information.
-
-- Corrected a bug in which 'dhcp_failover_send_poolresp()' was in fact
-  sending POOLREQ messages instead of POOLRESP mesasges.  This message
-  was essentially ignored since failover secondaries effectively do not
-  respond to POOLREQ messages.
-
-- Type definitions for various bitwidths of integers in the sunos5-5
-  build of ISC DHCP have been fixed.  It should compile and run more
-  easily when built in 64-bit for this platform.
-
-- "allow known-clients;" is now a legal syntax, to avoid confusion.
-
-- If one dhcp server chooses to 'load balance' a request to its failover
-  peer, it first checks to see if it believes said peer has a free
-  lease to allocate before ignoring the DISCOVER.
-
-- log() was logging a work buffer, rather than the value returned by
-  executing the statements configured by the user.  In some cases,
-  the work buffer and the intended results were the same.  In some other
-  cases, they were not.  This was fixed thanks to a patch from Gunnar
-  Fjone and directconnect.no.
-
-- Compiler warnings for some string type conversions was fixed, thanks
-  to Andreas Gustafsson.
-
-- The netbsd build environments were simplified to one, in which
-  -Wconversion is not used, thanks to Andreas Gustafsson.
-
-- How randomness in the backoff-cutoff dhclient configuration variable
-  is implemented was better documented in the manpage, and the behaviour
-  of dhclient in REQUEST timeout handling was changed to match that of
-  DISCOVER timeout handling.
-
-- Omapi was hardened against clients that pass in null values, thanks
-  to a patch from Mark Jason Dominus.
-
-- A bug was fixed in dhclient that kept it from doing client-side
-  ddns updates.  Thanks to a patch from Andreas Gustafsson, which
-  underwent some modification after review by Jason Vas Dias.
-
-- Failover implementations disconnected due to the network between
-  them (rather than one of the two shutting down) will now try to
-  re-establish the failover connection every 5 seconds, rather than
-  to simply try once and give up until one of them is restarted.
-  Thanks to a patch from Ulf Ekberg from Infoblox, and field testing
-  by Greger V. Teigre which led to an enhancement to it.
-
-- A problem that kept DHCP Failover secondaries from tearing down
-  ddns records was repaired.  Thanks to a patch from Ulf Ekberg from
-  Infoblox.
-
-- 64bit pointer sizes are detected properly on FreeBSD now.
-
-- A bug was repaired where the DHCP server would leave stale references
-  to host records on leases it once thought about offering to certain
-  clients.  The result would be to apply host and 'known' scopes to the
-  wrong clients (possibly denying booting).  NOTE:  The 'mis-host' patch
-  that was being circulated as a workaround is not the way this bug was
-  fixed.  If you were a victim of this bug in 3.0.1, you are cautioned
-  to proceed carefully and see if it fixes your problem.
-
-- A bug was repaired in the server's DHCPINFORM handling, where it
-  tried to divine the client's address from the source packet and
-  would get it wrong.  Thanks to Anshuman Singh Rawat.
-
-- A log message was introduced to help illuminate the case where the
-  server was unable to find a lease to assign to any BOOTP client.
-  Thanks to Daniel Baker.
-
-- A minor dhcpd.conf.5 manpage error was fixed.
-
-                       Changes since 3.0.1rc14
-
-- The global variable 'cur_time' was centralized and is now uniformly of a
-  type #defined in system-dependent headers.  It had previously been defined
-  in one of many places as a 32-bit value, and this causes mayhem on 64-bit
-  big endian systems.  It probably wasn't too healthy on little endian
-  systems either.
-
-- A printf format string error introduced in rc14 was repaired.
-
-- AIX system-dependent header file was altered to only define NO_SNPRINTF
-  if the condition used to #ifdef in vsnprintf in AIX' header files
-  is false.
-
-- The Alpha/OSF system-dependent header file was altered to define
-  NO_SNPRINTF on OS revisions older than 4.0G.
-
-- omapip/test.c had string.h added to its includes.
-
-                       Changes since 3.0.1rc13
-
-! CAN-2004-0460 - CERT VU#317350: Five stack overflow exploits were closed
-  in logging messages with excessively long hostnames provided by the
-  clients.  It is highly probable that these could have been used by
-  attackers to gain arbitrary root access on systems using ISC DHCP 3.0.1
-  release candidates 12 or 13.  Special thanks to Gregory Duchemin for
-  both finding and solving the problem.
-
-! CAN-2004-0461 - CERT VU#654390: Once the above was closed, an opening
-  in log_*() functions was evidented, on some specific platforms where
-  vsnprintf() was not believed to be available and calls were wrapped to
-  sprintf() instead.  Again, credit goes to Gregory Duchemin for finding
-  the problem.  Calls to snprintf() are now linked to a distribution-local
-  snprintf implementation, only in those cases where the architecture is
-  not known to provide one (see includes/cf/[arch].h).  If you experience
-  linking problems with snprintf/vsnprintf or 'isc_print_' functions, this
-  is where to look.  This vulnerability did not exist in any previously
-  published version of ISC DHCP.
-
-- Compilation on hpux 11.11 was repaired.
-
-- 'The cross-compile bug fix' was backed out.
-
-                       Changes since 3.0.1rc12
-
-- Fixed a bug in omapi lease lookup function, to form the hardware
-  address for the hash lookup correctly, thanks to a patch from
-  Richard Hirst.
-
-- Fixed a bug where dhcrelay was sending relayed responses back to the
-  broadcast address, but with the source's unicast mac address.  Should
-  now conform to rfc2131 section 4.1.
-
-- Cross-compile bug fix; use $(AR) instead of ar.  Thanks to Morten Brorup.
-
-- Fixed a crash bug in dhclient where dhcpd servers that do not provide
-  renewal times results in an FPE.  As a side effect, dhclient can now
-  properly handle 0xFFFFFFFF (-1) expiry times supplied by servers.  Thanks
-  to a patch from Burt Silverman.
-
-- The 'ping timeout' debugs from rc12 were removed to -DDEBUG only,
-  and reformatted to correct a compilation error on solaris platforms.
-
-- A patch was applied which fixes a case where leases read from the
-  leases database do not properly over-ride previously read leases.
-
-- dhcpctl.3 manpage was tweaked.
-
-                       Changes since 3.0.1rc11
-
-- A patch from Steve Campbell was applied with minor modifications to
-  permit reverse dns PTR record updates with values containing spaces.
-
-- A patch from Florian Lohoff was applied with some modifications to
-  dhcrelay.  It now discards packets whose hop count exceeds 10 by default,
-  and a command-line option (-c) can be used to set this threshold.
-
-- A failover bug relating to identifying peers by name length instead of
-  by name was fixed.
-
-- Delcaring failover configs within shared-network statements should no
-  longer result in error.
-
-- The -nw command line option to dhclient now works.
-
-- Thanks to a patch from Michael Richardson:
-       - Some problems with long option processing have been fixed.
-       - Some fixes to minires so that updates of KEY records will work.
-
-- contrib/ms2isc was updated by Shu-Min Chang of the Intel Corporation.
-  see contrib/ms2isc/readme.txt for revision notes.
-
-- Dhclient no longer uses shell commands to kill another instance of
-  itself, it sends the signal directly.  Thanks to a patch from Martin
-  Blapp.
-
-- The FreeBSD dhclient-script was changed so that a failure to write to
-  /etc/resolv.conf does not prematurely end the script.  This keeps dhclient
-  from looping infinitely when this is the case.  Thanks to a patch from
-  Martin Blapp.
-
-- A patch from Bill Stephens was applied which resolves a problem with lease
-  expiry times in failover configurations.
-
-- A memory leak in configuration parsing was closed thanks to a patch from
-  Steve G.
-
-- The function which discovers interfaces will now skip non-broadcast or
-  point-to-point interfaces, thanks to a patch from David Brownlee.
-
-- Options not yet known by the dhcpd or dhclient have had their names
-  changed such that they do not contain # symbols, in case they should ever
-  appear in a lease file.  An option that might have been named "#144" is
-  now "unknown-144".
-
-- Another patch from Bill Stephens which allows the ping-check timeout to
-  be configured as 'ping-timeout'.  Defaults to 1.
-
-                       Changes since 3.0.1rc10
-
-- Potential buffer overflows in minires repaired.
-
-- A change to the linux client script to use /bin/bash, since /bin/sh may
-  not be bash.
-
-- Some missing va_end cleanups thanks to a patch from Thomas Klausner.
-
-- A correction of boolean parsing syntax validation - some illegal syntaxes
-  that worked before are now detected and produce errs, some legal syntaxes
-  that errored before will now work properly.
-
-- Some search-and-replace errors that caused some options to change their
-  names was repaired.
-
-- Shu-min Chang of the Intel corporation has contributed a perl script and
-  module that converts the MS NT4 DHCP configuration to a ISC DHCP3
-  configuration file.
-
-- Applied the remainder of the dhcpctl memory leak patch provided by Bill
-  Squier at ReefEdge, Inc.  (groo@reefedge.com).
-
-- Missing non-optional failover peer configurations will now result in a soft
-  error rather than a null dereference.
-
-                       Changes since 3.0.1rc9
-
-- A format string was corrected to fix compiler warnings.
-
-- A number of spelling corrections were made in the man pages.
-
-- The dhclient.conf.5 man page was changed to refer to do-forward-updates
-  rather than a configuration option that doesn't exist.
-
-- A FreeBSD-specific bug in the interface removal handling was fixed.
-
-- A Linux-specific Token Ring detection problem was fixed.
-
-- Hashes removed from as-yet-unknown agent options, having those options
-  appear in reality before we know about them will no longer produce
-  self-corrupting lease databases.
-
-- dhclient will use the proper port numbers now when using the -g option.
-
-- A order-of-operations bug with 2 match clauses in 1 class statement is
-  fixed thanks to a patch from Andrew Matheson.
-
-- Compilation problems on Solaris were fixed.
-
-- Compilation problems when built with DEBUG or DEBUG_PACKET were repaired.
-
-- A fix to the dhcp ack process which makes certain group options will be
-  included in the first DHCPOFFER message was made thanks to a patch from
-  Ling Gou.
-
-- A few memory leaks were repaired thanks to patches from Bill Squier at
-  ReefEdge, Inc.  (groo@reefedge.com).
-
-- A fix for shared-networks that sometimes give clients options for the
-  wrong subnets (in particular, 'option routers') was applied, thanks to
-  Ted Lemon for the patch.
-
-- Omshell's handling of dotted octets as values was changed such that dots
-  one after the other produce zero values in the integer string.
-
-                       Changes since 3.0.1rc8
-
-- Fix a format string vulnerability in the server that could lead to a
-  remote root compromise (discovered by NGSEC Research Team, www.ngsec.com).
-
-- Add additional support for NetBSD/sparc64.
-
-- Fix a bug in the command-line parsing of the client.  Also, resolve
-  a memory leak.
-
-- Add better support for shells other than bash in the Linux client
-  script.
-
-- Various build fixes for modern versions of FreeBSD and Linux.
-
-- Fix a bad bounds check when printing binding state names.
-
-- Clarify documentation about fixed-address and multiple addresses.
-
-- Fix a typo in the authoritative error message.
-
-- Make a log entry when we can't write a billing class.
-
-- Use conversion targets that are the right size on all architectures.
-
-- Increment the hop count when relaying.
-
-- Log a message when lease state is changed through OMAPI.
-
-- Don't rerun the shared_network when evaluating the pool.
-
-- Fix a reversed test in the parser.
-
-- Change the type of rbuf_max.
-
-- Make FTS_LAST a manifest constant to quiet warnings.
-
-                       Changes since 3.0.1rc7
-
-- Fix two compiler warnings that are generated when compiling on Solaris
-  with gcc.   These stop the build, even though they weren't actually
-  errors, because we prefer that our builds generate no warnings.
-
-                       Changes since 3.0.1rc6
-
-- Don't allow a lease that's in the EXPIRED, RELEASED or RESET state
-  to be renewed.
-
-- Implement lease stealing for cases where the primary has fewer leases
-  than the secondary, as called for by the standard.
-
-- Add a fudge factor to the lease expiry acceptance code, (suggested
-  by Kevin Miller of CMU).
-
-- Fix a bug in permit_list_match that made it much too willing to say
-  that two permit lists matched.
-
-- Unless DEBUG_DNS_UPDATES is defined, print more user-friendly (and
-  also more compact) messages about DNS updates.
-
-- Fix a bug in generating wire-format domain names for the FQDN option.
-
-- Fix a bug where the FQDN option would not be returned if the client
-  requested it, contrary to the standard.
-
-- On Darwin, use the FreeBSD DHCP client script.
-
-- On NetBSD/sparc, don't check for casting warnings.
-
-- Add a flag in the DHCP client to disable updating the client's A
-  record when sending an FQDN option indicating that the client is
-  going to update its A record.
-
-- In the client, don't attempt a DNS update until one second after
-  configuring the new IP address, and if the update times out, keep
-  trying until a response, positive or negative, is received from the
-  DNS server.
-
-- Fix an uninitialized memory bug in the DHCP client.
-
-- Apply some FreeBSD-specific bug fixes suggested by Murray Stokely.
-
-- Fix a bug in ns_parserr(), where it was returning the wrong sort
-  of result code in some cases (suggested by Ben Harris of the
-  NetBSD project).
-
-- Fix a bug in is_identifier(), where it was checking against EOF
-  instead of the END_OF_FILE token (also suggested by Ben Harris).
-
-- Fix a bug where if an option universe contained no options, the
-  DHCP server could dump core (Walter Steiner).
-
-- Fix a bug in the handling of encapsulated options.
-
-- Fix a bug that prevented NWIP suboptions from being processed.
-
-- Delete the FTS_BOOTP and FTS_RESERVED states and implement them
-  as modifier flags to the FTS_ACTIVE state, as called for in the
-  failover protocol standard.
-
-- Fix bugs in the pool merging code that resulted in references and
-  dereferences of null pointers.   This bug had no impact unless the
-  POINTER_DEBUG flag was defined.
-
-- In the server, added a do-forward-updates flag that can be used to
-  disable forward updates in all cases, so that sites that want the
-  clients to take sole responsibility for updating their A record can
-  do so.
-
-- Make it possible to disable optimization of PTR record updates.
-
-                       Changes since 3.0.1rc5
-
-- Include some new documentation and changes provided by Karl Auer.
-
-- Add a workaround for some Lexmark printers that send a double-NUL-
-  terminated host-name option, which would break DNS updates.
-
-- Fix an off-by-one error in the MAC-address checking code for
-  DHCPRELEASE that was added in 3.0.1rc5.
-
-- Fix a bug where client-specific information was not being discarded
-  from the lease when it expired or was released, resulting in
-  problems if the lease was reallocated to a different client.
-
-- If more than one allocation pool is specified that has the same set
-  of constraints as another allocation pool on the same shared
-  network, merge the two pools.
-
-- Don't print an error in fallback_discard, since this just causes
-  confusion and does not appear to be helping to encourage anyone to
-  fix this bug.
-
-                       Changes since 3.0.1rc4
-
-- Fix a bug that would cause the DHCP server to spin if asked to parse
-  a certain kind of incorrect statement.
-
-- Fix a related bug that would prevent an error from being reported in
-  the same case.
-
-- Additional documentation.
-
-- Make sure that the hardware address matches the lease when
-  processing a DHCPRELEASE message.
-
-                       Changes since 3.0.1rc3
-
-- A minor bug fix in the arguments to a logging function call.
-- Documentation update for dhcpd.conf.
-
-                       Changes since 3.0.1rc2
-
-- Allow the primary to send a POOLREQ message.   This isn't what the current
-  failover draft says to do, so we may have to back it out if I can't get the
-  authors to relent, but the scheme for balancing that's specified in the
-  current draft seems needlessly hairy, so I'm floating a trial balloon.
-  The rc1 code did not implement the method described in the draft either.
-
-                       Changes since 3.0.1rc1
-
-- Treat NXDOMAIN and NXRRSET as success when we are trying to delete a
-  domain or RRSET.   This allows the DHCP server to forget about a name
-  it added to the DNS once it's been removed, even if the DHCP server
-  wasn't the one that removed it.
-
-- Install defaults for failover maximum outstanding updates and maximum
-  silent time.   This prevents problems that might occur if these values
-  were not configured.
-
-- Don't do DDNS deletes if ddns-update-style is none.
-
-- Return relay agent information options in DHCPNAK.   This prevents DHCPNAK
-  messages from being dropped when the relay agent information option contains
-  routing information.
-
-- Fix a problem where coming up in recover wouldn't result in an update
-  request being sent.
-
-- Add some more chatty messages when we start a recovery update and when it's
-  done.
-
-- Fix a possible problem where some state might have been left around
-  after the peer lost contact and regained contact about how many updates
-  were pending.
-
-- Don't nix a lease update because of a lease conflict.   This test has
-  never (as far as I know) prevented a mistake, and it appears to cause
-  problems with failover.
-
-- Add support in rc history code for keeping a selective history, rather
-  than a history of all references and dereferences.   This code is only used
-  when extensive additional debugging is enabled.
-
-                          Changes since 3.0
-
-- Make allocators for hash tables.   As a side effect, this fixes a memory
-  smash in the subclass allocation code.
-
-- Fix a small bug in omshell where if you try to close an object when
-  no object is open, it dumps core.
-
-- Fix an obscure coredump that could occur on shutdown.
-
-- Fix a bug in the recording of host declaration rubouts in the lease file.
-
-- Fix two potential spins in the host deletion code.
-
-- Fix a core dump that would happen if an application tried to update
-  a host object attribute with a null value.
-
-               Changes since 3.0 Release Candidate 12
-
-- Fix a memory leak in the evaluation code.
-
-- Fix an obscure core dump.
-
-- Print a couple of new warnings when parsing the configuration file
-  when crucial information is left out.
-
-- Log "no free leases" as an error.
-
-- Documentation updates.
-
-               Changes since 3.0 Release Candidate 11
-
-- Always return a subnet selection option if one is sent.
-
-- Fix a warning that was being printed because an automatic data
-  structure wasn't zeroed.
-
-- Fix some failover state transitions that were being handled
-  incorrectly.
-
-- When supersede_lease is called on a lease whose end time has already
-  expired, but for which a state transition has not yet been done, do
-  a state transition.   This fixes the case where if the secondary
-  allocated a lease to a client and the lease "expired" while the
-  secondary was in partner-down, no expiry event would actually
-  happen, so the lease would remain active until the primary was
-  restarted.
-
-               Changes since 3.0 Release Candidate 10
-
-- Fix a bug that was preventing released leases from changing state
-  in failover-enabled pools.
-
-- Fix a core dump in the client identifier finder code (for host
-  declarations).
-
-- Finish fixing a bug where bogus data would sometimes get logged to
-  the dhclient.leases file because it was opened as descriptor 2.
-
-- Fix the Linux dhclient-script according to suggestions made by
-  several people on the dhcp-client mailing list.
-
-- Log successful DNS updates at LOG_INFO, not LOG_ERROR.
-
-- Print an error message and refuse to run if a failover peer is
-  defined but not referenced by any pools.
-
-- Correct a confusing error message in failover.
-
-               Changes since 3.0 Release Candidate 9
-
-- Fix a bug in lease allocation for Dynamic BOOTP clients.
-
-         Changes since 3.0 Release Candidate 8 Patchlevel 2
-
-- Fix a bug that prevented update-static-leases from working.
-
-- Document failover-state OMAPI object.
-
-- Fix a compilation error on SunOS 4.
-
-         Changes since 3.0 Release Candidate 8 Patchlevel 1
-
-- Fix a parsing bug that broke dns updates (both interim and ad-hoc).
-  This was introduced in rc8pl1 as an unintended result of the memory
-  leakage fixes that were in pl1.
-
-- Fix a long-standing bug where the server would record that an update
-  had been done for a client with no name, even though no update had
-  been done, and then when the client's lease expired the deletion of
-  that nonexistant record would time out because the name was the null
-  string. 
-
-- Clean up the omshell, dhcpctl and omapi man pages a bit.
-
-               Changes since 3.0 Release Candidate 8
-
-- Fix a bug that could cause the DHCP server to spin if
-  one-lease-per-client was enabled.
-
-- Fix a bug that was causing core dumps on BSD/os in the presence of
-  malformed packets.
-
-- In partner-down state, don't restrict lease lengths to MCLT.
-
-- On the failover secondary, record the MCLT received from the primary
-  so that if we come up without a connection to the primary we don't
-  wind up giving out zero-length leases.
-
-- Fix some compilation problems on BSD/os.
-
-- Fix a bunch of memory leaks.
-
-- Fix a couple of bugs in the option printer.
-
-- Fix an obscure error reporting bug in the dns update code, and also
-  make the message clearer when a key algorithm isn't supported.
-
-- Fix a bug in the tracing code that prevented trace runs that used
-  tcp connections from being played back.
-
-- Add some additional debugging capability for catching memory leaks
-  on exit.
-
-- Make the client release the lease correctly on shutdown.
-
-- Add some configurability to the build system.
-
-- Install omshell manual page in man1, not man8.
-
-- Craig Gwydir sent in a patch that fixes a long-standing bug in the
-  DHCP client that could cause core dumps, but that for some reason
-  hadn't been noticed until now.
-
-               Changes since 3.0 Release Candidate 7
-
-- Fix a bug in failover where we weren't sending updates after a
-  transition from communications-interrupted to normal.
-
-- Handle expired/released/reset -> free transition according to the
-  protocol specification (this works - the other way not only wasn't
-  conformant, but also didn't work).
-
-- Add a control object in both client and server that allows either
-  daemon to be shut down cleanly.
-
-- When writing a lease, if we run out of disk space, shut down the
-  output file and insist on writing a new one before proceeding.
-
-- In the server, if the OMAPI listener port is occupied, keep trying
-  to get it, rather than simply giving up and exiting.
-
-- Support fetching variables from leases and also updating and adding
-  variables to leases via OMAPI.
-
-- If two failover peers have wildly different clocks, refuse to start
-  doing failover.
-
-- Fix a bug in the DNS update code that could cause core dumps when
-  running on alpha processors.
-
-- Fixed a bug in ddns updates for static lease entries, thanks to a
-  patch from Andrey M Linkevitch.
-
-- Add support for Darwin/MacOS X
-
-- Install omshell (including new documentation).
-
-- Support DNS updates in the client (this is a very obscure feature
-  that most DHCP client users probably will not be able to use).
-
-- Somewhat cleaner status logging in the client.
-
-- Make OMAPI key naming syntax compatible with the way keys are
-  actually named (key names are domain names).
-
-- Fix a bug in the lease file writer.
-
-- Install DHCP ISC headers in a different place than BIND 9 ISC
-  headers, to avoid causing trouble in BIND 9 builds.
-
-- Don't send updates for attributes on an object when the attributes
-  haven't changed.   Support deleting attributes on remote objects.
-
-- Fix a number of bugs in omshell, and add the unset and refresh
-  statements.
-
-- Handle disconnects in OMAPI a little bit more intelligently (so that
-  the caller gets ECONNRESET instead of EINVAL).
-
-- Fix a bunch of bugs in the handling of clients that have existing
-  leases when the try to renew their leases while failover is
-  operating.
-
-               Changes since 3.0 Release Candidate 6
-
-- Fix a core dump that could happen when processing a DHCPREQUEST from
-  a client that had a host declaration that contained both a
-  fixed-address declaration and a dhcp-client-identifier option
-  declaration, if the client identifier was longer than nine bytes.
-
-- Fix a memory leak that could happen in certain obscure cases when
-  using omapi to manipulate leases.
-
-- Fix some bugs and omissions in omshell.
-
-
-               Changes since 3.0 Release Candidate 5
-
-- Fix a bug in omapi_object_dereference that prevented objects in
-  chains from having their reference counts decreased on dereference.
-
-- Fix a bug in omapi_object_dereference that would prevent object
-  chains from being freed upon removal of the last reference external
-  to the chain.
-
-- Fix a number of other memory leaks in the OMAPI protocol subsystem.
-
-- Add code in the OMAPI protocol handler to trace memory leakage.
-
-- Clean up the memory allocation/reference history printer.
-
-- Support input of dotted quads and colon-separated hex lists as
-  attribute values in omshell.
-
-- Fix a typo in the Linux interface discovery code.
-
-- Conditionalize a piece of trace code that wasn't conditional.
-
-               Changes since 3.0 Release Candidate 4
-
-- Fix a bug that would prevent leases from being abandoned properly on
-  DHCPDECLINE.
-
-- Fix failover peer OMAPI support.
-
-- In failover, correctly handle expiration of leases.   Previously,
-  leases would never be reclaimed because they couldn't make the
-  transition from EXPIRED to FREE.
-
-- Fix some broken failover state transitions.
-
-- Documentation fixes.
-
-- Take out an unnecessary check in DHCP relay agent information option
-  stashing code that was preventing REBINDING clients from rebinding.
-
-- Prevent failover peers from allocating leases in DHCPREQUEST
-  processing if the lease belongs to the other server.
-
-- Record server version in lease file introductory comment.
-
-- Correctly report connection errors in OMAPI and failover.
-
-- Make authentication signature algorithm name comparisons in OMAPI
-  case-insensitive.
-
-- Fix compile problem on SunOS 4.x
-
-- If a signature algorithm is not terminated with '.', terminate it so
-  that comparisons between fully-qualified names will work
-  consistently.
-
-- Different SIOCGIFCONF probe code, may "fix" problem on some Linux
-  systems with the probe not working correctly.
-
-- Don't allow user to type omapi key on command line of omshell.
-
-               Changes since 3.0 Release Candidate 3
-
-- Do lease billing on startup in a way that I *think* will finally do
-  the billing correctly - the previous method could overbill as a
-  result of duplicate leases.
-
-- Document OMAPI server objects.
-
-         Changes since 3.0 Release Candidate 2 Patchlevel 1
-
-- Fix some problems in the DDNS update code.   Thanks to Albert
-  Herranz for figuring out the main problem.
-
-- Fix some reference counting errors on host entries that were causing
-  core dumps.
-
-- Fix a byte-swap bug in the token ring code, thanks to Jochen
-  Friedrich.
-
-- Fix a bug in lease billing, thanks to Jonas Bulow.
-
-               Changes since 3.0 Release Candidate 2
-
-- Change the conditions under which a DHCPRELEASE is actually
-  committed to be consistent with lease binding states rather than
-  using the lease end time.   This may fix some problems with the
-  billing class code.
-
-- Fix a bug where lease updates would fail on Digital Unix (and maybe
-  others) because malloc was called with a size of zero.
-
-- Fix a core dump that happens when the DHCP server can't create its
-  trace file.
-
-         Changes since 3.0 Release Candidate 1 Patchlevel 1
-
-- Fix the dhcp_failover_put_message to not attempt to allocate a
-  zero-length buffer.   Some versions of malloc() fail if you try to
-  allocate a zero-length buffer, and this was causing problems on,
-  e.g., Digital Unix.
-
-- Fix a case where the failover code was printing an error message
-  when no error had occurred.
-
-- Fix a problem where when a server went down and back up again, the
-  peer would not see a state transition and so would stay in the
-  non-communicating state.
-
-- Be smart about going into recover_wait.
-
-- Fix a problem in the failover implementation where peers would fail
-  to come into sync if interrupted in the RECOVER state.   This could
-  have been the cause of some problems people have reported recently.
-
-- Fix a problem with billing classes where they would not be unbilled
-  when the client lease expired.
-
-- If select fails, figure out which descriptor is bad, and cut it out
-  of the I/O loop.   This prevents a potentially nasty spin.  I
-  haven't heard any report it in a while, but it came up consistently
-  in testing.
-
-- Fix a bug in the relay agent where if you specified interfaces on
-  the command line, it would fail.
-
-- Fix a couple of small bugs in the omapi connection object (no known
-  user impact).
-
-- Add the missing 3.0 Beta 1 lease conversion script.
-
-- Read dhcp client script hooks if they exist, rather than only if
-  they're executable.
-
-               Changes since 3.0 Release Candidate 1
-
-- Fix a memory smash that happens when fixed-address leases are used.
-  ANY SITE AT WHICH FIXED-ADDRESS STATEMENTS ARE BEING USED SHOULD
-  UPGRADE IMMEDIATELY.   This has been a long-standing bug - thanks to
-  Alvise Nobile for discovering it and helping me to find it!
-
-- Fix a small bug in binary-to-ascii, thanks to H. Peter Anvin of
-  Transmeta.
-
-- There is a known problem with the DHCP server doing failover on
-  Compaq Alpha systems.   This patchlevel is not a release candidate
-  because of this bug.   The bug should be straightforward to fix, so
-  a new release candidate is expected shortly.
-
-- There is a known problem in the DDNS update code that is probably a
-  bug, and is not, as far as we know, fixed in this patchlevel.
-
-               Changes since 3.0 Beta 2 Patchlevel 24
-
-- Went over problematic failover state transitions and made them all
-  work, so that failover should now much less fragile.
-
-- Add some dhcpctl and omapi documentation
-
-- Fix compile errors when compiling with unusual predefines.
-
-- Make Token Ring work on Linux 2.4
-
-- Fix the Digital Unix BPF_WORDALIGN bug.
-
-- Fix some dhcp client documentation errors.
-
-- Update some parts of the README file.
-
-- Support GCC on SCO.
-
-               Changes since 3.0 Beta 2 Patchlevel 23
-
-- Fix a bug in the DNS update code where a status code was not being
-  checked.   This may have been causing core dumps.
-
-- When parsing the lease file, if a lease declaration includes a
-  billing class statement, and the lease already has a billing class,
-  unbill the old class.
-
-- When processing failover transactions, where acks will be deferred,
-  process the state transition immediately.
-
--  Don't try to use the new SIOCGIFCONF buffer size detection code on
-   Linux 2.0, which doesn't provide this functionality.
-
-- Apply a patch suggested by Tuan Uong for a problem in dlpi.c.
-
-- Fix a problem in using the which command in the configure script.
-
-- Fix a parse error in the client when setting up an omapi listener.
-
-- Document the -n and -g flags to the client.
-
-- Make sure there is always a stdin and stdout on startup.   This
-  prevents shell scripts from accidentally writing error messages into
-  configuration files that happen to be opened as stderr.
-
-- If an interface is removed, the client will now notice that it is
-  gone rather than spinning.   This has only been tested on NetBSD.
-
-- The client will attempt to get an address even if it can't create a
-  lease file.
-
-- Don't overwrite tracefiles.
-
-- Fix some memory allocation bugs in failover.
-
-               Changes since 3.0 Beta 2 Patchlevel 22
-
-- Apply some patches suggested by Cyrille Lefevre, who is maintaining
-  the FreeBSD ISC DHCP Distribution port.
-
-- Fix a core dump in DHCPRELEASE.
-
-               Changes since 3.0 Beta 2 Patchlevel 21
-
-- This time for sure: fix the spin described in the changes for pl20.
-
-               Changes since 3.0 Beta 2 Patchlevel 20
-
-- Fix a problem with Linux detecting large numbers of interfaces (Ben)
-
-- Fix a memory smash in the quotify code, which was introduced in
-  pl19.
-
-- Actually fix the spin described in the changes for pl20.   The
-  previous fix only partially fixed the problem - enough to get it
-  past the regression test.
-
-               Changes since 3.0 Beta 2 Patchlevel 19
-
-- Fix a bug that could cause the server to abort if compiled with
-  POINTER_DEBUG enabled.
-
-- Fix a bug that could cause the server to spin when responding to a
-  DHCPREQUEST.
-
-- Apply Joost Mulders' suggested patches for DLPI on x86.
-
-- Support NUL characters in quoted strings.
-
-- Install unformatted man pages on SunOS.
-
-               Changes since 3.0 Beta 2 Patchlevel 18
-
-- Allow the server to be placed in partner-down state using OMAPI.
-  (Damien Neil)
-
-- Implement omshell, which can be used to do arbitrary things to the
-  server (in theory). (Damien Neil)
-
-- Fix a case where if a client had two different leases the server could
-  actually dereference the second one when it hadn't been referenced,
-  leading to memory corruption and a core dump. (James Brister)
-
-- Fix a case where a client could request the address of another client's
-  lease, but find_lease wouldn't detect that the other client had it, and
-  would attempt to allocate it to the client, resulting in a lease conflict
-  message.
-
-- Fix a case where a client with more than one client identifier could be
-  given a lease where the hardware address was correct but the client
-  identifier was not, resulting in a lease conflict message.
-
-- Fix a problem where the server could write out a colon-separated
-  hex list as a value for a variable, which would then not parse.
-  The fix is to always write strings as quoted strings, with any
-  non-printable characters quoted as octal escape sequences.   So
-  a file written the old way still won't work, but new files written
-  this way will work.
-
-- Fix documentation for sending non-standard options.
-
-- Use unparsable names for unknown options.    WARNING: this will
-  break any configuration files that use the option-nnn convention.
-  If you want to continue to use this convention for some options,
-  please be sure to write a definition, like this:
-
-  option option-nnn code nnn = string;
-
-  You can use a descriptive name instead of option-nnn if you like.
-
-- Fix a problem where we would see a DHCPDISCOVER/DHCPOFFER/
-  DHCPREQUEST/DHCPACK/DHCPREQUEST/DHCPNAK sequence.   This was the
-  result of a deceptively silly bug in supersede_lease.
-
-- Fix client script exit status check, according to a fix supplied by
-  Hermann Lauer.
-
-- Fix an endianness bug in the tracefile support, regarding ICMP
-  messages.
-
-- Fix a bug in the client where the medium would not work correctly if
-  it contained quoted strings.
-
-                      ** there was no pl17 **
-
-               Changes since 3.0 Beta 2 Patchlevel 16
-
-- Add support for transaction tracing.   This allows the state of the
-  DHCP server on startup, and all the subsequent transactions, to be
-  recorded in a file which can then be played back to reproduce the
-  behaviour of the DHCP server.   This can be used to quickly
-  reproduce bugs that cause core dumps or corruption, and also for
-  tracking down memory leaks.
-
-- Incorporate some bug fixes provided by Joost Mulders for the DLPI
-  package which should clear up problems people have been seeing on
-  Solaris.
-
-- Fix bugs in the handling of options stored as linked lists (agent
-  options, fqdn options and nwip options) that could cause memory
-  corruption and core dumps.
-
-- Fix a bug in DHCPREQUEST handling that resulted in DHCPNAK messages
-  not being send in some cases when they were needed.
-
-- Make the lease structure somewhat more compact.
-
-- Make initial failover startup *much* faster.   This was researched
-  and implemented by Damien Neil.
-
-- Add a --version flag to all executables, which prints the program
-  name and version to standard output.
-
-- Don't rewrite the lease file every thousand leases.
-
-- A bug in nit.c for older SunOS machines was fixed by a patch sent in
-  by Takeshi Hagiwara.
-
-- Fix a memory corruption bug in the DHCP client.
-
-- Lots of documentation updates.
-
-- Add a feature allowing environment variables to be passed to the
-  DHCP client script on the DHCP client command line.
-
-- Fix client medium support, which had been broken for some time.
-
-- Fix a bug in the DHCP client initial startup backoff interval, which
-  would cause two DHCPDISCOVERS to be sent back-to-back on startup.
-
-
-               Changes since 3.0 Beta 2 Patchlevel 15
-
-- Some documentation tweaks.
-
-- Maybe fix a problem in the DLPI code.
-
-- Fix some error code space inconsistencies in ddns update code.
-
-- Support relay agents that intercept unicast DHCP messages to stuff
-  agent options into them.
-
-- Fix a small memory leak in the relay agent option support code.
-
-- Fix a core dump that would occur if a packet was sent with no
-  options.
-
-               Changes since 3.0 Beta 2 Patchlevel 14
-
-- Finish fixing a long-standing bug in the agent options code.   This
-  was causing core dumps and failing to operate correctly - in
-  particular, agent option stashing wasn't working.   Agent option
-  stashing should now be working, meaning that agent options can be
-  used in class statements to control address allocation.
-
-- Fix up documentation.
-
-- Fix a couple of small memory leaks that would have added up
-  significantly in a high-demand situation.
-
-- Add a log-facility configuration parameter.
-
-- Fix a compile error on some older operating systems.
-
-- Add the ability in the client to execute certain statements before
-  transmitting packets to the server.   Handy for debugging; not much
-  practical use otherwise.
-
-- Don't send faked-out giaddr when renewing or bound - again, useful
-  for debugging.
-
-               Changes since 3.0 Beta 2 Patchlevel 13
-
-- Fixed a problem where the fqdn decoder would sometimes try to store
-  an option with an (unsigned) negative length, resulting in a core
-  dump on some systems.
-
-- Work around the Win98 DHCP client, which NUL-terminates the FQDN
-  option.
-
-- Work around Win98 and Win2k clients that will claim they want to do
-  the update even when they don't have any way to do it.
-
-- Fix some log messages that can be printed when failover is operating
-  that were not printing enough information.
-
-- It was possible for a DHCPDISCOVER to get an allocation even when
-  the state machine said the server shouldn't be responding.
-
-- Don't load balance DHCPREQUESTs from clients in RENEWING and
-  REBINDING, since in RENEWING, if we heard it, it's for us, and in
-  REBINDING, the client wouldn't have got to REBINDING if its primary
-  were answering.
-
-- When we get a bogus state lease binding state transition, don't do
-  the transition.
-  
-
-               Changes since 3.0 Beta 2 Patchlevel 12
-
-- Fixed a couple of silly compile errors.
-
-               Changes since 3.0 Beta 2 Patchlevel 11
-
-- Albert Herranz tracked down and fixed a subtle bug in the base64
-  decoder that would prevent any key with an 'x' in its base64
-  representation from working correctly.
-
-- Thanks to Chris Cheney and Michael Sanders, we have a fix for the
-  hang that they both spotted in the DHCP server - when
-  one-lease-per-client was set, the code to release the "other" lease
-  could spin.
-
-- Fix a problem with alignment of the input buffer in bpf in cases
-  where two packets arrive in the same bpf read.
-
-- Fix a problem where the relay agent would crash if you specified an
-  interface name on the command line.
-
-- Add the ability to conditionalize client behaviour based on the
-  client state.
-
-- Add support for the FQDN option, and added support for a new way of
-  doing ddns updates (ddns update style interim) that allows more than
-  one DHCP server to update the DNS for the same network(s).   This
-  was implemented by Damien Neil with some additional functionality
-  added by Ted Lemon.
-
-- Damien added a "log" statement, so that the configuration file can
-  be made to log debugging information and other information.
-
-- Fixed a bug that caused option buffers not to be terminated with an
-  end option.
-
-- Fixed a long-standing bug in the support for option spaces where the
-  options are stored as an ordered list rather than in a hash table,
-  which could theoretically result in memory pool corruption.
-
-- Prevent hardware declarations with no actual hardware address from
-  being written as something unparsable, and behave correctly in the
-  face of a null hardware address on input.
-
-- Allow key names to be FQDNs, and qualify the algorithm name if it is
-  specified unqualified.
-
-- Modify the DDNS update code so that it never prints the "resolver
-  failed" message, but instead says *why* the resolver failed.
-
-- Officially support the subnet selection option, which now has an
-  RFC.
-
-- Fix a build bug on MacOS X.
-
-- Allow administrator to disable ping checking.
-
-- Clean up dhcpd.conf documentation and add more information about how
-  it works.
-
-               Changes since 3.0 Beta 2 Patchlevel 10
-
-- Fix a bug introduced during debugging (!) and accidentally committed
-  to CVS.
-
-               Changes since 3.0 Beta 2 Patchlevel 9
-
-- Fix DHCP client handling of vendor encapsulated options.
-
-- Fix a bug in the handling of relay agent information options introduced
-  in patchlevel 9.
-
-- Stash agent options on client leases by default, and use the stashed
-  options at renewal time.
-
-- Add the ability to test the client's binding state in the client
-  configuration language.
-
-- Fix a core dump in the DNS update code.
-
-- Fix some expression evaluation bugs that were causing updates to be
-  done when no client hostname was received.
-
-- Fix expression evaluation debugging printfs.
-
-- Teach pretty_print_option to print options in option spaces other than
-  the DHCP option space.
-
-- Add a warning message if the RHS of a not is not boolean.
-
-- Never select for more than a day, because some implementations of
-  select will just fail if the timeout is too long (!).
-
-- Fix a case where a DHCPDISCOVER from an unknown network would be
-  silently dropped.
-
-- Fix a bug where if a client requested an IP address for which a different
-  client had the lease, the DHCP server would reallocate it anyway.
-
-- Fix the DNS update code so that if the client changes its name, the DNS
-  will be correctly updated.
-
-               Changes since 3.0 Beta 2 Patchlevel 8
-
-- Oops, there was another subtle math error in the header-length
-  bounds-checking.
-
-               Changes since 3.0 Beta 2 Patchlevel 7
-
-- Oops, forgot to byte-swap udp header length before bounds-checking it.
-
-               Changes since 3.0 Beta 2 Patchlevel 6
-
-- Fix a possible DoS attack where a client could cause the checksummer
-  to dump core.   This was a read, not a write, so it shouldn't be
-  possible to exploit it any further than that.
-
-- Implement client- and server-side support for using the Client FQDN
-  option.
-
-- Support for other option spaces in the client has been added.   This
-  means that it is now possible to define a vendor option space on the
-  client, request options in that space from the server (which must
-  define the same option space), and then use those options in the
-  client.   This also allows NWIP and Client FQDN options to be used
-  meaningfully.
-
-- Add object initializer support.   This means that objects can now be
-  initialized to something other than all-zeros when allocated, which
-  makes, e.g., the interface object support code a little more robust.
-
-- Fix an off-by-one bug in the host stuffer.   This was causing host
-  deletes not the work, and may also have been causing OMAPI
-  connections to get dropped.   Thanks to James Brister for tracking
-  this one down!
-
-- Fixed a core dump in the interface discovery code that is triggered
-  when there is no subnet declaration for an interface, but the server
-  decides to continue running.   Thanks to Shane Kerr for tracking
-  down and fixing this problem.
-
-               Changes since 3.0 Beta 2 Patchlevel 5
-
-- Fix a bug in the recent enhancement to the interface discovery code
-  to support arbitrary-length interface lists.
-
-- Support NUL-terminated DHCP options when initializing client-script
-  environment.
-
-- Fix suffix operator.
-
-- Fix NetWare/IP option parsing.
-
-- Better error/status checking in dhcpctl initialization and omapi
-  connection code.
-
-- Fix a potential memory smash in dhcpctl code.
-
-- Fix SunOS4 and (maybe) Ultrix builds.
-
-- Fix a bug where a certain sort of incoming packet could cause a core
-  dump on Solaris (and probably elsewhere).
-
-- Add some more safety checks in error logging code.
-
-- Add support for ISC_R_INCOMPLETE in OMAPI protocol connection code.
-
-- Fix relay agent so that if an interface is specified on the command
-  line, the relay agent does not dump core.
-
-- Fix class matching so that match if can be combined with match or
-  spawn with.
-
-- Do not allow spurious leases in the lease database to introduce
-  potentially bogus leases into the in-memory database.
-
-- Fix a byte-order problem in the client hardware address type code
-  for OMAPI.
-
-- Be slightly less picky about what sort of hardware addresses OMAPI
-  can install in host declarations.
-
-               Changes since 3.0 Beta 2 Patchlevel 4
-
-- Incorporated Peter Marschall's proposed change to array/record
-  parsing, which allows things like the slp-agent option to be encoded
-  correctly.   Thanks very much to Peter for taking the initiative to
-  do this, and for doing such a careful job of it (e.g., updating the
-  comments)!
-
-- Added an encoding for the slp-agent option.   :')
-
-- Fixed SunOS 4 build.  Thanks to Robert Elz for responding to my
-  request for help on this with patches!
-
-- Incorporated a change that should fix a problem reported by Philippe
-  Jumelle where when the network connection between two servers is
-  lost, they never reconnect.
-
-- Fix client script files other than that for NetBSD to actually use
-  make_resolv_conf as documented in the manual page.
-
-- Fix a bug in the packet handling code that could result in a core
-  dump.
-
-- Fix a bug in the bootp code where responses on the local net would
-  be sent to the wrong MAC address.   Thanks to Jerry Schave for
-  catching this one.
-
-               Changes since 3.0 Beta 2 Patchlevel 3
-
-- In the DHCP client, execute client statements prior to using the values
-  of options, so that the client configuration can overried, e.g., the
-  lease renewal time.
-
-- Fix a reference counting error that would result in very reproducible
-  failures in updates, as well as occasional core dumps, if a zone was
-  declared without a key.
-
-- Fix some Linux 2.0 compilation problems.
-
-- Fix a bug in scope evaluation during execution of "on" statements that
-  caused values not to be recorded on leases.
-
-- If the dhcp-max-message-size option is specified in scope, and the
-  client didn't send this option, use the one specified in scope to
-  determine the maximum size of the response.
-
-               Changes since 3.0 Beta 2 Patchlevel 2
-
-- Fix a case where spawning subclasses were being allocated
-  incorrectly, resulting in a core dump.
-
-- Fix a case where the DHCP server might inappropriately NAK a
-  RENEWING client.
-
-- Fix a place dhcprequest() where static leases could leak.
-
-- Include memory.h in omapip_p.h so that we don't get warnings about
-  using memcmp().
-
-               Changes since 3.0 Beta 2 Patchlevel 1
-
-- Notice when SIOCFIGCONF returns more data than fit in the buffer -
-  allocate a larger buffer, and retry.   Thanks to Greg Fausak for
-  pointing this out.
-
-- In the server, if no interfaces were configured, report an error and
-  exit.
-
-- Don't ever record a state of 'startup'.
-
-- Don't try to evaluate the local failover binding address if none was
-  specified.   Thanks to Joseph Breu for finding this.
diff --git a/contrib/dhcp-3.0/client/clparse.c b/contrib/dhcp-3.0/client/clparse.c
deleted file mode 100644 (file)
index e5079a1..0000000
+++ /dev/null
@@ -1,1170 +0,0 @@
-/* clparse.c
-
-   Parser for dhclient config and lease files... */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * 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 ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC 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.
- *
- *   Internet Systems Consortium, Inc.
- *   950 Charter Street
- *   Redwood City, CA 94063
- *   <info@isc.org>
- *   http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''.  To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: clparse.c,v 1.62.2.7 2004/11/24 17:39:14 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-static TIME parsed_time;
-
-struct client_config top_level_config;
-
-u_int32_t default_requested_options [] = {
-       DHO_SUBNET_MASK,
-       DHO_BROADCAST_ADDRESS,
-       DHO_TIME_OFFSET,
-       DHO_ROUTERS,
-       DHO_DOMAIN_NAME,
-       DHO_DOMAIN_NAME_SERVERS,
-       DHO_HOST_NAME,
-       0
-};
-
-/* client-conf-file :== client-declarations END_OF_FILE
-   client-declarations :== <nil>
-                        | client-declaration
-                        | client-declarations client-declaration */
-
-isc_result_t read_client_conf ()
-{
-       struct client_config *config;
-       struct client_state *state;
-       struct interface_info *ip;
-       isc_result_t status;
-
-       /* Set up the initial dhcp option universe. */
-       initialize_common_option_spaces ();
-
-       /* Initialize the top level client configuration. */
-       memset (&top_level_config, 0, sizeof top_level_config);
-
-       /* Set some defaults... */
-       top_level_config.timeout = 60;
-       top_level_config.select_interval = 0;
-       top_level_config.reboot_timeout = 10;
-       top_level_config.retry_interval = 300;
-       top_level_config.backoff_cutoff = 15;
-       top_level_config.initial_interval = 3;
-       top_level_config.bootp_policy = P_ACCEPT;
-       top_level_config.script_name = path_dhclient_script;
-       top_level_config.requested_options = default_requested_options;
-       top_level_config.omapi_port = -1;
-       top_level_config.do_forward_update = 1;
-
-       group_allocate (&top_level_config.on_receipt, MDL);
-       if (!top_level_config.on_receipt)
-               log_fatal ("no memory for top-level on_receipt group");
-
-       group_allocate (&top_level_config.on_transmission, MDL);
-       if (!top_level_config.on_transmission)
-               log_fatal ("no memory for top-level on_transmission group");
-
-       status = read_client_conf_file (path_dhclient_conf,
-                                       (struct interface_info *)0,
-                                       &top_level_config);
-       if (status != ISC_R_SUCCESS) {
-               ;
-#ifdef LATER
-               /* Set up the standard name service updater routine. */
-               parse = (struct parse *)0;
-               status = new_parse (&parse, -1, default_client_config,
-                                   (sizeof default_client_config) - 1,
-                                   "default client configuration", 0);
-               if (status != ISC_R_SUCCESS)
-                       log_fatal ("can't begin default client config!");
-
-               do {
-                       token = peek_token (&val, (unsigned *)0, cfile);
-                       if (token == END_OF_FILE)
-                               break;
-                       parse_client_statement (cfile,
-                                               (struct interface_info *)0,
-                                               &top_level_config);
-               } while (1);
-               end_parse (&parse);
-#endif
-       }
-
-       /* Set up state and config structures for clients that don't
-          have per-interface configuration statements. */
-       config = (struct client_config *)0;
-       for (ip = interfaces; ip; ip = ip -> next) {
-               if (!ip -> client) {
-                       ip -> client = (struct client_state *)
-                               dmalloc (sizeof (struct client_state), MDL);
-                       if (!ip -> client)
-                               log_fatal ("no memory for client state.");
-                       memset (ip -> client, 0, sizeof *(ip -> client));
-                       ip -> client -> interface = ip;
-               }
-
-               if (!ip -> client -> config) {
-                       if (!config) {
-                               config = (struct client_config *)
-                                       dmalloc (sizeof (struct client_config),
-                                                MDL);
-                               if (!config)
-                                   log_fatal ("no memory for client config.");
-                               memcpy (config, &top_level_config,
-                                       sizeof top_level_config);
-                       }
-                       ip -> client -> config = config;
-               }
-       }
-       return status;
-}
-
-int read_client_conf_file (const char *name, struct interface_info *ip,
-                          struct client_config *client)
-{
-       int file;
-       struct parse *cfile;
-       const char *val;
-       int token;
-       isc_result_t status;
-       
-       if ((file = open (name, O_RDONLY)) < 0)
-               return uerr2isc (errno);
-
-       cfile = (struct parse *)0;
-       new_parse (&cfile, file, (char *)0, 0, path_dhclient_conf, 0);
-
-       do {
-               token = peek_token (&val, (unsigned *)0, cfile);
-               if (token == END_OF_FILE)
-                       break;
-               parse_client_statement (cfile, ip, client);
-       } while (1);
-       token = next_token (&val, (unsigned *)0, cfile);
-       status = (cfile -> warnings_occurred
-                 ? ISC_R_BADPARSE
-                 : ISC_R_SUCCESS);
-       close (file);
-       end_parse (&cfile);
-       return status;
-}
-
-
-/* lease-file :== client-lease-statements END_OF_FILE
-   client-lease-statements :== <nil>
-                    | client-lease-statements LEASE client-lease-statement */
-
-void read_client_leases ()
-{
-       int file;
-       struct parse *cfile;
-       const char *val;
-       int token;
-
-       /* Open the lease file.   If we can't open it, just return -
-          we can safely trust the server to remember our state. */
-       if ((file = open (path_dhclient_db, O_RDONLY)) < 0)
-               return;
-       cfile = (struct parse *)0;
-       new_parse (&cfile, file, (char *)0, 0, path_dhclient_db, 0);
-
-       do {
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (token == END_OF_FILE)
-                       break;
-               if (token != LEASE) {
-                       log_error ("Corrupt lease file - possible data loss!");
-                       skip_to_semi (cfile);
-                       break;
-               } else
-                       parse_client_lease_statement (cfile, 0);
-
-       } while (1);
-
-       close (file);
-       end_parse (&cfile);
-}
-
-/* client-declaration :== 
-       SEND option-decl |
-       DEFAULT option-decl |
-       SUPERSEDE option-decl |
-       PREPEND option-decl |
-       APPEND option-decl |
-       hardware-declaration |
-       REQUEST option-list |
-       REQUIRE option-list |
-       TIMEOUT number |
-       RETRY number |
-       REBOOT number |
-       SELECT_TIMEOUT number |
-       SCRIPT string |
-       VENDOR_SPACE string |
-       interface-declaration |
-       LEASE client-lease-statement |
-       ALIAS client-lease-statement |
-       KEY key-definition */
-
-void parse_client_statement (cfile, ip, config)
-       struct parse *cfile;
-       struct interface_info *ip;
-       struct client_config *config;
-{
-       int token;
-       const char *val;
-       struct option *option;
-       struct executable_statement *stmt, **p;
-       enum statement_op op;
-       int lose;
-       char *name;
-       struct data_string key_id;
-       enum policy policy;
-       int known;
-       int tmp, i;
-       isc_result_t status;
-
-       switch (peek_token (&val, (unsigned *)0, cfile)) {
-             case INCLUDE:
-               next_token (&val, (unsigned *)0, cfile);
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (token != STRING) {
-                       parse_warn (cfile, "filename string expected.");
-                       skip_to_semi (cfile);
-               } else {
-                       status = read_client_conf_file (val, ip, config);
-                       if (status != ISC_R_SUCCESS)
-                               parse_warn (cfile, "%s: bad parse.", val);
-                       parse_semi (cfile);
-               }
-               return;
-               
-             case KEY:
-               next_token (&val, (unsigned *)0, cfile);
-               if (ip) {
-                       /* This may seem arbitrary, but there's a reason for
-                          doing it: the authentication key database is not
-                          scoped.  If we allow the user to declare a key other
-                          than in the outer scope, the user is very likely to
-                          believe that the key will only be used in that
-                          scope.  If the user only wants the key to be used on
-                          one interface, because it's known that the other
-                          interface may be connected to an insecure net and
-                          the secret key is considered sensitive, we don't
-                          want to lull them into believing they've gotten
-                          their way.   This is a bit contrived, but people
-                          tend not to be entirely rational about security. */
-                       parse_warn (cfile, "key definition not allowed here.");
-                       skip_to_semi (cfile);
-                       break;
-               }
-               parse_key (cfile);
-               return;
-
-               /* REQUIRE can either start a policy statement or a
-                  comma-seperated list of names of required options. */
-             case REQUIRE:
-               next_token (&val, (unsigned *)0, cfile);
-               token = peek_token (&val, (unsigned *)0, cfile);
-               if (token == AUTHENTICATION) {
-                       policy = P_REQUIRE;
-                       goto do_policy;
-               }
-               parse_option_list (cfile, &config -> required_options);
-               return;
-
-             case IGNORE:
-               next_token (&val, (unsigned *)0, cfile);
-               policy = P_IGNORE;
-               goto do_policy;
-
-             case ACCEPT:
-               next_token (&val, (unsigned *)0, cfile);
-               policy = P_ACCEPT;
-               goto do_policy;
-
-             case PREFER:
-               next_token (&val, (unsigned *)0, cfile);
-               policy = P_PREFER;
-               goto do_policy;
-
-             case DONT:
-               next_token (&val, (unsigned *)0, cfile);
-               policy = P_DONT;
-               goto do_policy;
-
-             do_policy:
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (token == AUTHENTICATION) {
-                       if (policy != P_PREFER &&
-                           policy != P_REQUIRE &&
-                           policy != P_DONT) {
-                               parse_warn (cfile,
-                                           "invalid authentication policy.");
-                               skip_to_semi (cfile);
-                               return;
-                       }
-                       config -> auth_policy = policy;
-               } else if (token != TOKEN_BOOTP) {
-                       if (policy != P_PREFER &&
-                           policy != P_IGNORE &&
-                           policy != P_ACCEPT) {
-                               parse_warn (cfile, "invalid bootp policy.");
-                               skip_to_semi (cfile);
-                               return;
-                       }
-                       config -> bootp_policy = policy;
-               } else {
-                       parse_warn (cfile, "expecting a policy type.");
-                       skip_to_semi (cfile);
-                       return;
-               } 
-               break;
-
-             case OPTION:
-               token = next_token (&val, (unsigned *)0, cfile);
-
-               token = peek_token (&val, (unsigned *)0, cfile);
-               if (token == SPACE) {
-                       if (ip) {
-                               parse_warn (cfile,
-                                           "option space definitions %s",
-                                           " may not be scoped.");
-                               skip_to_semi (cfile);
-                               break;
-                       }
-                       parse_option_space_decl (cfile);
-                       return;
-               }
-
-               option = parse_option_name (cfile, 1, &known);
-               if (!option)
-                       return;
-
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (token != CODE) {
-                       parse_warn (cfile, "expecting \"code\" keyword.");
-                       skip_to_semi (cfile);
-                       free_option (option, MDL);
-                       return;
-               }
-               if (ip) {
-                       parse_warn (cfile,
-                                   "option definitions may only appear in %s",
-                                   "the outermost scope.");
-                       skip_to_semi (cfile);
-                       free_option (option, MDL);
-                       return;
-               }
-               if (!parse_option_code_definition (cfile, option))
-                       free_option (option, MDL);
-               return;
-
-             case MEDIA:
-               token = next_token (&val, (unsigned *)0, cfile);
-               parse_string_list (cfile, &config -> media, 1);
-               return;
-
-             case HARDWARE:
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (ip) {
-                       parse_hardware_param (cfile, &ip -> hw_address);
-               } else {
-                       parse_warn (cfile, "hardware address parameter %s",
-                                   "not allowed here.");
-                       skip_to_semi (cfile);
-               }
-               return;
-
-             case REQUEST:
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (config -> requested_options == default_requested_options)
-                       config -> requested_options = (u_int32_t *)0;
-               parse_option_list (cfile, &config -> requested_options);
-               return;
-
-             case TIMEOUT:
-               token = next_token (&val, (unsigned *)0, cfile);
-               parse_lease_time (cfile, &config -> timeout);
-               return;
-
-             case RETRY:
-               token = next_token (&val, (unsigned *)0, cfile);
-               parse_lease_time (cfile, &config -> retry_interval);
-               return;
-
-             case SELECT_TIMEOUT:
-               token = next_token (&val, (unsigned *)0, cfile);
-               parse_lease_time (cfile, &config -> select_interval);
-               return;
-
-             case OMAPI:
-               token = next_token (&val, (unsigned *)0, cfile);
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (token != PORT) {
-                       parse_warn (cfile,
-                                   "unexpected omapi subtype: %s", val);
-                       skip_to_semi (cfile);
-                       return;
-               }
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (token != NUMBER) {
-                       parse_warn (cfile, "invalid port number: `%s'", val);
-                       skip_to_semi (cfile);
-                       return;
-               }
-               tmp = atoi (val);
-               if (tmp < 0 || tmp > 65535)
-                       parse_warn (cfile, "invalid omapi port %d.", tmp);
-               else if (config != &top_level_config)
-                       parse_warn (cfile,
-                                   "omapi port only works at top level.");
-               else
-                       config -> omapi_port = tmp;
-               parse_semi (cfile);
-               return;
-               
-             case DO_FORWARD_UPDATE:
-               token = next_token (&val, (unsigned *)0, cfile);
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (!strcasecmp (val, "on") ||
-                   !strcasecmp (val, "true"))
-                       config -> do_forward_update = 1;
-               else if (!strcasecmp (val, "off") ||
-                        !strcasecmp (val, "false"))
-                       config -> do_forward_update = 0;
-               else {
-                       parse_warn (cfile, "expecting boolean value.");
-                       skip_to_semi (cfile);
-                       return;
-               }
-               parse_semi (cfile);
-               return;
-
-             case REBOOT:
-               token = next_token (&val, (unsigned *)0, cfile);
-               parse_lease_time (cfile, &config -> reboot_timeout);
-               return;
-
-             case BACKOFF_CUTOFF:
-               token = next_token (&val, (unsigned *)0, cfile);
-               parse_lease_time (cfile, &config -> backoff_cutoff);
-               return;
-
-             case INITIAL_INTERVAL:
-               token = next_token (&val, (unsigned *)0, cfile);
-               parse_lease_time (cfile, &config -> initial_interval);
-               return;
-
-             case SCRIPT:
-               token = next_token (&val, (unsigned *)0, cfile);
-               parse_string (cfile, &config -> script_name, (unsigned *)0);
-               return;
-
-             case VENDOR:
-               token = next_token (&val, (unsigned *)0, cfile);
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (token != OPTION) {
-                       parse_warn (cfile, "expecting 'vendor option space'");
-                       skip_to_semi (cfile);
-                       return;
-               }
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (token != SPACE) {
-                       parse_warn (cfile, "expecting 'vendor option space'");
-                       skip_to_semi (cfile);
-                       return;
-               }
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (!is_identifier (token)) {
-                       parse_warn (cfile, "expecting an identifier.");
-                       skip_to_semi (cfile);
-                       return;
-               }
-               config -> vendor_space_name = dmalloc (strlen (val) + 1, MDL);
-               if (!config -> vendor_space_name)
-                       log_fatal ("no memory for vendor option space name.");
-               strcpy (config -> vendor_space_name, val);
-               for (i = 0; i < universe_count; i++)
-                       if (!strcmp (universes [i] -> name,
-                                    config -> vendor_space_name))
-                               break;
-               if (i == universe_count) {
-                       log_error ("vendor option space %s not found.",
-                                  config -> vendor_space_name);
-               }
-               parse_semi (cfile);
-               return;
-
-             case INTERFACE:
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (ip)
-                       parse_warn (cfile, "nested interface declaration.");
-               parse_interface_declaration (cfile, config, (char *)0);
-               return;
-
-             case PSEUDO:
-               token = next_token (&val, (unsigned *)0, cfile);
-               token = next_token (&val, (unsigned *)0, cfile);
-               name = dmalloc (strlen (val) + 1, MDL);
-               if (!name)
-                       log_fatal ("no memory for pseudo interface name");
-               strcpy (name, val);
-               parse_interface_declaration (cfile, config, name);
-               return;
-               
-             case LEASE:
-               token = next_token (&val, (unsigned *)0, cfile);
-               parse_client_lease_statement (cfile, 1);
-               return;
-
-             case ALIAS:
-               token = next_token (&val, (unsigned *)0, cfile);
-               parse_client_lease_statement (cfile, 2);
-               return;
-
-             case REJECT:
-               token = next_token (&val, (unsigned *)0, cfile);
-               parse_reject_statement (cfile, config);
-               return;
-
-             default:
-               lose = 0;
-               stmt = (struct executable_statement *)0;
-               if (!parse_executable_statement (&stmt,
-                                                cfile, &lose, context_any)) {
-                       if (!lose) {
-                               parse_warn (cfile, "expecting a statement.");
-                               skip_to_semi (cfile);
-                       }
-               } else {
-                       struct executable_statement **eptr, *sptr;
-                       if (stmt &&
-                           (stmt -> op == send_option_statement ||
-                            (stmt -> op == on_statement &&
-                             (stmt -> data.on.evtypes & ON_TRANSMISSION)))) {
-                           eptr = &config -> on_transmission -> statements;
-                           if (stmt -> op == on_statement) {
-                                   sptr = (struct executable_statement *)0;
-                                   executable_statement_reference
-                                           (&sptr,
-                                            stmt -> data.on.statements, MDL);
-                                   executable_statement_dereference (&stmt,
-                                                                     MDL);
-                                   executable_statement_reference (&stmt,
-                                                                   sptr,
-                                                                   MDL);
-                                   executable_statement_dereference (&sptr,
-                                                                     MDL);
-                           }
-                       } else
-                           eptr = &config -> on_receipt -> statements;
-
-                       if (stmt) {
-                               for (; *eptr; eptr = &(*eptr) -> next)
-                                       ;
-                               executable_statement_reference (eptr,
-                                                               stmt, MDL);
-                       }
-                       return;
-               }
-               break;
-       }
-       parse_semi (cfile);
-}
-
-/* option-list :== option_name |
-                  option_list COMMA option_name */
-
-void parse_option_list (cfile, list)
-       struct parse *cfile;
-       u_int32_t **list;
-{
-       int ix;
-       int token;
-       const char *val;
-       pair p = (pair)0, q = (pair)0, r;
-       struct option *option;
-
-       ix = 0;
-       do {
-               token = peek_token (&val, (unsigned *)0, cfile);
-               if (token == SEMI) {
-                       token = next_token (&val, (unsigned *)0, cfile);
-                       break;
-               }
-               if (!is_identifier (token)) {
-                       parse_warn (cfile, "%s: expected option name.", val);
-                       token = next_token (&val, (unsigned *)0, cfile);
-                       skip_to_semi (cfile);
-                       return;
-               }
-               option = parse_option_name (cfile, 0, NULL);
-               if (!option) {
-                       parse_warn (cfile, "%s: expected option name.", val);
-                       return;
-               }
-               if (option -> universe != &dhcp_universe) {
-                       parse_warn (cfile,
-                               "%s.%s: Only global options allowed.",
-                               option -> universe -> name, option->name );
-                       skip_to_semi (cfile);
-                       return;
-               }
-               r = new_pair (MDL);
-               if (!r)
-                       log_fatal ("can't allocate pair for option code.");
-               r -> car = (caddr_t)(long)option -> code;
-               r -> cdr = (pair)0;
-               if (p)
-                       q -> cdr = r;
-               else
-                       p = r;
-               q = r;
-               ++ix;
-               token = next_token (&val, (unsigned *)0, cfile);
-       } while (token == COMMA);
-       if (token != SEMI) {
-               parse_warn (cfile, "expecting semicolon.");
-               skip_to_semi (cfile);
-               return;
-       }
-       /* XXX we can't free the list here, because we may have copied
-          XXX it from an outer config state. */
-       *list = (u_int32_t *)0;
-       if (ix) {
-               *list = dmalloc ((ix + 1) * sizeof **list, MDL);
-               if (!*list)
-                       log_error ("no memory for option list.");
-               else {
-                       ix = 0;
-                       for (q = p; q; q = q -> cdr)
-                               (*list) [ix++] = (u_int32_t)(long)q -> car;
-                       (*list) [ix] = 0;
-               }
-               while (p) {
-                       q = p -> cdr;
-                       free_pair (p, MDL);
-                       p = q;
-               }
-       }
-}
-
-/* interface-declaration :==
-       INTERFACE string LBRACE client-declarations RBRACE */
-
-void parse_interface_declaration (cfile, outer_config, name)
-       struct parse *cfile;
-       struct client_config *outer_config;
-       char *name;
-{
-       int token;
-       const char *val;
-       struct client_state *client, **cp;
-       struct interface_info *ip = (struct interface_info *)0;
-
-       token = next_token (&val, (unsigned *)0, cfile);
-       if (token != STRING) {
-               parse_warn (cfile, "expecting interface name (in quotes).");
-               skip_to_semi (cfile);
-               return;
-       }
-
-       if (!interface_or_dummy (&ip, val))
-               log_fatal ("Can't allocate interface %s.", val);
-
-       /* If we were given a name, this is a pseudo-interface. */
-       if (name) {
-               make_client_state (&client);
-               client -> name = name;
-               client -> interface = ip;
-               for (cp = &ip -> client; *cp; cp = &((*cp) -> next))
-                       ;
-               *cp = client;
-       } else {
-               if (!ip -> client) {
-                       make_client_state (&ip -> client);
-                       ip -> client -> interface = ip;
-               }
-               client = ip -> client;
-       }
-
-       if (!client -> config)
-               make_client_config (client, outer_config);
-
-       ip -> flags &= ~INTERFACE_AUTOMATIC;
-       interfaces_requested = 1;
-
-       token = next_token (&val, (unsigned *)0, cfile);
-       if (token != LBRACE) {
-               parse_warn (cfile, "expecting left brace.");
-               skip_to_semi (cfile);
-               return;
-       }
-
-       do {
-               token = peek_token (&val, (unsigned *)0, cfile);
-               if (token == END_OF_FILE) {
-                       parse_warn (cfile,
-                                   "unterminated interface declaration.");
-                       return;
-               }
-               if (token == RBRACE)
-                       break;
-               parse_client_statement (cfile, ip, client -> config);
-       } while (1);
-       token = next_token (&val, (unsigned *)0, cfile);
-}
-
-int interface_or_dummy (struct interface_info **pi, const char *name)
-{
-       struct interface_info *i;
-       struct interface_info *ip = (struct interface_info *)0;
-       isc_result_t status;
-
-       /* Find the interface (if any) that matches the name. */
-       for (i = interfaces; i; i = i -> next) {
-               if (!strcmp (i -> name, name)) {
-                       interface_reference (&ip, i, MDL);
-                       break;
-               }
-       }
-
-       /* If it's not a real interface, see if it's on the dummy list. */
-       if (!ip) {
-               for (ip = dummy_interfaces; ip; ip = ip -> next) {
-                       if (!strcmp (ip -> name, name)) {
-                               interface_reference (&ip, i, MDL);
-                               break;
-                       }
-               }
-       }
-
-       /* If we didn't find an interface, make a dummy interface as
-          a placeholder. */
-       if (!ip) {
-               if ((status = interface_allocate (&ip, MDL)) != ISC_R_SUCCESS)
-                       log_fatal ("Can't record interface %s: %s",
-                                  name, isc_result_totext (status));
-               strcpy (ip -> name, name);
-               if (dummy_interfaces) {
-                       interface_reference (&ip -> next,
-                                            dummy_interfaces, MDL);
-                       interface_dereference (&dummy_interfaces, MDL);
-               }
-               interface_reference (&dummy_interfaces, ip, MDL);
-       }
-       if (pi)
-               status = interface_reference (pi, ip, MDL);
-       else
-               status = ISC_R_FAILURE;
-       interface_dereference (&ip, MDL);
-       if (status != ISC_R_SUCCESS)
-               return 0;
-       return 1;
-}
-
-void make_client_state (state)
-       struct client_state **state;
-{
-       *state = ((struct client_state *)dmalloc (sizeof **state, MDL));
-       if (!*state)
-               log_fatal ("no memory for client state\n");
-       memset (*state, 0, sizeof **state);
-}
-
-void make_client_config (client, config)
-       struct client_state *client;
-       struct client_config *config;
-{
-       client -> config = (((struct client_config *)
-                            dmalloc (sizeof (struct client_config), MDL)));
-       if (!client -> config)
-               log_fatal ("no memory for client config\n");
-       memcpy (client -> config, config, sizeof *config);
-       if (!clone_group (&client -> config -> on_receipt,
-                         config -> on_receipt, MDL) ||
-           !clone_group (&client -> config -> on_transmission,
-                         config -> on_transmission, MDL))
-               log_fatal ("no memory for client state groups.");
-}
-
-/* client-lease-statement :==
-       RBRACE client-lease-declarations LBRACE
-
-       client-lease-declarations :==
-               <nil> |
-               client-lease-declaration |
-               client-lease-declarations client-lease-declaration */
-
-
-void parse_client_lease_statement (cfile, is_static)
-       struct parse *cfile;
-       int is_static;
-{
-       struct client_lease *lease, *lp, *pl, *next;
-       struct interface_info *ip = (struct interface_info *)0;
-       int token;
-       const char *val;
-       struct client_state *client = (struct client_state *)0;
-
-       token = next_token (&val, (unsigned *)0, cfile);
-       if (token != LBRACE) {
-               parse_warn (cfile, "expecting left brace.");
-               skip_to_semi (cfile);
-               return;
-       }
-
-       lease = ((struct client_lease *)
-                dmalloc (sizeof (struct client_lease), MDL));
-       if (!lease)
-               log_fatal ("no memory for lease.\n");
-       memset (lease, 0, sizeof *lease);
-       lease -> is_static = is_static;
-       if (!option_state_allocate (&lease -> options, MDL))
-               log_fatal ("no memory for lease options.\n");
-
-       do {
-               token = peek_token (&val, (unsigned *)0, cfile);
-               if (token == END_OF_FILE) {
-                       parse_warn (cfile, "unterminated lease declaration.");
-                       return;
-               }
-               if (token == RBRACE)
-                       break;
-               parse_client_lease_declaration (cfile, lease, &ip, &client);
-       } while (1);
-       token = next_token (&val, (unsigned *)0, cfile);
-
-       /* If the lease declaration didn't include an interface
-          declaration that we recognized, it's of no use to us. */
-       if (!ip) {
-               destroy_client_lease (lease);
-               return;
-       }
-
-       /* Make sure there's a client state structure... */
-       if (!ip -> client) {
-               make_client_state (&ip -> client);
-               ip -> client -> interface = ip;
-       }
-       if (!client)
-               client = ip -> client;
-
-       /* If this is an alias lease, it doesn't need to be sorted in. */
-       if (is_static == 2) {
-               ip -> client -> alias = lease;
-               return;
-       }
-
-       /* The new lease may supersede a lease that's not the
-          active lease but is still on the lease list, so scan the
-          lease list looking for a lease with the same address, and
-          if we find it, toss it. */
-       pl = (struct client_lease *)0;
-       for (lp = client -> leases; lp; lp = next) {
-               next = lp -> next;
-               if (lp -> address.len == lease -> address.len &&
-                   !memcmp (lp -> address.iabuf, lease -> address.iabuf,
-                            lease -> address.len)) {
-                       if (pl)
-                               pl -> next = next;
-                       else
-                               client -> leases = next;
-                       destroy_client_lease (lp);
-                       break;
-               } else
-                       pl = lp;
-       }
-
-       /* If this is a preloaded lease, just put it on the list of recorded
-          leases - don't make it the active lease. */
-       if (is_static) {
-               lease -> next = client -> leases;
-               client -> leases = lease;
-               return;
-       }
-               
-       /* The last lease in the lease file on a particular interface is
-          the active lease for that interface.    Of course, we don't know
-          what the last lease in the file is until we've parsed the whole
-          file, so at this point, we assume that the lease we just parsed
-          is the active lease for its interface.   If there's already
-          an active lease for the interface, and this lease is for the same
-          ip address, then we just toss the old active lease and replace
-          it with this one.   If this lease is for a different address,
-          then if the old active lease has expired, we dump it; if not,
-          we put it on the list of leases for this interface which are
-          still valid but no longer active. */
-       if (client -> active) {
-               if (client -> active -> expiry < cur_time)
-                       destroy_client_lease (client -> active);
-               else if (client -> active -> address.len ==
-                        lease -> address.len &&
-                        !memcmp (client -> active -> address.iabuf,
-                                 lease -> address.iabuf,
-                                 lease -> address.len))
-                       destroy_client_lease (client -> active);
-               else {
-                       client -> active -> next = client -> leases;
-                       client -> leases = client -> active;
-               }
-       }
-       client -> active = lease;
-
-       /* phew. */
-}
-
-/* client-lease-declaration :==
-       BOOTP |
-       INTERFACE string |
-       FIXED_ADDR ip_address |
-       FILENAME string |
-       SERVER_NAME string |
-       OPTION option-decl |
-       RENEW time-decl |
-       REBIND time-decl |
-       EXPIRE time-decl |
-       KEY id */
-
-void parse_client_lease_declaration (cfile, lease, ipp, clientp)
-       struct parse *cfile;
-       struct client_lease *lease;
-       struct interface_info **ipp;
-       struct client_state **clientp;
-{
-       int token;
-       const char *val;
-       char *t, *n;
-       struct interface_info *ip;
-       struct option_cache *oc;
-       struct client_state *client = (struct client_state *)0;
-       struct data_string key_id;
-
-       switch (next_token (&val, (unsigned *)0, cfile)) {
-             case KEY:
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (token != STRING && !is_identifier (token)) {
-                       parse_warn (cfile, "expecting key name.");
-                       skip_to_semi (cfile);
-                       break;
-               }
-               if (omapi_auth_key_lookup_name (&lease -> key, val) !=
-                   ISC_R_SUCCESS)
-                       parse_warn (cfile, "unknown key %s", val);
-               parse_semi (cfile);
-               break;
-             case TOKEN_BOOTP:
-               lease -> is_bootp = 1;
-               break;
-
-             case INTERFACE:
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (token != STRING) {
-                       parse_warn (cfile,
-                                   "expecting interface name (in quotes).");
-                       skip_to_semi (cfile);
-                       break;
-               }
-               interface_or_dummy (ipp, val);
-               break;
-
-             case NAME:
-               token = next_token (&val, (unsigned *)0, cfile);
-               ip = *ipp;
-               if (!ip) {
-                       parse_warn (cfile, "state name precedes interface.");
-                       break;
-               }
-               for (client = ip -> client; client; client = client -> next)
-                       if (client -> name && !strcmp (client -> name, val))
-                               break;
-               if (!client)
-                       parse_warn (cfile,
-                                   "lease specified for unknown pseudo.");
-               *clientp = client;
-               break;
-
-             case FIXED_ADDR:
-               if (!parse_ip_addr (cfile, &lease -> address))
-                       return;
-               break;
-
-             case MEDIUM:
-               parse_string_list (cfile, &lease -> medium, 0);
-               return;
-
-             case FILENAME:
-               parse_string (cfile, &lease -> filename, (unsigned *)0);
-               return;
-
-             case SERVER_NAME:
-               parse_string (cfile, &lease -> server_name, (unsigned *)0);
-               return;
-
-             case RENEW:
-               lease -> renewal = parse_date (cfile);
-               return;
-
-             case REBIND:
-               lease -> rebind = parse_date (cfile);
-               return;
-
-             case EXPIRE:
-               lease -> expiry = parse_date (cfile);
-               return;
-
-             case OPTION:
-               oc = (struct option_cache *)0;
-               if (parse_option_decl (&oc, cfile)) {
-                       save_option (oc -> option -> universe,
-                                    lease -> options, oc);
-                       option_cache_dereference (&oc, MDL);
-               }
-               return;
-
-             default:
-               parse_warn (cfile, "expecting lease declaration.");
-               skip_to_semi (cfile);
-               break;
-       }
-       token = next_token (&val, (unsigned *)0, cfile);
-       if (token != SEMI) {
-               parse_warn (cfile, "expecting semicolon.");
-               skip_to_semi (cfile);
-       }
-}
-
-void parse_string_list (cfile, lp, multiple)
-       struct parse *cfile;
-       struct string_list **lp;
-       int multiple;
-{
-       int token;
-       const char *val;
-       struct string_list *cur, *tmp;
-
-       /* Find the last medium in the media list. */
-       if (*lp) {
-               for (cur = *lp; cur -> next; cur = cur -> next)
-                       ;
-       } else {
-               cur = (struct string_list *)0;
-       }
-
-       do {
-               token = next_token (&val, (unsigned *)0, cfile);
-               if (token != STRING) {
-                       parse_warn (cfile, "Expecting media options.");
-                       skip_to_semi (cfile);
-                       return;
-               }
-
-               tmp = ((struct string_list *)
-                      dmalloc (strlen (val) + sizeof (struct string_list),
-                               MDL));
-               if (!tmp)
-                       log_fatal ("no memory for string list entry.");
-
-               strcpy (tmp -> string, val);
-               tmp -> next = (struct string_list *)0;
-
-               /* Store this medium at the end of the media list. */
-               if (cur)
-                       cur -> next = tmp;
-               else
-                       *lp = tmp;
-               cur = tmp;
-
-               token = next_token (&val, (unsigned *)0, cfile);
-       } while (multiple && token == COMMA);
-
-       if (token != SEMI) {
-               parse_warn (cfile, "expecting semicolon.");
-               skip_to_semi (cfile);
-       }
-}
-
-void parse_reject_statement (cfile, config)
-       struct parse *cfile;
-       struct client_config *config;
-{
-       int token;
-       const char *val;
-       struct iaddr addr;
-       struct iaddrlist *list;
-
-       do {
-               if (!parse_ip_addr (cfile, &addr)) {
-                       parse_warn (cfile, "expecting IP address.");
-                       skip_to_semi (cfile);
-                       return;
-               }
-
-               list = (struct iaddrlist *)dmalloc (sizeof (struct iaddrlist),
-                                                   MDL);
-               if (!list)
-                       log_fatal ("no memory for reject list!");
-
-               list -> addr = addr;
-               list -> next = config -> reject_list;
-               config -> reject_list = list;
-
-               token = next_token (&val, (unsigned *)0, cfile);
-       } while (token == COMMA);
-
-       if (token != SEMI) {
-               parse_warn (cfile, "expecting semicolon.");
-               skip_to_semi (cfile);
-       }
-}      
-
-/* allow-deny-keyword :== BOOTP
-                       | BOOTING
-                       | DYNAMIC_BOOTP
-                       | UNKNOWN_CLIENTS */
-
-int parse_allow_deny (oc, cfile, flag)
-       struct option_cache **oc;
-       struct parse *cfile;
-       int flag;
-{
-       enum dhcp_token token;
-       const char *val;
-       unsigned char rf = flag;
-       struct expression *data = (struct expression *)0;
-       int status;
-
-       parse_warn (cfile, "allow/deny/ignore not permitted here.");
-       skip_to_semi (cfile);
-       return 0;
-}
-
diff --git a/contrib/dhcp-3.0/client/dhclient-script.8 b/contrib/dhcp-3.0/client/dhclient-script.8
deleted file mode 100644 (file)
index d81cf41..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-.\"    dhclient-script.8
-.\"
-.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-.\" Copyright (c) 1996-2003 by Internet Software Consortium
-.\"
-.\" 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 ISC DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC 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.
-.\"
-.\"   Internet Systems Consortium, Inc.
-.\"   950 Charter Street
-.\"   Redwood City, CA 94063
-.\"   <info@isc.org>
-.\"   http://www.isc.org/
-.\"
-.\" This software has been written for Internet Systems Consortium
-.\" by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
-.\" To learn more about Internet Systems Consortium, see
-.\" ``http://www.isc.org/''.  To learn more about Vixie Enterprises,
-.\" see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
-.\" ``http://www.nominum.com''.
-.\"
-.\" $Id: dhclient-script.8,v 1.8.2.5 2004/06/10 17:59:12 dhankins Exp $
-.\"
-.TH dhclient-script 8
-.SH NAME
-dhclient-script - DHCP client network configuration script
-.SH DESCRIPTION
-The DHCP client network configuration script is invoked from time to
-time by \fBdhclient(8)\fR.  This script is used by the dhcp client to
-set each interface's initial configuration prior to requesting an
-address, to test the address once it has been offered, and to set the
-interface's final configuration once a lease has been acquired.  If no
-lease is acquired, the script is used to test predefined leases, if
-any, and also called once if no valid lease can be identified.
-.PP
-This script is not meant to be customized by the end user.  If local
-customizations are needed, they should be possible using the enter and
-exit hooks provided (see HOOKS for details).   These hooks will allow the
-user to override the default behaviour of the client in creating a
-.B /etc/resolv.conf
-file.
-.PP
-No standard client script exists for some operating systems, even though
-the actual client may work, so a pioneering user may well need to create
-a new script or modify an existing one.  In general, customizations specific
-to a particular computer should be done in the
-.B ETCDIR/dhclient.conf
-file.   If you find that you can't make such a customization without
-customizing
-.B ETCDIR/dhclient.conf
-or using the enter and exit hooks, please submit a bug report.
-.SH HOOKS
-When it starts, the client script first defines a shell function,
-.B make_resolv_conf ,
-which is later used to create the
-.B /etc/resolv.conf
-file.   To override the default behaviour, redefine this function in
-the enter hook script.
-.PP
-On after defining the make_resolv_conf function, the client script checks
-for the presence of an executable
-.B ETCDIR/dhclient-enter-hooks
-script, and if present, it invokes the script inline, using the Bourne
-shell '.' command.   The entire environment documented under OPERATION
-is available to this script, which may modify the environment if needed
-to change the behaviour of the script.   If an error occurs during the
-execution of the script, it can set the exit_status variable to a nonzero
-value, and
-.B CLIENTBINDIR/dhclient-script
-will exit with that error code immediately after the client script exits.
-.PP
-After all processing has completed,
-.B CLIENTBINDIR/dhclient-script
-checks for the presence of an executable
-.B ETCDIR/dhclient-exit-hooks
-script, which if present is invoked using the '.' command.  The exit
-status of dhclient-script will be passed to dhclient-exit-hooks in the
-exit_status shell variable, and will always be zero if the script
-succeeded at the task for which it was invoked.   The rest of the
-environment as described previously for dhclient-enter-hooks is also
-present.   The
-.B ETCDIR/dhclient-exit-hooks
-script can modify the valid of exit_status to change the exit status
-of dhclient-script.
-.SH OPERATION
-When dhclient needs to invoke the client configuration script, it
-defines a set of variables in the environment, and then invokes
-.B CLIENTBINDIR/dhclient-script.
-In all cases, $reason is set to the name of the reason why the script
-has been invoked.   The following reasons are currently defined:
-MEDIUM, PREINIT, BOUND, RENEW, REBIND, REBOOT, EXPIRE, FAIL and TIMEOUT.
-.PP
-.SH MEDIUM
-The DHCP client is requesting that an interface's media type
-be set.  The interface name is passed in $interface, and the media
-type is passed in $medium.
-.SH PREINIT
-The DHCP client is requesting that an interface be configured as
-required in order to send packets prior to receiving an actual
-address.   For clients which use the BSD socket library, this means
-configuring the interface with an IP address of 0.0.0.0 and a
-broadcast address of 255.255.255.255.   For other clients, it may be
-possible to simply configure the interface up without actually giving
-it an IP address at all.   The interface name is passed in $interface,
-and the media type in $medium.
-.PP
-If an IP alias has been declared in dhclient.conf, its address will be
-passed in $alias_ip_address, and that ip alias should be deleted from
-the interface, along with any routes to it.
-.SH BOUND
-The DHCP client has done an initial binding to a new address.   The
-new ip address is passed in $new_ip_address, and the interface name is
-passed in $interface.   The media type is passed in $medium.   Any
-options acquired from the server are passed using the option name
-described in \fBdhcp-options\fR, except that dashes ('-') are replaced
-by underscores ('_') in order to make valid shell variables, and the
-variable names start with new_.   So for example, the new subnet mask
-would be passed in $new_subnet_mask.
-.PP
-Before actually configuring the address, dhclient-script should
-somehow ARP for it and exit with a nonzero status if it receives a
-reply.   In this case, the client will send a DHCPDECLINE message to
-the server and acquire a different address.   This may also be done in
-the RENEW, REBIND, or REBOOT states, but is not required, and indeed
-may not be desirable.
-.PP
-When a binding has been completed, a lot of network parameters are
-likely to need to be set up.   A new /etc/resolv.conf needs to be
-created, using the values of $new_domain_name and
-$new_domain_name_servers (which may list more than one server,
-separated by spaces).   A default route should be set using
-$new_routers, and static routes may need to be set up using
-$new_static_routes.
-.PP
-If an IP alias has been declared, it must be set up here.   The alias
-IP address will be written as $alias_ip_address, and other DHCP
-options that are set for the alias (e.g., subnet mask) will be passed
-in variables named as described previously except starting with
-$alias_ instead of $new_.   Care should be taken that the alias IP
-address not be used if it is identical to the bound IP address
-($new_ip_address), since the other alias parameters may be incorrect
-in this case.
-.SH RENEW
-When a binding has been renewed, the script is called as in BOUND,
-except that in addition to all the variables starting with $new_,
-there is another set of variables starting with $old_.  Persistent
-settings that may have changed need to be deleted - for example, if a
-local route to the bound address is being configured, the old local
-route should be deleted.  If the default route has changed, the old default
-route should be deleted.  If the static routes have changed, the old
-ones should be deleted.  Otherwise, processing can be done as with
-BOUND.
-.SH REBIND
-The DHCP client has rebound to a new DHCP server.  This can be handled
-as with RENEW, except that if the IP address has changed, the ARP
-table should be cleared.
-.SH REBOOT
-The DHCP client has successfully reacquired its old address after a
-reboot.   This can be processed as with BOUND.
-.SH EXPIRE
-The DHCP client has failed to renew its lease or acquire a new one,
-and the lease has expired.   The IP address must be relinquished, and
-all related parameters should be deleted, as in RENEW and REBIND.
-.SH FAIL
-The DHCP client has been unable to contact any DHCP servers, and any
-leases that have been tested have not proved to be valid.   The
-parameters from the last lease tested should be deconfigured.   This
-can be handled in the same way as EXPIRE.
-.SH TIMEOUT
-The DHCP client has been unable to contact any DHCP servers.
-However, an old lease has been identified, and its parameters have
-been passed in as with BOUND.   The client configuration script should
-test these parameters and, if it has reason to believe they are valid,
-should exit with a value of zero.   If not, it should exit with a
-nonzero value.
-.PP
-The usual way to test a lease is to set up the network as with REBIND
-(since this may be called to test more than one lease) and then ping
-the first router defined in $routers.  If a response is received, the
-lease must be valid for the network to which the interface is
-currently connected.   It would be more complete to try to ping all of
-the routers listed in $new_routers, as well as those listed in
-$new_static_routes, but current scripts do not do this.
-.SH FILES
-Each operating system should generally have its own script file,
-although the script files for similar operating systems may be similar
-or even identical.   The script files included in Internet
-Systems Consortium DHCP distribution appear in the distribution tree
-under client/scripts, and bear the names of the operating systems on
-which they are intended to work.
-.SH BUGS
-If more than one interface is being used, there's no obvious way to
-avoid clashes between server-supplied configuration parameters - for
-example, the stock dhclient-script rewrites /etc/resolv.conf.   If
-more than one interface is being configured, /etc/resolv.conf will be
-repeatedly initialized to the values provided by one server, and then
-the other.   Assuming the information provided by both servers is
-valid, this shouldn't cause any real problems, but it could be
-confusing.
-.SH SEE ALSO
-dhclient(8), dhcpd(8), dhcrelay(8), dhclient.conf(5) and
-dhclient.leases(5).
-.SH AUTHOR
-.B dhclient-script(8)
-has been written for Internet Systems Consortium
-by Ted Lemon in cooperation with Vixie
-Enterprises.  To learn more about Internet Systems Consortium,
-see
-.B http://www.isc.org.
-To learn more about Vixie
-Enterprises, see
-.B http://www.vix.com.
diff --git a/contrib/dhcp-3.0/client/dhclient.8 b/contrib/dhcp-3.0/client/dhclient.8
deleted file mode 100644 (file)
index 01d1368..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-.\"    dhclient.8
-.\"
-.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-.\" Copyright (c) 1996-2003 by Internet Software Consortium
-.\"
-.\" 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 ISC DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC 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.
-.\"
-.\"   Internet Systems Consortium, Inc.
-.\"   950 Charter Street
-.\"   Redwood City, CA 94063
-.\"   <info@isc.org>
-.\"   http://www.isc.org/
-.\"
-.\" $Id: dhclient.8,v 1.12.2.9 2004/09/29 23:01:46 dhankins Exp $
-.\"
-.TH dhclient 8
-.SH NAME
-dhclient - Dynamic Host Configuration Protocol Client
-.SH SYNOPSIS
-.B dhclient
-[
-.B -p
-.I port
-]
-[
-.B -d
-]
-[
-.B -q
-]
-[
-.B -1
-]
-[
-.B -r
-]
-[
-.B -lf
-.I lease-file
-]
-[
-.B -pf
-.I pid-file
-]
-[
-.B -cf
-.I config-file
-]
-[
-.B -sf
-.I script-file
-]
-[
-.B -s
-server
-]
-[
-.B -g
-relay
-]
-[
-.B -n
-]
-[
-.B -nw
-]
-[
-.B -w
-]
-[
-.I if0
-[
-.I ...ifN
-]
-]
-.SH DESCRIPTION
-The Internet Systems Consortium DHCP Client, dhclient, provides a
-means for configuring one or more network interfaces using the Dynamic
-Host Configuration Protocol, BOOTP protocol, or if these protocols
-fail, by statically assigning an address.
-.SH OPERATION
-.PP
-The DHCP protocol allows a host to contact a central server which
-maintains a list of IP addresses which may be assigned on one or more
-subnets.   A DHCP client may request an address from this pool, and
-then use it on a temporary basis for communication on network.   The
-DHCP protocol also provides a mechanism whereby a client can learn
-important details about the network to which it is attached, such as
-the location of a default router, the location of a name server, and
-so on.
-.PP
-On startup, dhclient reads the
-.IR dhclient.conf
-for configuration instructions.   It then gets a list of all the
-network interfaces that are configured in the current system.   For
-each interface, it attempts to configure the interface using the DHCP
-protocol.
-.PP
-In order to keep track of leases across system reboots and server
-restarts, dhclient keeps a list of leases it has been assigned in the
-dhclient.leases(5) file.   On startup, after reading the dhclient.conf
-file, dhclient reads the dhclient.leases file to refresh its memory
-about what leases it has been assigned.
-.PP
-When a new lease is acquired, it is appended to the end of the
-dhclient.leases file.   In order to prevent the file from becoming
-arbitrarily large, from time to time dhclient creates a new
-dhclient.leases file from its in-core lease database.  The old version
-of the dhclient.leases file is retained under the name
-.IR dhclient.leases~
-until the next time dhclient rewrites the database.
-.PP
-Old leases are kept around in case the DHCP server is unavailable when
-dhclient is first invoked (generally during the initial system boot
-process).   In that event, old leases from the dhclient.leases file
-which have not yet expired are tested, and if they are determined to
-be valid, they are used until either they expire or the DHCP server
-becomes available.
-.PP
-A mobile host which may sometimes need to access a network on which no
-DHCP server exists may be preloaded with a lease for a fixed
-address on that network.   When all attempts to contact a DHCP server
-have failed, dhclient will try to validate the static lease, and if it
-succeeds, will use that lease until it is restarted.
-.PP
-A mobile host may also travel to some networks on which DHCP is not
-available but BOOTP is.   In that case, it may be advantageous to
-arrange with the network administrator for an entry on the BOOTP
-database, so that the host can boot quickly on that network rather
-than cycling through the list of old leases.
-.SH COMMAND LINE
-.PP
-The names of the network interfaces that dhclient should attempt to
-configure may be specified on the command line.  If no interface names
-are specified on the command line dhclient will normally identify all
-network interfaces, eliminating non-broadcast interfaces if
-possible, and attempt to configure each interface.
-.PP
-It is also possible to specify interfaces by name in the
-.B dhclient.conf(5)
-file.   If interfaces are specified in this way, then the client will
-only configure interfaces that are either specified in the
-configuration file or on the command line, and will ignore all other
-interfaces.
-.PP
-If the DHCP client should listen and transmit on a port other than the
-standard (port 68), the
-.B -p
-flag may used.  It should be followed by the udp port number that
-dhclient should use.  This is mostly useful for debugging purposes.
-If a different port is specified for the client to listen on and
-transmit on, the client will also use a different destination port -
-one greater than the specified destination port.
-.PP
-The DHCP client normally transmits any protocol messages it sends
-before acquiring an IP address to, 255.255.255.255, the IP limited
-broadcast address.   For debugging purposes, it may be useful to have
-the server transmit these messages to some other address.   This can
-be specified with the 
-.B -s
-flag, followed by the IP address or domain name of the destination.
-.PP
-For testing purposes, the giaddr field of all packets that the client
-sends can be set using the
-.B -g
-flag, followed by the IP address to send.   This is only useful for testing,
-and should not be expected to work in any consistent or useful way.
-.PP
-The DHCP client will normally run in the foreground until it has
-configured an interface, and then will revert to running in the
-background.   To run force dhclient to always run as a foreground
-process, the
-.B -d
-flag should be specified.  This is useful when running the client
-under a debugger, or when running it out of inittab on System V
-systems.
-.PP
-The client normally prints a startup message and displays the
-protocol sequence to the standard error descriptor until it has
-acquired an address, and then only logs messages using the
-.B syslog (3)
-facility.   The
-.B -q
-flag prevents any messages other than errors from being printed to the
-standard error descriptor.
-.PP
-The client normally doesn't release the current lease as it is not
-required by the DHCP protocol.  Some cable ISPs require their clients
-to notify the server if they wish to release an assigned IP address.
-The
-.B -r
-flag explicitly releases the current lease, and once the lease has been
-released, the client exits.
-.PP
-The
-.B -1
-flag cause dhclient to try once to get a lease.  If it fails, dhclient exits
-with exit code two.
-.PP
-The DHCP client normally gets its configuration information from
-.B ETCDIR/dhclient.conf,
-its lease database from
-.B DBDIR/dhclient.leases,
-stores its process ID in a file called
-.B RUNDIR/dhclient.pid,
-and configures the network interface using
-.B CLIENTBINDIR/dhclient-script
-To specify different names and/or locations for these files, use the
-.B -cf,
-.B -lf,
-.B -pf
-and
-.B -sf
-flags, respectively, followed by the name of the file.   This can be
-particularly useful if, for example,
-.B DBDIR
-or
-.B RUNDIR
-has not yet been mounted when the DHCP client is started.
-.PP
-The DHCP client normally exits if it isn't able to identify any
-network interfaces to configure.   On laptop computers and other
-computers with hot-swappable I/O buses, it is possible that a
-broadcast interface may be added after system startup.   The
-.B -w
-flag can be used to cause the client not to exit when it doesn't find
-any such interfaces.   The
-.B omshell (8)
-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.
-.PP
-The DHCP client can be directed not to attempt to configure any interfaces
-using the
-.B -n
-flag.   This is most likely to be useful in combination with the
-.B -w
-flag.
-.PP
-The client can also be instructed to become a daemon immediately, rather
-than waiting until it has acquired an IP address.   This can be done by
-supplying the
-.B -nw
-flag.
-.SH CONFIGURATION
-The syntax of the dhclient.conf(5) file is discussed separately.
-.SH OMAPI
-The DHCP client provides some ability to control it while it is
-running, without stopping it.  This capability is provided using OMAPI,
-an API for manipulating remote objects.  OMAPI clients connect to the
-client using TCP/IP, authenticate, and can then examine the client's
-current status and make changes to it. 
-.PP
-Rather than implementing the underlying OMAPI protocol directly, user
-programs should use the dhcpctl API or OMAPI itself.   Dhcpctl is a
-wrapper that handles some of the housekeeping chores that OMAPI does
-not do automatically.   Dhcpctl and OMAPI are documented in \fBdhcpctl(3)\fR
-and \fBomapi(3)\fR.   Most things you'd want to do with the client can
-be done directly using the \fBomshell(1)\fR command, rather than
-having to write a special program.
-.SH THE CONTROL OBJECT
-The control object allows you to shut the client down, releasing all
-leases that it holds and deleting any DNS records it may have added.
-It also allows you to pause the client - this unconfigures any
-interfaces the client is using.   You can then restart it, which
-causes it to reconfigure those interfaces.   You would normally pause
-the client prior to going into hibernation or sleep on a laptop
-computer.   You would then resume it after the power comes back.
-This allows PC cards to be shut down while the computer is hibernating
-or sleeping, and then reinitialized to their previous state once the
-computer comes out of hibernation or sleep.
-.PP
-The control object has one attribute - the state attribute.   To shut
-the client down, set its state attribute to 2.   It will automatically
-do a DHCPRELEASE.   To pause it, set its state attribute to 3.   To
-resume it, set its state attribute to 4.
-.PP
-.SH FILES
-.B CLIENTBINDIR/dhclient-script,
-.B ETCDIR/dhclient.conf, DBDIR/dhclient.leases, RUNDIR/dhclient.pid,
-.B DBDIR/dhclient.leases~.
-.SH SEE ALSO
-dhcpd(8), dhcrelay(8), dhclient-script(8), dhclient.conf(5),
-dhclient.leases(5).
-.SH AUTHOR
-.B dhclient(8)
-has been written for Internet Systems Consortium
-by Ted Lemon in cooperation with Vixie
-Enterprises.  To learn more about Internet Systems Consortium,
-see
-.B http://www.isc.org
-To learn more about Vixie
-Enterprises, see
-.B http://www.vix.com.
-.PP
-This client was substantially modified and enhanced by Elliot Poger
-for use on Linux while he was working on the MosquitoNet project at
-Stanford.
-.PP
-The current version owes much to Elliot's Linux enhancements, but
-was substantially reorganized and partially rewritten by Ted Lemon
-so as to use the same networking framework that the Internet Systems
-Consortium DHCP server uses.   Much system-specific configuration code
-was moved into a shell script so that as support for more operating
-systems is added, it will not be necessary to port and maintain
-system-specific configuration code to these operating systems - instead,
-the shell script can invoke the native tools to accomplish the same
-purpose.
-.PP
diff --git a/contrib/dhcp-3.0/client/dhclient.c b/contrib/dhcp-3.0/client/dhclient.c
deleted file mode 100644 (file)
index 709c507..0000000
+++ /dev/null
@@ -1,3162 +0,0 @@
-/* dhclient.c
-
-   DHCP Client. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * 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 ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC 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.
- *
- *   Internet Systems Consortium, Inc.
- *   950 Charter Street
- *   Redwood City, CA 94063
- *   <info@isc.org>
- *   http://www.isc.org/
- *
- * This code is based on the original client state machine that was
- * written by Elliot Poger.  The code has been extensively hacked on
- * by Ted Lemon since then, so any mistakes you find are probably his
- * fault and not Elliot's.
- */
-
-#ifndef lint
-static char ocopyright[] =
-"$Id: dhclient.c,v 1.129.2.23 2004/11/24 17:39:14 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include "version.h"
-
-TIME default_lease_time = 43200; /* 12 hours... */
-TIME max_lease_time = 86400; /* 24 hours... */
-
-const char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
-const char *path_dhclient_db = _PATH_DHCLIENT_DB;
-const char *path_dhclient_pid = _PATH_DHCLIENT_PID;
-static char path_dhclient_script_array [] = _PATH_DHCLIENT_SCRIPT;
-char *path_dhclient_script = path_dhclient_script_array;
-
-int dhcp_max_agent_option_packet_length = 0;
-
-int interfaces_requested = 0;
-
-struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
-struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } };
-struct in_addr inaddr_any;
-struct sockaddr_in sockaddr_broadcast;
-struct in_addr giaddr;
-
-/* ASSERT_STATE() does nothing now; it used to be
-   assert (state_is == state_shouldbe). */
-#define ASSERT_STATE(state_is, state_shouldbe) {}
-
-static char copyright[] = "Copyright 2004 Internet Systems Consortium.";
-static char arr [] = "All rights reserved.";
-static char message [] = "Internet Systems Consortium DHCP Client";
-static char url [] = "For info, please visit http://www.isc.org/products/DHCP";
-
-u_int16_t local_port=0;
-u_int16_t remote_port=0;
-int no_daemon=0;
-struct string_list *client_env=NULL;
-int client_env_count=0;
-int onetry=0;
-int quiet=0;
-int nowait=0;
-
-static void usage PROTO ((void));
-
-void do_release(struct client_state *);
-
-int main (argc, argv, envp)
-       int argc;
-       char **argv, **envp;
-{
-       int i;
-       struct servent *ent;
-       struct interface_info *ip;
-       struct client_state *client;
-       unsigned seed;
-       char *server = (char *)0;
-       char *relay = (char *)0;
-       isc_result_t status;
-       int release_mode = 0;
-       omapi_object_t *listener;
-       isc_result_t result;
-       int persist = 0;
-       int omapi_port;
-       int no_dhclient_conf = 0;
-       int no_dhclient_db = 0;
-       int no_dhclient_pid = 0;
-       int no_dhclient_script = 0;
-       char *s;
-
-       /* Make sure we have stdin, stdout and stderr. */
-       i = open ("/dev/null", O_RDWR);
-       if (i == 0)
-               i = open ("/dev/null", O_RDWR);
-       if (i == 1) {
-               i = open ("/dev/null", O_RDWR);
-               log_perror = 0; /* No sense logging to /dev/null. */
-       } else if (i != -1)
-               close (i);
-
-#ifdef SYSLOG_4_2
-       openlog ("dhclient", LOG_NDELAY);
-       log_priority = LOG_DAEMON;
-#else
-       openlog ("dhclient", LOG_NDELAY, LOG_DAEMON);
-#endif
-
-#if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
-       setlogmask (LOG_UPTO (LOG_INFO));
-#endif 
-
-       /* Set up the OMAPI. */
-       status = omapi_init ();
-       if (status != ISC_R_SUCCESS)
-               log_fatal ("Can't initialize OMAPI: %s",
-                          isc_result_totext (status));
-
-       /* Set up the OMAPI wrappers for various server database internal
-          objects. */
-       dhcp_common_objects_setup ();
-
-       dhcp_interface_discovery_hook = dhclient_interface_discovery_hook;
-       dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook;
-       dhcp_interface_startup_hook = dhclient_interface_startup_hook;
-
-       for (i = 1; i < argc; i++) {
-               if (!strcmp (argv [i], "-r")) {
-                       release_mode = 1;
-                       no_daemon = 1;
-               } else if (!strcmp (argv [i], "-p")) {
-                       if (++i == argc)
-                               usage ();
-                       local_port = htons (atoi (argv [i]));
-                       log_debug ("binding to user-specified port %d",
-                              ntohs (local_port));
-               } else if (!strcmp (argv [i], "-d")) {
-                       no_daemon = 1;
-                } else if (!strcmp (argv [i], "-pf")) {
-                        if (++i == argc)
-                                usage ();
-                        path_dhclient_pid = argv [i];
-                       no_dhclient_pid = 1;
-                } else if (!strcmp (argv [i], "-cf")) {
-                        if (++i == argc)
-                                usage ();
-                        path_dhclient_conf = argv [i];
-                       no_dhclient_conf = 1;
-                } else if (!strcmp (argv [i], "-lf")) {
-                        if (++i == argc)
-                                usage ();
-                        path_dhclient_db = argv [i];
-                       no_dhclient_db = 1;
-               } else if (!strcmp (argv [i], "-sf")) {
-                       if (++i == argc)
-                               usage ();
-                        path_dhclient_script = argv [i];
-                       no_dhclient_script = 1;
-               } else if (!strcmp (argv [i], "-1")) {
-                       onetry = 1;
-               } else if (!strcmp (argv [i], "-q")) {
-                       quiet = 1;
-                       quiet_interface_discovery = 1;
-               } else if (!strcmp (argv [i], "-s")) {
-                       if (++i == argc)
-                               usage ();
-                       server = argv [i];
-               } else if (!strcmp (argv [i], "-g")) {
-                       if (++i == argc)
-                               usage ();
-                       relay = argv [i];
-               } else if (!strcmp (argv [i], "-nw")) {
-                       nowait = 1;
-               } else if (!strcmp (argv [i], "-n")) {
-                       /* do not start up any interfaces */
-                       interfaces_requested = 1;
-               } else if (!strcmp (argv [i], "-w")) {
-                       /* do not exit if there are no broadcast interfaces. */
-                       persist = 1;
-               } else if (!strcmp (argv [i], "-e")) {
-                       struct string_list *tmp;
-                       if (++i == argc)
-                               usage ();
-                       tmp = dmalloc (strlen (argv [i]) + sizeof *tmp, MDL);
-                       if (!tmp)
-                               log_fatal ("No memory for %s", argv [i]);
-                       strcpy (tmp -> string, argv [i]);
-                       tmp -> next = client_env;
-                       client_env = tmp;
-                       client_env_count++;
-               } else if (!strcmp (argv [i], "--version")) {
-                       log_info ("isc-dhclient-%s", DHCP_VERSION);
-                       exit (0);
-               } else if (argv [i][0] == '-') {
-                   usage ();
-               } else {
-                   struct interface_info *tmp = (struct interface_info *)0;
-                   status = interface_allocate (&tmp, MDL);
-                   if (status != ISC_R_SUCCESS)
-                       log_fatal ("Can't record interface %s:%s",
-                                  argv [i], isc_result_totext (status));
-                   if (strlen (argv [i]) > sizeof tmp -> name)
-                           log_fatal ("%s: interface name too long (max %ld)",
-                                      argv [i], (long)strlen (argv [i]));
-                   strcpy (tmp -> name, argv [i]);
-                   if (interfaces) {
-                           interface_reference (&tmp -> next,
-                                                interfaces, MDL);
-                           interface_dereference (&interfaces, MDL);
-                   }
-                   interface_reference (&interfaces, tmp, MDL);
-                   tmp -> flags = INTERFACE_REQUESTED;
-                   interfaces_requested = 1;
-               }
-       }
-
-       if (!no_dhclient_conf && (s = getenv ("PATH_DHCLIENT_CONF"))) {
-               path_dhclient_conf = s;
-       }
-       if (!no_dhclient_db && (s = getenv ("PATH_DHCLIENT_DB"))) {
-               path_dhclient_db = s;
-       }
-       if (!no_dhclient_pid && (s = getenv ("PATH_DHCLIENT_PID"))) {
-               path_dhclient_pid = s;
-       }
-       if (!no_dhclient_script && (s = getenv ("PATH_DHCLIENT_SCRIPT"))) {
-               path_dhclient_script = s;
-       }
-
-       /* first kill of any currently running client */
-       if (release_mode) {
-               FILE *pidfd;
-               pid_t oldpid;
-               long temp;
-               int e;
-
-               oldpid = 0;
-               if ((pidfd = fopen(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);
-               }
-       }
-
-       if (!quiet) {
-               log_info ("%s %s", message, DHCP_VERSION);
-               log_info (copyright);
-               log_info (arr);
-               log_info (url);
-               log_info ("%s", "");
-       } else
-               log_perror = 0;
-
-       /* If we're given a relay agent address to insert, for testing
-          purposes, figure out what it is. */
-       if (relay) {
-               if (!inet_aton (relay, &giaddr)) {
-                       struct hostent *he;
-                       he = gethostbyname (relay);
-                       if (he) {
-                               memcpy (&giaddr, he -> h_addr_list [0],
-                                       sizeof giaddr);
-                       } else {
-                               log_fatal ("%s: no such host", relay);
-                       }
-               }
-       }
-
-       /* Default to the DHCP/BOOTP port. */
-       if (!local_port) {
-               /* If we're faking a relay agent, and we're not using loopback,
-                  use the server port, not the client port. */
-               if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
-                       local_port = htons(67);
-               } else {
-                       ent = getservbyname ("dhcpc", "udp");
-                       if (!ent)
-                               local_port = htons (68);
-                       else
-                               local_port = ent -> s_port;
-#ifndef __CYGWIN32__
-                       endservent ();
-#endif
-               }
-       }
-
-       /* If we're faking a relay agent, and we're not using loopback,
-          we're using the server port, not the client port. */
-       if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
-               remote_port = local_port;
-       } else
-               remote_port = htons (ntohs (local_port) - 1);   /* XXX */
-
-       /* Get the current time... */
-       GET_TIME (&cur_time);
-
-       sockaddr_broadcast.sin_family = AF_INET;
-       sockaddr_broadcast.sin_port = remote_port;
-       if (server) {
-               if (!inet_aton (server, &sockaddr_broadcast.sin_addr)) {
-                       struct hostent *he;
-                       he = gethostbyname (server);
-                       if (he) {
-                               memcpy (&sockaddr_broadcast.sin_addr,
-                                       he -> h_addr_list [0],
-                                       sizeof sockaddr_broadcast.sin_addr);
-                       } else
-                               sockaddr_broadcast.sin_addr.s_addr =
-                                       INADDR_BROADCAST;
-               }
-       } else {
-               sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
-       }
-
-       inaddr_any.s_addr = INADDR_ANY;
-
-       /* Discover all the network interfaces. */
-       discover_interfaces (DISCOVER_UNCONFIGURED);
-
-       /* Parse the dhclient.conf file. */
-       read_client_conf ();
-
-       /* Parse the lease database. */
-       read_client_leases ();
-
-       /* Rewrite the lease database... */
-       rewrite_client_leases ();
-
-       /* XXX */
-/*     config_counter(&snd_counter, &rcv_counter); */
-
-       /* If no broadcast interfaces were discovered, call the script
-          and tell it so. */
-       if (!interfaces) {
-               /* Call dhclient-script with the NBI flag, in case somebody
-                  cares. */
-               script_init ((struct client_state *)0, "NBI",
-                            (struct string_list *)0);
-               script_go ((struct client_state *)0);
-
-               /* If we haven't been asked to persist, waiting for new
-                  interfaces, then just exit. */
-               if (!persist) {
-                       /* Nothing more to do. */
-                       log_info ("No broadcast interfaces found - exiting.");
-                       exit (0);
-               }
-       } else if (!release_mode) {
-               /* Call the script with the list of interfaces. */
-               for (ip = interfaces; ip; ip = ip -> next) {
-                       /* If interfaces were specified, don't configure
-                          interfaces that weren't specified! */
-                       if (interfaces_requested &&
-                           ((ip -> flags & (INTERFACE_REQUESTED |
-                                            INTERFACE_AUTOMATIC)) !=
-                            INTERFACE_REQUESTED))
-                               continue;
-                       script_init (ip -> client,
-                                    "PREINIT", (struct string_list *)0);
-                       if (ip -> client -> alias)
-                               script_write_params (ip -> client, "alias_",
-                                                    ip -> client -> alias);
-                       script_go (ip -> client);
-               }
-       }
-
-       /* At this point, all the interfaces that the script thinks
-          are relevant should be running, so now we once again call
-          discover_interfaces(), and this time ask it to actually set
-          up the interfaces. */
-       discover_interfaces (interfaces_requested
-                            ? DISCOVER_REQUESTED
-                            : DISCOVER_RUNNING);
-
-       /* Make up a seed for the random number generator from current
-          time plus the sum of the last four bytes of each
-          interface's hardware address interpreted as an integer.
-          Not much entropy, but we're booting, so we're not likely to
-          find anything better. */
-       seed = 0;
-       for (ip = interfaces; ip; ip = ip -> next) {
-               int junk;
-               memcpy (&junk,
-                       &ip -> hw_address.hbuf [ip -> hw_address.hlen -
-                                              sizeof seed], sizeof seed);
-               seed += junk;
-       }
-       srandom (seed + cur_time);
-
-       /* Start a configuration state machine for each interface. */
-       for (ip = interfaces; ip; ip = ip -> next) {
-               ip -> flags |= INTERFACE_RUNNING;
-               for (client = ip -> client; client; client = client -> next) {
-                       if (release_mode)
-                               do_release (client);
-                       else {
-                               client -> state = S_INIT;
-                               /* Set up a timeout to start the initialization
-                                  process. */
-                               add_timeout (cur_time + random () % 5,
-                                            state_reboot, client, 0, 0);
-                       }
-               }
-       }
-
-       if (release_mode)
-               return 0;
-
-       /* Start up a listener for the object management API protocol. */
-       if (top_level_config.omapi_port != -1) {
-               listener = (omapi_object_t *)0;
-               result = omapi_generic_new (&listener, MDL);
-               if (result != ISC_R_SUCCESS)
-                       log_fatal ("Can't allocate new generic object: %s\n",
-                                  isc_result_totext (result));
-               result = omapi_protocol_listen (listener,
-                                               (unsigned)
-                                               top_level_config.omapi_port,
-                                               1);
-               if (result != ISC_R_SUCCESS)
-                       log_fatal ("Can't start OMAPI protocol: %s",
-                                  isc_result_totext (result));
-       }
-
-       /* Set up the bootp packet handler... */
-       bootp_packet_handler = do_packet;
-
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
-               defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
-       dmalloc_cutoff_generation = dmalloc_generation;
-       dmalloc_longterm = dmalloc_outstanding;
-       dmalloc_outstanding = 0;
-#endif
-
-       /* If we're not supposed to wait before getting the address,
-          don't. */
-       if (nowait)
-               go_daemon ();
-
-       /* If we're not going to daemonize, write the pid file
-          now. */
-       if (no_daemon || nowait)
-               write_client_pid_file ();
-
-       /* Start dispatching packets and timeouts... */
-       dispatch ();
-
-       /*NOTREACHED*/
-       return 0;
-}
-
-static void usage ()
-{
-       log_info ("%s %s", message, DHCP_VERSION);
-       log_info (copyright);
-       log_info (arr);
-       log_info (url);
-
-       log_error ("Usage: dhclient [-1dqr] [-nw] [-p <port>] %s",
-                  "[-s server]");
-       log_error ("                [-cf config-file] [-lf lease-file]%s",
-                  "[-pf pid-file] [-e VAR=val]");
-       log_fatal ("                [-sf script-file] [interface]");
-}
-
-isc_result_t find_class (struct class **c,
-               const char *s, const char *file, int line)
-{
-       return 0;
-}
-
-int check_collection (packet, lease, collection)
-       struct packet *packet;
-       struct lease *lease;
-       struct collection *collection;
-{
-       return 0;
-}
-
-void classify (packet, class)
-       struct packet *packet;
-       struct class *class;
-{
-}
-
-int unbill_class (lease, class)
-       struct lease *lease;
-       struct class *class;
-{
-       return 0;
-}
-
-int find_subnet (struct subnet **sp,
-                struct iaddr addr, const char *file, int line)
-{
-       return 0;
-}
-
-/* Individual States:
- * 
- * Each routine is called from the dhclient_state_machine() in one of
- * these conditions:
- * -> entering INIT state
- * -> recvpacket_flag == 0: timeout in this state
- * -> otherwise: received a packet in this state
- *
- * Return conditions as handled by dhclient_state_machine():
- * Returns 1, sendpacket_flag = 1: send packet, reset timer.
- * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
- * Returns 0: finish the nap which was interrupted for no good reason.
- *
- * Several per-interface variables are used to keep track of the process:
- *   active_lease: the lease that is being used on the interface
- *                 (null pointer if not configured yet).
- *   offered_leases: leases corresponding to DHCPOFFER messages that have
- *                  been sent to us by DHCP servers.
- *   acked_leases: leases corresponding to DHCPACK messages that have been
- *                sent to us by DHCP servers.
- *   sendpacket: DHCP packet we're trying to send.
- *   destination: IP address to send sendpacket to
- * In addition, there are several relevant per-lease variables.
- *   T1_expiry, T2_expiry, lease_expiry: lease milestones
- * In the active lease, these control the process of renewing the lease;
- * In leases on the acked_leases list, this simply determines when we
- * can no longer legitimately use the lease.
- */
-
-void state_reboot (cpp)
-       void *cpp;
-{
-       struct client_state *client = cpp;
-
-       /* If we don't remember an active lease, go straight to INIT. */
-       if (!client -> active ||
-           client -> active -> is_bootp ||
-           client -> active -> expiry <= cur_time) {
-               state_init (client);
-               return;
-       }
-
-       /* We are in the rebooting state. */
-       client -> state = S_REBOOTING;
-
-       /* make_request doesn't initialize xid because it normally comes
-          from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
-          so pick an xid now. */
-       client -> xid = random ();
-
-       /* Make a DHCPREQUEST packet, and set appropriate per-interface
-          flags. */
-       make_request (client, client -> active);
-       client -> destination = iaddr_broadcast;
-       client -> first_sending = cur_time;
-       client -> interval = client -> config -> initial_interval;
-
-       /* Zap the medium list... */
-       client -> medium = (struct string_list *)0;
-
-       /* Send out the first DHCPREQUEST packet. */
-       send_request (client);
-}
-
-/* Called when a lease has completely expired and we've been unable to
-   renew it. */
-
-void state_init (cpp)
-       void *cpp;
-{
-       struct client_state *client = cpp;
-
-       ASSERT_STATE(state, S_INIT);
-
-       /* Make a DHCPDISCOVER packet, and set appropriate per-interface
-          flags. */
-       make_discover (client, client -> active);
-       client -> xid = client -> packet.xid;
-       client -> destination = iaddr_broadcast;
-       client -> state = S_SELECTING;
-       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);
-}
-
-/* state_selecting is called when one or more DHCPOFFER packets have been
-   received and a configurable period of time has passed. */
-
-void state_selecting (cpp)
-       void *cpp;
-{
-       struct client_state *client = cpp;
-       struct client_lease *lp, *next, *picked;
-
-
-       ASSERT_STATE(state, S_SELECTING);
-
-       /* Cancel state_selecting and send_discover timeouts, since either
-          one could have got us here. */
-       cancel_timeout (state_selecting, client);
-       cancel_timeout (send_discover, client);
-
-       /* We have received one or more DHCPOFFER packets.   Currently,
-          the only criterion by which we judge leases is whether or
-          not we get a response when we arp for them. */
-       picked = (struct client_lease *)0;
-       for (lp = client -> offered_leases; lp; lp = next) {
-               next = lp -> next;
-
-               /* Check to see if we got an ARPREPLY for the address
-                  in this particular lease. */
-               if (!picked) {
-                       picked = lp;
-                       picked -> next = (struct client_lease *)0;
-               } else {
-                     freeit:
-                       destroy_client_lease (lp);
-               }
-       }
-       client -> offered_leases = (struct client_lease *)0;
-
-       /* If we just tossed all the leases we were offered, go back
-          to square one. */
-       if (!picked) {
-               client -> state = S_INIT;
-               state_init (client);
-               return;
-       }
-
-       /* If it was a BOOTREPLY, we can just take the address right now. */
-       if (picked -> is_bootp) {
-               client -> new = picked;
-
-               /* Make up some lease expiry times
-                  XXX these should be configurable. */
-               client -> new -> expiry = cur_time + 12000;
-               client -> new -> renewal += cur_time + 8000;
-               client -> new -> rebind += cur_time + 10000;
-
-               client -> state = S_REQUESTING;
-
-               /* Bind to the address we received. */
-               bind_lease (client);
-               return;
-       }
-
-       /* Go to the REQUESTING state. */
-       client -> destination = iaddr_broadcast;
-       client -> state = S_REQUESTING;
-       client -> first_sending = cur_time;
-       client -> interval = client -> config -> initial_interval;
-
-       /* Make a DHCPREQUEST packet from the lease we picked. */
-       make_request (client, picked);
-       client -> xid = client -> packet.xid;
-
-       /* Toss the lease we picked - we'll get it back in a DHCPACK. */
-       destroy_client_lease (picked);
-
-       /* Add an immediate timeout to send the first DHCPREQUEST packet. */
-       send_request (client);
-}  
-
-/* state_requesting is called when we receive a DHCPACK message after
-   having sent out one or more DHCPREQUEST packets. */
-
-void dhcpack (packet)
-       struct packet *packet;
-{
-       struct interface_info *ip = packet -> interface;
-       struct client_state *client;
-       struct client_lease *lease;
-       struct option_cache *oc;
-       struct data_string ds;
-       int i;
-       
-       /* If we're not receptive to an offer right now, or if the offer
-          has an unrecognizable transaction id, then just drop it. */
-       for (client = ip -> client; client; client = client -> next) {
-               if (client -> xid == packet -> raw -> xid)
-                       break;
-       }
-       if (!client ||
-           (packet -> interface -> hw_address.hlen - 1 !=
-            packet -> raw -> hlen) ||
-           (memcmp (&packet -> interface -> hw_address.hbuf [1],
-                    packet -> raw -> chaddr, packet -> raw -> hlen))) {
-#if defined (DEBUG)
-               log_debug ("DHCPACK in wrong transaction.");
-#endif
-               return;
-       }
-
-       if (client -> state != S_REBOOTING &&
-           client -> state != S_REQUESTING &&
-           client -> state != S_RENEWING &&
-           client -> state != S_REBINDING) {
-#if defined (DEBUG)
-               log_debug ("DHCPACK in wrong state.");
-#endif
-               return;
-       }
-
-       log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
-
-       lease = packet_to_lease (packet, client);
-       if (!lease) {
-               log_info ("packet_to_lease failed.");
-               return;
-       }
-
-       client -> new = lease;
-
-       /* Stop resending DHCPREQUEST. */
-       cancel_timeout (send_request, client);
-
-       /* Figure out the lease time. */
-       oc = lookup_option (&dhcp_universe, client -> new -> options,
-                           DHO_DHCP_LEASE_TIME);
-       memset (&ds, 0, sizeof ds);
-       if (oc &&
-           evaluate_option_cache (&ds, packet, (struct lease *)0, client,
-                                  packet -> options, client -> new -> options,
-                                  &global_scope, oc, MDL)) {
-               if (ds.len > 3)
-                       client -> new -> expiry = getULong (ds.data);
-               else
-                       client -> new -> expiry = 0;
-               data_string_forget (&ds, MDL);
-       } else
-                       client -> new -> expiry = 0;
-
-       if (!client -> new -> expiry) {
-               log_error ("no expiry time on offered lease.");
-               /* XXX this is going to be bad - if this _does_
-                  XXX happen, we should probably dynamically 
-                  XXX disqualify the DHCP server that gave us the
-                  XXX bad packet from future selections and
-                  XXX then go back into the init state. */
-               state_init (client);
-               return;
-       }
-
-       /* A number that looks negative here is really just very large,
-          because the lease expiry offset is unsigned. */
-       if (client -> new -> expiry < 0)
-               client -> new -> expiry = TIME_MAX;
-       /* Take the server-provided renewal time if there is one. */
-       oc = lookup_option (&dhcp_universe, client -> new -> options,
-                           DHO_DHCP_RENEWAL_TIME);
-       if (oc &&
-           evaluate_option_cache (&ds, packet, (struct lease *)0, client,
-                                  packet -> options, client -> new -> options,
-                                  &global_scope, oc, MDL)) {
-               if (ds.len > 3)
-                       client -> new -> renewal = getULong (ds.data);
-               else
-                       client -> new -> renewal = 0;
-               data_string_forget (&ds, MDL);
-       } else
-                       client -> new -> renewal = 0;
-
-       /* If it wasn't specified by the server, calculate it. */
-       if (!client -> new -> renewal)
-               client -> new -> renewal = client -> new -> expiry / 2 + 1;
-
-       if (client -> new -> renewal <= 0)
-               client -> new -> renewal = TIME_MAX;
-
-       /* Now introduce some randomness to the renewal time: */
-       if (client -> new -> renewal <= TIME_MAX / 3 - 3)
-               client -> new -> renewal =
-                               (((client -> new -> renewal + 3) * 3 / 4) +
-                                   (random () % /* XXX NUMS */
-                                    ((client -> new -> renewal + 3) / 4)));
-
-       /* Same deal with the rebind time. */
-       oc = lookup_option (&dhcp_universe, client -> new -> options,
-                           DHO_DHCP_REBINDING_TIME);
-       if (oc &&
-           evaluate_option_cache (&ds, packet, (struct lease *)0, client,
-                                  packet -> options, client -> new -> options,
-                                  &global_scope, oc, MDL)) {
-               if (ds.len > 3)
-                       client -> new -> rebind = getULong (ds.data);
-               else
-                       client -> new -> rebind = 0;
-               data_string_forget (&ds, MDL);
-       } else
-                       client -> new -> rebind = 0;
-
-       if (client -> new -> rebind <= 0) {
-               if (client -> new -> expiry <= TIME_MAX / 7)
-                       client -> new -> rebind =
-                                       client -> new -> expiry * 7 / 8;
-               else
-                       client -> new -> rebind =
-                                       client -> new -> expiry / 8 * 7;
-       }
-
-       /* Make sure our randomness didn't run the renewal time past the
-          rebind time. */
-       if (client -> new -> renewal > client -> new -> rebind) {
-               if (client -> new -> rebind <= TIME_MAX / 3)
-                       client -> new -> renewal =
-                                       client -> new -> rebind * 3 / 4;
-               else
-                       client -> new -> renewal =
-                                       client -> new -> rebind / 4 * 3;
-       }
-
-       client -> new -> expiry += cur_time;
-       /* Lease lengths can never be negative. */
-       if (client -> new -> expiry < cur_time)
-               client -> new -> expiry = TIME_MAX;
-       client -> new -> renewal += cur_time;
-       if (client -> new -> renewal < cur_time)
-               client -> new -> renewal = TIME_MAX;
-       client -> new -> rebind += cur_time;
-       if (client -> new -> rebind < cur_time)
-               client -> new -> rebind = TIME_MAX;
-
-       bind_lease (client);
-}
-
-void bind_lease (client)
-       struct client_state *client;
-{
-       struct interface_info *ip = client -> interface;
-
-       /* Remember the medium. */
-       client -> new -> medium = client -> medium;
-
-       /* Run the client script with the new parameters. */
-       script_init (client, (client -> state == S_REQUESTING
-                         ? "BOUND"
-                         : (client -> state == S_RENEWING
-                            ? "RENEW"
-                            : (client -> state == S_REBOOTING
-                               ? "REBOOT" : "REBIND"))),
-                    client -> new -> medium);
-       if (client -> active && client -> state != S_REBOOTING)
-               script_write_params (client, "old_", client -> active);
-       script_write_params (client, "new_", client -> new);
-       if (client -> alias)
-               script_write_params (client, "alias_", client -> alias);
-
-       /* If the BOUND/RENEW code detects another machine using the
-          offered address, it exits nonzero.  We need to send a
-          DHCPDECLINE and toss the lease. */
-       if (script_go (client)) {
-               make_decline (client, client -> new);
-               send_decline (client);
-               destroy_client_lease (client -> new);
-               client -> new = (struct client_lease *)0;
-               state_init (client);
-               return;
-       }
-
-       /* Write out the new lease. */
-       write_client_lease (client, client -> new, 0, 0);
-
-       /* Replace the old active lease with the new one. */
-       if (client -> active)
-               destroy_client_lease (client -> active);
-       client -> active = client -> new;
-       client -> new = (struct client_lease *)0;
-
-       /* Set up a timeout to start the renewal process. */
-       add_timeout (client -> active -> renewal,
-                    state_bound, client, 0, 0);
-
-       log_info ("bound to %s -- renewal in %ld seconds.",
-             piaddr (client -> active -> address),
-             (long)(client -> active -> renewal - cur_time));
-       client -> state = S_BOUND;
-       reinitialize_interfaces ();
-       go_daemon ();
-       if (client -> config -> do_forward_update) {
-               client -> dns_update_timeout = 1;
-               add_timeout (cur_time + 1, client_dns_update_timeout,
-                            client, 0, 0);
-       }
-}  
-
-/* state_bound is called when we've successfully bound to a particular
-   lease, but the renewal time on that lease has expired.   We are
-   expected to unicast a DHCPREQUEST to the server that gave us our
-   original lease. */
-
-void state_bound (cpp)
-       void *cpp;
-{
-       struct client_state *client = cpp;
-       int i;
-       struct option_cache *oc;
-       struct data_string ds;
-
-       ASSERT_STATE(state, S_BOUND);
-
-       /* T1 has expired. */
-       make_request (client, client -> active);
-       client -> xid = client -> packet.xid;
-
-       memset (&ds, 0, sizeof ds);
-       oc = lookup_option (&dhcp_universe, client -> active -> options,
-                           DHO_DHCP_SERVER_IDENTIFIER);
-       if (oc &&
-           evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0,
-                                  client, (struct option_state *)0,
-                                  client -> active -> options,
-                                  &global_scope, oc, MDL)) {
-               if (ds.len > 3) {
-                       memcpy (client -> destination.iabuf, ds.data, 4);
-                       client -> destination.len = 4;
-               } else
-                       client -> destination = iaddr_broadcast;
-
-               data_string_forget (&ds, MDL);
-       } else
-               client -> destination = iaddr_broadcast;
-
-       client -> first_sending = cur_time;
-       client -> interval = client -> config -> initial_interval;
-       client -> state = S_RENEWING;
-
-       /* Send the first packet immediately. */
-       send_request (client);
-}  
-
-/* state_stop is called when we've been told to shut down.   We unconfigure
-   the interfaces, and then stop operating until told otherwise. */
-
-void state_stop (cpp)
-       void *cpp;
-{
-       struct client_state *client = cpp;
-       int i;
-
-       /* Cancel all timeouts. */
-       cancel_timeout (state_selecting, client);
-       cancel_timeout (send_discover, client);
-       cancel_timeout (send_request, client);
-       cancel_timeout (state_bound, client);
-
-       /* If we have an address, unconfigure it. */
-       if (client -> active) {
-               script_init (client, "STOP", client -> active -> medium);
-               script_write_params (client, "old_", client -> active);
-               if (client -> alias)
-                       script_write_params (client, "alias_",
-                                            client -> alias);
-               script_go (client);
-       }
-}  
-
-int commit_leases ()
-{
-       return 0;
-}
-
-int write_lease (lease)
-       struct lease *lease;
-{
-       return 0;
-}
-
-int write_host (host)
-       struct host_decl *host;
-{
-       return 0;
-}
-
-void db_startup (testp)
-       int testp;
-{
-}
-
-void bootp (packet)
-       struct packet *packet;
-{
-       struct iaddrlist *ap;
-
-       if (packet -> raw -> op != BOOTREPLY)
-               return;
-
-       /* If there's a reject list, make sure this packet's sender isn't
-          on it. */
-       for (ap = packet -> interface -> client -> config -> reject_list;
-            ap; ap = ap -> next) {
-               if (addr_eq (packet -> client_addr, ap -> addr)) {
-                       log_info ("BOOTREPLY from %s rejected.",
-                             piaddr (ap -> addr));
-                       return;
-               }
-       }
-       
-       dhcpoffer (packet);
-
-}
-
-void dhcp (packet)
-       struct packet *packet;
-{
-       struct iaddrlist *ap;
-       void (*handler) PROTO ((struct packet *));
-       const char *type;
-
-       switch (packet -> packet_type) {
-             case DHCPOFFER:
-               handler = dhcpoffer;
-               type = "DHCPOFFER";
-               break;
-
-             case DHCPNAK:
-               handler = dhcpnak;
-               type = "DHCPNACK";
-               break;
-
-             case DHCPACK:
-               handler = dhcpack;
-               type = "DHCPACK";
-               break;
-
-             default:
-               return;
-       }
-
-       /* If there's a reject list, make sure this packet's sender isn't
-          on it. */
-       for (ap = packet -> interface -> client -> config -> reject_list;
-            ap; ap = ap -> next) {
-               if (addr_eq (packet -> client_addr, ap -> addr)) {
-                       log_info ("%s from %s rejected.",
-                             type, piaddr (ap -> addr));
-                       return;
-               }
-       }
-       (*handler) (packet);
-}
-
-void dhcpoffer (packet)
-       struct packet *packet;
-{
-       struct interface_info *ip = packet -> interface;
-       struct client_state *client;
-       struct client_lease *lease, *lp;
-       int i;
-       int stop_selecting;
-       const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
-       struct iaddrlist *ap;
-       struct option_cache *oc;
-       char obuf [1024];
-       
-#ifdef DEBUG_PACKET
-       dump_packet (packet);
-#endif 
-
-       /* Find a client state that matches the xid... */
-       for (client = ip -> client; client; client = client -> next)
-               if (client -> xid == packet -> raw -> xid)
-                       break;
-
-       /* If we're not receptive to an offer right now, or if the offer
-          has an unrecognizable transaction id, then just drop it. */
-       if (!client ||
-           client -> state != S_SELECTING ||
-           (packet -> interface -> hw_address.hlen - 1 !=
-            packet -> raw -> hlen) ||
-           (memcmp (&packet -> interface -> hw_address.hbuf [1],
-                    packet -> raw -> chaddr, packet -> raw -> hlen))) {
-#if defined (DEBUG)
-               log_debug ("%s in wrong transaction.", name);
-#endif
-               return;
-       }
-
-       sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr));
-
-
-       /* If this lease doesn't supply the minimum required parameters,
-          blow it off. */
-       if (client -> config -> required_options) {
-           for (i = 0; client -> config -> required_options [i]; i++) {
-               if (!lookup_option
-                   (&dhcp_universe, packet -> options,
-                    client -> config -> required_options [i])) {
-                   log_info ("%s: no %s option.",
-                             obuf, (dhcp_universe.options
-                                    [client -> config -> required_options [i]]
-                                    -> name));
-                               return;
-                       }
-               }
-       }
-
-       /* If we've already seen this lease, don't record it again. */
-       for (lease = client -> offered_leases; lease; lease = lease -> next) {
-               if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
-                   !memcmp (lease -> address.iabuf,
-                            &packet -> raw -> yiaddr, lease -> address.len)) {
-                       log_debug ("%s: already seen.", obuf);
-                       return;
-               }
-       }
-
-       lease = packet_to_lease (packet, client);
-       if (!lease) {
-               log_info ("%s: packet_to_lease failed.", obuf);
-               return;
-       }
-
-       /* If this lease was acquired through a BOOTREPLY, record that
-          fact. */
-       if (!packet -> options_valid || !packet -> packet_type)
-               lease -> is_bootp = 1;
-
-       /* Record the medium under which this lease was offered. */
-       lease -> medium = client -> medium;
-
-       /* Figure out when we're supposed to stop selecting. */
-       stop_selecting = (client -> first_sending +
-                         client -> config -> select_interval);
-
-       /* If this is the lease we asked for, put it at the head of the
-          list, and don't mess with the arp request timeout. */
-       if (lease -> address.len == client -> requested_address.len &&
-           !memcmp (lease -> address.iabuf,
-                    client -> requested_address.iabuf,
-                    client -> requested_address.len)) {
-               lease -> next = client -> offered_leases;
-               client -> offered_leases = lease;
-       } else {
-               /* Put the lease at the end of the list. */
-               lease -> next = (struct client_lease *)0;
-               if (!client -> offered_leases)
-                       client -> offered_leases = lease;
-               else {
-                       for (lp = client -> offered_leases; lp -> next;
-                            lp = lp -> next)
-                               ;
-                       lp -> next = lease;
-               }
-       }
-
-       /* If the selecting interval has expired, go immediately to
-          state_selecting().  Otherwise, time out into
-          state_selecting at the select interval. */
-       if (stop_selecting <= 0)
-               state_selecting (client);
-       else {
-               add_timeout (stop_selecting, state_selecting, client, 0, 0);
-               cancel_timeout (send_discover, client);
-       }
-       log_info ("%s", obuf);
-}
-
-/* Allocate a client_lease structure and initialize it from the parameters
-   in the specified packet. */
-
-struct client_lease *packet_to_lease (packet, client)
-       struct packet *packet;
-       struct client_state *client;
-{
-       struct client_lease *lease;
-       unsigned i;
-       struct option_cache *oc;
-       struct data_string data;
-
-       lease = (struct client_lease *)new_client_lease (MDL);
-
-       if (!lease) {
-               log_error ("packet_to_lease: no memory to record lease.\n");
-               return (struct client_lease *)0;
-       }
-
-       memset (lease, 0, sizeof *lease);
-
-       /* Copy the lease options. */
-       option_state_reference (&lease -> options, packet -> options, MDL);
-
-       lease -> address.len = sizeof (packet -> raw -> yiaddr);
-       memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr,
-               lease -> address.len);
-
-       memset (&data, 0, sizeof data);
-
-       if (client -> config -> vendor_space_name) {
-               i = DHO_VENDOR_ENCAPSULATED_OPTIONS;
-
-               /* See if there was a vendor encapsulation option. */
-               oc = lookup_option (&dhcp_universe, lease -> options, i);
-               if (oc &&
-                   client -> config -> vendor_space_name &&
-                   evaluate_option_cache (&data, packet,
-                                          (struct lease *)0, client,
-                                          packet -> options, lease -> options,
-                                          &global_scope, oc, MDL)) {
-                       if (data.len) {
-                               parse_encapsulated_suboptions
-                                       (packet -> options, &dhcp_options [i],
-                                        data.data, data.len, &dhcp_universe,
-                                        client -> config -> vendor_space_name
-                                               );
-                       }
-                       data_string_forget (&data, MDL);
-               }
-       } else
-               i = 0;
-
-       /* Figure out the overload flag. */
-       oc = lookup_option (&dhcp_universe, lease -> options,
-                           DHO_DHCP_OPTION_OVERLOAD);
-       if (oc &&
-           evaluate_option_cache (&data, packet, (struct lease *)0, client,
-                                  packet -> options, lease -> options,
-                                  &global_scope, oc, MDL)) {
-               if (data.len > 0)
-                       i = data.data [0];
-               else
-                       i = 0;
-               data_string_forget (&data, MDL);
-       } else
-               i = 0;
-
-       /* If the server name was filled out, copy it. */
-       if (!(i & 2) && packet -> raw -> sname [0]) {
-               unsigned len;
-               /* Don't count on the NUL terminator. */
-               for (len = 0; len < 64; len++)
-                       if (!packet -> raw -> sname [len])
-                               break;
-               lease -> server_name = dmalloc (len + 1, MDL);
-               if (!lease -> server_name) {
-                       log_error ("dhcpoffer: no memory for filename.\n");
-                       destroy_client_lease (lease);
-                       return (struct client_lease *)0;
-               } else {
-                       memcpy (lease -> server_name,
-                               packet -> raw -> sname, len);
-                       lease -> server_name [len] = 0;
-               }
-       }
-
-       /* Ditto for the filename. */
-       if (!(i & 1) && packet -> raw -> file [0]) {
-               unsigned len;
-               /* Don't count on the NUL terminator. */
-               for (len = 0; len < 64; len++)
-                       if (!packet -> raw -> file [len])
-                               break;
-               lease -> filename = dmalloc (len + 1, MDL);
-               if (!lease -> filename) {
-                       log_error ("dhcpoffer: no memory for filename.\n");
-                       destroy_client_lease (lease);
-                       return (struct client_lease *)0;
-               } else {
-                       memcpy (lease -> filename,
-                               packet -> raw -> file, len);
-                       lease -> filename [len] = 0;
-               }
-       }
-
-       execute_statements_in_scope ((struct binding_value **)0,
-                                    (struct packet *)packet,
-                                    (struct lease *)0, client,
-                                    lease -> options, lease -> options,
-                                    &global_scope,
-                                    client -> config -> on_receipt,
-                                    (struct group *)0);
-
-       return lease;
-}      
-
-void dhcpnak (packet)
-       struct packet *packet;
-{
-       struct interface_info *ip = packet -> interface;
-       struct client_state *client;
-
-       /* Find a client state that matches the xid... */
-       for (client = ip -> client; client; client = client -> next)
-               if (client -> xid == packet -> raw -> xid)
-                       break;
-
-       /* If we're not receptive to an offer right now, or if the offer
-          has an unrecognizable transaction id, then just drop it. */
-       if (!client ||
-           (packet -> interface -> hw_address.hlen - 1 !=
-            packet -> raw -> hlen) ||
-           (memcmp (&packet -> interface -> hw_address.hbuf [1],
-                    packet -> raw -> chaddr, packet -> raw -> hlen))) {
-#if defined (DEBUG)
-               log_debug ("DHCPNAK in wrong transaction.");
-#endif
-               return;
-       }
-
-       if (client -> state != S_REBOOTING &&
-           client -> state != S_REQUESTING &&
-           client -> state != S_RENEWING &&
-           client -> state != S_REBINDING) {
-#if defined (DEBUG)
-               log_debug ("DHCPNAK in wrong state.");
-#endif
-               return;
-       }
-
-       log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
-
-       if (!client -> active) {
-#if defined (DEBUG)
-               log_info ("DHCPNAK with no active lease.\n");
-#endif
-               return;
-       }
-
-       destroy_client_lease (client -> active);
-       client -> active = (struct client_lease *)0;
-
-       /* Stop sending DHCPREQUEST packets... */
-       cancel_timeout (send_request, client);
-
-       client -> state = S_INIT;
-       state_init (client);
-}
-
-/* Send out a DHCPDISCOVER packet, and set a timeout to send out another
-   one after the right interval has expired.  If we don't get an offer by
-   the time we reach the panic interval, call the panic function. */
-
-void send_discover (cpp)
-       void *cpp;
-{
-       struct client_state *client = cpp;
-
-       int result;
-       int interval;
-       int increase = 1;
-
-       /* Figure out how long it's been since we started transmitting. */
-       interval = cur_time - client -> first_sending;
-
-       /* If we're past the panic timeout, call the script and tell it
-          we haven't found anything for this interface yet. */
-       if (interval > client -> config -> timeout) {
-               state_panic (client);
-               return;
-       }
-
-       /* If we're selecting media, try the whole list before doing
-          the exponential backoff, but if we've already received an
-          offer, stop looping, because we obviously have it right. */
-       if (!client -> offered_leases &&
-           client -> config -> media) {
-               int fail = 0;
-             again:
-               if (client -> medium) {
-                       client -> medium = client -> medium -> next;
-                       increase = 0;
-               } 
-               if (!client -> medium) {
-                       if (fail)
-                               log_fatal ("No valid media types for %s!",
-                                      client -> interface -> name);
-                       client -> medium =
-                               client -> config -> media;
-                       increase = 1;
-               }
-                       
-               log_info ("Trying medium \"%s\" %d",
-                         client -> medium -> string, increase);
-               script_init (client, "MEDIUM", client -> medium);
-               if (script_go (client)) {
-                       fail = 1;
-                       goto again;
-               }
-       }
-
-       /* If we're supposed to increase the interval, do so.  If it's
-          currently zero (i.e., we haven't sent any packets yet), set
-          it to initial_interval; otherwise, add to it a random number
-          between zero and two times itself.  On average, this means
-          that it will double with every transmission. */
-       if (increase) {
-               if (!client -> interval)
-                       client -> interval =
-                               client -> config -> initial_interval;
-               else
-                       client -> interval += ((random () >> 2) %
-                                              (2 * client -> interval));
-
-               /* Don't backoff past cutoff. */
-               if (client -> interval >
-                   client -> config -> backoff_cutoff)
-                       client -> interval =
-                               ((client -> config -> backoff_cutoff / 2)
-                                + ((random () >> 2) %
-                                   client -> config -> backoff_cutoff));
-       } else if (!client -> interval)
-               client -> interval = client -> config -> initial_interval;
-               
-       /* If the backoff would take us to the panic timeout, just use that
-          as the interval. */
-       if (cur_time + client -> interval >
-           client -> first_sending + client -> config -> timeout)
-               client -> interval =
-                       (client -> first_sending +
-                        client -> config -> timeout) - cur_time + 1;
-
-       /* Record the number of seconds since we started sending. */
-       if (interval < 65536)
-               client -> packet.secs = htons (interval);
-       else
-               client -> packet.secs = htons (65535);
-       client -> secs = client -> packet.secs;
-
-       log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
-             client -> name ? client -> name : client -> interface -> name,
-             inet_ntoa (sockaddr_broadcast.sin_addr),
-             ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
-
-       /* Send out a packet. */
-       result = send_packet (client -> interface, (struct packet *)0,
-                             &client -> packet,
-                             client -> packet_length,
-                             inaddr_any, &sockaddr_broadcast,
-                             (struct hardware *)0);
-
-       add_timeout (cur_time + client -> interval,
-                    send_discover, client, 0, 0);
-}
-
-/* state_panic gets called if we haven't received any offers in a preset
-   amount of time.   When this happens, we try to use existing leases that
-   haven't yet expired, and failing that, we call the client script and
-   hope it can do something. */
-
-void state_panic (cpp)
-       void *cpp;
-{
-       struct client_state *client = cpp;
-       struct client_lease *loop;
-       struct client_lease *lp;
-
-       loop = lp = client -> active;
-
-       log_info ("No DHCPOFFERS received.");
-
-       /* We may not have an active lease, but we may have some
-          predefined leases that we can try. */
-       if (!client -> active && client -> leases)
-               goto activate_next;
-
-       /* Run through the list of leases and see if one can be used. */
-       while (client -> active) {
-               if (client -> active -> expiry > cur_time) {
-                       log_info ("Trying recorded lease %s",
-                             piaddr (client -> active -> address));
-                       /* Run the client script with the existing
-                          parameters. */
-                       script_init (client, "TIMEOUT",
-                                    client -> active -> medium);
-                       script_write_params (client, "new_", client -> active);
-                       if (client -> alias)
-                               script_write_params (client, "alias_",
-                                                    client -> alias);
-
-                       /* If the old lease is still good and doesn't
-                          yet need renewal, go into BOUND state and
-                          timeout at the renewal time. */
-                       if (!script_go (client)) {
-                           if (cur_time < client -> active -> renewal) {
-                               client -> state = S_BOUND;
-                               log_info ("bound: renewal in %ld %s.",
-                                         (long)(client -> active -> renewal -
-                                                cur_time), "seconds");
-                               add_timeout (client -> active -> renewal,
-                                            state_bound, client, 0, 0);
-                           } else {
-                               client -> state = S_BOUND;
-                               log_info ("bound: immediate renewal.");
-                               state_bound (client);
-                           }
-                           reinitialize_interfaces ();
-                           go_daemon ();
-                           return;
-                       }
-               }
-
-               /* If there are no other leases, give up. */
-               if (!client -> leases) {
-                       client -> leases = client -> active;
-                       client -> active = (struct client_lease *)0;
-                       break;
-               }
-
-       activate_next:
-               /* Otherwise, put the active lease at the end of the
-                  lease list, and try another lease.. */
-               for (lp = client -> leases; lp -> next; lp = lp -> next)
-                       ;
-               lp -> next = client -> active;
-               if (lp -> next) {
-                       lp -> next -> next = (struct client_lease *)0;
-               }
-               client -> active = client -> leases;
-               client -> leases = client -> leases -> next;
-
-               /* If we already tried this lease, we've exhausted the
-                  set of leases, so we might as well give up for
-                  now. */
-               if (client -> active == loop)
-                       break;
-               else if (!loop)
-                       loop = client -> active;
-       }
-
-       /* No leases were available, or what was available didn't work, so
-          tell the shell script that we failed to allocate an address,
-          and try again later. */
-       if (onetry) {
-               if (!quiet)
-                       log_info ("Unable to obtain a lease on first try.%s",
-                                 "  Exiting.");
-               exit (2);
-       }
-
-       log_info ("No working leases in persistent database - sleeping.");
-       script_init (client, "FAIL", (struct string_list *)0);
-       if (client -> alias)
-               script_write_params (client, "alias_", client -> alias);
-       script_go (client);
-       client -> state = S_INIT;
-       add_timeout (cur_time +
-                    ((client -> config -> retry_interval + 1) / 2 +
-                     (random () % client -> config -> retry_interval)),
-                    state_init, client, 0, 0);
-       go_daemon ();
-}
-
-void send_request (cpp)
-       void *cpp;
-{
-       struct client_state *client = cpp;
-
-       int result;
-       int interval;
-       struct sockaddr_in destination;
-       struct in_addr from;
-
-       /* Figure out how long it's been since we started transmitting. */
-       interval = cur_time - client -> first_sending;
-
-       /* If we're in the INIT-REBOOT or REQUESTING state and we're
-          past the reboot timeout, go to INIT and see if we can
-          DISCOVER an address... */
-       /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
-          means either that we're on a network with no DHCP server,
-          or that our server is down.  In the latter case, assuming
-          that there is a backup DHCP server, DHCPDISCOVER will get
-          us a new address, but we could also have successfully
-          reused our old address.  In the former case, we're hosed
-          anyway.  This is not a win-prone situation. */
-       if ((client -> state == S_REBOOTING ||
-            client -> state == S_REQUESTING) &&
-           interval > client -> config -> reboot_timeout) {
-       cancel:
-               client -> state = S_INIT;
-               cancel_timeout (send_request, client);
-               state_init (client);
-               return;
-       }
-
-       /* If we're in the reboot state, make sure the media is set up
-          correctly. */
-       if (client -> state == S_REBOOTING &&
-           !client -> medium &&
-           client -> active -> medium ) {
-               script_init (client, "MEDIUM", client -> active -> medium);
-
-               /* If the medium we chose won't fly, go to INIT state. */
-               if (script_go (client))
-                       goto cancel;
-
-               /* Record the medium. */
-               client -> medium = client -> active -> medium;
-       }
-
-       /* If the lease has expired, relinquish the address and go back
-          to the INIT state. */
-       if (client -> state != S_REQUESTING &&
-           cur_time > client -> active -> expiry) {
-               /* Run the client script with the new parameters. */
-               script_init (client, "EXPIRE", (struct string_list *)0);
-               script_write_params (client, "old_", client -> active);
-               if (client -> alias)
-                       script_write_params (client, "alias_",
-                                            client -> alias);
-               script_go (client);
-
-               /* Now do a preinit on the interface so that we can
-                  discover a new address. */
-               script_init (client, "PREINIT", (struct string_list *)0);
-               if (client -> alias)
-                       script_write_params (client, "alias_",
-                                            client -> alias);
-               script_go (client);
-
-               client -> state = S_INIT;
-               state_init (client);
-               return;
-       }
-
-       /* Do the exponential backoff... */
-       if (!client -> interval)
-               client -> interval = client -> config -> initial_interval;
-       else {
-               client -> interval += ((random () >> 2) %
-                                      (2 * client -> interval));
-       }
-       
-       /* Don't backoff past cutoff. */
-       if (client -> interval >
-           client -> config -> backoff_cutoff)
-               client -> interval =
-                       ((client -> config -> backoff_cutoff / 2)
-                        + ((random () >> 2) %
-                                       client -> config -> backoff_cutoff));
-
-       /* If the backoff would take us to the expiry time, just set the
-          timeout to the expiry time. */
-       if (client -> state != S_REQUESTING &&
-           cur_time + client -> interval > client -> active -> expiry)
-               client -> interval =
-                       client -> active -> expiry - cur_time + 1;
-
-       /* If the lease T2 time has elapsed, or if we're not yet bound,
-          broadcast the DHCPREQUEST rather than unicasting. */
-       if (client -> state == S_REQUESTING ||
-           client -> state == S_REBOOTING ||
-           cur_time > client -> active -> rebind)
-               destination.sin_addr = sockaddr_broadcast.sin_addr;
-       else
-               memcpy (&destination.sin_addr.s_addr,
-                       client -> destination.iabuf,
-                       sizeof destination.sin_addr.s_addr);
-       destination.sin_port = remote_port;
-       destination.sin_family = AF_INET;
-#ifdef HAVE_SA_LEN
-       destination.sin_len = sizeof destination;
-#endif
-
-       if (client -> state == S_RENEWING ||
-           client -> state == S_REBINDING)
-               memcpy (&from, client -> active -> address.iabuf,
-                       sizeof from);
-       else
-               from.s_addr = INADDR_ANY;
-
-       /* Record the number of seconds since we started sending. */
-       if (client -> state == S_REQUESTING)
-               client -> packet.secs = client -> secs;
-       else {
-               if (interval < 65536)
-                       client -> packet.secs = htons (interval);
-               else
-                       client -> packet.secs = htons (65535);
-       }
-
-       log_info ("DHCPREQUEST on %s to %s port %d",
-             client -> name ? client -> name : client -> interface -> name,
-             inet_ntoa (destination.sin_addr),
-             ntohs (destination.sin_port));
-
-       if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
-           fallback_interface)
-               result = send_packet (fallback_interface,
-                                     (struct packet *)0,
-                                     &client -> packet,
-                                     client -> packet_length,
-                                     from, &destination,
-                                     (struct hardware *)0);
-       else
-               /* Send out a packet. */
-               result = send_packet (client -> interface, (struct packet *)0,
-                                     &client -> packet,
-                                     client -> packet_length,
-                                     from, &destination,
-                                     (struct hardware *)0);
-
-       add_timeout (cur_time + client -> interval,
-                    send_request, client, 0, 0);
-}
-
-void send_decline (cpp)
-       void *cpp;
-{
-       struct client_state *client = cpp;
-
-       int result;
-
-       log_info ("DHCPDECLINE on %s to %s port %d",
-             client -> name ? client -> name : client -> interface -> name,
-             inet_ntoa (sockaddr_broadcast.sin_addr),
-             ntohs (sockaddr_broadcast.sin_port));
-
-       /* Send out a packet. */
-       result = send_packet (client -> interface, (struct packet *)0,
-                             &client -> packet,
-                             client -> packet_length,
-                             inaddr_any, &sockaddr_broadcast,
-                             (struct hardware *)0);
-}
-
-void send_release (cpp)
-       void *cpp;
-{
-       struct client_state *client = cpp;
-
-       int result;
-       struct sockaddr_in destination;
-       struct in_addr from;
-
-       memcpy (&from, client -> active -> address.iabuf,
-               sizeof from);
-       memcpy (&destination.sin_addr.s_addr,
-               client -> destination.iabuf,
-               sizeof destination.sin_addr.s_addr);
-       destination.sin_port = remote_port;
-       destination.sin_family = AF_INET;
-#ifdef HAVE_SA_LEN
-       destination.sin_len = sizeof destination;
-#endif
-
-       /* Set the lease to end now, so that we don't accidentally
-          reuse it if we restart before the old expiry time. */
-       client -> active -> expiry =
-               client -> active -> renewal =
-               client -> active -> rebind = cur_time;
-       if (!write_client_lease (client, client -> active, 1, 1)) {
-               log_error ("Can't release lease: lease write failed.");
-               return;
-       }
-
-       log_info ("DHCPRELEASE on %s to %s port %d",
-             client -> name ? client -> name : client -> interface -> name,
-             inet_ntoa (destination.sin_addr),
-             ntohs (destination.sin_port));
-
-       if (fallback_interface)
-               result = send_packet (fallback_interface,
-                                     (struct packet *)0,
-                                     &client -> packet,
-                                     client -> packet_length,
-                                     from, &destination,
-                                     (struct hardware *)0);
-       else
-               /* Send out a packet. */
-               result = send_packet (client -> interface, (struct packet *)0,
-                                     &client -> packet,
-                                     client -> packet_length,
-                                     from, &destination,
-                                     (struct hardware *)0);
-}
-
-void make_client_options (client, lease, type, sid, rip, prl, op)
-       struct client_state *client;
-       struct client_lease *lease;
-       u_int8_t *type;
-       struct option_cache *sid;
-       struct iaddr *rip;
-       u_int32_t *prl;
-       struct option_state **op;
-{
-       unsigned i;
-       struct option_cache *oc;
-       struct buffer *bp = (struct buffer *)0;
-
-       /* If there are any leftover options, get rid of them. */
-       if (*op)
-               option_state_dereference (op, MDL);
-
-       /* Allocate space for options. */
-       option_state_allocate (op, MDL);
-
-       /* Send the server identifier if provided. */
-       if (sid)
-               save_option (&dhcp_universe, *op, sid);
-
-       oc = (struct option_cache *)0;
-
-       /* Send the requested address if provided. */
-       if (rip) {
-               client -> requested_address = *rip;
-               if (!(make_const_option_cache
-                     (&oc, (struct buffer **)0, rip -> iabuf, rip -> len,
-                      &dhcp_options [DHO_DHCP_REQUESTED_ADDRESS], MDL)))
-                       log_error ("can't make requested address cache.");
-               else {
-                       save_option (&dhcp_universe, *op, oc);
-                       option_cache_dereference (&oc, MDL);
-               }
-       } else {
-               client -> requested_address.len = 0;
-       }
-
-       if (!(make_const_option_cache
-             (&oc, (struct buffer **)0,
-              type, 1, &dhcp_options [DHO_DHCP_MESSAGE_TYPE], MDL)))
-               log_error ("can't make message type.");
-       else {
-               save_option (&dhcp_universe, *op, oc);
-               option_cache_dereference (&oc, MDL);
-       }
-
-       if (prl) {
-               /* Figure out how many parameters were requested. */
-               for (i = 0; prl [i]; i++)
-                       ;
-               if (!buffer_allocate (&bp, i, MDL))
-                       log_error ("can't make parameter list buffer.");
-               else {
-                       for (i = 0; prl [i]; i++)
-                               bp -> data [i] = prl [i];
-                       if (!(make_const_option_cache
-                             (&oc, &bp, (u_int8_t *)0, i,
-                              &dhcp_options [DHO_DHCP_PARAMETER_REQUEST_LIST],
-                              MDL)))
-                               log_error ("can't make option cache");
-                       else {
-                               save_option (&dhcp_universe, *op, oc);
-                               option_cache_dereference (&oc, MDL);
-                       }
-               }
-       }
-
-       /* Run statements that need to be run on transmission. */
-       if (client -> config -> on_transmission)
-               execute_statements_in_scope
-                       ((struct binding_value **)0,
-                        (struct packet *)0, (struct lease *)0, client,
-                        (lease ? lease -> options : (struct option_state *)0),
-                        *op, &global_scope,
-                        client -> config -> on_transmission,
-                        (struct group *)0);
-}
-
-void make_discover (client, lease)
-       struct client_state *client;
-       struct client_lease *lease;
-{
-       unsigned char discover = DHCPDISCOVER;
-       int i;
-       struct option_state *options = (struct option_state *)0;
-
-       memset (&client -> packet, 0, sizeof (client -> packet));
-
-       make_client_options (client,
-                            lease, &discover, (struct option_cache *)0,
-                            lease ? &lease -> address : (struct iaddr *)0,
-                            client -> config -> requested_options,
-                            &options);
-
-       /* Set up the option buffer... */
-       client -> packet_length =
-               cons_options ((struct packet *)0, &client -> packet,
-                             (struct lease *)0, client,
-                             /* maximum packet size */1500,
-                             (struct option_state *)0,
-                             options,
-                             /* scope */ &global_scope,
-                             /* overload */ 0,
-                             /* terminate */0,
-                             /* bootpp    */0,
-                             (struct data_string *)0,
-                             client -> config -> vendor_space_name);
-
-       option_state_dereference (&options, MDL);
-       if (client -> packet_length < BOOTP_MIN_LEN)
-               client -> packet_length = BOOTP_MIN_LEN;
-
-       client -> packet.op = BOOTREQUEST;
-       client -> packet.htype = client -> interface -> hw_address.hbuf [0];
-       client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
-       client -> packet.hops = 0;
-       client -> packet.xid = random ();
-       client -> packet.secs = 0; /* filled in by send_discover. */
-
-       if (can_receive_unicast_unconfigured (client -> interface))
-               client -> packet.flags = 0;
-       else
-               client -> packet.flags = htons (BOOTP_BROADCAST);
-
-       memset (&(client -> packet.ciaddr),
-               0, sizeof client -> packet.ciaddr);
-       memset (&(client -> packet.yiaddr),
-               0, sizeof client -> packet.yiaddr);
-       memset (&(client -> packet.siaddr),
-               0, sizeof client -> packet.siaddr);
-       client -> packet.giaddr = giaddr;
-       if (client -> interface -> hw_address.hlen > 0)
-           memcpy (client -> packet.chaddr,
-                   &client -> interface -> hw_address.hbuf [1],
-                   (unsigned)(client -> interface -> hw_address.hlen - 1));
-
-#ifdef DEBUG_PACKET
-       dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
-#endif
-}
-
-
-void make_request (client, lease)
-       struct client_state *client;
-       struct client_lease *lease;
-{
-       unsigned char request = DHCPREQUEST;
-       int i, j;
-       unsigned char *tmp, *digest;
-       unsigned char *old_digest_loc;
-       struct option_cache *oc;
-
-       memset (&client -> packet, 0, sizeof (client -> packet));
-
-       if (client -> state == S_REQUESTING)
-               oc = lookup_option (&dhcp_universe, lease -> options,
-                                   DHO_DHCP_SERVER_IDENTIFIER);
-       else
-               oc = (struct option_cache *)0;
-
-       if (client -> sent_options)
-               option_state_dereference (&client -> sent_options, MDL);
-
-       make_client_options (client, lease, &request, oc,
-                            ((client -> state == S_REQUESTING ||
-                              client -> state == S_REBOOTING)
-                             ? &lease -> address
-                             : (struct iaddr *)0),
-                            client -> config -> requested_options,
-                            &client -> sent_options);
-
-       /* Set up the option buffer... */
-       client -> packet_length =
-               cons_options ((struct packet *)0, &client -> packet,
-                             (struct lease *)0, client,
-                             /* maximum packet size */1500,
-                             (struct option_state *)0,
-                             client -> sent_options, 
-                             /* scope */ &global_scope,
-                             /* overload */ 0,
-                             /* terminate */0,
-                             /* bootpp    */0,
-                             (struct data_string *)0,
-                             client -> config -> vendor_space_name);
-
-       if (client -> packet_length < BOOTP_MIN_LEN)
-               client -> packet_length = BOOTP_MIN_LEN;
-
-       client -> packet.op = BOOTREQUEST;
-       client -> packet.htype = client -> interface -> hw_address.hbuf [0];
-       client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
-       client -> packet.hops = 0;
-       client -> packet.xid = client -> xid;
-       client -> packet.secs = 0; /* Filled in by send_request. */
-
-       /* If we own the address we're requesting, put it in ciaddr;
-          otherwise set ciaddr to zero. */
-       if (client -> state == S_BOUND ||
-           client -> state == S_RENEWING ||
-           client -> state == S_REBINDING) {
-               memcpy (&client -> packet.ciaddr,
-                       lease -> address.iabuf, lease -> address.len);
-               client -> packet.flags = 0;
-       } else {
-               memset (&client -> packet.ciaddr, 0,
-                       sizeof client -> packet.ciaddr);
-               if (can_receive_unicast_unconfigured (client -> interface))
-                       client -> packet.flags = 0;
-               else
-                       client -> packet.flags = htons (BOOTP_BROADCAST);
-       }
-
-       memset (&client -> packet.yiaddr, 0,
-               sizeof client -> packet.yiaddr);
-       memset (&client -> packet.siaddr, 0,
-               sizeof client -> packet.siaddr);
-       if (client -> state != S_BOUND &&
-           client -> state != S_RENEWING)
-               client -> packet.giaddr = giaddr;
-       else
-               memset (&client -> packet.giaddr, 0,
-                       sizeof client -> packet.giaddr);
-       if (client -> interface -> hw_address.hlen > 0)
-           memcpy (client -> packet.chaddr,
-                   &client -> interface -> hw_address.hbuf [1],
-                   (unsigned)(client -> interface -> hw_address.hlen - 1));
-
-#ifdef DEBUG_PACKET
-       dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
-#endif
-}
-
-void make_decline (client, lease)
-       struct client_state *client;
-       struct client_lease *lease;
-{
-       unsigned char decline = DHCPDECLINE;
-       int i;
-       struct option_cache *oc;
-
-       struct option_state *options = (struct option_state *)0;
-
-       oc = lookup_option (&dhcp_universe, lease -> options,
-                           DHO_DHCP_SERVER_IDENTIFIER);
-       make_client_options (client, lease, &decline, oc,
-                            &lease -> address, (u_int32_t *)0, &options);
-
-       /* Set up the option buffer... */
-       memset (&client -> packet, 0, sizeof (client -> packet));
-       client -> packet_length =
-               cons_options ((struct packet *)0, &client -> packet,
-                             (struct lease *)0, client, 0,
-                             (struct option_state *)0, options,
-                             &global_scope, 0, 0, 0, (struct data_string *)0,
-                             client -> config -> vendor_space_name);
-       option_state_dereference (&options, MDL);
-       if (client -> packet_length < BOOTP_MIN_LEN)
-               client -> packet_length = BOOTP_MIN_LEN;
-       option_state_dereference (&options, MDL);
-
-       client -> packet.op = BOOTREQUEST;
-       client -> packet.htype = client -> interface -> hw_address.hbuf [0];
-       client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
-       client -> packet.hops = 0;
-       client -> packet.xid = client -> xid;
-       client -> packet.secs = 0; /* Filled in by send_request. */
-       if (can_receive_unicast_unconfigured (client -> interface))
-               client -> packet.flags = 0;
-       else
-               client -> packet.flags = htons (BOOTP_BROADCAST);
-
-       /* ciaddr must always be zero. */
-       memset (&client -> packet.ciaddr, 0,
-               sizeof client -> packet.ciaddr);
-       memset (&client -> packet.yiaddr, 0,
-               sizeof client -> packet.yiaddr);
-       memset (&client -> packet.siaddr, 0,
-               sizeof client -> packet.siaddr);
-       client -> packet.giaddr = giaddr;
-       memcpy (client -> packet.chaddr,
-               &client -> interface -> hw_address.hbuf [1],
-               client -> interface -> hw_address.hlen);
-
-#ifdef DEBUG_PACKET
-       dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
-#endif
-}
-
-void make_release (client, lease)
-       struct client_state *client;
-       struct client_lease *lease;
-{
-       unsigned char request = DHCPRELEASE;
-       int i;
-       struct option_cache *oc;
-
-       struct option_state *options = (struct option_state *)0;
-
-       memset (&client -> packet, 0, sizeof (client -> packet));
-
-       oc = lookup_option (&dhcp_universe, lease -> options,
-                           DHO_DHCP_SERVER_IDENTIFIER);
-       make_client_options (client, lease, &request, oc,
-                            (struct iaddr *)0, (u_int32_t *)0,
-                            &options);
-
-       /* Set up the option buffer... */
-       client -> packet_length =
-               cons_options ((struct packet *)0, &client -> packet,
-                             (struct lease *)0, client,
-                             /* maximum packet size */1500,
-                             (struct option_state *)0,
-                             options,
-                             /* scope */ &global_scope,
-                             /* overload */ 0,
-                             /* terminate */0,
-                             /* bootpp    */0,
-                             (struct data_string *)0,
-                             client -> config -> vendor_space_name);
-
-       if (client -> packet_length < BOOTP_MIN_LEN)
-               client -> packet_length = BOOTP_MIN_LEN;
-       option_state_dereference (&options, MDL);
-
-       client -> packet.op = BOOTREQUEST;
-       client -> packet.htype = client -> interface -> hw_address.hbuf [0];
-       client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
-       client -> packet.hops = 0;
-       client -> packet.xid = random ();
-       client -> packet.secs = 0;
-       client -> packet.flags = 0;
-       memcpy (&client -> packet.ciaddr,
-               lease -> address.iabuf, lease -> address.len);
-       memset (&client -> packet.yiaddr, 0,
-               sizeof client -> packet.yiaddr);
-       memset (&client -> packet.siaddr, 0,
-               sizeof client -> packet.siaddr);
-       client -> packet.giaddr = giaddr;
-       memcpy (client -> packet.chaddr,
-               &client -> interface -> hw_address.hbuf [1],
-               client -> interface -> hw_address.hlen);
-
-#ifdef DEBUG_PACKET
-       dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
-#endif
-}
-
-void destroy_client_lease (lease)
-       struct client_lease *lease;
-{
-       int i;
-
-       if (lease -> server_name)
-               dfree (lease -> server_name, MDL);
-       if (lease -> filename)
-               dfree (lease -> filename, MDL);
-       option_state_dereference (&lease -> options, MDL);
-       free_client_lease (lease, MDL);
-}
-
-FILE *leaseFile;
-
-void rewrite_client_leases ()
-{
-       struct interface_info *ip;
-       struct client_state *client;
-       struct client_lease *lp;
-
-       if (leaseFile)
-               fclose (leaseFile);
-       leaseFile = fopen (path_dhclient_db, "w");
-       if (!leaseFile) {
-               log_error ("can't create %s: %m", path_dhclient_db);
-               return;
-       }
-
-       /* Write out all the leases attached to configured interfaces that
-          we know about. */
-       for (ip = interfaces; ip; ip = ip -> next) {
-               for (client = ip -> client; client; client = client -> next) {
-                       for (lp = client -> leases; lp; lp = lp -> next) {
-                               write_client_lease (client, lp, 1, 0);
-                       }
-                       if (client -> active)
-                               write_client_lease (client,
-                                                   client -> active, 1, 0);
-               }
-       }
-
-       /* Write out any leases that are attached to interfaces that aren't
-          currently configured. */
-       for (ip = dummy_interfaces; ip; ip = ip -> next) {
-               for (client = ip -> client; client; client = client -> next) {
-                       for (lp = client -> leases; lp; lp = lp -> next) {
-                               write_client_lease (client, lp, 1, 0);
-                       }
-                       if (client -> active)
-                               write_client_lease (client,
-                                                   client -> active, 1, 0);
-               }
-       }
-       fflush (leaseFile);
-}
-
-void write_lease_option (struct option_cache *oc,
-                        struct packet *packet, struct lease *lease,
-                        struct client_state *client_state,
-                        struct option_state *in_options,
-                        struct option_state *cfg_options,
-                        struct binding_scope **scope,
-                        struct universe *u, void *stuff)
-{
-       const char *name, *dot;
-       struct data_string ds;
-       int status;
-       struct client_state *client;
-
-       memset (&ds, 0, sizeof ds);
-
-       if (u != &dhcp_universe) {
-               name = u -> name;
-               dot = ".";
-       } else {
-               name = "";
-               dot = "";
-       }
-       if (evaluate_option_cache (&ds, packet, lease, client_state,
-                                  in_options, cfg_options, scope, oc, MDL)) {
-               fprintf (leaseFile,
-                        "  option %s%s%s %s;\n",
-                        name, dot, oc -> option -> name,
-                        pretty_print_option (oc -> option,
-                                             ds.data, ds.len, 1, 1));
-               data_string_forget (&ds, MDL);
-       }
-}
-
-int write_client_lease (client, lease, rewrite, makesure)
-       struct client_state *client;
-       struct client_lease *lease;
-       int rewrite;
-       int makesure;
-{
-       int i;
-       struct tm *t;
-       static int leases_written;
-       struct option_cache *oc;
-       struct data_string ds;
-       pair *hash;
-       int errors = 0;
-       char *s;
-
-       if (!rewrite) {
-               if (leases_written++ > 20) {
-                       rewrite_client_leases ();
-                       leases_written = 0;
-               }
-       }
-
-       /* If the lease came from the config file, we don't need to stash
-          a copy in the lease database. */
-       if (lease -> is_static)
-               return 1;
-
-       if (!leaseFile) {       /* XXX */
-               leaseFile = fopen (path_dhclient_db, "w");
-               if (!leaseFile) {
-                       log_error ("can't create %s: %m", path_dhclient_db);
-                       return 0;
-               }
-       }
-
-       errno = 0;
-       fprintf (leaseFile, "lease {\n");
-       if (lease -> is_bootp) {
-               fprintf (leaseFile, "  bootp;\n");
-               if (errno) {
-                       ++errors;
-                       errno = 0;
-               }
-       }
-       fprintf (leaseFile, "  interface \"%s\";\n",
-                client -> interface -> name);
-       if (errno) {
-               ++errors;
-               errno = 0;
-       }
-       if (client -> name) {
-               fprintf (leaseFile, "  name \"%s\";\n", client -> name);
-               if (errno) {
-                       ++errors;
-                       errno = 0;
-               }
-       }
-       fprintf (leaseFile, "  fixed-address %s;\n",
-                piaddr (lease -> address));
-       if (errno) {
-               ++errors;
-               errno = 0;
-       }
-       if (lease -> filename) {
-               s = quotify_string (lease -> filename, MDL);
-               if (s) {
-                       fprintf (leaseFile, "  filename \"%s\";\n", s);
-                       if (errno) {
-                               ++errors;
-                               errno = 0;
-                       }
-                       dfree (s, MDL);
-               } else
-                       errors++;
-
-       }
-       if (lease -> server_name) {
-               s = quotify_string (lease -> filename, MDL);
-               if (s) {
-                       fprintf (leaseFile, "  server-name \"%s\";\n", s);
-                       if (errno) {
-                               ++errors;
-                               errno = 0;
-                       }
-                       dfree (s, MDL);
-               } else
-                       ++errors;
-       }
-       if (lease -> medium) {
-               s = quotify_string (lease -> medium -> string, MDL);
-               if (s) {
-                       fprintf (leaseFile, "  medium \"%s\";\n", s);
-                       if (errno) {
-                               ++errors;
-                               errno = 0;
-                       }
-                       dfree (s, MDL);
-               } else
-                       errors++;
-       }
-       if (errno != 0) {
-               errors++;
-               errno = 0;
-       }
-
-       memset (&ds, 0, sizeof ds);
-
-       for (i = 0; i < lease -> options -> universe_count; i++) {
-               option_space_foreach ((struct packet *)0, (struct lease *)0,
-                                     client, (struct option_state *)0,
-                                     lease -> options, &global_scope,
-                                     universes [i],
-                                     client, write_lease_option);
-       }
-
-       /* Note: the following is not a Y2K bug - it's a Y1.9K bug.   Until
-          somebody invents a time machine, I think we can safely disregard
-          it. */
-       t = gmtime (&lease -> renewal);
-       fprintf (leaseFile,
-                "  renew %d %d/%d/%d %02d:%02d:%02d;\n",
-                t -> tm_wday, t -> tm_year + 1900,
-                t -> tm_mon + 1, t -> tm_mday,
-                t -> tm_hour, t -> tm_min, t -> tm_sec);
-       if (errno != 0) {
-               errors++;
-               errno = 0;
-       }
-       t = gmtime (&lease -> rebind);
-       fprintf (leaseFile,
-                "  rebind %d %d/%d/%d %02d:%02d:%02d;\n",
-                t -> tm_wday, t -> tm_year + 1900,
-                t -> tm_mon + 1, t -> tm_mday,
-                t -> tm_hour, t -> tm_min, t -> tm_sec);
-       if (errno != 0) {
-               errors++;
-               errno = 0;
-       }
-       t = gmtime (&lease -> expiry);
-       fprintf (leaseFile,
-                "  expire %d %d/%d/%d %02d:%02d:%02d;\n",
-                t -> tm_wday, t -> tm_year + 1900,
-                t -> tm_mon + 1, t -> tm_mday,
-                t -> tm_hour, t -> tm_min, t -> tm_sec);
-       if (errno != 0) {
-               errors++;
-               errno = 0;
-       }
-       fprintf (leaseFile, "}\n");
-       if (errno != 0) {
-               errors++;
-               errno = 0;
-       }
-       fflush (leaseFile);
-       if (errno != 0) {
-               errors++;
-               errno = 0;
-       }
-       if (!errors && makesure) {
-               if (fsync (fileno (leaseFile)) < 0) {
-                       log_info ("write_client_lease: %m");
-                       return 0;
-               }
-       }
-       return errors ? 0 : 1;
-}
-
-/* Variables holding name of script and file pointer for writing to
-   script.   Needless to say, this is not reentrant - only one script
-   can be invoked at a time. */
-char scriptName [256];
-FILE *scriptFile;
-
-void script_init (client, reason, medium)
-       struct client_state *client;
-       const char *reason;
-       struct string_list *medium;
-{
-       struct string_list *sl, *next;
-
-       if (client) {
-               for (sl = client -> env; sl; sl = next) {
-                       next = sl -> next;
-                       dfree (sl, MDL);
-               }
-               client -> env = (struct string_list *)0;
-               client -> envc = 0;
-               
-               if (client -> interface) {
-                       client_envadd (client, "", "interface", "%s",
-                                      client -> interface -> name);
-               }
-               if (client -> name)
-                       client_envadd (client,
-                                      "", "client", "%s", client -> name);
-               if (medium)
-                       client_envadd (client,
-                                      "", "medium", "%s", medium -> string);
-
-               client_envadd (client, "", "reason", "%s", reason);
-               client_envadd (client, "", "pid", "%ld", (long int)getpid ());
-       }
-}
-
-struct envadd_state {
-       struct client_state *client;
-       const char *prefix;
-};
-
-void client_option_envadd (struct option_cache *oc,
-                          struct packet *packet, struct lease *lease,
-                          struct client_state *client_state,
-                          struct option_state *in_options,
-                          struct option_state *cfg_options,
-                          struct binding_scope **scope,
-                          struct universe *u, void *stuff)
-{
-       struct envadd_state *es = stuff;
-       struct data_string data;
-       memset (&data, 0, sizeof data);
-
-       if (evaluate_option_cache (&data, packet, lease, client_state,
-                                  in_options, cfg_options, scope, oc, MDL)) {
-               if (data.len) {
-                       char name [256];
-                       if (dhcp_option_ev_name (name, sizeof name,
-                                                oc -> option)) {
-                               client_envadd (es -> client, es -> prefix,
-                                              name, "%s",
-                                              (pretty_print_option
-                                               (oc -> option,
-                                                data.data, data.len,
-                                                0, 0)));
-                               data_string_forget (&data, MDL);
-                       }
-               }
-       }
-}
-
-void script_write_params (client, prefix, lease)
-       struct client_state *client;
-       const char *prefix;
-       struct client_lease *lease;
-{
-       int i;
-       struct data_string data;
-       struct option_cache *oc;
-       pair *hash;
-       char *s, *t;
-       struct envadd_state es;
-
-       es.client = client;
-       es.prefix = prefix;
-
-       client_envadd (client,
-                      prefix, "ip_address", "%s", piaddr (lease -> address));
-
-       /* For the benefit of Linux (and operating systems which may
-          have similar needs), compute the network address based on
-          the supplied ip address and netmask, if provided.  Also
-          compute the broadcast address (the host address all ones
-          broadcast address, not the host address all zeroes
-          broadcast address). */
-
-       memset (&data, 0, sizeof data);
-       oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK);
-       if (oc && evaluate_option_cache (&data, (struct packet *)0,
-                                        (struct lease *)0, client,
-                                        (struct option_state *)0,
-                                        lease -> options,
-                                        &global_scope, oc, MDL)) {
-               if (data.len > 3) {
-                       struct iaddr netmask, subnet, broadcast;
-
-                       memcpy (netmask.iabuf, data.data, data.len);
-                       netmask.len = data.len;
-                       data_string_forget (&data, MDL);
-
-                       subnet = subnet_number (lease -> address, netmask);
-                       if (subnet.len) {
-                           client_envadd (client, prefix, "network_number",
-                                          "%s", piaddr (subnet));
-
-                           oc = lookup_option (&dhcp_universe,
-                                               lease -> options,
-                                               DHO_BROADCAST_ADDRESS);
-                           if (!oc ||
-                               !(evaluate_option_cache
-                                 (&data, (struct packet *)0,
-                                  (struct lease *)0, client,
-                                  (struct option_state *)0,
-                                  lease -> options,
-                                  &global_scope, oc, MDL))) {
-                               broadcast = broadcast_addr (subnet, netmask);
-                               if (broadcast.len) {
-                                   client_envadd (client,
-                                                  prefix, "broadcast_address",
-                                                  "%s", piaddr (broadcast));
-                               }
-                           }
-                       }
-               }
-               data_string_forget (&data, MDL);
-       }
-
-       if (lease -> filename)
-               client_envadd (client,
-                              prefix, "filename", "%s", lease -> filename);
-       if (lease -> server_name)
-               client_envadd (client, prefix, "server_name",
-                              "%s", lease -> server_name);
-
-       for (i = 0; i < lease -> options -> universe_count; i++) {
-               option_space_foreach ((struct packet *)0, (struct lease *)0,
-                                     client, (struct option_state *)0,
-                                     lease -> options, &global_scope,
-                                     universes [i],
-                                     &es, client_option_envadd);
-       }
-       client_envadd (client, prefix, "expiry", "%d", (int)(lease -> expiry));
-}
-
-int script_go (client)
-       struct client_state *client;
-{
-       int rval;
-       char *scriptName;
-       char *argv [2];
-       char **envp;
-       char *epp [3];
-       char reason [] = "REASON=NBI";
-       static char client_path [] = CLIENT_PATH;
-       int i;
-       struct string_list *sp, *next;
-       int pid, wpid, wstatus;
-
-       if (client)
-               scriptName = client -> config -> script_name;
-       else
-               scriptName = top_level_config.script_name;
-
-       envp = dmalloc (((client ? client -> envc : 2) +
-                        client_env_count + 2) * sizeof (char *), MDL);
-       if (!envp) {
-               log_error ("No memory for client script environment.");
-               return 0;
-       }
-       i = 0;
-       /* Copy out the environment specified on the command line,
-          if any. */
-       for (sp = client_env; sp; sp = sp -> next) {
-               envp [i++] = sp -> string;
-       }
-       /* Copy out the environment specified by dhclient. */
-       if (client) {
-               for (sp = client -> env; sp; sp = sp -> next) {
-                       envp [i++] = sp -> string;
-               }
-       } else {
-               envp [i++] = reason;
-       }
-       /* Set $PATH. */
-       envp [i++] = client_path;
-       envp [i] = (char *)0;
-
-       argv [0] = scriptName;
-       argv [1] = (char *)0;
-
-       pid = fork ();
-       if (pid < 0) {
-               log_error ("fork: %m");
-               wstatus = 0;
-       } else if (pid) {
-               do {
-                       wpid = wait (&wstatus);
-               } while (wpid != pid && wpid > 0);
-               if (wpid < 0) {
-                       log_error ("wait: %m");
-                       wstatus = 0;
-               }
-       } else {
-               execve (scriptName, argv, envp);
-               log_error ("execve (%s, ...): %m", scriptName);
-               exit (0);
-       }
-
-       if (client) {
-               for (sp = client -> env; sp; sp = next) {
-                       next = sp -> next;
-                       dfree (sp, MDL);
-               }
-               client -> env = (struct string_list *)0;
-               client -> envc = 0;
-       }
-       dfree (envp, MDL);
-       GET_TIME (&cur_time);
-       return (WIFEXITED (wstatus) ?
-               WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
-}
-
-void client_envadd (struct client_state *client,
-                   const char *prefix, const char *name, const char *fmt, ...)
-{
-       char spbuf [1024];
-       char *s;
-       unsigned len, i;
-       struct string_list *val;
-       va_list list;
-
-       va_start (list, fmt);
-       len = vsnprintf (spbuf, sizeof spbuf, fmt, list);
-       va_end (list);
-
-       val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ +
-                      len + sizeof *val, MDL);
-       if (!val)
-               return;
-       s = val -> string;
-       strcpy (s, prefix);
-       strcat (s, name);
-       s += strlen (s);
-       *s++ = '=';
-       if (len >= sizeof spbuf) {
-               va_start (list, fmt);
-               vsnprintf (s, len + 1, fmt, list);
-               va_end (list);
-       } else
-               strcpy (s, spbuf);
-       val -> next = client -> env;
-       client -> env = val;
-       client -> envc++;
-}
-
-int dhcp_option_ev_name (buf, buflen, option)
-       char *buf;
-       size_t buflen;
-       struct option *option;
-{
-       int i, j;
-       const char *s;
-
-       j = 0;
-       if (option -> universe != &dhcp_universe) {
-               s = option -> universe -> name;
-               i = 0;
-       } else { 
-               s = option -> name;
-               i = 1;
-       }
-
-       do {
-               while (*s) {
-                       if (j + 1 == buflen)
-                               return 0;
-                       if (*s == '-')
-                               buf [j++] = '_';
-                       else
-                               buf [j++] = *s;
-                       ++s;
-               }
-               if (!i) {
-                       s = option -> name;
-                       if (j + 1 == buflen)
-                               return 0;
-                       buf [j++] = '_';
-               }
-               ++i;
-       } while (i != 2);
-
-       buf [j] = 0;
-       return 1;
-}
-
-void go_daemon ()
-{
-       static int state = 0;
-       int pid;
-       int i;
-
-       /* Don't become a daemon if the user requested otherwise. */
-       if (no_daemon) {
-               write_client_pid_file ();
-               return;
-       }
-
-       /* Only do it once. */
-       if (state)
-               return;
-       state = 1;
-
-       /* Stop logging to stderr... */
-       log_perror = 0;
-
-       /* Become a daemon... */
-       if ((pid = fork ()) < 0)
-               log_fatal ("Can't fork daemon: %m");
-       else if (pid)
-               exit (0);
-       /* Become session leader and get pid... */
-       pid = setsid ();
-
-       /* Close standard I/O descriptors. */
-        close(0);
-        close(1);
-        close(2);
-
-       /* Reopen them on /dev/null. */
-       i = open ("/dev/null", O_RDWR);
-       if (i == 0)
-               i = open ("/dev/null", O_RDWR);
-       if (i == 1) {
-               i = open ("/dev/null", O_RDWR);
-               log_perror = 0; /* No sense logging to /dev/null. */
-       } else if (i != -1)
-               close (i);
-
-       write_client_pid_file ();
-}
-
-void write_client_pid_file ()
-{
-       FILE *pf;
-       int pfdesc;
-
-       pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
-
-       if (pfdesc < 0) {
-               log_error ("Can't create %s: %m", path_dhclient_pid);
-               return;
-       }
-
-       pf = fdopen (pfdesc, "w");
-       if (!pf)
-               log_error ("Can't fdopen %s: %m", path_dhclient_pid);
-       else {
-               fprintf (pf, "%ld\n", (long)getpid ());
-               fclose (pf);
-       }
-}
-
-void client_location_changed ()
-{
-       struct interface_info *ip;
-       struct client_state *client;
-
-       for (ip = interfaces; ip; ip = ip -> next) {
-               for (client = ip -> client; client; client = client -> next) {
-                       switch (client -> state) {
-                             case S_SELECTING:
-                               cancel_timeout (send_discover, client);
-                               break;
-
-                             case S_BOUND:
-                               cancel_timeout (state_bound, client);
-                               break;
-
-                             case S_REBOOTING:
-                             case S_REQUESTING:
-                             case S_RENEWING:
-                               cancel_timeout (send_request, client);
-                               break;
-
-                             case S_INIT:
-                             case S_REBINDING:
-                             case S_STOPPED:
-                               break;
-                       }
-                       client -> state = S_INIT;
-                       state_reboot (client);
-               }
-       }
-}
-
-void do_release(client) 
-       struct client_state *client;
-{
-       struct data_string ds;
-       struct option_cache *oc;
-
-       /* Pick a random xid. */
-       client -> xid = random ();
-
-       /* is there even a lease to release? */
-       if (client -> active) {
-               /* Make a DHCPRELEASE packet, and set appropriate per-interface
-                  flags. */
-               make_release (client, client -> active);
-
-               memset (&ds, 0, sizeof ds);
-               oc = lookup_option (&dhcp_universe,
-                                   client -> active -> options,
-                                   DHO_DHCP_SERVER_IDENTIFIER);
-               if (oc &&
-                   evaluate_option_cache (&ds, (struct packet *)0,
-                                          (struct lease *)0, client,
-                                          (struct option_state *)0,
-                                          client -> active -> options,
-                                          &global_scope, oc, MDL)) {
-                       if (ds.len > 3) {
-                               memcpy (client -> destination.iabuf,
-                                       ds.data, 4);
-                               client -> destination.len = 4;
-                       } else
-                               client -> destination = iaddr_broadcast;
-
-                       data_string_forget (&ds, MDL);
-               } else
-                       client -> destination = iaddr_broadcast;
-               client -> first_sending = cur_time;
-               client -> interval = client -> config -> initial_interval;
-       
-               /* Zap the medium list... */
-               client -> medium = (struct string_list *)0;
-       
-               /* Send out the first and only DHCPRELEASE packet. */
-               send_release (client);
-
-               /* Do the client script RELEASE operation. */
-               script_init (client,
-                            "RELEASE", (struct string_list *)0);
-               if (client -> alias)
-                       script_write_params (client, "alias_",
-                                            client -> alias);
-               script_write_params (client, "old_", client -> active);
-               script_go (client);
-       }
-
-       /* Cancel any timeouts. */
-       cancel_timeout (state_bound, client);
-       cancel_timeout (send_discover, client);
-       cancel_timeout (state_init, client);
-       cancel_timeout (send_request, client);
-       cancel_timeout (state_reboot, client);
-       client -> state = S_STOPPED;
-}
-
-int dhclient_interface_shutdown_hook (struct interface_info *interface)
-{
-       do_release (interface -> client);
-
-       return 1;
-}
-
-int dhclient_interface_discovery_hook (struct interface_info *tmp)
-{
-       struct interface_info *last, *ip;
-       /* See if we can find the client from dummy_interfaces */
-       last = 0;
-       for (ip = dummy_interfaces; ip; ip = ip -> next) {
-               if (!strcmp (ip -> name, tmp -> name)) {
-                       /* Remove from dummy_interfaces */
-                       if (last) {
-                               ip = (struct interface_info *)0;
-                               interface_reference (&ip, last -> next, MDL);
-                               interface_dereference (&last -> next, MDL);
-                               if (ip -> next) {
-                                       interface_reference (&last -> next,
-                                                            ip -> next, MDL);
-                                       interface_dereference (&ip -> next,
-                                                              MDL);
-                               }
-                       } else {
-                               ip = (struct interface_info *)0;
-                               interface_reference (&ip,
-                                                    dummy_interfaces, MDL);
-                               interface_dereference (&dummy_interfaces, MDL);
-                               if (ip -> next) {
-                                       interface_reference (&dummy_interfaces,
-                                                            ip -> next, MDL);
-                                       interface_dereference (&ip -> next,
-                                                              MDL);
-                               }
-                       }
-                       /* Copy "client" to tmp */
-                       if (ip -> client) {
-                               tmp -> client = ip -> client;
-                               tmp -> client -> interface = tmp;
-                       }
-                       interface_dereference (&ip, MDL);
-                       break;
-               }
-               last = ip;
-       }
-       return 1;
-}
-
-isc_result_t dhclient_interface_startup_hook (struct interface_info *interface)
-{
-       struct interface_info *ip;
-       struct client_state *client;
-
-       /* This code needs some rethinking.   It doesn't test against
-          a signal name, and it just kind of bulls into doing something
-          that may or may not be appropriate. */
-
-       if (interfaces) {
-               interface_reference (&interface -> next, interfaces, MDL);
-               interface_dereference (&interfaces, MDL);
-       }
-       interface_reference (&interfaces, interface, MDL);
-
-       discover_interfaces (DISCOVER_UNCONFIGURED);
-
-       for (ip = interfaces; ip; ip = ip -> next) {
-               /* If interfaces were specified, don't configure
-                  interfaces that weren't specified! */
-               if (ip -> flags & INTERFACE_RUNNING ||
-                  (ip -> flags & (INTERFACE_REQUESTED |
-                                    INTERFACE_AUTOMATIC)) !=
-                    INTERFACE_REQUESTED)
-                       continue;
-               script_init (ip -> client,
-                            "PREINIT", (struct string_list *)0);
-               if (ip -> client -> alias)
-                       script_write_params (ip -> client, "alias_",
-                                            ip -> client -> alias);
-               script_go (ip -> client);
-       }
-       
-       discover_interfaces (interfaces_requested
-                            ? DISCOVER_REQUESTED
-                            : DISCOVER_RUNNING);
-
-       for (ip = interfaces; ip; ip = ip -> next) {
-               if (ip -> flags & INTERFACE_RUNNING)
-                       continue;
-               ip -> flags |= INTERFACE_RUNNING;
-               for (client = ip -> client; client; client = client -> next) {
-                       client -> state = S_INIT;
-                       /* Set up a timeout to start the initialization
-                         &n