Merge 3.0b2pl2 with head.

This commit is contained in:
mellon 2000-09-04 23:19:27 +00:00
parent 96f1451685
commit e59a2459c4
21 changed files with 1030 additions and 928 deletions

View File

@ -1,7 +1,6 @@
Internet Software Consortium
Dynamic Host Configuration Protocol Distribution
Version 3, Beta 2, Patchlevel 0
January 21, 2000
Internet Software Consortium DHCP Distribution
Version 3, Beta 2, Patchlevel 2
September 4, 2000
README FILE
@ -19,33 +18,35 @@ the ISC DHCP Distribution.
3.3 BUILDING IT
4 INSTALLING THE DHCP DISTRIBUTION
5 USING THE DHCP DISTRIBUTION
5.1 LINUX
5.1.1 IF_TR.H NOT FOUND
5.1.2 SO_ATTACH_FILTER UNDECLARED
5.1.3 PROTOCOL NOT CONFIGURED
5.1.4 BROADCAST
5.1.5 FIREWALL RULES
5.1.6 IP BOOTP AGENT
5.1.7 MULTIPLE INTERFACES
5.2 SCO
5.3 HP-UX
5.4 ULTRIX
5.5 FreeBSD
5.6 NeXTSTEP
5.7 SOLARIS
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
7 KNOWN 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. 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.
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.
@ -94,33 +95,38 @@ system.
RELEASE STATUS
This is the first beta release of version 3.0 of the ISC DHCP
Distribution. Development of this release is approaching the point
at which it will be frozen, and no significant new features will be
This is the second beta release of version 3.0 of the ISC DHCP
Distribution. Development of this release is approaching the point at
which it will be frozen, and no significant new features will be
added.
In this release, the server and relay agent currently work well on
NetBSD, Linux after kernel version 2.0.30, FreeBSD, BSD/OS, Ultrix,
Digital Alpha OSF/1, Solaris and SunOS 4.1.4. They run on AIX, HPUX,
IRIX and Linux 2.0.30 and earlier kernels but support only a single
broadcast network interface. They also runs on QNX as long as only
one broadcast network interface is configured and a host route is
added from that interface to the 255.255.255.255 broadcast address.
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 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, BSD/os, Linux, Solaris and NextStep. The client
depends on a system-dependent shell script to do network
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.
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
@ -135,14 +141,14 @@ information. On Digital Unix, type ``man pfilt''.
To build the DHCP Distribution, unpack the compressed tar file using
the tar utility and the gzip command - type something like:
zcat dhcp-3.0b2pl0.tar.gz |tar xvf -
zcat dhcp-3.0b2pl2.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.0b2pl0 subdirectory that you've just
Now, cd to the dhcp-3.0b2pl2 subdirectory that you've just
created and configure the source tree by typing:
./configure
@ -155,21 +161,9 @@ your own.
DYNAMIC DNS UPDATES
An interim implementation of dynamic DNS updates is included in this
release. This implementation is not built by default. To use this
implementation, you must have installed the latest version of bind 8.2
(see http://www.isc.org for more information about BIND). The
configuration utility assumes that the BIND 8.2 distribution libraries
and includes are under the /usr/local/bind directory, except on
FreeBSD, where it assumes they are in /usr/local. If you have
installed them elsewhere, you should set the BINDLIB and BINDINC
variables in site.conf to override the values that will be set by the
configure script from Makefile.conf.
Assuming that you have BIND 8.2.2-P3 or later installed, you can build
dynamic DNS update support using:
./configure --with-nsupdate
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
@ -196,6 +190,40 @@ 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,
@ -265,18 +293,25 @@ Linux 2.2.x kernels.
LINUX: BROADCAST
On older versions of Linux (versions prior to 2.2), there is a
potential problem with the broadcast address being sent incorrectly.
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 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.
(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
@ -302,21 +337,6 @@ Another route that has worked for some users is:
If you are not using eth0 as your network interface, you should
specify the network interface you *are* using in your route command.
LINUX: FIREWALL RULES
If you are running the DHCP server or client on a Linux system that's
also acting as a firewall, you must be sure to allow DHCP packets
through the firewall - Linux firewalls make filtering decisions before
they make the forwarding decision, so they will filter packets that
are intended for the firewall itself, as well as packets intended to
be forwarded. 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.
LINUX: IP BOOTP AGENT
Some versions of the Linux 2.1 kernel apparently prevent dhcpd from
@ -439,35 +459,51 @@ matter, but please check with Sun first.
SUPPORT
The Internet Software Consortium DHCP server is not a commercial
product, and is not supported in that sense. 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@fugue.com
mailing list.
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 (or both) - whichever is appropriate to your
application. This includes reporting bugs. Please do not report
bugs in old software releases - fetch the latest release and see if
the bug is still in that copy 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 2.0, you don't have to upgrade to 3.0
before you can report bugs.
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.
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 2.0, you don't have
to upgrade to 3.0 before you can report bugs.
PLEASE DO NOT REPORT BUGS IF YOU ARE NOT 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!
HOW TO REPORT BUGS
HOW TO REPORT BUGS OR REQUEST SUPPORT
When you report bugs, 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.
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.
- The specific operating system name and version of the
machine on which the DHCP server or client is running.
@ -484,13 +520,14 @@ problem.
may be hard for you to figure it out, so don't go crazy
trying.
- The specific version of the DHCP distribution you're
running, for example 2.0b1pl19, not 2.0.
running, for example "2.0b1pl19", not "2.0".
- 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.
- 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).
send them until you're asked). Huge means more than 100
kilobytes each.
- 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
@ -519,20 +556,28 @@ 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.fugue.com/dhcp/lists for details on how to
subscribe. If you don't have WorldWide Web access, you can send mail
to dhcp-request@fugue.com and tell me which lists you want to
subscribe to, but please use the web interface if you can, since I
have to handle the -request mailing list manually, and I will give you
the third degree if you make me do your subscription manually.
Please see http://www.isc.org/services/public/lists/dhcp-lists.html
for details on how to subscribe to the ISC DHCP mailing lists.
PLEASE DO NOT SEND REQUESTS FOR SUPPORT DIRECTLY TO ME! The number of
people using the DHCP Distribution is sufficiently large that if I
take an interrupt every time any one of those people runs into
trouble, I will never get any more coding done.
PLEASE DO NOT SEND REQUESTS FOR SUPPORT DIRECTLY TO THE ENGINEERS WHO
WORK ON THE ISC DHCP DISTRIBUTION! Do not even Cc: us - we do read
the public mailing lists! 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. If your question can only be answered by one of us, we will
answer it on the public mailing list. When we have time.
PLEASE DO NOT CALL US ON THE PHONE FOR SUPPORT! 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.
PLEASE DO NOT CALL ME ON THE PHONE FOR SUPPORT! Answering the phone
takes a lot more of my time and attention than answering email. If you
do call me on the phone, I will tell you to send email to the mailing
list, and I won't answer your question, so there's no point in doing
it.

View File

@ -1,423 +1,64 @@
Internet Software Consortium
Dynamic Host Configuration Protocol Distribution
Version 3, Beta 2, Patchlevel 0
January 21, 2000
Internet Software Consortium DHCP Distribution
Version 3, Beta 2, Patchlevel 2
September 4, 2000
Release Notes
This is a development snapshot of Version 3 of the Internet Software
Consortium DHCP Distribution.
PLANS
NEW FEATURES
Version 3 of the ISC DHCP Distribution adds conditional behaviour,
address pools with access control, and client classing. An interim
implementation of dynamic DNS updates for the server only is included,
but is not supported. The README file contains information about how
to enable this - it is not compiled into the DHCP server by default.
Version 3, Beta 2 of the ISC DHCP Distribution includes the following
features that are new since version 2.0:
Features in upcoming releases, starting with 3.1, will include
Dynamic DNS Support, DHCPv4 16-bit option codes, asynchronous DNS
query resolution, DHCP Authentication, and support for a DHCP
Interserver Protocol and live querying and update of the DHCP
database. Not all of this is done yet (see below).
- 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.
This release is running in production at the ISC and at quite a few
other sites. At this point, the 3.0 release is reasonably stable, but
is really only recommended for sites that are in a position to
experiment, or for sites that need the new features. Bug reports are
enthusiastically solicited.
This beta release is quite new, and is running in production at only a
few sites. We strongly recommend that you exercise caution in
installing it. The 3.0 Beta 2 lease file is not backwards compatible
with the 3.0 Beta 1 lease file, so if you have to go back, you will
have to convert your lease files back to the 3.0 Beta 1 format - if
you try to run a 3.0 Beta 1 server on a 3.0 Beta 2 lease file, it will
cheerfully delete all your leases. Having said that, of course the
way that new releases of open source software become stable is by
people using them, finding the bugs, and reporting the bugs. So
while we urge you to exercise caution, we would also appreciate any
testing or production use you can safely do.
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 interim Dynamic DNS Update support is the result of work by Lans
Carstensen and Brian Dols at Rose-Hulman Institute of Technology, Jim
Watt at Perkin-Elmer, Irina Goble at Integrated Measurement Systems,
and Brian Murrell at BC Tel Advanced Communications. I'd like to
express my thanks to all of these good people here.
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 Perkin-Elmer, Irina Goble at Integrated
Measurement Systems, 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 June 6, 1999
Changes since 3.0 Beta 2 Patchlevel 1
- Integrated Irina Goble's Dynamic DNS update patches, with some
changes, thanks to Brian Murrell of BC Tel. These changes are only
enabled if you explicitly specify it with the configure script, and
we currently have no documentation.
- 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.
- Heavily updated README file.
- In the server, if no interfaces were configured, report an error and
exit.
- Updated dhclient man page to document all current command-line
arguments.
- Don't ever record a state of 'startup'.
- Added a -s flag to both the client and server, for debugging only,
so that the client and server can both be run using the socket API
on a single machine that has no network interfaces (e.g., with lo0).
- Added support for three new subexpressions that return data:
leased-address, reverse and binary-to-ascii.
- Fixed a problem where TOKEN_NOT and NOT were both kinds of tokens,
which prevented "not authoritative" from working.
- Updated the pretty-printer for the 'X' type so that it will output
ASCII text if the buffer being output contains all printable
characters. This is useful, e.g., for using the host-name option
in the client.
- Add support for an always-broadcast flag, which, when enabled,
causes the DHCP server to broadcast responses to all clients in the
scope in which it is enabled, even if the client didn't request that
the response be broadcast. This is useful for working around
clients that have buggy support for the protocol.
- Fix (I hope!) a compilation problem with the declaration of the
fallback_discard function on some versions of Linux.
- Fix a bug that caused the offered lease time to be zero (or possibly
some random value from the stack) if the client did not request a
specific lease duration.
- Add support for a one-lease-per-client flag, which if enabled in the
scope in which a client appears, causes any leases the client holds
to be freed as soon as a DHCPREQUEST is received from the client for
some other IP address. This will only work if the client has only
one network interface, so caution is urged in the use of this
feature.
- Fix a mistake in the example in the dhcpd.conf manual page that
talks about the "spawn with" statement.
Changes since May 27, 1999
- Fix some typos in the token ring code that I made while
incorporating Andrew's changes.
- Fix some problems with scope evaluation related to BOOTP clients.
Changes since May 7, 1999
- Add LPF token ring support, contributed by Andrew Chittenden.
- Fix a serious bug in some server option evaluations, where it was
looking for the values in the DHCP option space instead of the
server option space.
- Prevent the server from failing to configure a client that retries
its initial DHCPDISCOVER too quickly.
- Tweak semantics of lease limits so that if any class a client is in
has a limit, then the client can't get a lease just because it's
also in a class with no limits.
- Correct an operator precedence bug in abandoned lease handling.
- Provide more complete documentation for classes and correct errors
in existing documentation.
- Fix some pointer non-debug code paths.
- Add support for encode_int() operand
- Fix documentation for concat operator.
- Edit dhcp options manual page for consistency.
Changes since May 6, 1999
- Reverse precedence of user-supplied parameter request list so that
user can override client's preferences.
- Do not call abort () when uninitialized pointers are passed to
allocation functions unless POINTER_DEBUG is defined.
- Fix a bug in parsing colon-seperated hex octet lists in data
expressions.
- Fix a number of cases where the server would dump core in
evaluate_*_expression if the options buffer was a NULL pointer.
- Fix incorrect handling of exists subexpression.
Changes since April 24, 1999
- In DHCPINFORM, allow for buggy clients that do not set ciaddr by
using the IP source address from the IP header if ciaddr is zero.
- Fix some memory allocation botches in the DHCP server.
- Use parameter request list option from scope if it is present and
client didn't send one.
- Allow for RFC1541 clients that set ciaddr when REQUESTING by
checking server-identifier option as well as ciaddr before
unicasting.
- Add support for concat data subexpression.
- Add support for specifying option data as a data expression instead
of in the option's specified format.
- Fix a compile error on some Linux 2.0-based distributions.
Changes since April 23, 1999
- Fix a duplicate declaration of the object file copyright in dlpi.c. Sigh.
Changes since April 12, 1999
- Fix a bug that would cause a core dump in DHCPINFORM.
- Document DHCP server lease allocation algorithm in dhcpd.conf manual
page. Also document pool access control lists.
- Add support for site-defined option spaces.
- Do not respond with NAK if ciaddr is set and giaddr/interface origin
network segment doesn't match, since ciaddr means client is
unicasting using IP routing.
- Support DHCPINFORM even on unknown networks.
- Make pool scope less specific than class scope.
- Enforce maximum lease length after applying default lease time.
- Add support for a bunch of options that were added in RFC2132.
- Undo a mistaken change in the interface discovery code that caused
(e.g.) lo0 to be recognized as a broadcast interface.
- Tweak (hopefully fix) UDP/IP checksum algorithm.
- Support compilation on MacOS X.
Changes since April 8, 1999
- Support DHCPINFORM.
- Fix up some references to error() which I didn't notice earlier
because I don't do compilation testing on Linux.
- Add a boolean expression, "known", which returns true if the client
whose request is currently being processed has a host declaration.
- Do path keyword substitution on unformatted manual pages before
installing them.
- Use length from UDP header to compute UDP checksum, because some
buggy relay agents send UDP header lengths that disagree with IP
header length and actual bytes sent.
- Make error logging when packets with bad checksums or lengths are
received work more correctly.
- Fix a null pointer dereference that would occur when processing
bootp packets from networks to which the server was not directly
connected.
Changes since March 30, 1999
- Install unformatted manual pages on Linux
- SGI Irix support
- Generalize option support and add parser support for defining new
option spaces.
- Support for generating vendor-encapsulated-options option from
user-specified option space, rather than having to encode it as
hex.
- Fix hash table code to do the right thing with nul-terminated
strings - before they'd all get hashed into the same bucket.
- Fix a parser bug caused by dereferencing an uninitialized variable
that prevented the parser from working correctly on some systems but
allowed it to work on others.
- Document how to define new options, as well as how to set up
vendor-encapsulated-options option.
- When responding to bootp clients, use the subnet mask from the
subnet declaration as we do for DHCP clients if no explicit subnet
mask option was defined.
- Add always-send-rfc1048 option to force the server to send
rfc1048-style options (what everybody uses now) even if the client
doesn't send the right magic cookie.
- Fix some bugs in class support that became obvious when I tried to
use the vendor-encapsulated-option support in a reasonable way.
- Fix some memory leaks.
Changes since March 29, 1999 (second snapshot)
- Fix a memory allocation bug
- Move support for allow and deny keywords (WRT to server option
space) into common code so that they can be used within
conditionals.
Changes since March 29, 1999 (first snapshot)
- Build two new manual pages.
- Undo IFF_POINTOPOINT change from March 26.
- Add entry, exit and resolv.conf building hooks to dhclient-script.
Changes since March 26, 1999
- Set broadcast flag in DHCPDISCOVER packet if appropriate.
- Fix parsing of pool permits and address range statements.
- Account for tabs in parse_warn().
Changes since March 15, 1999
- Only use min-secs parameter on DHCPDISCOVER packets.
- Restore support for server-identifier keyword.
- Fix dhcp-class-identifier name to be vendor-class-identifier.
- Add support for defining new DHCP options, e.g.:
option new-option-name code 198 = array of ip-address;
option new-option-name 10.20.30.1, 10.20.30.2;
- Support added for AIX 4.1.5.0 (and hopefully other versions).
- Use /var/run instead of /etc on Digital Unix.
- Change DHCP client exponential backoff code to back off more slowly,
so that it is more robust in lossy environments, at the expense of
being a bit less polite to the server.
- Don't request a specific lease interval in the client unless the
user says to do so.
- Don't print DHCPXXX in wrong xxx messages unless DEBUG is defined.
- Fix handling of secs field.
- Fix handling of append statement.
- Fix documentation for append and prepend statements.
- Fix server support for parameter request list and maximum message
size.
- Parameterize more hardware types in discover_interfaces. Check for
IFF_BROADCAST instead of !IFF_POINTOPOINT
- Print kernel configuration warning message if we get EINVAL when
opening or configuring the Linux packet filter.
- Fix a bug in UDP checksum code (thanks to John Nemeth for figuring
this out) and re-enable UDP checksumming. This allows the client
to work with some buggy DHCP servers that can't handle zero
checksums in the UDP header - in particular, the one John's cable
modem ISP is using.
- Don't report packet header checksum errors unless we see a lot of
them. It's perfectly normal for some number of checksum errors to
occur.
- Refer to the dhcpd.leases man page when printing an error message
prior to exiting because there's no lease database.
- Add information to the README telling the reader how to get to the
manual pages.
- Fix the server packet transmission code to unicast when it can.
- Fix a typo in the dhcpd.conf manual page.
CHANGES SINCE VERSION 2.0
- Support for conditional behaviour - i.e., what the client sends can
be used to determine what response the client gets, in a very
general way.
- Support for client classing - that is, clients can be assigned to
classes based on what they send, and then address assignments can be
made based on the client's class. A per-class limit on the number
of addresses assignable can be made. It is possible to spawn new
classes on the fly based on a template, so that address limitations
can be done on a per-customer basis - e.g., when using relay agent
options, a particular customer's circuit ID can be used to classify
all hosts at the customer site as part of a class which is generated
on the fly the first time the circuit ID is seen. The class
template from which this class is created can specify a limit of,
say, four leases. This would have the effect of limiting all
customer sites behind relay agents that attach circuit IDs to the
packets they forward to a maximum of four leases each.
- Memory allocation behaviour has been completely redone.
- Support for more than one pool of addresses per network segment.
This permits clients to be allocated addresses out of different
ranges, even within a subnet, based on what classes they're in,
whether or not they are known (have host declarations), whether or
not they have authenticated, and that sort of thing. Parameters,
including things like lease times and also things like options to be
sent to the client, can vary from address pool to address pool.
UPCOMING WORK
I have a bunch of unintegrated code to do authentication. The only
reason it's not integrated is that I've decided it's incorrect, and
I'm going to have to hack the in-memory database to make it correct.
So expect the lease data structure to change, and probably expect the
host data structure to change as well, in order to fully support
authentication. Some bits of authentication support are already
scattered here and there. You may see references in the code to the
failover protocol. I was testing some theories, but this code isn't
functional in any sense, although it will be in the future.
Integration between DHCP and Dynamic DNS is the most-requested
feature, and you can expect work on this to occur in the near future.
Irina Goble has some code that several people are running with 2.0
with some success right now, and while I don't promise to integrate
this particular code, something will certainly be happening in April
or May.
There's already some support for DHCPv4NG 16-bit option codes, but it's
not complete, and won't be very interesting until we have a DHCP
futures draft out and Microsoft implements it in their clients. When
this draft is a bit closer to completion, the ISC will release a
sample implementation - it's not too hard, and it'll be cool to be
able to say at the IETF that there's something available, even if it
won't be deployable for a while yet. You will be able to run the
DHCPv4NG server with existing DHCPv4 clients, because the protocol
provides for interoperability between new servers and old clients, as
well as new clients and old servers.
The all-singing, all-dancing Interserver Protocol has been put on the
back burner in favor of the DHCP Failover Protocol, which solves the
problem of providing redundant DHCP service with no more than two DHCP
servers. This protocol is coming along quite nicely - we had a
meeting in February at Cisco, and lots of progress was made. Cisco
and Process Software both have implementations of an older version of
the protocol, and will presumably have support for the new protocol in
the not-too-distant future. The ISC will go straight to the new
protocol, once the next draft comes out and as time allows.
Live querying and update of the DHCP database will involve creating a
unix domain or secure (peer-to-peer IPSEC or TLS) TCP socket to the
DHCP server, sending requests for information, receiving responses,
and sending updates. Most of the read-only DHCP status information
will be available through SNMP, but the private query/update socket
will allow, for example, registration of clients without restarting
the server, and adjusting parameters on classes - e.g., reducing or
increasing the number of leases clients in a particular spawned class
may hold.
We will be providing anonymous CVS support as soon as we can.
- Don't try to evaluate the local failover binding address if none was
specified. Thanks to Joseph Breu for finding this.

View File

@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: clparse.c,v 1.7 2000/07/20 05:59:17 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: clparse.c,v 1.8 2000/09/04 23:19:29 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -949,7 +949,8 @@ void parse_client_lease_declaration (cfile, lease, ipp, clientp)
skip_to_semi (cfile);
break;
}
if (tsig_key_lookup (&lease -> key, val) != ISC_R_SUCCESS)
if (omapi_auth_key_lookup_name (&lease -> key, val) !=
ISC_R_SUCCESS)
parse_warn (cfile, "unknown key %s", val);
parse_semi (cfile);
break;

View File

@ -41,7 +41,7 @@
#ifndef lint
static char ocopyright[] =
"$Id: dhclient.c,v 1.31 2000/07/23 07:13:57 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 Internet Software Consortium. All rights reserved.\n";
"$Id: dhclient.c,v 1.32 2000/09/04 23:19:30 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -65,8 +65,6 @@ struct in_addr inaddr_any;
struct sockaddr_in sockaddr_broadcast;
struct in_addr giaddr;
struct binding_scope global_scope;
/* ASSERT_STATE() does nothing now; it used to be
assert (state_is == state_shouldbe). */
#define ASSERT_STATE(state_is, state_shouldbe) {}
@ -74,8 +72,7 @@ struct binding_scope global_scope;
static char copyright[] = "Copyright 1995-2000 Internet Software Consortium.";
static char arr [] = "All rights reserved.";
static char message [] = "Internet Software Consortium DHCP Client";
static char contrib [] = "\nPlease contribute if you find this software useful.";
static char url [] = "For info, please visit http://www.isc.org/dhcp-contrib.html\n";
static char url [] = "For info, please visit http://www.isc.org/products/DHCP";
u_int16_t local_port;
u_int16_t remote_port;
@ -229,7 +226,6 @@ int main (argc, argv, envp)
log_info ("%s %s", message, DHCP_VERSION);
log_info (copyright);
log_info (arr);
log_info (contrib);
log_info (url);
} else
log_perror = 0;
@ -661,7 +657,7 @@ void dhcpack (packet)
log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
lease = packet_to_lease (packet);
lease = packet_to_lease (packet, client);
if (!lease) {
log_info ("packet_to_lease failed.");
return;
@ -1010,7 +1006,7 @@ void dhcpoffer (packet)
}
}
lease = packet_to_lease (packet);
lease = packet_to_lease (packet, client);
if (!lease) {
log_info ("packet_to_lease failed.");
return;
@ -1063,8 +1059,9 @@ void dhcpoffer (packet)
/* Allocate a client_lease structure and initialize it from the parameters
in the specified packet. */
struct client_lease *packet_to_lease (packet)
struct client_lease *packet_to_lease (packet, client)
struct packet *packet;
struct client_state *client;
{
struct client_lease *lease;
int i;
@ -1699,7 +1696,8 @@ void make_client_options (client, lease, type, sid, rip, prl, op)
/* Run statements that need to be run on transmission. */
if (client -> config -> on_transmission)
execute_statements_in_scope
((struct packet *)0, (struct lease *)0,
((struct binding_value **)0,
(struct packet *)0, (struct lease *)0,
(lease ? lease -> options : (struct option_state *)0),
*op, &global_scope,
client -> config -> on_transmission,
@ -2229,7 +2227,8 @@ void script_write_params (client, prefix, lease)
client_envadd (client, prefix, "server_name",
"%s", lease -> server_name);
execute_statements_in_scope ((struct packet *)0,
execute_statements_in_scope ((struct binding_value **)0,
(struct packet *)0,
(struct lease *)0, lease -> options,
lease -> options, &global_scope,
client -> config -> on_receipt,

View File

@ -47,7 +47,7 @@
#ifndef lint
static char copyright[] =
"$Id: bpf.c,v 1.3 2000/06/10 18:17:20 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: bpf.c,v 1.4 2000/09/04 23:19:31 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -359,28 +359,33 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct sockaddr_in *to;
struct hardware *hto;
{
unsigned bufp = 0;
unsigned char buf [256];
struct iovec iov [2];
unsigned hbufp = 0, ibufp = 0;
double hw [4];
double ip [32];
struct iovec iov [3];
int result;
int fudge;
if (!strcmp (interface -> name, "fallback"))
return send_fallback (interface, packet, raw,
len, from, to, hto);
/* Assemble the headers... */
assemble_hw_header (interface, buf, &bufp, hto);
assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
assemble_hw_header (interface, (unsigned char *)hw, &hbufp, hto);
assemble_udp_ip_header (interface,
(unsigned char *)ip, &ibufp, from.s_addr,
to -> sin_addr.s_addr, to -> sin_port,
(unsigned char *)raw, len);
/* Fire it off */
iov [0].iov_base = (char *)buf;
iov [0].iov_len = bufp;
iov [1].iov_base = (char *)raw;
iov [1].iov_len = len;
iov [0].iov_base = ((char *)hw);
iov [0].iov_len = hbufp;
iov [1].iov_base = ((char *)ip);
iov [1].iov_len = ibufp;
iov [2].iov_base = (char *)raw;
iov [2].iov_len = len;
result = writev(interface -> wfdesc, iov, 2);
result = writev(interface -> wfdesc, iov, 3);
if (result < 0)
log_error ("send_packet: %m");
return result;
@ -512,6 +517,12 @@ int can_receive_unicast_unconfigured (ip)
return 1;
}
int supports_multiple_interfaces (ip)
struct interface_info *ip;
{
return 1;
}
void maybe_setup_fallback ()
{
isc_result_t status;

View File

@ -50,7 +50,7 @@
#ifndef lint
static char copyright[] =
"$Id: comapi.c,v 1.2 2000/07/08 20:52:11 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: comapi.c,v 1.3 2000/09/04 23:19:31 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -77,7 +77,7 @@ void dhcp_common_objects_setup ()
dhcp_group_lookup,
dhcp_group_create,
dhcp_group_remove, 0, 0, 0,
sizeof (struct group));
sizeof (struct group_object));
if (status != ISC_R_SUCCESS)
log_fatal ("Can't register group object type: %s",
isc_result_totext (status));
@ -410,7 +410,6 @@ isc_result_t dhcp_group_create (omapi_object_t **lp,
status = group_object_allocate (&group, MDL);
if (status != ISC_R_SUCCESS)
return status;
memset (group, 0, sizeof *group);
group -> flags = GROUP_OBJECT_DYNAMIC;
status = omapi_object_reference (lp, (omapi_object_t *)group, MDL);
group_object_dereference (&group, MDL);

View File

@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: discover.c,v 1.5 2000/07/08 20:52:12 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: discover.c,v 1.6 2000/09/04 23:19:32 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -79,7 +79,7 @@ void discover_interfaces (state)
{
struct interface_info *tmp, *ip;
struct interface_info *last, *next;
char buf [8192];
char buf [512];
struct ifconf ic;
struct ifreq ifr;
int i;
@ -95,6 +95,7 @@ void discover_interfaces (state)
#endif
isc_result_t status;
static int setup_fallback = 0;
int wifcount = 0;
if (!dhcp_type_interface) {
status = omapi_object_type_register
@ -113,6 +114,7 @@ void discover_interfaces (state)
log_fatal ("Can't create addrlist socket");
/* Get the interface configuration information... */
gifconf_again:
ic.ifc_len = sizeof buf;
ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
i = ioctl(sock, SIOCGIFCONF, &ic);
@ -120,6 +122,16 @@ void discover_interfaces (state)
if (i < 0)
log_fatal ("ioctl: SIOCGIFCONF: %m");
/* If the SIOCGIFCONF resulted in more data than would fit in
a buffer, allocate a bigger buffer. */
if (ic.ifc_ifcu.ifcu_buf == buf &&
ic.ifc_len > sizeof buf) {
ic.ifc_ifcu.ifcu_buf = dmalloc ((size_t)ic.ifc_len, MDL);
if (!ic.ifc_ifcu.ifcu_buf)
log_fatal ("Can't allocate SIOCGIFCONF buffer.");
goto gifconf_again;
}
/* If we already have a list of interfaces, and we're running as
a DHCP server, the interfaces were requested. */
if (interfaces && (state == DISCOVER_SERVER ||
@ -270,6 +282,10 @@ void discover_interfaces (state)
}
}
/* If we allocated a buffer, free it. */
if (ic.ifc_ifcu.ifcu_buf != buf)
dfree (ic.ifc_ifcu.ifcu_buf, MDL);
#if defined (LINUX_SLASHPROC_DISCOVERY)
/* On Linux, interfaces that don't have IP addresses don't
show up in the SIOCGIFCONF syscall. This only matters for
@ -496,12 +512,30 @@ void discover_interfaces (state)
/* We must have a subnet declaration for each interface. */
if (!tmp -> shared_network && (state == DISCOVER_SERVER)) {
log_error ("%s", "");
log_error ("No subnet declaration for %s (%s).",
tmp -> name, inet_ntoa (foo.sin_addr));
log_error ("Please write a subnet declaration in %s",
"your dhcpd.conf file for the");
log_fatal ("network segment to which interface %s %s",
tmp -> name, "is attached.");
if (supports_multiple_interfaces (tmp)) {
log_error ("Ignoring requests on %s.",
tmp -> name);
log_error ("If this is not what you want, %s",
"please write");
log_error ("a subnet declaration in your %s",
"dhcpd.conf file for");
log_error ("the network segment to %s %s %s",
"which interface",
tmp -> name, "is attached.");
goto next;
} else {
log_error ("You must write a subnet %s",
" declaration for this");
log_error ("subnet. You cannot prevent %s",
"the DHCP server");
log_error ("from listening on this subnet %s",
"because your");
log_fatal ("operating system does not %s.",
"support this capability");
}
}
/* Find subnets that don't have valid interface
@ -522,6 +556,7 @@ void discover_interfaces (state)
/* Register the interface... */
if_register_receive (tmp);
if_register_send (tmp);
wifcount++;
#if defined (HAVE_SETFD)
if (fcntl (tmp -> rfdesc, F_SETFD, 1) < 0)
log_error ("Can't set close-on-exec on %s: %m",
@ -532,6 +567,7 @@ void discover_interfaces (state)
tmp -> name);
}
#endif
next:
interface_dereference (&tmp, MDL);
if (next)
interface_reference (&tmp, next, MDL);
@ -552,6 +588,11 @@ void discover_interfaces (state)
close (sock);
if (state == DISCOVER_SERVER && wifcount == 0) {
log_info ("%s", "");
log_fatal ("Not configured to listen on any interfaces!");
}
if (!setup_fallback) {
setup_fallback = 1;
maybe_setup_fallback ();

View File

@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: options.c,v 1.7 2000/07/08 20:53:57 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: options.c,v 1.8 2000/09/04 23:19:32 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#define DHCP_OPTION_DATA
@ -205,7 +205,7 @@ int cons_options (inpacket, outpacket, lease, mms, in_options, cfg_options,
int mms;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope *scope;
struct binding_scope **scope;
int overload; /* Overload flags that may be set. */
int terminate;
int bootpp;
@ -420,7 +420,7 @@ int store_options (buffer, buflen, packet, lease,
struct lease *lease;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope *scope;
struct binding_scope **scope;
unsigned *priority_list;
int priority_len;
unsigned first_cutoff, second_cutoff;
@ -751,7 +751,7 @@ int hashed_option_get (result, universe, packet, lease,
struct option_state *in_options;
struct option_state *cfg_options;
struct option_state *options;
struct binding_scope *scope;
struct binding_scope **scope;
unsigned code;
{
struct option_cache *oc;
@ -776,7 +776,7 @@ int agent_option_get (result, universe, packet, lease,
struct option_state *in_options;
struct option_state *cfg_options;
struct option_state *options;
struct binding_scope *scope;
struct binding_scope **scope;
unsigned code;
{
struct agent_options *ao;
@ -1154,7 +1154,7 @@ int store_option (result, universe, packet, lease,
struct lease *lease;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope *scope;
struct binding_scope **scope;
struct option_cache *oc;
{
struct data_string d1, d2;
@ -1201,7 +1201,7 @@ int option_space_encapsulate (result, packet, lease,
struct lease *lease;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope *scope;
struct binding_scope **scope;
struct data_string *name;
{
struct universe *u;
@ -1229,7 +1229,7 @@ int hashed_option_space_encapsulate (result, packet, lease,
struct lease *lease;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope *scope;
struct binding_scope **scope;
struct universe *universe;
{
pair p, *hash;
@ -1263,7 +1263,7 @@ int nwip_option_space_encapsulate (result, packet, lease,
struct lease *lease;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope *scope;
struct binding_scope **scope;
struct universe *universe;
{
pair p, *hash;
@ -1376,7 +1376,7 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
(struct lease *)0,
decoded_packet -> options,
(struct option_state *)0,
(struct binding_scope *)0,
(struct binding_scope **)0,
op, MDL);
if (dp.len > 0)
decoded_packet -> packet_type = dp.data [0];

View File

@ -43,11 +43,17 @@
#ifndef lint
static char copyright[] =
"$Id: tables.c,v 1.5 2000/06/10 18:17:20 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: tables.c,v 1.6 2000/09/04 23:19:33 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
/* XXXDPN: Moved here from hash.c, when it moved to libomapi. Not sure
where these really belong. */
HASH_FUNCTIONS (group, const char *, struct group_object)
HASH_FUNCTIONS (universe, const char *, struct universe)
HASH_FUNCTIONS (option, const char *, struct option)
/* DHCP Option names, formats and codes, from RFC1533.
Format codes:

View File

@ -73,9 +73,7 @@
#include "dhcp.h"
#include "statement.h"
#include "tree.h"
#include "hash.h"
#include "inet.h"
#include "auth.h"
#include "dhctoken.h"
#include <isc/result.h>
@ -261,7 +259,7 @@ struct lease {
unsigned char uid_buf [32];
char *hostname;
char *client_hostname;
struct binding_scope scope;
struct binding_scope *scope;
struct host_decl *host;
struct subnet *subnet;
struct pool *pool;
@ -374,6 +372,7 @@ struct lease_state {
#define SV_LIMITED_BROADCAST_ADDRESS 33
#define SV_REMOTE_PORT 34
#define SV_LOCAL_ADDRESS 35
#define SV_OMAPI_KEY 36
#if !defined (DEFAULT_DEFAULT_LEASE_TIME)
# define DEFAULT_DEFAULT_LEASE_TIME 43200
@ -590,13 +589,6 @@ struct class {
struct executable_statement *statements;
};
struct tsig_key {
int refcnt;
char *name;
char *algorithm;
struct data_string key;
};
/* DHCP client lease structure... */
struct client_lease {
struct client_lease *next; /* Next lease in list. */
@ -605,7 +597,7 @@ struct client_lease {
char *server_name; /* Name of boot server. */
char *filename; /* Name of file we're supposed to boot. */
struct string_list *medium; /* Network medium. */
struct tsig_key *key; /* Key used in basic DHCP authentication. */
struct auth_key *key; /* Key used in basic DHCP authentication. */
unsigned int is_static : 1; /* If set, lease is from config file. */
unsigned int is_bootp: 1; /* If set, lease was aquired with BOOTP. */
@ -820,7 +812,7 @@ struct dns_zone {
char *name;
struct option_cache *primary;
struct option_cache *secondary;
struct tsig_key *key;
struct auth_key *key;
};
/* Bitmask of dhcp option codes. */
@ -892,11 +884,11 @@ int parse_options PROTO ((struct packet *));
int parse_option_buffer PROTO ((struct packet *, unsigned char *, unsigned));
int cons_options PROTO ((struct packet *, struct dhcp_packet *, struct lease *,
int, struct option_state *, struct option_state *,
struct binding_scope *,
struct binding_scope **,
int, int, int, struct data_string *));
int store_options PROTO ((unsigned char *, unsigned, struct packet *,
struct lease *, struct option_state *,
struct option_state *, struct binding_scope *,
struct option_state *, struct binding_scope **,
unsigned *, int, unsigned, unsigned, int));
const char *pretty_print_option PROTO ((unsigned int, const unsigned char *,
unsigned, int, int));
@ -906,12 +898,12 @@ void do_packet PROTO ((struct interface_info *,
int hashed_option_get PROTO ((struct data_string *, struct universe *,
struct packet *, struct lease *,
struct option_state *, struct option_state *,
struct option_state *, struct binding_scope *,
struct option_state *, struct binding_scope **,
unsigned));
int agent_option_get PROTO ((struct data_string *, struct universe *,
struct packet *, struct lease *,
struct option_state *, struct option_state *,
struct option_state *, struct binding_scope *,
struct option_state *, struct binding_scope **,
unsigned));
void hashed_option_set PROTO ((struct universe *, struct option_state *,
struct option_cache *,
@ -939,24 +931,24 @@ int agent_option_state_dereference PROTO ((struct universe *,
int store_option PROTO ((struct data_string *,
struct universe *, struct packet *, struct lease *,
struct option_state *, struct option_state *,
struct binding_scope *, struct option_cache *));
struct binding_scope **, struct option_cache *));
int option_space_encapsulate PROTO ((struct data_string *,
struct packet *, struct lease *,
struct option_state *,
struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct data_string *));
int hashed_option_space_encapsulate PROTO ((struct data_string *,
struct packet *, struct lease *,
struct option_state *,
struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct universe *));
int nwip_option_space_encapsulate PROTO ((struct data_string *,
struct packet *, struct lease *,
struct option_state *,
struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct universe *));
/* dhcpd.c */
@ -1071,7 +1063,7 @@ int parse_warn (struct parse *, const char *, ...)
__attribute__((__format__(__printf__,2,3)));
/* tree.c */
extern struct binding_scope global_scope;
extern struct binding_scope *global_scope;
pair cons PROTO ((caddr_t, pair));
int make_const_option_cache PROTO ((struct option_cache **, struct buffer **,
u_int8_t *, unsigned, struct option *,
@ -1092,7 +1084,7 @@ int option_cache PROTO ((struct option_cache **, struct data_string *,
struct expression *, struct option *));
int evaluate_expression (struct binding_value **, struct packet *,
struct lease *, struct option_state *,
struct option_state *, struct binding_scope *,
struct option_state *, struct binding_scope **,
struct expression *);
int binding_value_dereference (struct binding_value **, const char *, int);
int fundef_dereference (struct fundef **, const char *, int);
@ -1100,43 +1092,44 @@ int fundef_dereference (struct fundef **, const char *, int);
int evaluate_dns_expression PROTO ((ns_updrec **, struct packet *,
struct lease *, struct option_state *,
struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct expression *));
#endif
int evaluate_boolean_expression PROTO ((int *,
struct packet *, struct lease *,
struct option_state *,
struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct expression *));
int evaluate_data_expression PROTO ((struct data_string *,
struct packet *, struct lease *,
struct option_state *,
struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct expression *));
int evaluate_numeric_expression PROTO
((unsigned long *, struct packet *, struct lease *,
struct option_state *, struct option_state *, struct binding_scope *,
struct option_state *, struct option_state *,
struct binding_scope **,
struct expression *));
int evaluate_option_cache PROTO ((struct data_string *,
struct packet *, struct lease *,
struct option_state *, struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct option_cache *,
const char *, int));
int evaluate_boolean_option_cache PROTO ((int *,
struct packet *, struct lease *,
struct option_state *,
struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct option_cache *,
const char *, int));
int evaluate_boolean_expression_result PROTO ((int *,
struct packet *, struct lease *,
struct option_state *,
struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct expression *));
void expression_dereference PROTO ((struct expression **, const char *, int));
int is_dns_expression PROTO ((struct expression *));
@ -1166,7 +1159,8 @@ void ack_lease PROTO ((struct packet *, struct lease *,
unsigned int, TIME, char *, int));
void dhcp_reply PROTO ((struct lease *));
int find_lease PROTO ((struct lease **, struct packet *,
struct shared_network *, int *, const char *, int));
struct shared_network *, int *, int *,
const char *, int));
int mockup_lease PROTO ((struct lease **, struct packet *,
struct shared_network *,
struct host_decl *));
@ -1210,8 +1204,6 @@ int group_allocate (struct group **, const char *, int);
int group_reference (struct group **, struct group *, const char *, int);
int group_dereference (struct group **, const char *, int);
struct dhcp_packet *new_dhcp_packet PROTO ((const char *, int));
struct hash_table *new_hash_table PROTO ((int, const char *, int));
struct hash_bucket *new_hash_bucket PROTO ((const char *, int));
struct protocol *new_protocol PROTO ((const char *, int));
struct lease_state *new_lease_state PROTO ((const char *, int));
struct domain_search_list *new_domain_search_list PROTO ((const char *, int));
@ -1228,13 +1220,9 @@ void free_domain_search_list PROTO ((struct domain_search_list *,
const char *, int));
void free_lease_state PROTO ((struct lease_state *, const char *, int));
void free_protocol PROTO ((struct protocol *, const char *, int));
void free_hash_bucket PROTO ((struct hash_bucket *, const char *, int));
void free_hash_table PROTO ((struct hash_table *, const char *, int));
void free_dhcp_packet PROTO ((struct dhcp_packet *, const char *, int));
struct client_lease *new_client_lease PROTO ((const char *, int));
void free_client_lease PROTO ((struct client_lease *, const char *, int));
struct auth_key *new_auth_key PROTO ((unsigned, const char *, int));
void free_auth_key PROTO ((struct auth_key *, const char *, int));
struct permit *new_permit PROTO ((const char *, int));
void free_permit PROTO ((struct permit *, const char *, int));
pair new_pair PROTO ((const char *, int));
@ -1286,13 +1274,12 @@ int packet_reference PROTO ((struct packet **,
int packet_dereference PROTO ((struct packet **, const char *, int));
int binding_scope_allocate PROTO ((struct binding_scope **,
const char *, int));
int binding_scope_reference PROTO ((struct binding_scope **,
struct binding_scope *,
const char *, int));
int dns_zone_allocate PROTO ((struct dns_zone **, const char *, int));
int dns_zone_reference PROTO ((struct dns_zone **,
struct dns_zone *, const char *, int));
int tsig_key_allocate PROTO ((struct tsig_key **, const char *, int));
int tsig_key_reference PROTO ((struct tsig_key **,
struct tsig_key *, const char *, int));
int tsig_key_dereference PROTO ((struct tsig_key **, const char *, int));
/* print.c */
char *print_hw_addr PROTO ((int, int, unsigned char *));
@ -1358,6 +1345,7 @@ isc_result_t fallback_discard PROTO ((omapi_object_t *));
#if defined (USE_SOCKET_SEND)
int can_unicast_without_arp PROTO ((struct interface_info *));
int can_receive_unicast_unconfigured PROTO ((struct interface_info *));
int supports_multiple_interfaces (struct interface_info *);
void maybe_setup_fallback PROTO ((void));
#endif
@ -1385,6 +1373,7 @@ ssize_t receive_packet PROTO ((struct interface_info *,
#if defined (USE_BPF_SEND)
int can_unicast_without_arp PROTO ((struct interface_info *));
int can_receive_unicast_unconfigured PROTO ((struct interface_info *));
int supports_multiple_interfaces (struct interface_info *);
void maybe_setup_fallback PROTO ((void));
#endif
@ -1412,6 +1401,7 @@ ssize_t receive_packet PROTO ((struct interface_info *,
#if defined (USE_LPF_SEND)
int can_unicast_without_arp PROTO ((struct interface_info *));
int can_receive_unicast_unconfigured PROTO ((struct interface_info *));
int supports_multiple_interfaces (struct interface_info *);
void maybe_setup_fallback PROTO ((void));
#endif
@ -1440,6 +1430,7 @@ ssize_t receive_packet PROTO ((struct interface_info *,
#if defined (USE_NIT_SEND)
int can_unicast_without_arp PROTO ((struct interface_info *));
int can_receive_unicast_unconfigured PROTO ((struct interface_info *));
int supports_multiple_interfaces (struct interface_info *);
void maybe_setup_fallback PROTO ((void));
#endif
@ -1478,6 +1469,7 @@ ssize_t send_packet PROTO ((struct interface_info *,
struct sockaddr_in *, struct hardware *));
int can_unicast_without_arp PROTO ((struct interface_info *));
int can_receive_unicast_unconfigured PROTO ((struct interface_info *));
int supports_multiple_interfaces (struct interface_info *);
void maybe_setup_fallback PROTO ((void));
#endif
@ -1530,21 +1522,6 @@ void remove_protocol PROTO ((struct protocol *));
OMAPI_OBJECT_ALLOC_DECL (interface,
struct interface_info, dhcp_type_interface)
/* hash.c */
struct hash_table *new_hash PROTO ((hash_reference, hash_dereference, int));
void add_hash PROTO ((struct hash_table *,
const unsigned char *, unsigned, hashed_object_t *,
const char *, int));
void delete_hash_entry PROTO ((struct hash_table *, const unsigned char *,
unsigned, const char *, int));
int hash_lookup PROTO ((hashed_object_t **, struct hash_table *,
const unsigned char *, unsigned, const char *, int));
int hash_foreach (struct hash_table *, hash_foreach_func);
int casecmp (const void *s, const void *t, unsigned long len);
HASH_FUNCTIONS_DECL (group, const char *, struct group_object)
HASH_FUNCTIONS_DECL (universe, const char *, struct universe)
HASH_FUNCTIONS_DECL (option, const char *, struct option)
/* tables.c */
extern struct universe dhcp_universe;
extern struct universe nwip_universe;
@ -1557,6 +1534,9 @@ struct universe **universes;
extern struct hash_table *universe_hash;
void initialize_common_option_spaces PROTO ((void));
struct universe *config_universe;
HASH_FUNCTIONS_DECL (group, const char *, struct group_object)
HASH_FUNCTIONS_DECL (universe, const char *, struct universe)
HASH_FUNCTIONS_DECL (option, const char *, struct option)
/* stables.c */
#if defined (FAILOVER_PROTOCOL)
@ -1575,22 +1555,6 @@ extern struct universe server_universe;
extern struct option server_options [256];
void initialize_server_option_spaces PROTO ((void));
/* convert.c */
u_int32_t getULong PROTO ((const unsigned char *));
int32_t getLong PROTO ((const unsigned char *));
u_int32_t getUShort PROTO ((const unsigned char *));
int32_t getShort PROTO ((const unsigned char *));
u_int32_t getUChar PROTO ((const unsigned char *));
void putULong PROTO ((unsigned char *, u_int32_t));
void putLong PROTO ((unsigned char *, int32_t));
void putUShort PROTO ((unsigned char *, u_int32_t));
void putShort PROTO ((unsigned char *, int32_t));
void putUChar PROTO ((unsigned char *, u_int32_t));
int converted_length PROTO ((const unsigned char *,
unsigned int, unsigned int));
int binary_to_ascii PROTO ((unsigned char *, const unsigned char *,
unsigned int, unsigned int));
/* inet.c */
struct iaddr subnet_number PROTO ((struct iaddr, struct iaddr));
struct iaddr ip_addr PROTO ((struct iaddr, struct iaddr, u_int32_t));
@ -1649,7 +1613,7 @@ void client_envadd (struct client_state *,
const char *, const char *, const char *, ...)
__attribute__((__format__(__printf__,4,5)));
struct client_lease *packet_to_lease PROTO ((struct packet *));
struct client_lease *packet_to_lease (struct packet *, struct client_state *);
void go_daemon PROTO ((void));
void write_client_pid_file PROTO ((void));
void client_location_changed PROTO ((void));
@ -1789,8 +1753,6 @@ void tkey_free (ns_tsig_key **);
#endif
isc_result_t enter_dns_zone (struct dns_zone *);
isc_result_t dns_zone_lookup (struct dns_zone **, const char *);
isc_result_t enter_tsig_key (struct tsig_key *);
isc_result_t tsig_key_lookup (struct tsig_key **, const char *);
int dns_zone_dereference PROTO ((struct dns_zone **, const char *, int));
#if defined (NSUPDATE)
ns_rcode find_cached_zone (const char *, ns_class, char *,
@ -1800,7 +1762,6 @@ void forget_zone (struct dns_zone **);
void repudiate_zone (struct dns_zone **);
#endif /* NSUPDATE */
HASH_FUNCTIONS_DECL (dns_zone, const char *, struct dns_zone)
HASH_FUNCTIONS_DECL (tsig_key, const char *, struct tsig_key)
/* resolv.c */
extern char path_resolv_conf [];
@ -1834,16 +1795,18 @@ int unbill_class PROTO ((struct lease *, struct class *));
int bill_class PROTO ((struct lease *, struct class *));
/* execute.c */
int execute_statements PROTO ((struct packet *,
int execute_statements PROTO ((struct binding_value **result,
struct packet *,
struct lease *,
struct option_state *, struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct executable_statement *));
void execute_statements_in_scope PROTO ((struct packet *,
void execute_statements_in_scope PROTO ((struct binding_value **result,
struct packet *,
struct lease *,
struct option_state *,
struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct group *, struct group *));
int executable_statement_dereference PROTO ((struct executable_statement **,
const char *, int));
@ -1851,13 +1814,9 @@ void write_statements (FILE *, struct executable_statement *, int);
int find_matching_case (struct executable_statement **,
struct packet *, struct lease *,
struct option_state *, struct option_state *,
struct binding_scope *,
struct binding_scope **,
struct expression *, struct executable_statement *);
/* auth.c */
void enter_auth_key PROTO ((struct data_string *, struct auth_key *));
const struct auth_key *auth_key_lookup PROTO ((struct data_string *));
/* comapi.c */
extern omapi_object_type_t *dhcp_type_interface;
extern omapi_object_type_t *dhcp_type_group;
@ -2226,13 +2185,17 @@ isc_result_t dhcp_failover_state_signal PROTO ((omapi_object_t *,
const char *, va_list));
isc_result_t dhcp_failover_state_transition (dhcp_failover_state_t *,
const char *);
isc_result_t dhcp_failover_set_service_state (dhcp_failover_state_t *state);
isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *,
enum failover_state);
isc_result_t dhcp_failover_peer_state_changed (dhcp_failover_state_t *,
failover_message_t *);
int dhcp_failover_pool_rebalance (dhcp_failover_state_t *);
int dhcp_failover_pool_check (struct pool *);
int dhcp_failover_state_pool_check (dhcp_failover_state_t *);
void dhcp_failover_timeout (void *);
void dhcp_failover_send_contact (void *);
isc_result_t dhcp_failover_send_state (dhcp_failover_state_t *);
isc_result_t dhcp_failover_send_updates (dhcp_failover_state_t *);
int dhcp_failover_queue_update (struct lease *, int);
void dhcp_failover_ack_queue_remove (dhcp_failover_state_t *, struct lease *);
@ -2242,6 +2205,8 @@ isc_result_t dhcp_failover_state_set_value PROTO ((omapi_object_t *,
omapi_typed_data_t *));
void dhcp_failover_keepalive (void *);
void dhcp_failover_reconnect (void *);
void dhcp_failover_startup_timeout (void *);
void dhcp_failover_link_startup_timeout (void *);
void dhcp_failover_listener_restart (void *);
isc_result_t dhcp_failover_state_get_value PROTO ((omapi_object_t *,
omapi_object_t *,
@ -2262,6 +2227,8 @@ isc_result_t dhcp_failover_state_remove PROTO ((omapi_object_t *,
int dhcp_failover_state_match (dhcp_failover_state_t *, u_int8_t *, unsigned);
const char *dhcp_failover_reject_reason_print (int);
const char *dhcp_failover_state_name_print (enum failover_state);
const char *dhcp_failover_message_name (unsigned);
const char *dhcp_failover_option_name (unsigned);
failover_option_t *dhcp_failover_option_printf (unsigned, char *,
unsigned *,
unsigned,
@ -2284,17 +2251,29 @@ isc_result_t dhcp_failover_send_bind_ack (dhcp_failover_state_t *,
int, const char *);
isc_result_t dhcp_failover_send_poolreq (dhcp_failover_state_t *);
isc_result_t dhcp_failover_send_poolresp (dhcp_failover_state_t *, int);
isc_result_t dhcp_failover_send_update_request (dhcp_failover_state_t *);
isc_result_t dhcp_failover_send_update_request_all (dhcp_failover_state_t *);
isc_result_t dhcp_failover_send_update_done (dhcp_failover_state_t *);
isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *,
failover_message_t *);
isc_result_t dhcp_failover_process_bind_ack (dhcp_failover_state_t *,
failover_message_t *);
isc_result_t dhcp_failover_generate_update_queue (dhcp_failover_state_t *,
int);
isc_result_t dhcp_failover_process_update_request (dhcp_failover_state_t *,
failover_message_t *);
isc_result_t dhcp_failover_process_update_request_all (dhcp_failover_state_t *,
failover_message_t *);
isc_result_t dhcp_failover_process_update_done (dhcp_failover_state_t *,
failover_message_t *);
void dhcp_failover_recover_done (void *);
void failover_print PROTO ((char *, unsigned *, unsigned, const char *));
void update_partner PROTO ((struct lease *));
int load_balance_mine (struct packet *, dhcp_failover_state_t *);
binding_state_t binding_state_transition_check (struct lease *,
dhcp_failover_state_t *,
binding_state_t);
int lease_mine_to_extend (struct lease *);
int lease_mine_to_reallocate (struct lease *);
OMAPI_OBJECT_ALLOC_DECL (dhcp_failover_state, dhcp_failover_state_t,
dhcp_type_failover_state)

View File

@ -158,6 +158,9 @@ typedef struct {
#define DHCP_FAILOVER_MAX_MESSAGE_SIZE 2048
/* Failover server flags. */
#define FTF_STARTUP 1
typedef struct {
u_int8_t type;
@ -214,9 +217,10 @@ typedef struct {
u_int32_t xid;
} dhcp_failover_link_t;
typedef struct {
typedef struct _dhcp_failover_listener {
OMAPI_OBJECT_PREAMBLE;
unsigned local_port;
struct _dhcp_failover_listener *next;
omapi_addr_t address;
} dhcp_failover_listener_t;
#endif /* FAILOVER_PROTOCOL */
@ -226,31 +230,55 @@ enum failover_state {
partner_down,
normal,
communications_interrupted,
potential_conflict_nic,
resolution_interrupted,
potential_conflict,
recover
recover,
recover_done,
shut_down,
paused,
startup
};
/* Service states are simplifications of failover states, particularly
useful because the startup state isn't actually implementable as a
seperate failover state without maintaining a state stack. */
enum service_state {
unknown_service_state,
cooperating,
not_cooperating,
service_partner_down,
not_responding,
service_startup
};
#if defined (FAILOVER_PROTOCOL)
typedef struct _dhcp_failover_config {
struct option_cache *address;
int port;
u_int32_t max_flying_updates;
enum failover_state state;
TIME stos;
u_int32_t max_response_delay;
} dhcp_failover_config_t;
typedef struct _dhcp_failover_state {
OMAPI_OBJECT_PREAMBLE;
struct _dhcp_failover_state *next;
char *name; /* Name of this failover instance. */
struct option_cache *address; /* Partner's IP address or hostname. */
int port; /* Partner's TCP port. */
struct option_cache *server_addr; /* IP address on which to listen. */
dhcp_failover_config_t me; /* My configuration. */
dhcp_failover_config_t partner; /* Partner's configuration. */
enum failover_state saved_state; /* Saved state during startup. */
struct data_string server_identifier; /* Server identifier (IP addr) */
int listen_port; /* Port on which to listen. */
u_int32_t max_flying_updates;
u_int32_t mclt;
u_int8_t *hba; /* Hash bucket array for load balancing. */
int load_balance_max_secs;
enum failover_state partner_state;
TIME partner_stos;
enum failover_state my_state;
TIME my_stos;
enum service_state service_state;
const char *nrr; /* Printable reason why we're in the
not_responding service state (empty
string if we are responding. */
dhcp_failover_link_t *link_to_peer; /* Currently-established link
to peer. */
@ -263,13 +291,6 @@ typedef struct _dhcp_failover_state {
TIME last_timestamp_received; /* The last timestamp we sent that
has been returned by our partner. */
TIME skew; /* The skew between our clock and our partner's. */
u_int32_t max_transmit_idle; /* Always send a poll if we haven't sent
some other packet more recently than
this. */
u_int32_t max_response_delay; /* If the returned timestamp on the
last packet we received is older
than this, communications have been
interrupted. */
struct lease *update_queue_head; /* List of leases we haven't sent
to peer. */
struct lease *update_queue_tail;
@ -277,6 +298,9 @@ typedef struct _dhcp_failover_state {
struct lease *ack_queue_head; /* List of lease updates the peer
hasn't yet acked. */
struct lease *ack_queue_tail;
struct lease *send_update_done; /* When we get a BNDACK for this
lease, send an UPDDONE message. */
int cur_unacked_updates; /* Number of updates we've sent
that have not yet been acked. */
} dhcp_failover_state_t;

View File

@ -85,7 +85,7 @@
/* Define this if you want DHCP failover protocol support in the DHCP
server. */
/* #define FAILOVER_PROTOCOL */
#define FAILOVER_PROTOCOL
/* Define this if you want DNS update functionality to be available. */

View File

@ -1,3 +1,3 @@
/* Current version of ISC DHCP Distribution. */
#define DHCP_VERSION "V3.0b2pl0-20000719"
#define DHCP_VERSION "V3.0b2pl2"

View File

@ -206,8 +206,9 @@ isc_result_t omapi_wait_for_completion (omapi_object_t *object,
if (waiter -> inner)
omapi_object_dereference (&waiter -> inner, MDL);
status = waiter -> waitstatus;
omapi_waiter_dereference (&waiter, MDL);
return ISC_R_SUCCESS;
return status;;
}
isc_result_t omapi_one_dispatch (omapi_object_t *wo,
@ -492,6 +493,14 @@ isc_result_t omapi_waiter_signal_handler (omapi_object_t *h,
if (!strcmp (name, "ready")) {
waiter = (omapi_waiter_object_t *)h;
waiter -> ready = 1;
waiter -> waitstatus = ISC_R_SUCCESS;
return ISC_R_SUCCESS;
}
if (!strcmp (name, "status")) {
waiter = (omapi_waiter_object_t *)h;
waiter -> ready = 1;
waiter -> waitstatus = va_arg (ap, isc_result_t);
return ISC_R_SUCCESS;
}

View File

@ -43,7 +43,7 @@
#ifndef lint
static char ocopyright[] =
"$Id: dhcrelay.c,v 1.5 2000/07/20 05:59:20 mellon Exp $ Copyright (c) 1997-2000 Internet Software Consortium. All rights reserved.\n";
"$Id: dhcrelay.c,v 1.6 2000/09/04 23:19:36 mellon Exp $ Copyright (c) 1997-2000 Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -107,12 +107,10 @@ struct server_list {
struct sockaddr_in to;
} *servers;
static char copyright [] =
"Copyright 1997, 1998, 1999 Internet Software Consortium.";
static char copyright [] = "Copyright 1997-2000 Internet Software Consortium.";
static char arr [] = "All rights reserved.";
static char message [] = "Internet Software Consortium DHCP Relay Agent";
static char contrib [] = "\nPlease contribute if you find this software useful.";
static char url [] = "For info, please visit http://www.isc.org/dhcp-contrib.html\n";
static char url [] = "For info, please visit http://www.isc.org/products/DHCP";
int main (argc, argv, envp)
int argc;
@ -223,7 +221,6 @@ int main (argc, argv, envp)
log_info ("%s %s", message, DHCP_VERSION);
log_info (copyright);
log_info (arr);
log_info (contrib);
log_info (url);
} else {
quiet = 0;

View File

@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: bootp.c,v 1.12 2000/06/10 18:17:21 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: bootp.c,v 1.13 2000/09/04 23:19:37 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -93,7 +93,7 @@ void bootp (packet)
packet -> raw -> hlen, MDL);
lease = (struct lease *)0;
find_lease (&lease, packet, packet -> shared_network, 0, MDL);
find_lease (&lease, packet, packet -> shared_network, 0, 0, MDL);
/* Find an IP address in the host_decl that matches the
specified network. */
@ -155,20 +155,23 @@ void bootp (packet)
option_state_allocate (&options, MDL);
/* Execute the subnet statements. */
execute_statements_in_scope (packet, lease, packet -> options, options,
execute_statements_in_scope ((struct binding_value **)0,
packet, lease, packet -> options, options,
&lease -> scope, lease -> subnet -> group,
(struct group *)0);
/* Execute statements from class scopes. */
for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope
(packet, lease, packet -> options, options,
((struct binding_value **)0,
packet, lease, packet -> options, options,
&lease -> scope, packet -> classes [i - 1] -> group,
lease -> subnet -> group);
}
/* Execute the host statements. */
execute_statements_in_scope (packet, lease, packet -> options, options,
execute_statements_in_scope ((struct binding_value **)0,
packet, lease, packet -> options, options,
&lease -> scope,
hp -> group, subnet -> group);
@ -315,7 +318,8 @@ void bootp (packet)
}
/* Execute the commit statements, if there are any. */
execute_statements (packet, lease, packet -> options,
execute_statements ((struct binding_value **)0,
packet, lease, packet -> options,
options, &lease -> scope, lease -> on_commit);
/* We're done with the option state. */

View File

@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: confpars.c,v 1.5 2000/07/08 20:52:19 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: confpars.c,v 1.6 2000/09/04 23:19:37 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -584,12 +584,6 @@ int parse_statement (cfile, group, type, host_decl, declaration)
return declaration;
}
if (declaration) {
parse_warn (cfile,
"parameters not allowed after first declaration.");
return 1;
}
return 0;
}
@ -610,8 +604,7 @@ void parse_failover_peer (cfile, group, type)
int i;
struct expression *expr;
isc_result_t status;
struct option_cache **paddr;
int *pport;
dhcp_failover_config_t *cp;
token = next_token (&val, cfile);
if (token != PEER) {
@ -685,12 +678,14 @@ void parse_failover_peer (cfile, group, type)
peer -> name = name;
/* Set the initial state. */
peer -> my_state = communications_interrupted;
peer -> my_stos = cur_time;
peer -> partner_state = unknown_state;
peer -> partner_stos = cur_time;
peer -> me.state = potential_conflict;
peer -> me.stos = cur_time;
peer -> partner.state = unknown_state;
peer -> partner.stos = cur_time;
do {
cp = &peer -> me;
peer:
token = next_token (&val, cfile);
switch (token) {
case RBRACE:
@ -709,54 +704,33 @@ void parse_failover_peer (cfile, group, type)
break;
case PEER:
token = next_token (&val, cfile);
switch (token) {
case ADDRESS:
paddr = &peer -> address;
goto doaddr;
case PORT:
pport = &peer -> port;
goto doport;
default:
parse_warn (cfile,
"expecting 'address' or 'port'");
skip_to_rbrace (cfile, 1);
dhcp_failover_state_dereference (&peer, MDL);
return;
}
break;
cp = &peer -> partner;
goto peer;
case ADDRESS:
paddr = &peer -> server_addr;
doaddr:
expr = (struct expression *)0;
if (!parse_ip_addr_or_hostname (&expr, cfile, 0)) {
skip_to_rbrace (cfile, 1);
dhcp_failover_state_dereference (&peer, MDL);
return;
}
option_cache (paddr, (struct data_string *)0, expr,
option_cache (&cp -> address,
(struct data_string *)0, expr,
(struct option *)0);
expression_dereference (&expr, MDL);
break;
case PORT:
pport = &peer -> listen_port;
doport:
token = next_token (&val, cfile);
if (token != NUMBER) {
parse_warn (cfile, "expecting number");
skip_to_rbrace (cfile, 1);
}
*pport = atoi (val);
cp -> port = atoi (val);
break;
case MAX_TRANSMIT_IDLE:
tp = &peer -> max_transmit_idle;
goto parse_idle;
case MAX_RESPONSE_DELAY:
tp = &peer -> max_response_delay;
tp = &cp -> max_response_delay;
parse_idle:
token = next_token (&val, cfile);
if (token != NUMBER) {
@ -769,7 +743,7 @@ void parse_failover_peer (cfile, group, type)
break;
case MAX_UNACKED_UPDATES:
tp = &peer -> max_flying_updates;
tp = &cp -> max_flying_updates;
goto parse_idle;
case MCLT:
@ -893,6 +867,7 @@ void parse_failover_state_declaration (struct parse *cfile,
const char *val;
char *name;
dhcp_failover_state_t *state;
dhcp_failover_config_t *cp;
if (!peer) {
token = next_token (&val, cfile);
@ -949,25 +924,21 @@ void parse_failover_state_declaration (struct parse *cfile,
case RBRACE:
break;
case MY:
cp = &state -> me;
do_state:
token = next_token (&val, cfile);
if (token != STATE) {
parse_warn (cfile, "expecting 'state'");
goto bogus;
}
parse_failover_state (cfile,
&state -> my_state,
&state -> my_stos);
&cp -> state, &cp -> stos);
break;
case PARTNER:
token = next_token (&val, cfile);
if (token != STATE) {
parse_warn (cfile, "expecting 'state'");
goto bogus;
}
parse_failover_state (cfile,
&state -> partner_state,
&state -> partner_stos);
break;
cp = &state -> partner;
goto do_state;
default:
bogus:
parse_warn (cfile, "expecting state setting.");
@ -991,6 +962,10 @@ void parse_failover_state (cfile, state, stos)
token = next_token (&val, cfile);
switch (token) {
case UNKNOWN_STATE:
state_in = unknown_state;
break;
case PARTNER_DOWN:
state_in = partner_down;
break;
@ -1003,11 +978,11 @@ void parse_failover_state (cfile, state, stos)
state_in = communications_interrupted;
break;
case POTENTIAL_CONFLICT:
state_in = potential_conflict;
case RESOLUTION_INTERRUPTED:
state_in = resolution_interrupted;
break;
case POTENTIAL_CONFLICT_NIC:
case POTENTIAL_CONFLICT:
state_in = potential_conflict;
break;
@ -1015,8 +990,20 @@ void parse_failover_state (cfile, state, stos)
state_in = recover;
break;
case UNKNOWN_STATE:
state_in = unknown_state;
case RECOVER_DONE:
state_in = recover_done;
break;
case SHUTDOWN:
state_in = shut_down;
break;
case PAUSED:
state_in = paused;
break;
case STARTUP:
state_in = startup;
break;
default:
@ -1491,11 +1478,14 @@ void parse_host_declaration (cfile, group)
if (host -> named_group && host -> named_group -> group) {
if (host -> group -> statements ||
(host -> group -> authoritative !=
host -> named_group -> group -> authoritative))
host -> named_group -> group -> authoritative)) {
if (host -> group -> next)
group_dereference (&host -> group -> next,
MDL);
group_reference (&host -> group -> next,
host -> named_group -> group,
MDL);
else {
} else {
group_dereference (&host -> group, MDL);
group_reference (&host -> group,
host -> named_group -> group,
@ -1613,8 +1603,8 @@ int parse_class_declaration (cp, cfile, group, type)
memset (&data, 0, sizeof data);
if (!parse_cshl (&data, cfile)) {
class_dereference (&pc, MDL);
}
return 0;
}
} else {
parse_warn (cfile, "Expecting string or hex list.");
class_dereference (&pc, MDL);
@ -1754,6 +1744,7 @@ int parse_class_declaration (cp, cfile, group, type)
break;
}
token = next_token (&val, cfile);
class -> spawning = 1;
token = next_token (&val, cfile);
if (token != WITH) {
parse_warn (cfile,
@ -1761,7 +1752,6 @@ int parse_class_declaration (cp, cfile, group, type)
skip_to_semi (cfile);
break;
}
class -> spawning = 1;
submatch:
if (class -> submatch) {
parse_warn (cfile,
@ -2550,8 +2540,15 @@ int parse_lease_declaration (struct lease **lp, struct parse *cfile)
seenbit = 0;
special_set:
binding = find_binding (&lease -> scope, val);
if (lease -> scope)
binding = find_binding (lease -> scope, val);
else
binding = (struct binding *)0;
if (!binding) {
if (!lease -> scope)
if (!(binding_scope_allocate
(&lease -> scope, MDL)))
log_fatal ("no memory for scope");
binding = dmalloc (sizeof *binding, MDL);
if (!binding)
log_fatal ("No memory for lease %s.",
@ -2660,8 +2657,8 @@ int parse_lease_declaration (struct lease **lp, struct parse *cfile)
}
if (newbinding) {
binding -> next = lease -> scope.bindings;
lease -> scope.bindings = binding;
binding -> next = lease -> scope -> bindings;
lease -> scope -> bindings = binding;
}
parse_semi (cfile);
break;

View File

@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: dhcp.c,v 1.15 2000/07/08 20:52:19 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: dhcp.c,v 1.16 2000/09/04 23:19:38 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -114,7 +114,8 @@ void dhcpdiscover (packet, ms_nulltp)
dhcp_failover_state_t *peer;
#endif
find_lease (&lease, packet, packet -> shared_network, 0, MDL);
find_lease (&lease, packet, packet -> shared_network,
0, &allocatedp, MDL);
if (lease && lease -> client_hostname &&
db_printable (lease -> client_hostname))
@ -138,11 +139,16 @@ void dhcpdiscover (packet, ms_nulltp)
: packet -> interface -> name);
#if defined (FAILOVER_PROTOCOL)
if (lease && !lease_mine_to_extend (lease)) {
log_info ("%s: letting peer %s answer", msgbuf,
lease -> pool -> failover_peer -> name);
goto out;
}
if (lease && lease -> pool && lease -> pool -> failover_peer) {
peer = lease -> pool -> failover_peer;
if (peer -> service_state == not_responding ||
peer -> service_state == service_startup) {
log_info ("%s: not responding%s",
peer -> name, peer -> nrr);
goto out;
}
} else
peer = (dhcp_failover_state_t *)0;
#endif
/* Sourceless packets don't make sense here. */
@ -183,10 +189,8 @@ void dhcpdiscover (packet, ms_nulltp)
XXX be forced to switch servers (and IP addresses) just because
XXX of bad luck, when it's possible for it to get the address it
XXX is requesting. Not sure this is allowed. */
if (allocatedp && lease && lease -> pool &&
lease -> pool -> failover_peer) {
peer = lease -> pool -> failover_peer;
if (peer -> my_state == normal) {
if (allocatedp && peer) {
if (peer -> service_state == cooperating) {
if (!load_balance_mine (packet, peer)) {
log_debug ("%s: load balance to peer %s",
msgbuf, peer -> name);
@ -197,8 +201,8 @@ void dhcpdiscover (packet, ms_nulltp)
#endif
/* If it's an expired lease, get rid of any bindings. */
if (lease -> ends < cur_time && lease -> scope.bindings)
free_bindings (&lease -> scope, MDL);
if (lease -> ends < cur_time && lease -> scope)
binding_scope_dereference (&lease -> scope, MDL);
/* Set the lease to really expire in 2 minutes, unless it has
not yet expired, in which case leave its expiry time alone. */
@ -225,6 +229,9 @@ void dhcprequest (packet, ms_nulltp)
int status;
char msgbuf [1024]; /* XXX */
char *s;
#if defined (FAILOVER_PROTOCOL)
dhcp_failover_state_t *peer;
#endif
oc = lookup_option (&dhcp_universe, packet -> options,
DHO_DHCP_REQUESTED_ADDRESS);
@ -249,8 +256,9 @@ void dhcprequest (packet, ms_nulltp)
lease = (struct lease *)0;
if (find_subnet (&subnet, cip, MDL))
find_lease (&lease, packet,
subnet -> shared_network, &ours, MDL);
subnet -> shared_network, &ours, 0, MDL);
/* XXX consider using allocatedp arg to find_lease to see
XXX that this isn't a compliant DHCPREQUEST. */
if (lease && lease -> client_hostname &&
db_printable (lease -> client_hostname))
@ -275,11 +283,29 @@ void dhcprequest (packet, ms_nulltp)
: packet -> interface -> name);
#if defined (FAILOVER_PROTOCOL)
if (lease && !lease_mine_to_extend (lease)) {
log_info ("%s: letting peer %s answer", msgbuf,
lease -> pool -> failover_peer -> name);
goto out;
}
if (lease && lease -> pool && lease -> pool -> failover_peer) {
peer = lease -> pool -> failover_peer;
if (peer -> service_state == not_responding ||
peer -> service_state == service_startup) {
log_info ("%s: not responding%s",
peer -> name, peer -> nrr);
goto out;
}
if (peer -> service_state == cooperating) {
/* XXX */
/* If the client is in RENEWING state and sends
us a DHCPREQUEST, we're going to ignore it,
so it's going to have to fall back to REBINDING
state before it can get a response from the
other server. Ick. */
if (!load_balance_mine (packet, peer)) {
log_debug ("%s: load balance to peer %s",
msgbuf, peer -> name);
goto out;
}
}
} else
peer = (dhcp_failover_state_t *)0;
#endif
/* If a client on a given network REQUESTs a lease on an
@ -364,35 +390,6 @@ void dhcprequest (packet, ms_nulltp)
}
}
#if defined (FAILOVER_PROTOCOL) && 0 /* XXX this isn't the same as above! */
/* If we found a lease, but it belongs to a failover peer, and
the client is in the SELECTING state, ignore the request -
it's not ours. */
if (lease && (lease -> flags & PEER_IS_OWNER) &&
lookup_option (&dhcp_universe, packet -> options,
DHO_DHCP_SERVER_IDENTIFIER)) {
log_info ("%s: ignored (not for me)", msgbuf);
goto out;
}
/* If we found a lease, but it belongs to a failover peer, and
we are communicating with that peer, drop it. This really
shouldn't happen - if the peer is up, it should have renewed
the client while the client was in the RENEWING state. However,
there are cases where the client won't be able to get unicast
packets to its server, but will be able to get broadcast packets
to its server, so for now I'm taking that possibility into
account, although this should be revisited later. Oh, also if
the client comes up in the REBINDING state, we'll see it here,
and shouldn't respond until its server has had a chance at it. */
if (lease && (lease -> flags & PEER_IS_OWNER) &&
lease -> pool && lease -> pool -> failover_peer &&
lease -> pool -> failover_peer -> my_state == normal) {
log_info ("%s: ignored (not for me)", msgbuf);
goto out;
}
#endif /* FAILOVER_PROTOCOL */
/* If the address the client asked for is ours, but it wasn't
available for the client, NAK it. */
if (!lease && ours) {
@ -426,6 +423,7 @@ void dhcprelease (packet, ms_nulltp)
char *s;
char msgbuf [1024]; /* XXX */
/* DHCPRELEASE must not specify address in requested-address
option, but old protocol specs weren't explicit about this,
so let it go. */
@ -492,15 +490,21 @@ void dhcprelease (packet, ms_nulltp)
lease ? "" : "not ");
#if defined (FAILOVER_PROTOCOL)
if (lease && !lease_mine_to_extend (lease)) {
if (lease && lease -> pool && lease -> pool -> failover_peer) {
dhcp_failover_state_t *peer = lease -> pool -> failover_peer;
if (peer -> service_state == not_responding ||
peer -> service_state == service_startup) {
log_info ("%s: ignored%s",
peer -> name, peer -> nrr);
goto out;
}
/* DHCPRELEASE messages are unicast, so if the client
sent the DHCPRELEASE to us, it's not going to send it
to the peer. Not sure why this would happen, and
if it does happen I think we still have to change the
lease state.
lease state, so that's what we're doing.
XXX See what it says in the draft about this. */
log_info ("%s: peer %s holds lease",
msgbuf, lease -> pool -> failover_peer -> name);
}
#endif
@ -523,7 +527,7 @@ void dhcpdecline (packet, ms_nulltp)
struct option_cache *oc;
struct data_string data;
struct option_state *options = (struct option_state *)0;
int ignorep;
int ignorep = 0;
int i;
const char *status;
char *s;
@ -566,20 +570,12 @@ void dhcpdecline (packet, ms_nulltp)
? inet_ntoa (packet -> raw -> giaddr)
: packet -> interface -> name);
#if defined (FAILOVER_PROTOCOL)
if (lease && !lease_mine_to_extend (lease)) {
if (!ignorep)
log_info ("%s: peer %s holds lease", msgbuf,
lease -> pool -> failover_peer -> name);
goto out;
}
#endif
option_state_allocate (&options, MDL);
/* Execute statements in scope starting with the subnet scope. */
if (lease)
execute_statements_in_scope (packet, (struct lease *)0,
execute_statements_in_scope ((struct binding_value **)0,
packet, (struct lease *)0,
packet -> options, options,
&global_scope,
lease -> subnet -> group,
@ -588,7 +584,8 @@ void dhcpdecline (packet, ms_nulltp)
/* Execute statements in the class scopes. */
for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope
(packet, (struct lease *)0, packet -> options, options,
((struct binding_value **)0,
packet, (struct lease *)0, packet -> options, options,
&global_scope, packet -> classes [i - 1] -> group,
lease ? lease -> subnet -> group : (struct group *)0);
}
@ -599,14 +596,33 @@ void dhcpdecline (packet, ms_nulltp)
evaluate_boolean_option_cache (&ignorep, packet, lease,
packet -> options, options,
&lease -> scope, oc, MDL)) {
/* If we found a lease, mark it as unusable and complain. */
if (lease) {
abandon_lease (lease, "declined.");
status = "abandoned";
/* If we found a lease, mark it as unusable and complain. */
if (lease) {
#if defined (FAILOVER_PROTOCOL)
if (lease -> pool && lease -> pool -> failover_peer) {
dhcp_failover_state_t *peer =
lease -> pool -> failover_peer;
if (peer -> service_state == not_responding ||
peer -> service_state == service_startup) {
if (!ignorep)
log_info ("%s: ignored%s",
peer -> name, peer -> nrr);
goto out;
}
/* DHCPDECLINE messages are broadcast, so we can safely
ignore the DHCPDECLINE if the peer has the lease.
XXX Of course, at this point that information has been
lost. */
}
status = "not found";
#endif
abandon_lease (lease, "declined.");
status = "abandoned";
}
status = "not found";
} else
status = "ignored";
status = "ignored";
if (!ignorep)
log_info ("%s: %s", msgbuf, status);
@ -700,7 +716,8 @@ void dhcpinform (packet, ms_nulltp)
/* Execute statements in scope starting with the subnet scope. */
if (subnet)
execute_statements_in_scope (packet, (struct lease *)0,
execute_statements_in_scope ((struct binding_value **)0,
packet, (struct lease *)0,
packet -> options, options,
&global_scope, subnet -> group,
(struct group *)0);
@ -708,7 +725,8 @@ void dhcpinform (packet, ms_nulltp)
/* Execute statements in the class scopes. */
for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope
(packet, (struct lease *)0, packet -> options, options,
((struct binding_value **)0,
packet, (struct lease *)0, packet -> options, options,
&global_scope, packet -> classes [i - 1] -> group,
subnet ? subnet -> group : (struct group *)0);
}
@ -1231,7 +1249,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
}
/* Execute statements in scope starting with the subnet scope. */
execute_statements_in_scope (packet, lease,
execute_statements_in_scope ((struct binding_value **)0,
packet, lease,
packet -> options,
state -> options, &lease -> scope,
lease -> subnet -> group,
@ -1239,7 +1258,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
/* If the lease is from a pool, run the pool scope. */
if (lease -> pool)
execute_statements_in_scope (packet, lease,
execute_statements_in_scope ((struct binding_value **)0,
packet, lease,
packet -> options,
state -> options, &lease -> scope,
lease -> pool -> group,
@ -1248,7 +1268,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
/* Execute statements from class scopes. */
for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope
(packet, lease, packet -> options, state -> options,
((struct binding_value **)0,
packet, lease, packet -> options, state -> options,
&lease -> scope, packet -> classes [i - 1] -> group,
(lease -> pool
? lease -> pool -> group
@ -1258,7 +1279,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
/* If we have a host_decl structure, run the options associated
with its group. */
if (lease -> host)
execute_statements_in_scope (packet, lease, packet -> options,
execute_statements_in_scope ((struct binding_value **)0,
packet, lease, packet -> options,
state -> options, &lease -> scope,
lease -> host -> group,
(lease -> pool
@ -1444,8 +1466,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
}
/* If we are configured to do per-class billing, do it. */
if (have_billing_classes) {
if (have_billing_classes && !(lease -> flags & STATIC_LEASE)) {
/* See if the lease is currently being billed to a
class, and if so, whether or not it can continue to
be billed to that class. */
@ -1628,19 +1649,21 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
XXX What do we do in this case?
XXX should the expiry timer on the lease
XXX set tsfp and tstp to zero? */
if (lease -> tsfp == 0)
if (lease -> tsfp < cur_time) {
lease_time = peer -> mclt;
else
} else {
lease_time = (lease -> tsfp - cur_time
+ peer -> mclt);
}
} else {
if (cur_time + lease_time > lease -> tsfp &&
lease_time > peer -> mclt / 2)
lease_time > peer -> mclt / 2) {
lt -> tstp = (cur_time + lease_time +
peer -> mclt / 2);
else
} else {
lt -> tstp = (cur_time + lease_time +
lease_time / 2);
}
}
lt -> cltt = cur_time;
@ -1733,20 +1756,11 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
else
lease -> flags &= ~MS_NULL_TERMINATION;
/* If there are statements to execute when the lease is
committed, execute them. */
if (lease -> on_commit && (!offer || offer == DHCPACK)) {
execute_statements (packet, lease, packet -> options,
state -> options, &lease -> scope,
lease -> on_commit);
if (lease -> on_commit)
executable_statement_dereference (&lease -> on_commit,
MDL);
}
/* Save any bindings. */
lt -> scope.bindings = lease -> scope.bindings;
lease -> scope.bindings = (struct binding *)0;
if (lease -> scope) {
binding_scope_reference (&lt -> scope, lease -> scope, MDL);
binding_scope_dereference (&lease -> scope, MDL);
}
/* Replace the old lease hostname with the new one, if it's changed. */
oc = lookup_option (&dhcp_universe, packet -> options, DHO_HOST_NAME);
@ -1774,6 +1788,18 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
data_string_forget (&d1, MDL);
}
/* If there are statements to execute when the lease is
committed, execute them. */
if (lease -> on_commit && (!offer || offer == DHCPACK)) {
execute_statements ((struct binding_value **)0,
packet, lt, packet -> options,
state -> options, &lease -> scope,
lease -> on_commit);
if (lease -> on_commit)
executable_statement_dereference (&lease -> on_commit,
MDL);
}
/* Don't call supersede_lease on a mocked-up lease. */
if (lease -> flags & STATIC_LEASE) {
/* Copy the hardware address into the static lease
@ -2412,7 +2438,7 @@ void dhcp_reply (lease)
int find_lease (struct lease **lp,
struct packet *packet, struct shared_network *share, int *ours,
const char *file, int line)
int *allocatedp, const char *file, int line)
{
struct lease *uid_lease = (struct lease *)0;
struct lease *ip_lease = (struct lease *)0;
@ -2665,33 +2691,25 @@ int find_lease (struct lease **lp,
/* Toss ip_lease if it hasn't yet expired and doesn't belong to the
client. */
if (ip_lease &&
((ip_lease -> uid &&
(!have_client_identifier ||
ip_lease -> uid_len != client_identifier.len ||
memcmp (ip_lease -> uid, client_identifier.data,
ip_lease -> uid_len))) ||
(!ip_lease -> uid &&
(ip_lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
ip_lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
memcmp (&ip_lease -> hardware_addr.hbuf [1],
packet -> raw -> chaddr,
(unsigned)(ip_lease -> hardware_addr.hlen - 1)))))) {
(ip_lease -> uid ?
(!have_client_identifier ||
ip_lease -> uid_len != client_identifier.len ||
memcmp (ip_lease -> uid, client_identifier.data,
ip_lease -> uid_len)) :
(ip_lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
ip_lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
memcmp (&ip_lease -> hardware_addr.hbuf [1],
packet -> raw -> chaddr,
(unsigned)(ip_lease -> hardware_addr.hlen - 1))))) {
/* If we're not doing failover, the only state in which
we can allocate this lease to the client is FTS_FREE.
If we are doing failover, and this lease is part of a
failover pool, then if we're the primary, state has to be
FTS_FREE; if we're the secondary, state has to be
FTS_BACKUP. */
if ((ip_lease -> binding_state != FTS_FREE &&
ip_lease -> binding_state != FTS_BACKUP)
#if defined (FAILOVER_PROTOCOL)
||
(ip_lease -> pool -> failover_peer &&
((ip_lease -> binding_state == FTS_FREE &&
ip_lease -> pool -> failover_peer -> i_am == secondary)
||
(ip_lease -> binding_state == FTS_BACKUP &&
ip_lease -> pool -> failover_peer -> i_am == primary)))
If we are doing failover, things are more complicated. */
if (
#if !defined (FAILOVER_PROTOCOL)
(ip_lease -> binding_state != FTS_FREE &&
ip_lease -> binding_state != FTS_BACKUP)
#else
!lease_mine_to_reallocate (lease)
#endif
) {
#if defined (DEBUG_FIND_LEASE)
@ -2702,7 +2720,9 @@ int find_lease (struct lease **lp,
if (ours && ip_lease -> binding_state != FTS_ACTIVE)
*ours = 0;
lease_dereference (&ip_lease, MDL);
}
} else
if (allocatedp)
*allocatedp = 1;
}
/* If for some reason the client has more than one lease
@ -2945,6 +2965,9 @@ int find_lease (struct lease **lp,
lease_dereference (&lease, MDL);
}
if (lease && allocatedp && lease -> ends <= cur_time)
*allocatedp = 1;
out:
if (have_client_identifier)
data_string_forget (&client_identifier, MDL);
@ -3036,8 +3059,8 @@ void static_lease_dereference (lease, file, line)
if (lease -> on_commit)
executable_statement_dereference (&lease -> on_commit,
file, line);
if (&lease -> scope)
free_bindings (&lease -> scope, file, line);
if (lease -> scope)
binding_scope_dereference (&lease -> scope, file, line);
if (lease -> uid != lease -> uid_buf) {
dfree (lease -> uid, file, line);
lease -> uid = (unsigned char *)0;

View File

@ -43,15 +43,14 @@
#ifndef lint
static char ocopyright[] =
"$Id: dhcpd.c,v 1.21 2000/07/20 05:59:20 mellon Exp $ Copyright 1995-2000 Internet Software Consortium.";
"$Id: dhcpd.c,v 1.22 2000/09/04 23:19:38 mellon Exp $ Copyright 1995-2000 Internet Software Consortium.";
#endif
static char copyright[] =
"Copyright 1995-2000 Internet Software Consortium.";
static char arr [] = "All rights reserved.";
static char message [] = "Internet Software Consortium DHCP Server";
static char contrib [] = "\nPlease contribute if you find this software useful.";
static char url [] = "For info, please visit http://www.isc.org/dhcp-contrib.html\n";
static char url [] = "For info, please visit http://www.isc.org/products/DHCP";
#include "dhcpd.h"
#include "version.h"
@ -60,7 +59,6 @@ static char url [] = "For info, please visit http://www.isc.org/dhcp-contrib.htm
static void usage PROTO ((void));
TIME cur_time;
struct binding_scope global_scope;
struct iaddr server_identifier;
int server_identifier_matched;
@ -139,6 +137,18 @@ const char *path_dhcpd_pid = _PATH_DHCPD_PID;
int dhcp_max_agent_option_packet_length = DHCP_MTU_MAX;
static omapi_auth_key_t *omapi_key = (omapi_auth_key_t *)0;
static isc_result_t verify_addr (omapi_object_t *l, omapi_addr_t *addr) {
return ISC_R_SUCCESS;
}
static isc_result_t verify_auth (omapi_object_t *p, omapi_auth_key_t *a) {
if (a != omapi_key)
return ISC_R_INVALIDKEY;
return ISC_R_SUCCESS;
}
int main (argc, argv, envp)
int argc;
char **argv, **envp;
@ -166,6 +176,9 @@ int main (argc, argv, envp)
struct parse *parse;
int lose;
int omapi_port;
omapi_object_t *auth;
struct tsig_key *key;
omapi_typed_data_t *td;
int no_dhcpd_conf = 0;
int no_dhcpd_db = 0;
int no_dhcpd_pid = 0;
@ -288,7 +301,6 @@ int main (argc, argv, envp)
log_info ("%s %s", message, DHCP_VERSION);
log_info (copyright);
log_info (arr);
log_info (contrib);
log_info (url);
} else {
quiet = 0;
@ -365,7 +377,8 @@ int main (argc, argv, envp)
/* Now try to get the lease file name. */
option_state_allocate (&options, MDL);
execute_statements_in_scope ((struct packet *)0,
execute_statements_in_scope ((struct binding_value **)0,
(struct packet *)0,
(struct lease *)0,
(struct option_state *)0,
options, &global_scope,
@ -416,6 +429,24 @@ int main (argc, argv, envp)
data_string_forget (&db, MDL);
}
oc = lookup_option (&server_universe, options, SV_OMAPI_KEY);
if (oc &&
evaluate_option_cache (&db, (struct packet *)0,
(struct lease *)0, options,
(struct option_state *)0,
&global_scope, oc, MDL)) {
s = dmalloc (db.len + 1, MDL);
if (!s)
log_fatal ("no memory for OMAPI key filename.");
memcpy (s, db.data, db.len);
s [db.len] = 0;
data_string_forget (&db, MDL);
result = omapi_auth_key_lookup_name (&omapi_key, s);
dfree (s, MDL);
if (result != ISC_R_SUCCESS)
log_fatal ("Invalid OMAPI key: %s", s);
}
oc = lookup_option (&server_universe, options, SV_LOCAL_PORT);
if (oc &&
evaluate_option_cache (&db, (struct packet *)0,
@ -513,6 +544,9 @@ int main (argc, argv, envp)
isc_result_totext (result));
result = omapi_protocol_listen (listener,
(unsigned)omapi_port, 1);
if (result == ISC_R_SUCCESS && omapi_key)
result = omapi_protocol_configure_security
(listener, verify_addr, verify_auth);
if (result != ISC_R_SUCCESS)
log_fatal ("Can't start OMAPI protocol: %s",
isc_result_totext (result));

View File

@ -346,6 +346,249 @@ immediately allocated to the client. If the address is available for
allocation but has been previously assigned to a different client, the
server will keep looking in hopes of finding an address that has never
before been assigned to a client.
.SH DHCP FAILOVER
This version of the ISC DHCP server supports the DHCP failover
protocol as documented in draft-ietf-dhc-failover-07.txt. This is
not a final protocol document, and we have not done interoperability
testing with other vendors' implementations of this protocol, so you
must not assume that this implementation conforms to the standard.
If you wish to use the failover protocol, make sure that both failover
peers are running the same version of the ISC DHCP server.
.PP
The failover protocol allows two DHCP servers (and no more than two)
to share a common address pool. Each server will have about half of
the available IP addresses in the pool at any given time for
allocation. If one server fails, the other server will continue to
renew leases out of the pool, and will allocate new addresses out of
the roughly half of available addresses that it had when
communications with the other server were lost.
.PP
It is possible during a prolonged failure to tell the remaining server
that the other server is down, in which case the remaining server will
(over time) reclaim all the addresses the other server had available
for allocation, and begin to reuse them. This is called putting the
server into the PARTNER-DOWN state.
.PP
When the other server comes back online, it should automatically
detect that it has been offline and request a complete update from the
server that was running in the PARTNER-DOWN state, and then both
servers will resume processing together.
.PP
It is possible to get into a dangerous situation: if you put one
server into the PARTNER-DOWN state, and then *that* server goes down,
and the other server comes back up, the other server will not know
that the first server was in the PARTNER-DOWN state, and may issue
addresses previously issued by the other server to different clients,
resulting in IP address conflicts. Before putting a server into
PARTNER-DOWN state, therefore, make
.I sure
that the other server will not restart automatically.
.PP
The failover protocol defines a primary server role and a secondary
server role. There are some differences in how primaries and
secondaries act, but most of the differences simply have to do with
providing a way for each peer to behave in the opposite way from the
other. So one server must be configured as primary, and the other
must be configured as secondary, and it doesn't matter too much which
one is which.
.SH CONFIGURING FAILOVER
In order to configure failover, you need to write a peer declaration
that configures the failover protocol, and you need to write peer
references in each pool declaration for which you want to do
failover. You do not have to do failover for all pools on a given
network segment. You must not tell one server it's doing failover
on a particular address pool and tell the other it is not. You must
not have any common address pools on which you are not doing
failover.
.PP
The server currently does very little sanity checking, so if you
configure it wrong, it will just fail in odd ways. I would recommend
therefore that you either do failover or don't do failover, but don't
do any mixed pools. Also, use the same master configuration file for
both servers, and have a seperate file that contains the peer
declaration and includes the master file. This will help you to avoid
configuration mismatches. As our implementation evolves, this will
become less of a problem. A basic sample dhcpd.conf file for a
primary server might look like this:
.PP
.nf
failover peer "foo" {
primary;
address anthrax.rc.vix.com;
port 519;
peer address trantor.rc.vix.com;
peer port 520;
max-response-delay 60;
max-unacked-updates 10;
mclt 3600;
hba ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00;
load balance max seconds 3;
}
include "/etc/dhcpd.master";
.fi
.PP
The statements in the peer declaration are as follows:
.PP
.B The
.I primary
.B and
.I secondary
.B statements
.PP
[ \fBprimary\fR | \fBsecondary\fR ]
.PP
This determines whether the server is primary or secondary, as
described earlier under DHCP FAILOVER.
.PP
.B The
.I address
.B statement
.PP
.B address
.I address
.PP
The \fBaddress\fR statement declares the IP address on which the server
should listen for connections from its failover peer. This statement
can be omitted, in which case the server will accept connections to
any of its configured IP addresses.
.PP
.B The
.I peer address
.B statement
.PP
.B peer address
.I address
.PP
The \fBpeer address\fR statement declares the IP address to which the
server should connect to reach its failover peer for failover
messages.
.PP
.B The
.I port
.B statement
.PP
.B port
.I port-number
.PP
The \fBport\fR statement declares the TCP port on which the server
should listen for connections from its failover peer. This statement
may not currently be omitted, because the failover protocol does not
yet have a reserved TCP port number.
.PP
.B The
.I peer port
.B statement
.PP
.B peer port
.I port-number
.PP
The \fBpeer port\fR statement declares the TCP port to which the
server should connect to reach its failover peer for failover
messages. This statement may not be omitted because the failover
protocol does not yet have a reserved TCP port number. The port
number declared in the \fBpeer port\fR statement may be the same as
the port number declared in the \fBport\fR statement.
.PP
.B The
.I max-response-delay
.B statement
.PP
.nf
.B max-response-delay
.I seconds
.fi
.PP
The \fBmax-response-delay\fR statement tells the DHCP server how
many seconds may pass without receiving a message from its failover
peer before it assumes that connection has failed. This number
should be small enough that a transient network failure that breaks
the connection will not result in the servers being out of
communication for a long time, but large enough that the server isn't
constantly making and breaking connections. This parameter must be
specified.
.PP
.B The
.I max-unacked-updates
.B statement
.PP
.B max-unacked-updates
.I count
.PP
The \fBmax-unacked-updates\fR statement tells the DHCP server how
many many BINDUPD messages it can send before it receives a BNDACK
from the failover peer. We don't have enough operational experience
to say what a good value for this is, but 10 seems to work. This
parameter must be specified.
.PP
.B The
.I mclt
.B statement
.PP
.B mclt
.I seconds
.PP
The \fBmclt\fR statement defines the Maximum Client Lead Time. It
must be specified on the primary, and may not be specified on the
secondary. This is the length of time for which a lease may be
renewed by either failover peer without contacting the other. The
longer you set this, the longer it will take for the running server to
recover IP addresses after moving into PARTNER-DOWN state. The
shorter you set it, the more load your servers will experience when
they are not communicating. A value of something like 3600 is
probably reasonable, but again bear in mind that we have no real
operational experience with this.
.PP
.B The
.I split
.B statement
.PP
.B split
.I index
.PP
The split statement specifies the split between the primary and
secondary for the purposes of load balancing. Whenever a client
makes a DHCP request, the DHCP server runs a hash on the client
identification. If the hash comes out to less than the split value,
the primary answers. If it comes out to equal to or more than the
split, the secondary answers. This value should generally be set to
128, and can only be configured on the primary.
.PP
.B The
.I hba
.B statement
.PP
.B hba
.I colon-seperated-hex-list
.PP
The hba statement specifies the split between the primary and
secondary as a bitmap rather than a cutoff, which theoretically allows
for finer-grained control. In practice, there is probably no need
for such fine-grained control, however. An example hba statement:
.PP
.nf
hba ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00;
.fi
.PP
.B The
.I load balance max seconds
.B statement
.PP
.B load balance max seconds
.I seconds
.PP
This statement allows you to configure a cutoff after which load
balancing is disabled. The cutoff is based on the number of seconds
since the client sent its first DHCPDISCOVER or DHCPREQUEST message,
and only works with clients that correctly implement the \fIsecs\fR
field - fortunately most clients do. We recommend setting this to
something like 3 or 5. The effect of this is that if one of the
failover peers gets into a state where it is responding to failover
messages but not responding to some client requests, the other
failover peer will take over its client load automatically as the
clients retry.
.SH CLIENT CLASSING
Clients can be seperated into classes, and treated differently
depending on what class they are in. This seperation can be done
@ -526,9 +769,7 @@ The DHCP server has the ability to dynamically update the Domain Name
System. Within the configuration files, you can define how you want
the Domain Name System to be updated. These updates are RFC 2136
compliant so any DNS server supporting RFC 2136 should be able to
accept updates from the DHCP server. The DHCP server will only
perform DNS updates if it has been built with DNS updates enabled as
described in the README file that comes with the DHCP distribution.
accept updates from the DHCP server.
.PP
The Dynamic DNS update scheme implemented in this version of the ISC
DHCP server is an interim implementation, which does not implement any
@ -607,37 +848,73 @@ by sending a DHCPRELEASE message, the server will likewise remove the
A and PTR records.
.SH DYNAMIC DNS UPDATE SECURITY
.PP
Support for TSIG and DNSSEC is not yet available. When you set your
DNS server up to allow updates from the DHCP server, you may
be exposing it to unauthorized updates. To avoid this, the best you
can do right now is to use IP address-based packet filtering to
prevent unauthorized hosts from submitting update requests.
When you set your DNS server up to allow updates from the DHCP server,
you may be exposing it to unauthorized updates. To avoid this, you
should use TSIG signatures - a method of cryptographically signing
updates using a shared secret key. As long as you protect the
secrecy of this key, your updates should also be secure. Note,
however, that the DHCP protocol itself provides no security, and that
clients can therefore provide information to the DHCP server which the
DHCP server will then use in its updates, with the constraints
described previously.
.PP
The DNS server must be configured to allow updates for any zone that
the DHCP server will be updating. For example, let us say that
clients in the sneedville.edu domain will be assigned addresses on the
10.10.17.0/24 subnet. In that case, assuming you are using ISC BIND
8.2.1 or later, you would need to have the following declarations in
your /etc/named.conf file:
10.10.17.0/24 subnet. In that case, you will need a key declaration
for the TSIG key you will be using, and also two zone declarations -
one for the zone containing A records that will be updates and one for
the zone containing PTR records - for ISC BIND, something like this:
.PP
.nf
zone "sneedville.edu" {
key DHCP_UPDATER {
algorithm HMAC-MD5.SIG-ALG.REG.INT;
secret pRP5FapFoJ95JEL06sv4PQ==;
};
zone "example.org" {
type master;
file "sneedville.edu.db";
allow-update { localhost; };
file "example.org.db";
allow-update { key DHCP_UPDATER; };
};
zone "17.10.10.in-addr.arpa" {
type master;
file "10.10.17.db";
allow-update { localhost; };
allow-update { key DHCP_UPDATER; };
};
.fi
.PP
This assumes that your DHCP server and your name server will be
running on the same computer - the "localhost" name is taken in the
DNS server as an alias for all of that host's IP addresses, and
updates from any of those addresses will be accepted.
You will also have to configure your DHCP server to do updates to
these zones. To do so, you need to add something like this to your
dhcpd.conf file:
.PP
.nf
key DHCP_UPDATER {
algorithm HMAC-MD5.SIG-ALG.REG.INT;
secret pRP5FapFoJ95JEL06sv4PQ==;
};
zone EXAMPLE.ORG. {
primary 127.0.0.1;
key DHCP_UPDATER;
}
zone 17.127.10.in-addr.arpa. {
primary 127.0.0.1;
key DHCP_UPDATER;
}
.fi
.PP
You should choose your own secret key, of course. The ISC BIND 8 and
9 distributions come with a program for generating secret keys called
dnskeygen. The version that comes with BIND 9 is likely to produce a
substantially more random key, so we recommend you use that one even
if you are not using BIND 9 as your DNS server. The key above was
generated with the command:
.nf
dnskeygen -H 128 -u -c -n DHCP_UPDATER
.fi
.PP
You may wish to enable logging of DNS transactions on your DNS server.
To do so, you might write a logging statement like the following:
@ -683,6 +960,12 @@ followed by a series of statements to execute when the event happens,
enclosed in braces. Events are used to implement dynamic DNS
updates, so you should not define your own event handlers if you are
using the built-in dynamic DNS update mechanism.
.PP
The built-in version of the dynamic DNS update mechanism is in a text
string towards the top of server/dhcpd.c. If you want to use events
for things other than DNS updates, and you also want DNS updates, you
will have to start out by copying this code into your dhcpd.conf file
and modifying it.
.SH REFERENCE: DECLARATIONS
.PP
.B The

View File

@ -50,7 +50,7 @@
#ifndef lint
static char copyright[] =
"$Id: omapi.c,v 1.4 2000/07/08 20:52:20 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: omapi.c,v 1.5 2000/09/04 23:19:42 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -284,14 +284,20 @@ isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id,
((omapi_object_t *)lease -> billing_class),
MDL);
return ISC_R_NOTFOUND;
} else if (!omapi_ds_strcmp (name, "hardware-address"))
return omapi_make_const_value
(value, name, &lease -> hardware_addr.hbuf [1],
(unsigned)(lease -> hardware_addr.hlen - 1), MDL);
else if (!omapi_ds_strcmp (name, "hardware-type"))
return omapi_make_int_value (value, name,
lease -> hardware_addr.hbuf [0],
MDL);
} else if (!omapi_ds_strcmp (name, "hardware-address")) {
if (lease -> hardware_addr.hlen)
return omapi_make_const_value
(value, name, &lease -> hardware_addr.hbuf [1],
(unsigned)(lease -> hardware_addr.hlen - 1),
MDL);
return ISC_R_NOTFOUND;
} else if (!omapi_ds_strcmp (name, "hardware-type")) {
if (lease -> hardware_addr.hlen)
return omapi_make_int_value
(value, name, lease -> hardware_addr.hbuf [0],
MDL);
return ISC_R_NOTFOUND;
}
/* Try to find some inner object that can take the value. */
if (h -> inner && h -> inner -> type -> get_value) {
@ -485,30 +491,33 @@ isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_name (c, "hardware-address");
if (status != ISC_R_SUCCESS)
return status;
status = (omapi_connection_put_uint32
(c, (unsigned long)(lease -> hardware_addr.hlen - 1)));
if (status != ISC_R_SUCCESS)
return status;
status = (omapi_connection_copyin
(c, &lease -> hardware_addr.hbuf [1],
(unsigned long)(lease -> hardware_addr.hlen - 1)));
if (status != ISC_R_SUCCESS)
return status;
if (lease -> hardware_addr.hlen) {
status = omapi_connection_put_name (c, "hardware-address");
if (status != ISC_R_SUCCESS)
return status;
status = (omapi_connection_put_uint32
(c,
(unsigned long)(lease -> hardware_addr.hlen - 1)));
if (status != ISC_R_SUCCESS)
return status;
status = (omapi_connection_copyin
(c, &lease -> hardware_addr.hbuf [1],
(unsigned long)(lease -> hardware_addr.hlen - 1)));
status = omapi_connection_put_name (c, "hardware-type");
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32 (c, sizeof (int));
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32 (c,
lease -> hardware_addr.hbuf [0]);
if (status != ISC_R_SUCCESS)
return status;
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_name (c, "hardware-type");
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32 (c, sizeof (int));
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32
(c, lease -> hardware_addr.hbuf [0]);
if (status != ISC_R_SUCCESS)
return status;
}
status = omapi_connection_put_name (c, "ends");