summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.conf15
-rw-r--r--Makefile.dist10
-rw-r--r--README52
-rw-r--r--RELNOTES191
-rw-r--r--TODO7
-rw-r--r--client/Makefile.dist38
-rw-r--r--client/clparse.c140
-rw-r--r--client/dhclient.c123
-rw-r--r--client/dhclient.conf.536
-rwxr-xr-xclient/scripts/linux2
-rwxr-xr-xclient/scripts/solaris14
-rw-r--r--common/Makefile.dist37
-rw-r--r--common/alloc.c49
-rw-r--r--common/bpf.c36
-rw-r--r--common/conflex.c68
-rw-r--r--common/convert.c8
-rw-r--r--common/dhcp-options.5234
-rw-r--r--common/dispatch.c495
-rw-r--r--common/dlpi.c26
-rw-r--r--common/dns.c527
-rw-r--r--common/execute.c118
-rw-r--r--common/hash.c9
-rw-r--r--common/icmp.c29
-rw-r--r--common/inet_addr.c4
-rw-r--r--common/interact.c242
-rw-r--r--common/lpf.c252
-rw-r--r--common/memory.c228
-rw-r--r--common/nit.c22
-rw-r--r--common/options.c330
-rw-r--r--common/packet.c6
-rw-r--r--common/parse.c1047
-rw-r--r--common/print.c16
-rw-r--r--common/resolv.c208
-rw-r--r--common/socket.c37
-rw-r--r--common/sysconf.c141
-rw-r--r--common/tables.c568
-rw-r--r--common/tree.c740
-rw-r--r--common/upf.c22
-rwxr-xr-xconfigure4
-rw-r--r--doc/IANA-arp-parameters145
-rw-r--r--doc/draft-ietf-dhc-authentication-03.txt446
-rw-r--r--doc/draft-ietf-dhc-dhcp-09.txt2519
-rw-r--r--doc/draft-ietf-dhc-dhcp-dns-02.txt356
-rw-r--r--doc/draft-ietf-dhc-new-options-00.txt110
-rw-r--r--doc/draft-ietf-dhc-options-1533update-06.txt2127
-rw-r--r--doc/draft-ietf-dhc-options-opt127-02.txt167
-rw-r--r--doc/draft-ietf-dhc-renumbering-00.txt390
-rw-r--r--includes/cf/freebsd.h8
-rw-r--r--includes/cf/linux.h8
-rw-r--r--includes/cf/sco.h2
-rw-r--r--includes/cf/sunos5-5.h11
-rw-r--r--includes/cf/ultrix.h2
-rw-r--r--includes/dhcp.h7
-rw-r--r--includes/dhcpd.h408
-rw-r--r--includes/dhctoken.h25
-rw-r--r--includes/hash.h7
-rw-r--r--includes/osdep.h14
-rw-r--r--includes/statement.h68
-rw-r--r--includes/tree.h107
-rw-r--r--relay/Makefile.dist33
-rw-r--r--relay/dhcrelay.c49
-rw-r--r--server/Makefile.dist39
-rw-r--r--server/bootp.c214
-rw-r--r--server/class.c272
-rw-r--r--server/confpars.c736
-rw-r--r--server/db.c5
-rw-r--r--server/dhcp.c834
-rw-r--r--server/dhcpd.c32
-rw-r--r--server/dhcpd.conf43
-rw-r--r--server/dhcpd.conf.548
-rw-r--r--server/dhcpd.leases.cat5170
-rw-r--r--server/dhcpdi.c1075
-rw-r--r--site.conf3
73 files changed, 3318 insertions, 13293 deletions
diff --git a/Makefile.conf b/Makefile.conf
index a9c7954c..951114c3 100644
--- a/Makefile.conf
+++ b/Makefile.conf
@@ -92,7 +92,7 @@ VARDB = /var/db
#LIBS = -lresolv -lsocket -lnsl -lgen
#CC=gcc
#COPTS = -Wall -Wno-unused -Wno-implicit -Wno-comment \
-# -Wno-uninitialized -Wno-char-subscripts -Wno-switch -Werror
+# -Wno-uninitialized -Wno-char-subscripts -Werror
#CF = cf/sunos5-5.h
#ADMMANDIR = /usr/share/man/cat1m
#ADMMANEXT = .1m
@@ -132,12 +132,11 @@ VARDB = /var/db
#VARDB = /etc
##--alphaosf--
-## BSD/OS 2.1 and higher.
+## BSD/OS 2.1
##--bsdos--
#LIBS= -lresolv
#CC=gcc2
#CF = cf/bsdos.h
-#SCRIPT=bsdos
##--bsdos--
## FreeBSD
@@ -150,7 +149,7 @@ VARDB = /var/db
##--rhapsody--
#CF = cf/rhapsody.h
#COPTS = -Wall -Wno-unused -Wno-implicit -Wno-comment \
-# -Wno-uninitialized -Wno-switch -Werror -pipe
+# -Wno-uninitialized -Werror -pipe
#SCRIPT=rhapsody
##--rhapsody--
@@ -158,7 +157,7 @@ VARDB = /var/db
##--netbsd--
#CF = cf/netbsd.h
#COPTS = -Wall -Wstrict-prototypes -Wno-unused -Wno-implicit -Wno-comment \
-# -Wno-uninitialized -Werror -Wno-switch -pipe
+# -Wno-uninitialized -Werror -pipe
#SCRIPT=netbsd
##--netbsd--
@@ -177,7 +176,7 @@ VARDB = /var/db
## Linux 1.x
##--linux-1--
-#COPTS = -DLINUX_1_X
+#COPTS = -DLINUX_MAJOR=1 -DLINUX_MINOR=0
#CF = cf/linux.h
#ADMMANDIR = /usr/man/man8
#ADMMANEXT = .8
@@ -190,7 +189,7 @@ VARDB = /var/db
## Linux 2.0
##--linux-2.0--
-#COPTS = -DLINUX_2_0
+#COPTS = -DLINUX_MAJOR=2 -DLINUX_MINOR=0
#CF = cf/linux.h
#ADMMANDIR = /usr/man/man8
#ADMMANEXT = .8
@@ -203,7 +202,7 @@ VARDB = /var/db
## Linux 2.1
##--linux-2.1--
-#COPTS = -DLINUX_2_1
+#COPTS = -DLINUX_MAJOR=2 -DLINUX_MINOR=1
#CF = cf/linux.h
#ADMMANDIR = /usr/man/man8
#ADMMANEXT = .8
diff --git a/Makefile.dist b/Makefile.dist
index e1e10fe9..2ecaaedc 100644
--- a/Makefile.dist
+++ b/Makefile.dist
@@ -1,6 +1,6 @@
# Makefile.dist
#
-# Copyright (c) 1996, 1997, 1998 The Internet Software Consortium.
+# Copyright (c) 1996, 1997 The Internet Software Consortium.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
# OF THE POSSIBILITY OF SUCH DAMAGE.
#
-SUBDIRS= common server client relay statmsg sysconfd dhcpctl
+SUBDIRS= common server client relay
all:
@for dir in ${SUBDIRS}; do \
@@ -44,12 +44,6 @@ install:
(cd $$dir; $(MAKE) install); \
done
-depend:
- @for dir in ${SUBDIRS}; do \
- echo "Making dependencies in $$dir"; \
- (cd $$dir; $(MAKE) depend); \
- done
-
clean:
@for dir in ${SUBDIRS}; do \
echo "Cleaning in $$dir"; \
diff --git a/README b/README
index 28aa1c8e..cdac32e2 100644
--- a/README
+++ b/README
@@ -1,17 +1,15 @@
Internet Software Consortium
Dynamic Host Configuration Protocol Distribution
- Development Snapshot
- November 22, 1997
-
-This is a development snapshot of work in progress on version 2.0 of
-the Internet Software Consortium DHCP Distribution. In version 2.0,
-this distribution includes a DHCP server, a DHCP client, and a
-BOOTP/DHCP relay agent. The engineering snapshot has become a lot
-more stable since the last snapshot, and will soon go into beta.
-However, DHCP server users running a production environment should
-probably still use the latest version on the 1.0 release branch, which
-is more stable, having been in a feature freeze since November of
-1996.
+ Version 2, Beta 1, Patchlevel 8
+ December 23, 1998
+
+This is the first Beta release of Version 2 of the Internet Software
+Consortium DHCP Distribution. In version 2.0, this distribution
+includes a DHCP server, a DHCP client, and a BOOTP/DHCP relay agent.
+This beta is believed to be fairly stable. However, DHCP server users
+running a production environment should probably still use version
+1.0, which is more stable, having been in a feature freeze since
+November of 1996.
In this release, the server and relay agent currently work well on
Digital Alpha OSF/1, SunOS 4.1.4, NetBSD, FreeBSD, BSD/OS and Ultrix.
@@ -48,9 +46,9 @@ 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-2.0b1pl6.tar.gz |tar xvf -
+ zcat dhcp-2.0b1pl8.tar.gz |tar xvf -
-Now, cd to the dhcp-2.0b1pl6 subdirectory that you've just created and
+Now, cd to the dhcp-2.0b1pl8 subdirectory that you've just created and
configure the source tree by typing:
./configure
@@ -75,7 +73,7 @@ Once you have successfully gotten the DHCP Distribution to build, you
can install it by typing ``make install''. If you already have an old
version of the DHCP Distribution installed, you may want to save it
before typing ``make install''.
-
+
LINUX
There are three big LINUX issues: the all-ones broadcast address,
@@ -185,19 +183,6 @@ BROADCAST_ADDRESS[0]="255.255.255.255"
LANCONFIG_ARGS[0]="ether"
DHCP_ENABLE[0]=0
-The above hack supposedly does not work on HP-UX version 9.x.
-However, another hack which supposedly _does_ work on 9.x is to add
-the following entry to your /etc/hosts or DNS database:
-
-255.255.255.255 all-ones
-
-Then modify the broadcast as follows (change to suit your
-configuration, of course):
-
-ifconfig lan0 [your ip addr] netmask [your netmask] broadcast all-ones
-
-I would appreciate any reports as to how well this works for you.
-
ULTRIX
Now that we have Ultrix packet filter support, the DHCP Distribution
@@ -223,6 +208,17 @@ The NeXTSTEP support uses the NeXTSTEP Berkeley Packet Filter
extension, which is not included in the base NextStep system. You
must install this extension in order to get dhcpd or dhclient to work.
+ SOLARIS
+
+One problem which has been observed and is not fixed in this patchlevel
+has to do with using DLPI on Solaris 2.6 machines, probably only on Intel,
+but possibly also on SPARC. The symptom of this problem is that you never
+receive any DHCP packets. If you are running Solaris 2.6, and you
+encounter this symptom, and you are running the DHCP server on a machine
+with a single broadcast network interface, you may wish to edit the
+includes/site.h file and uncomment the #define USE_SOCKETS line. Then
+type ``make clean; make''.
+
SUPPORT
The Internet Software Consortium DHCP server is not a commercial
diff --git a/RELNOTES b/RELNOTES
index 55aa3e78..36030a51 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -1,12 +1,13 @@
Internet Software Consortium
Dynamic Host Configuration Protocol Distribution
- Development Snapshot
- December 2, 1997
+ Version 2, Beta 1, Patchlevel 8
+ December 23, 1998
Release Notes
-This is the first development snapshot of Version 3 of the Internet
-Software Consortium DHCP Distribution.
+This is the first Beta release of Version 2 of the Internet Software
+Consortium DHCP Distribution. This beta is believed to be fairly
+stable.
PLANS
@@ -35,9 +36,8 @@ server:
This version is now in Beta testing, and is planned for release in
mid-1998. It has a number of new features, and is the release that we
would expect sites that want some stability but need the new lease
-testing feature, better NAKing, or need a client or relay agent. Note
-that it is possible to run the Version 1 server with the Version 2
-client.
+testing feature, or need a client or relay agent. Note that it is
+possible to run the Version 1 server with the Version 2 client.
Version 3 of the ISC DHCP Distribution will add Dynamic DNS Support,
asynchronous DNS query resolution, DHCP Authentication, and possibly
@@ -46,7 +46,182 @@ database. This release is not expected to be stable in the near
future, and is intended for sites that are in a position to
experiment, or for sites that desperately need the new features.
- CHANGES
+ CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 6
+
+- Add support for Linux Packet Filter (thanks to Brian Murrell, Interlinx).
+
+- Add support for FDDI hardware type.
+
+- Fix a long-standing bug in DLPI support where the ethertype was
+ being set incorrectly (thanks to Gong Wei, CCENet).
+
+- Don't use DLPI RAW mode on Solaris.
+
+- In the client, when a lease expires, the interface to which that
+ lease is attached is unconfigured. On systems that use the socket
+ API, the interface needs to then be reconfigured with the 0.0.0.0
+ address so that it can be used to get a new address.
+
+- Add fallback support for Linux. This fixes a problem with the
+ relay agent when relaying over non-broadcast links, and may also fix
+ some obscure problems with unicasting DHCPACKs in both the server and
+ relay agent.
+
+- When allocating leases, if the oldest lease is abandoned, try to
+ find a younger-but-still-expired lease rather than reclaiming the
+ abandoned lease.
+
+- Add more documentation to README.
+
+- The absence of the /etc/dhclient.conf file is no longer considered
+ an error.
+
+- The dhcp client's lease file name can be specified on the command
+ line.
+
+- The DHCP client should no longer zap interfaces that it has not been
+ directed to configure.
+
+- If a client starts up in the init-reboot state, the xid will be a
+ "random" number rather than always being zero, as was previously the
+ case.
+
+- In addition to comparing transaction IDs, compare hardware addresses
+ in response packets to verify that they are ours.
+
+- Rewrite the client lease database after 20 leases have been written.
+
+- Fix the exponential backoff code.
+
+- Add a Y2k comment to indicate that something suspicious-looking is
+ in fact _not_ a problem.
+
+- Use mkstemp if possible.
+
+- Add missing fi in various client scripts.
+
+- Use "search" instead of "domain" in linux resolv.conf files.
+
+- Specify a hop count in all route command on solaris.
+
+- If an allocation fails, don't try to zero out the allocation buffer
+ we didn't get.
+
+- Support subnets that are subsets of other subnets - that is, for
+ example, 10.0.1.0/24 and 10.0.0.0/16. This is useful in fairly
+ obscure circumstances.
+
+- Don't set the lease end time if it's already expired.
+
+- Don't define INADDR_LOOPBACK on FreeBSD if it's already defined in a
+ system header.
+
+- Use the broadcast address in the relay agent if we are using the BSD
+ socket API.
+
+- Allow host declarations without names.
+
+- Allow the server identifier option to be specified.
+
+- Don't dump hostnames into the lease file if they contain
+ non-printable characters.
+
+- Copy the entire client hardware address buffer that the client sends
+ to the output packet, not just the portion of it that's supposedly
+ significant according to the hardware address length field. This
+ is done for the benefit of certain Microsoft clients.
+
+- Don't send a second ICMP echo request if we receive two DHCPDISCOVER
+ messages in quick succession. This prevents a rather annoying
+ timing race in configuring some Win95 clients.
+
+- Fix up dhcp-options man page to make it more readable. Note that
+ netbios-name-server is the same thing as WINS.
+
+
+ CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 5
+
+- Define some extra DLPI support flags that make DLPI work much better
+ on Solaris.
+
+- Fix inet_aton prototype/declaration to match Internet Software
+ Consortium BIND distribution.
+
+- Document new server-identifier functionality.
+
+ CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 4
+
+- Do not use -Wstrict-prototypes on Solaris with gcc - if the Internet
+ Software Consortium BIND distribution is not installed, this produces
+ errors.
+
+- Actually use the new DLPI support on Solaris - although the code was
+ added in Patchlevel 2, it wasn't enabled (blush).
+
+- Fix a prototype bug that's exposed when DLPI support is enabled on
+ Solaris.
+
+ CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 3
+
+- Fix a makefile botch that prevents the DHCP Distribution from
+ from compiling on Solaris with gcc. Sigh.
+
+ CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 2
+
+- Allow server-identifier in any scope. Use in-scope server
+ identifier option rather than the default, if one exists.
+
+- Delete newlines from abandoned lease reclaimation warning.
+
+- Only release other applicable leases held by a client when the
+ client sends a DHCPREQUEST.
+
+- Fix core dump when find_lease didn't find a lease.
+
+- Update dhcpd.leases man page.
+
+ CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 1
+
+- Use -Wno-char-subscript on Solaris to prevent bogus warnings from
+ gcc on Solaris 2.6.
+
+- Add support for Apple's new Rhapsody operating system.
+
+- Use DLPI on Solaris instead of using the BSD Sockets API.
+
+- Fix two network input buffer overflow problems which could allow an
+ attacker to pervert the stack.
+
+- Fix an ancient typo that could theoretically cause memory
+ corruption.
+
+- Sort abandoned leases in at current time rather than end of time.
+ This allows abandoned leases to be reclaimed if there are no
+ available free leases.
+
+- If a client explicitly requests a lease that's been abandoned, it's
+ probably the system that was answering pings on that address, so let it
+ have the lease.
+
+- Fix a bunch of type conversion errors that are flagged by the Solaris
+ C compiler.
+
+ CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 0
+
+- Fix two potential buffer overflow problems.
+
+- Differentiate between versions of Linux for better success in
+ compiling.
+
+- Fix bug in linux client script regarding routing setup.
+
+- Clarify socket API error message on multiple interfaces.
+
+- Fix broken comparison that was setting IP source address to zero.
+
+- Reclaim abandoned leases if we run out of free leases.
+
+ CHANGES FROM THE DECEMBER 2, 1997 SNAPSHOT
- Use %ld to print pid_t and cast pid_t values to long to avoid
inconsistent declarations between different POSIX flavours.
diff --git a/TODO b/TODO
index a0523649..f1391360 100644
--- a/TODO
+++ b/TODO
@@ -13,20 +13,15 @@ Things to do, not in any particular order...
- Server-to-server protocol
-- Perl scripts to convert from other DHCP and BOOTP servers' config
- files to the ISC DHCPD format.
-
- Token ring support for bpf/nit interfaces
-- FDDI support for bpf/nit interfaces
+- FDDI support for bpf/nit interfaces (mostly done)
- Other network hardware support for low-level interfaces?
- Standard socket API for sending to all-ones broadcast and figuring
out which interface a packet came in on?
-- Raw socket support for single-interface machines
-
- IPv6/DHCPv6 support
- Dhcpd running on MacOS Open Transport
diff --git a/client/Makefile.dist b/client/Makefile.dist
index df9b6504..77db1120 100644
--- a/client/Makefile.dist
+++ b/client/Makefile.dist
@@ -1,6 +1,6 @@
# Makefile.dist
#
-# Copyright (c) 1996, 1997, 1998 The Internet Software Consortium.
+# Copyright (c) 1996, 1997 The Internet Software Consortium.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -45,31 +45,26 @@ CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS)
all: $(PROG) $(CATMANPAGES)
install: $(PROG) $(CATMANPAGES)
- @for dir in $(CLIENTBINDIR) $(ETC) $(ADMMANDIR) $(FFMANDIR) $(VARDB); \
- do \
- case $$dir in \
- /*) base=/ ;; \
- *) base="" ;; \
- esac; \
- slash=""; \
- for elt in `echo $$dir |sed -e 's/\// /g'`; do \
- if [ ! -d $$base/$$elt ]; then \
- echo Making $$base/$$elt; \
- mkdir $$base/$$elt; \
- chmod 755 $$base/$$elt; \
- fi; \
- base=$$base$$slash$$elt; \
- slash=/; \
- done; \
- done
$(INSTALL) dhclient $(CLIENTBINDIR)
$(CHMOD) 755 $(CLIENTBINDIR)/dhclient
- @if [ x$(SCRIPT) = xnone ]; then \
+ if [ x$(SCRIPT) = xnone ]; then \
echo "No client script available."; \
else \
$(INSTALL) scripts/$(SCRIPT) $(ETC)/dhclient-script; \
$(CHMOD) 700 $(ETC)/dhclient-script; \
fi
+ if [ ! -d $(ADMMANDIR) ]; then \
+ mkdir $(ADMMANDIR); \
+ chmod 755 $(ADMMANDIR); \
+ fi
+ if [ ! -d $(FFMANDIR) ]; then \
+ mkdir $(FFMANDIR); \
+ chmod 755 $(FFMANDIR); \
+ fi
+ if [ ! -d $(VARDB) ]; then \
+ mkdir $(VARDB); \
+ chmod 755 $(VARDB); \
+ fi
$(MANINSTALL) $(MANFROM) dhclient.cat8 $(MANTO) \
$(ADMMANDIR)/dhclient$(ADMMANEXT)
$(MANINSTALL) $(MANFROM) dhclient-script.cat8 $(MANTO) \
@@ -79,12 +74,9 @@ install: $(PROG) $(CATMANPAGES)
$(MANINSTALL) $(MANFROM) dhclient.leases.cat5 $(MANTO) \
$(FFMANDIR)/dhclient.leases$(FFMANEXT)
-depend:
- makedepend $(INCLUDES) $(PREDEFINES) $(SRCS)
-
clean:
-rm -f $(OBJS)
-
+
realclean: clean
-rm -f $(PROG) $(CATMANPAGES) *~ #*
diff --git a/client/clparse.c b/client/clparse.c
index 5b700372..e55ea610 100644
--- a/client/clparse.c
+++ b/client/clparse.c
@@ -3,7 +3,7 @@
Parser for dhclient config and lease files... */
/*
- * Copyright (c) 1997, 1998 The Internet Software Consortium.
+ * Copyright (c) 1997 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: clparse.c,v 1.17 1998/10/22 04:52:23 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
+"$Id: clparse.c,v 1.13.2.2 1998/07/10 23:17:00 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -51,6 +51,7 @@ static char copyright[] =
static TIME parsed_time;
struct client_config top_level_config;
+u_int32_t requested_lease_time;
/* client-conf-file :== client-declarations EOF
client-declarations :== <nil>
@@ -105,11 +106,11 @@ int read_client_conf ()
top_level_config.requested_options
[top_level_config.requested_option_count++] =
DHO_HOST_NAME;
- top_level_config.requested_lease_time = 7200;
- top_level_config.send_options.dhcp_options [DHO_DHCP_LEASE_TIME].data
- = (unsigned char *)&top_level_config.requested_lease_time;
- top_level_config.send_options.dhcp_options [DHO_DHCP_LEASE_TIME].len
- = sizeof top_level_config.requested_lease_time;
+ requested_lease_time = 7200;
+ top_level_config.send_options [DHO_DHCP_LEASE_TIME].data
+ = (unsigned char *)&requested_lease_time;
+ top_level_config.send_options [DHO_DHCP_LEASE_TIME].len
+ = sizeof requested_lease_time;
if ((cfile = fopen (path_dhclient_conf, "r")) != NULL) {
do {
@@ -125,7 +126,7 @@ int read_client_conf ()
}
/* Set up state and config structures for clients that don't
- have per-interface configuration statements. */
+ have per-interface configuration declarations. */
config = (struct client_config *)0;
for (ip = interfaces; ip; ip = ip -> next) {
if (!ip -> client) {
@@ -135,7 +136,6 @@ int read_client_conf ()
error ("no memory for client state.");
memset (ip -> client, 0, sizeof *(ip -> client));
}
-
if (!ip -> client -> config) {
if (!config) {
config = (struct client_config *)
@@ -144,12 +144,6 @@ int read_client_conf ()
error ("no memory for client config.");
memcpy (config, &top_level_config,
sizeof top_level_config);
- i = DHO_DHCP_LEASE_TIME;
- config -> send_options.dhcp_options [i].data =
- (unsigned char *)&config -> requested_lease_time;
- top_level_config.send_options.dhcp_options [DHO_DHCP_LEASE_TIME].len
- = sizeof top_level_config.requested_lease_time;
-
}
ip -> client -> config = config;
}
@@ -214,47 +208,39 @@ void parse_client_statement (cfile, ip, config)
int token;
char *val;
struct option *option;
- struct executable_statement *stmt, **p;
- enum statement op op;
switch (next_token (&val, cfile)) {
case SEND:
- p = &config -> on_tranmission;
- op = send_option_statement;
- do_option:
- token = next_token (&val, cfile);
- option = parse_option_name (cfile);
- if (!option) {
- *lose = 1;
- return (struct executable_statement *)0;
- }
- stmt = parse_option_statement (cfile, 1, option,
- send_option_statement);
- for (; *p; p = &((*p) -> next))
- ;
- *p = stmt;
- stmt -> next = (struct executable_statement *)0;
+ parse_option_decl (cfile, &config -> send_options [0]);
return;
case DEFAULT:
- p = &config -> on_receipt;
- op = default_option_statement;
- goto do_option;
+ option = parse_option_decl (cfile, &config -> defaults [0]);
+ if (option)
+ config -> default_actions [option -> code] =
+ ACTION_DEFAULT;
+ return;
case SUPERSEDE:
- p = &config -> on_receipt;
- op = supersede_option_statement;
- goto do_option;
+ option = parse_option_decl (cfile, &config -> defaults [0]);
+ if (option)
+ config -> default_actions [option -> code] =
+ ACTION_SUPERSEDE;
+ return;
case APPEND:
- p = &config -> on_receipt;
- op = append_option_statement;
- goto do_option;
+ option = parse_option_decl (cfile, &config -> defaults [0]);
+ if (option)
+ config -> default_actions [option -> code] =
+ ACTION_APPEND;
+ return;
case PREPEND:
- p = &config -> on_receipt;
- op = prepend_option_statement;
- goto do_option;
+ option = parse_option_decl (cfile, &config -> defaults [0]);
+ if (option)
+ config -> default_actions [option -> code] =
+ ACTION_PREPEND;
+ return;
case MEDIA:
parse_string_list (cfile, &config -> media, 1);
@@ -751,16 +737,76 @@ struct option *parse_option_decl (cfile, options)
u_int8_t buf [4];
u_int8_t hunkbuf [1024];
int hunkix = 0;
+ char *vendor;
char *fmt;
+ struct universe *universe;
struct option *option;
struct iaddr ip_addr;
u_int8_t *dp;
int len;
int nul_term = 0;
- option = parse_option_name (cfile);
- if (!option)
- return;
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting identifier after option keyword.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ return (struct option *)0;
+ }
+ vendor = malloc (strlen (val) + 1);
+ if (!vendor)
+ error ("no memory for vendor information.");
+ strcpy (vendor, val);
+ token = peek_token (&val, cfile);
+ if (token == DOT) {
+ /* Go ahead and take the DOT token... */
+ token = next_token (&val, cfile);
+
+ /* The next token should be an identifier... */
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting identifier after '.'");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ return (struct option *)0;
+ }
+
+ /* Look up the option name hash table for the specified
+ vendor. */
+ universe = ((struct universe *)
+ hash_lookup (&universe_hash,
+ (unsigned char *)vendor, 0));
+ /* If it's not there, we can't parse the rest of the
+ declaration. */
+ if (!universe) {
+ parse_warn ("no vendor named %s.", vendor);
+ skip_to_semi (cfile);
+ return (struct option *)0;
+ }
+ } else {
+ /* Use the default hash table, which contains all the
+ standard dhcp option names. */
+ val = vendor;
+ universe = &dhcp_universe;
+ }
+
+ /* Look up the actual option info... */
+ option = (struct option *)hash_lookup (universe -> hash,
+ (unsigned char *)val, 0);
+
+ /* If we didn't get an option structure, it's an undefined option. */
+ if (!option) {
+ if (val == vendor)
+ parse_warn ("no option named %s", val);
+ else
+ parse_warn ("no option named %s for vendor %s",
+ val, vendor);
+ skip_to_semi (cfile);
+ return (struct option *)0;
+ }
+
+ /* Free the initial identifier token. */
+ free (vendor);
/* Parse the option data... */
do {
diff --git a/client/dhclient.c b/client/dhclient.c
index 785c9148..fa8c132d 100644
--- a/client/dhclient.c
+++ b/client/dhclient.c
@@ -55,8 +55,8 @@
*/
#ifndef lint
-static char copyright[] =
-"$Id: dhclient.c,v 1.49 1998/04/09 04:26:24 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+static char ocopyright[] =
+"$Id: dhclient.c,v 1.44.2.7 1998/12/23 14:18:49 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -70,8 +70,6 @@ char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
char *path_dhclient_db = _PATH_DHCLIENT_DB;
char *path_dhclient_pid = _PATH_DHCLIENT_PID;
-int dhcp_max_agent_option_packet_length = 0;
-
int interfaces_requested = 0;
int log_perror = 1;
@@ -85,16 +83,19 @@ struct sockaddr_in sockaddr_broadcast;
assert (state_is == state_shouldbe). */
#define ASSERT_STATE(state_is, state_shouldbe) {}
-#ifdef USE_FALLBACK
-struct interface_info fallback_interface;
-#endif
-
u_int16_t local_port;
u_int16_t remote_port;
int log_priority;
int no_daemon;
int save_scripts;
+static char copyright[] =
+"Copyright 1995, 1996, 1997, 1998 The Internet Software Consortium.";
+static char arr [] = "All rights reserved.";
+static char message [] = "Internet Software Consortium DHCP Client V2.0b1pl8";
+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 void usage PROTO ((void));
int main (argc, argv, envp)
@@ -105,6 +106,7 @@ int main (argc, argv, envp)
struct servent *ent;
struct interface_info *ip;
int seed;
+ int quiet;
#ifdef SYSLOG_4_2
openlog ("dhclient", LOG_NDELAY);
@@ -128,6 +130,13 @@ int main (argc, argv, envp)
no_daemon = 1;
} else if (!strcmp (argv [i], "-D")) {
save_scripts = 1;
+ } else if (!strcmp (argv [i], "-lf")) {
+ if (++i == argc)
+ usage ();
+ path_dhclient_db = argv [i];
+ } else if (!strcmp (argv [i], "-q")) {
+ quiet = 1;
+ quiet_interface_discovery = 1;
} else if (argv [i][0] == '-') {
usage ();
} else {
@@ -145,6 +154,15 @@ int main (argc, argv, envp)
interfaces = tmp;
}
}
+
+ if (!quiet) {
+ note (message);
+ note (copyright);
+ note (arr);
+ note (contrib);
+ note (url);
+ }
+
/* Default to the DHCP/BOOTP port. */
if (!local_port) {
ent = getservbyname ("dhcpc", "udp");
@@ -240,9 +258,6 @@ int main (argc, argv, envp)
/* Set up the bootp packet handler... */
bootp_packet_handler = do_packet;
- /* Start listening on the sysconf socket... */
- sysconf_startup (status_message);
-
/* Start dispatching packets and timeouts... */
dispatch ();
@@ -252,7 +267,7 @@ int main (argc, argv, envp)
static void usage ()
{
- error ("Usage: dhclient [-c] [-p <port>] [interface]");
+ error ("Usage: dhclient [-c] [-p <port>] [-lf lease-file] [interface]");
}
void cleanup ()
@@ -1189,6 +1204,14 @@ void send_request (ipp)
ip -> client -> alias);
script_go (ip);
+ /* Now do a preinit on the interface so that we can
+ discover a new address. */
+ script_init (ip, "PREINIT", (struct string_list *)0);
+ if (ip -> client -> alias)
+ script_write_params (ip, "alias_",
+ ip -> client -> alias);
+ script_go (ip);
+
ip -> client -> state = S_INIT;
state_init (ip);
return;
@@ -1251,16 +1274,15 @@ void send_request (ipp)
inet_ntoa (destination.sin_addr),
ntohs (destination.sin_port));
-#ifdef USE_FALLBACK
- if (destination.sin_addr.s_addr != INADDR_BROADCAST)
- result = send_fallback (&fallback_interface,
- (struct packet *)0,
- &ip -> client -> packet,
- ip -> client -> packet_length,
- from, &destination,
- (struct hardware *)0);
+ if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
+ fallback_interface)
+ result = send_packet (fallback_interface,
+ (struct packet *)0,
+ &ip -> client -> packet,
+ ip -> client -> packet_length,
+ from, &destination,
+ (struct hardware *)0);
else
-#endif /* USE_FALLBACK */
/* Send out a packet. */
result = send_packet (ip, (struct packet *)0,
&ip -> client -> packet,
@@ -1383,8 +1405,8 @@ void make_discover (ip, lease)
/* Set up the option buffer... */
ip -> client -> packet_length =
- cons_options ((struct packet *)0, &ip -> client -> packet, 0,
- options, (struct agent_options *)0, 0, 0, 0);
+ cons_options ((struct packet *)0, &ip -> client -> packet,
+ options, 0, 0, 0);
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
ip -> client -> packet_length = BOOTP_MIN_LEN;
@@ -1490,8 +1512,8 @@ void make_request (ip, lease)
/* Set up the option buffer... */
ip -> client -> packet_length =
- cons_options ((struct packet *)0, &ip -> client -> packet, 0,
- options, (struct agent_options *)0, 0, 0, 0);
+ cons_options ((struct packet *)0, &ip -> client -> packet,
+ options, 0, 0, 0);
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
ip -> client -> packet_length = BOOTP_MIN_LEN;
@@ -1589,8 +1611,8 @@ void make_decline (ip, lease)
/* Set up the option buffer... */
ip -> client -> packet_length =
- cons_options ((struct packet *)0, &ip -> client -> packet, 0,
- options, (struct agent_options *)0, 0, 0, 0);
+ cons_options ((struct packet *)0, &ip -> client -> packet,
+ options, 0, 0, 0);
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
ip -> client -> packet_length = BOOTP_MIN_LEN;
@@ -1655,8 +1677,8 @@ void make_release (ip, lease)
/* Set up the option buffer... */
ip -> client -> packet_length =
- cons_options ((struct packet *)0, &ip -> client -> packet, 0,
- options, (struct agent_options *)0, 0, 0, 0);
+ cons_options ((struct packet *)0, &ip -> client -> packet,
+ options, 0, 0, 0);
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
ip -> client -> packet_length = BOOTP_MIN_LEN;
@@ -2093,46 +2115,3 @@ void write_client_pid_file ()
fclose (pf);
}
}
-
-void status_message (header, data)
- struct sysconf_header *header;
- void *data;
-{
- switch (header -> type) {
- case NETWORK_LOCATION_CHANGED:
- client_location_changed ();
- break;
-
- default:
- break;
- }
-}
-
-void client_location_changed ()
-{
- struct interface_info *ip;
-
- for (ip = interfaces; ip; ip = ip -> next) {
- switch (ip -> client -> state) {
- case S_SELECTING:
- cancel_timeout (send_discover, ip);
- break;
-
- case S_BOUND:
- cancel_timeout (state_bound, ip);
- break;
-
- case S_REBOOTING:
- case S_REQUESTING:
- case S_RENEWING:
- cancel_timeout (send_request, ip);
- break;
-
- case S_INIT:
- case S_REBINDING:
- break;
- }
- ip -> client -> state = S_INIT;
- state_reboot (ip);
- }
-}
diff --git a/client/dhclient.conf.5 b/client/dhclient.conf.5
index be03f040..c5af648c 100644
--- a/client/dhclient.conf.5
+++ b/client/dhclient.conf.5
@@ -230,9 +230,10 @@ needs, several option modifiers are available.
.B default
.I statement
.PP
- \fBdefault [ \fIoption declaration\fR ] \fB;\fR
+ \fBdefault { [ \fIoption declaration\fR ]
+[\fB,\fI ... \fIoption declaration\fR ]\fB}\fR
.PP
-If for some option the client should use the value supplied by
+If for some set of options the client should use the value supplied by
the server, but needs to use some default value if no value was supplied
by the server, these values can be defined in the
.B default
@@ -242,11 +243,12 @@ statement.
.B supersede
.I statement
.PP
- \fBsupersede [ \fIoption declaration\fR ] \fB;\fR
+ \fBsupersede { [ \fIoption declaration\fR ]
+[\fB,\fI ... \fIoption declaration\fR ]\fB}\fR
.PP
-If for some option the client should always use a locally-configured
-value or values rather than whatever is supplied by the server, these
-values can be defined in the
+If for some set of options the client should always use its own value
+rather than any value supplied by the server, these values can be
+defined in the
.B supersede
statement.
.PP
@@ -254,11 +256,12 @@ statement.
.B prepend
.I statement
.PP
- \fBprepend [ \fIoption declaration\fR ] \fB;\fR
+ \fBprepend { [ \fIoption declaration\fR ]
+[\fB,\fI ... \fIoption declaration\fR ]\fB}\fR
.PP
-If for some option the client should use both a value it
-supplies, and then any values supplied by
-the server, these values can be defined in the
+If for some set of options the client should first a value it
+supplies, and then use the values supplied by
+the server, if any, these values can be defined in the
.B prepend
statement. The
.B prepend
@@ -269,11 +272,12 @@ allow more than one value to be given.
.B append
.I statement
.PP
- \fBappend [ \fIoption declaration\fR ] \fB;\fR
+ \fBappend { [ \fIoption declaration\fR ]
+[\fB,\fI ... \fIoption declaration\fR ]\fB}\fR
.PP
-If for some option the client should first any values supplied
-to it by the server, and then some values it supplies, those values
-should be defined in the
+If for some set of options the client should first a value it
+supplies, and then use the values supplied by
+the server, if any, these values can be defined in the
.B append
statement. The
.B append
@@ -426,8 +430,8 @@ specified as zero. The year is specified with the century, so it
should generally be four digits except for really long leases. The
month is specified as a number starting with 1 for January. The day
of the month is likewise specified starting with 1. The hour is a
-number between 0 and 23, the minute a number between 0 and 59, and the
-second also a number between 0 and 59.
+number between 0 and 23, the minute a number between 0 and 69, and the
+second also a number between 0 and 69.
.SH ALIAS DECLARATIONS
\fBalias { \fI declarations ... \fB}\fR
.PP
diff --git a/client/scripts/linux b/client/scripts/linux
index 57f8d1c5..9f6e0e11 100755
--- a/client/scripts/linux
+++ b/client/scripts/linux
@@ -88,7 +88,7 @@ if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg
route add -host $alias_ip_address $interface:0
fi
- echo search $new_domain_name >/etc/resolv.conf
+ echo domain $new_domain_name >/etc/resolv.conf
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf
done
diff --git a/client/scripts/solaris b/client/scripts/solaris
index 4f60ebaa..3945d4e7 100755
--- a/client/scripts/solaris
+++ b/client/scripts/solaris
@@ -69,15 +69,15 @@ if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
[ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
ifconfig $interface inet $new_ip_address $new_netmask_arg \
$new_broadcast_arg $medium
- route add $new_ip_address 127.1 >/dev/null 2>&1
+ route add $new_ip_address 127.1 1 >/dev/null 2>&1
for router in $new_routers; do
- route add default $router >/dev/null 2>&1
+ route add default $router 1 >/dev/null 2>&1
done
fi
if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
- route add $alias_ip_address 127.0.0.1
+ route add $alias_ip_address 127.0.0.1 1
fi
echo search $new_domain_name >/etc/resolv.conf
for nameserver in $new_domain_name_servers; do
@@ -102,7 +102,7 @@ if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
fi
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
- route add $alias_ip_address 127.0.0.1
+ route add $alias_ip_address 127.0.0.1 1
fi
exit 0
fi
@@ -120,11 +120,11 @@ if [ x$reason = xTIMEOUT ]; then
if [ x$new_ip_address != x$alias_ip_address ] && \
[ x$alias_ip_address != x ]; then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
- route add $alias_ip_address 127.0.0.1
+ route add $alias_ip_address 127.0.0.1 1
fi
- route add $new_ip_address 127.1 >/dev/null 2>&1
+ route add $new_ip_address 127.1 1 >/dev/null 2>&1
for router in $new_routers; do
- route add default $router >/dev/null 2>&1
+ route add default $router 1 >/dev/null 2>&1
done
echo search $new_domain_name >/etc/resolv.conf.std
for nameserver in $new_domain_name_servers; do
diff --git a/common/Makefile.dist b/common/Makefile.dist
index 063a94bc..61393346 100644
--- a/common/Makefile.dist
+++ b/common/Makefile.dist
@@ -1,7 +1,6 @@
# Makefile.dist
#
-# Copyright (c) 1996, 1997, 1998 The Internet Software Consortium.
-# All rights reserved.
+# Copyright (c) 1996 The Internet Software Consortium. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -32,13 +31,11 @@
CATMANPAGES = dhcp-options.cat5
SRC = raw.c parse.c nit.c icmp.c dispatch.c conflex.c upf.c bpf.c socket.c \
- dlpi.c packet.c memory.c print.c options.c inet.c convert.c \
- tree.c tables.c hash.c alloc.c errwarn.c inet_addr.c dns.c \
- resolv.c sysconf.c interact.c execute.c discover.c
+ lpf.c packet.c memory.c print.c options.c inet.c convert.c \
+ tree.c tables.c hash.c alloc.c errwarn.c inet_addr.c dlpi.c
OBJ = raw.o parse.o nit.o icmp.o dispatch.o conflex.o upf.o bpf.o socket.o \
- dlpi.o packet.o memory.o print.o options.o inet.o convert.o \
- tree.o tables.o hash.o alloc.o errwarn.o inet_addr.o dns.o \
- resolv.o sysconf.o interact.o execute.o discover.o
+ lpf.o packet.o memory.o print.o options.o inet.o convert.o \
+ tree.o tables.o hash.o alloc.o errwarn.o inet_addr.o dlpi.o
MAN = dhcp-options.5
DEBUG = -g
@@ -53,31 +50,17 @@ libdhcp.a: $(OBJ)
ranlib libdhcp.a
install: $(CATMANPAGES)
- @for dir in $(FFMANDIR); do \
- case $$dir in \
- /*) base=/ ;; \
- *) base="" ;; \
- esac; \
- slash=""; \
- for elt in `echo $$dir |sed -e 's/\// /g'`; do \
- if [ ! -d $$base/$$elt ]; then \
- echo Making $$base/$$elt; \
- mkdir $$base/$$elt; \
- chmod 755 $$base/$$elt; \
- fi; \
- base=$$base$$slash$$elt; \
- slash=/; \
- done; \
- done
+ if [ ! -d $(FFMANDIR) ]; then \
+ mkdir $(FFMANDIR); \
+ chmod 755 $(FFMANDIR); \
+ fi
$(MANINSTALL) $(MANFROM) dhcp-options.cat5 $(MANTO) \
$(FFMANDIR)/dhcp-options$(FFMANEXT)
-depend:
- makedepend $(INCLUDES) $(PREDEFINES) $(SRCS)
clean:
-rm -f $(OBJ)
-
+
realclean: clean
-rm -f libdhcp.a *~ #* $(CATMANPAGES)
diff --git a/common/alloc.c b/common/alloc.c
index 78d681b2..a9584622 100644
--- a/common/alloc.c
+++ b/common/alloc.c
@@ -3,7 +3,7 @@
Memory allocation... */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: alloc.c,v 1.15 1998/06/25 02:53:00 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: alloc.c,v 1.13.2.1 1998/11/24 22:17:15 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -90,29 +90,28 @@ struct dhcp_packet *new_dhcp_packet (name)
return rval;
}
-struct expression *new_expression (name)
+struct tree *new_tree (name)
char *name;
{
- struct expression *rval = dmalloc (sizeof (struct expression), name);
+ struct tree *rval = dmalloc (sizeof (struct tree), name);
return rval;
}
-struct option_cache *free_option_caches;
+struct tree_cache *free_tree_caches;
-struct option_cache *new_option_cache (name)
+struct tree_cache *new_tree_cache (name)
char *name;
{
- struct option_cache *rval;
+ struct tree_cache *rval;
- if (free_option_caches) {
- rval = free_option_caches;
- free_option_caches =
- (struct option_cache *)(rval -> expression);
+ if (free_tree_caches) {
+ rval = free_tree_caches;
+ free_tree_caches =
+ (struct tree_cache *)(rval -> value);
} else {
- rval = dmalloc (sizeof (struct option_cache), name);
+ rval = dmalloc (sizeof (struct tree_cache), name);
if (!rval)
- error ("unable to allocate option cache for %s.",
- name);
+ error ("unable to allocate tree cache for %s.", name);
}
return rval;
}
@@ -301,19 +300,12 @@ void free_hash_table (ptr, name)
dfree ((VOIDPTR)ptr, name);
}
-void free_expression (ptr, name)
- struct expression *ptr;
+void free_tree_cache (ptr, name)
+ struct tree_cache *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
-}
-
-void free_option_cache (ptr, name)
- struct option_cache *ptr;
- char *name;
-{
- ptr -> expression = (struct expression *)free_option_caches;
- free_option_caches = ptr;
+ ptr -> value = (unsigned char *)free_tree_caches;
+ free_tree_caches = ptr;
}
void free_packet (ptr, name)
@@ -329,3 +321,10 @@ void free_dhcp_packet (ptr, name)
{
dfree ((VOIDPTR)ptr, name);
}
+
+void free_tree (ptr, name)
+ struct tree *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
diff --git a/common/bpf.c b/common/bpf.c
index e47aa1f7..3e4b422f 100644
--- a/common/bpf.c
+++ b/common/bpf.c
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: bpf.c,v 1.19 1997/10/20 21:47:13 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: bpf.c,v 1.19.2.2 1998/12/22 22:39:19 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -137,12 +137,12 @@ void if_register_send (info)
}
#endif /* USE_BPF_SEND */
-#ifdef USE_BPF_RECEIVE
+#if defined (USE_BPF_RECEIVE) || defined (USE_LPF_RECEIVE)
/* Packet filter program...
XXX Changes to the filter program may require changes to the constant
offsets used in if_register_send to patch the BPF program! XXX */
-struct bpf_insn filter [] = {
+struct bpf_insn dhcp_bpf_filter [] = {
/* Make sure this is an IP packet... */
BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
@@ -169,6 +169,10 @@ struct bpf_insn filter [] = {
BPF_STMT(BPF_RET+BPF_K, 0),
};
+int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
+#endif
+
+#if defined (USE_BPF_RECEIVE)
void if_register_receive (info)
struct interface_info *info;
{
@@ -220,13 +224,13 @@ void if_register_receive (info)
info -> rbuf_len = 0;
/* Set up the bpf filter program structure. */
- p.bf_len = sizeof filter / sizeof (struct bpf_insn);
- p.bf_insns = filter;
+ p.bf_len = dhcp_bpf_filter_len;
+ p.bf_insns = dhcp_bpf_filter;
/* Patch the server port into the BPF program...
XXX changes to filter program may require changes
to the insn number(s) used below! XXX */
- filter [8].k = ntohs (local_port);
+ dhcp_bpf_filter [8].k = ntohs (local_port);
if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0)
error ("Can't install packet filter program: %m");
@@ -255,6 +259,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
unsigned char buf [256];
struct iovec iov [2];
+ 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,
@@ -383,4 +391,20 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
} while (!length);
return 0;
}
+
+int can_unicast_without_arp ()
+{
+ return 1;
+}
+
+void maybe_setup_fallback ()
+{
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ if_register_fallback (fbi);
+ add_protocol ("fallback", fallback_interface -> wfdesc,
+ fallback_discard, fallback_interface);
+ }
+}
#endif
diff --git a/common/conflex.c b/common/conflex.c
index dca909f3..ebb09885 100644
--- a/common/conflex.c
+++ b/common/conflex.c
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: conflex.c,v 1.34 1998/10/17 13:34:31 mellon Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
+"$Id: conflex.c,v 1.29.2.1 1998/12/22 22:39:58 mellon Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -104,14 +104,14 @@ static int get_char (cfile)
cur_line = line2;
prev_line = line1;
} else {
- cur_line = line1;
- prev_line = line2;
+ cur_line = line2;
+ prev_line = line1;
}
line++;
lpos = 1;
cur_line [0] = 0;
} else if (c != EOF) {
- if (lpos <= 80) {
+ if (lpos <= 81) {
cur_line [lpos - 1] = c;
cur_line [lpos] = 0;
}
@@ -354,8 +354,6 @@ static int intern (atom, dfv)
switch (tolower (atom [0])) {
case 'a':
- if (!strcasecmp (atom + 1, "nd"))
- return AND;
if (!strcasecmp (atom + 1, "ppend"))
return APPEND;
if (!strcasecmp (atom + 1, "llow"))
@@ -364,8 +362,6 @@ static int intern (atom, dfv)
return ALIAS;
if (!strcasecmp (atom + 1, "bandoned"))
return ABANDONED;
- if (!strcasecmp (atom + 1, "dd"))
- return ADD;
break;
case 'b':
if (!strcasecmp (atom + 1, "ackoff-cutoff"))
@@ -376,12 +372,7 @@ static int intern (atom, dfv)
return BOOTING;
if (!strcasecmp (atom + 1, "oot-unknown-clients"))
return BOOT_UNKNOWN_CLIENTS;
- if (!strcasecmp (atom + 1, "reak"))
- return BREAK;
- break;
case 'c':
- if (!strcasecmp (atom + 1, "heck"))
- return CHECK;
if (!strcasecmp (atom + 1, "lass"))
return CLASS;
if (!strcasecmp (atom + 1, "iaddr"))
@@ -414,31 +405,20 @@ static int intern (atom, dfv)
}
break;
case 'e':
- if (isascii (atom [1]) && tolower (atom [1]) == 'x') {
- if (!strcasecmp (atom + 2, "tract-int"))
- return EXTRACT_INT;
- if (!strcasecmp (atom + 2, "ists"))
- return EXISTS;
- }
if (!strcasecmp (atom + 1, "thernet"))
return ETHERNET;
if (!strcasecmp (atom + 1, "nds"))
return ENDS;
if (!strcasecmp (atom + 1, "xpire"))
return EXPIRE;
- if (!strncasecmp (atom + 1, "ls", 2)) {
- if (!strcasecmp (atom + 3, "e"))
- return ELSE;
- if (!strcasecmp (atom + 3, "if"))
- return ELSIF;
- break;
- }
break;
case 'f':
if (!strcasecmp (atom + 1, "ilename"))
return FILENAME;
if (!strcasecmp (atom + 1, "ixed-address"))
return FIXED_ADDR;
+ if (!strcasecmp (atom + 1, "ddi"))
+ return FDDI;
break;
case 'g':
if (!strcasecmp (atom + 1, "iaddr"))
@@ -461,8 +441,6 @@ static int intern (atom, dfv)
return INITIAL_INTERVAL;
if (!strcasecmp (atom + 1, "nterface"))
return INTERFACE;
- if (!strcasecmp (atom + 1, "f"))
- return IF;
break;
case 'l':
if (!strcasecmp (atom + 1, "ease"))
@@ -471,13 +449,6 @@ static int intern (atom, dfv)
case 'm':
if (!strcasecmp (atom + 1, "ax-lease-time"))
return MAX_LEASE_TIME;
- if (!strncasecmp (atom + 1, "in-", 3)) {
- if (!strcasecmp (atom + 4, "lease-time"))
- return MIN_LEASE_TIME;
- if (!strcasecmp (atom + 4, "secs"))
- return MIN_SECS;
- break;
- }
if (!strncasecmp (atom + 1, "edi", 3)) {
if (!strcasecmp (atom + 4, "a"))
return MEDIA;
@@ -485,12 +456,8 @@ static int intern (atom, dfv)
return MEDIUM;
break;
}
- if (!strcasecmp (atom + 1, "atch"))
- return MATCH;
break;
case 'n':
- if (!strcasecmp (atom + 1, "ot"))
- return NOT;
if (!strcasecmp (atom + 1, "ameserver"))
return NAMESERVER;
if (!strcasecmp (atom + 1, "etmask"))
@@ -499,8 +466,6 @@ static int intern (atom, dfv)
return NEXT_SERVER;
break;
case 'o':
- if (!strcasecmp (atom + 1, "r"))
- return OR;
if (!strcasecmp (atom + 1, "ption"))
return OPTION;
if (!strcasecmp (atom + 1, "ne-lease-per-client"))
@@ -531,14 +496,14 @@ static int intern (atom, dfv)
return REJECT;
break;
case 's':
- if (!strcasecmp (atom + 1, "uffix"))
- return SUFFIX;
if (!strcasecmp (atom + 1, "earch"))
return SEARCH;
if (!strcasecmp (atom + 1, "tarts"))
return STARTS;
if (!strcasecmp (atom + 1, "iaddr"))
return SIADDR;
+ if (!strcasecmp (atom + 1, "ubnet"))
+ return SUBNET;
if (!strcasecmp (atom + 1, "hared-network"))
return SHARED_NETWORK;
if (!strcasecmp (atom + 1, "erver-name"))
@@ -553,17 +518,6 @@ static int intern (atom, dfv)
return SCRIPT;
if (!strcasecmp (atom + 1, "upersede"))
return SUPERSEDE;
- if (!strncasecmp (atom + 1, "ub", 2)) {
- if (!strcasecmp (atom + 3, "string"))
- return SUBSTRING;
- if (!strcasecmp (atom + 3, "net"))
- return SUBNET;
- if (!strcasecmp (atom + 3, "class"))
- return SUBCLASS;
- break;
- }
- if (!strcasecmp (atom + 1, "pawn"))
- return SPAWN;
break;
case 't':
if (!strcasecmp (atom + 1, "imestamp"))
@@ -580,8 +534,6 @@ static int intern (atom, dfv)
return USER_CLASS;
if (!strcasecmp (atom + 1, "se-host-decl-names"))
return USE_HOST_DECL_NAMES;
- if (!strcasecmp (atom + 1, "se-lease-addr-for-default-route"))
- return USE_HOST_DECL_NAMES;
if (!strcasecmp (atom + 1, "nknown-clients"))
return UNKNOWN_CLIENTS;
break;
@@ -589,10 +541,6 @@ static int intern (atom, dfv)
if (!strcasecmp (atom + 1, "endor-class"))
return VENDOR_CLASS;
break;
- case 'w':
- if (!strcasecmp (atom + 1, "ith"))
- return WITH;
- break;
case 'y':
if (!strcasecmp (atom + 1, "iaddr"))
return YIADDR;
diff --git a/common/convert.c b/common/convert.c
index 47f7b199..42f488b3 100644
--- a/common/convert.c
+++ b/common/convert.c
@@ -4,7 +4,7 @@
can't be assumed to be aligned. */
/*
- * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: convert.c,v 1.5 1998/03/16 06:09:32 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: convert.c,v 1.4.2.1 1998/06/25 21:11:28 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -102,7 +102,7 @@ void putLong (obuf, val)
void putUShort (obuf, val)
unsigned char *obuf;
- u_int32_t val;
+ unsigned int val;
{
u_int16_t tmp = htons (val);
memcpy (obuf, &tmp, sizeof tmp);
@@ -110,7 +110,7 @@ void putUShort (obuf, val)
void putShort (obuf, val)
unsigned char *obuf;
- int32_t val;
+ int val;
{
int16_t tmp = htons (val);
memcpy (obuf, &tmp, sizeof tmp);
diff --git a/common/dhcp-options.5 b/common/dhcp-options.5
index 95d95714..3375c507 100644
--- a/common/dhcp-options.5
+++ b/common/dhcp-options.5
@@ -1,6 +1,6 @@
.\" dhcp-options.5
.\"
-.\" Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
+.\" Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -126,7 +126,8 @@ no checking is done to ensure the correctness of the entered data.
.PP
The standard options are:
.PP
- \fBoption subnet-mask\fR \fIip-address\fR\fB;\fR
+.B option subnet-mask \fIip-address\fR\fB;\fR
+.RS 0.25i
.PP
The subnet mask option specifies the client's subnet mask as per RFC
950. If no subnet mask option is provided anywhere in scope, as a
@@ -136,114 +137,162 @@ for the network on which an address is being assigned. However,
subnet-mask option declaration that is in scope for the address being
assigned will override the subnet mask specified in the subnet
declaration.
+.RE
.PP
- \fBoption time-offset\fR \fIint32\fR\fB;\fR
+.B option time-offset \fIint32\fR\fB;\fR
+.RS 0.25i
.PP
The time-offset option specifies the offset of the client's subnet in
seconds from Coordinated Universal Time (UTC).
+.RE
.PP
- \fBoption routers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option routers \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The routers option specifies a list of IP addresses for routers on the
client's subnet. Routers should be listed in order of preference.
+.RE
.PP
- \fBoption time-servers\fR \fIip-address [, \fIip-address\fR ... ]\fB;\fR
+.B option time-servers \fIip-address\fR [, \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The time-server option specifies a list of RFC 868 time servers
available to the client. Servers should be listed in order of
preference.
+.RE
.PP
- \fBoption\fR \fBien116-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ];
+.B option \fBien116-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+];
+.RS 0.25i
.PP
The ien116-name-servers option specifies a list of IEN 116 name servers
available to the client. Servers should be listed in order of
preference.
+.RE
.PP
- \fBoption\fR \fBdomain-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBdomain-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The domain-name-servers option specifies a list of Domain Name System
(STD 13, RFC 1035) name servers available to the client. Servers
should be listed in order of preference.
+.RE
.PP
- \fBoption\fR \fBlog-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBlog-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The log-server option specifies a list of MIT-LCS UDP log servers
available to the client. Servers should be listed in order of
preference.
+.RE
.PP
- \fBoption\fR \fBcookie-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBcookie-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The cookie server option specifies a list of RFC 865 cookie
servers available to the client. Servers should be listed in order
of preference.
+.RE
.PP
- \fBoption\fR \fBlpr-servers\fR \fIip-address \fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBlpr-servers\fR \fIip-address \fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The LPR server option specifies a list of RFC 1179 line printer
servers available to the client. Servers should be listed in order
of preference.
+.RE
.PP
- \fBoption\fR \fBimpress-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBimpress-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The impress-server option specifies a list of Imagen Impress servers
available to the client. Servers should be listed in order of
preference.
+.RE
.PP
- \fBoption\fR \fBresource-location-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBresource-location-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies a list of RFC 887 Resource Location
servers available to the client. Servers should be listed in order
of preference.
+.RE
.PP
- \fBoption\fR \fBhost-name\fR \fIstring\fR\fB;\fR
+.B option \fBhost-name\fR \fIstring\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the name of the client. The name may or may
not be qualified with the local domain name (it is preferable to use
the domain-name option to specify the domain name). See RFC 1035 for
character set restrictions.
+.RE
.PP
- \fBoption\fR \fBboot-size\fR \fIuint16\fR\fB;\fR
+.B option \fBboot-size\fR \fIuint16\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the length in 512-octet blocks of the default
boot image for the client.
+.RE
.PP
- \fBoption\fR \fBmerit-dump\fR \fIstring\fR\fB;\fR
+.B option \fBmerit-dump\fR \fIstring\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the path-name of a file to which the client's
core image should be dumped in the event the client crashes. The
path is formatted as a character string consisting of characters from
the NVT ASCII character set.
+.RE
.PP
- \fBoption\fR \fBdomain-name\fR \fIstring\fR\fB;\fR
+.B option \fBdomain-name\fR \fIstring\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the domain name that client should use when
resolving hostnames via the Domain Name System.
+.RE
.PP
- \fBoption\fR \fBswap-server\fR \fIip-address\fR\fB;\fR
+.B option \fBswap-server\fR \fIip-address\fR\fB;\fR
+.RS 0.25i
.PP
This specifies the IP address of the client's swap server.
+.RE
.PP
- \fBoption\fR \fBroot-path\fR \fIstring\fB;\fR\fR
+.B option \fBroot-path\fR \fIstring\fB;\fR\fR
+.RS 0.25i
.PP
This option specifies the path-name that contains the client's root
disk. The path is formatted as a character string consisting of
characters from the NVT ASCII character set.
+.RE
.PP
- \fBoption\fR \fBip-forwarding\fR \fIflag\fR\fB;\fR
+.B option \fBip-forwarding\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies whether the client should configure its IP
layer for packet forwarding. A value of 0 means disable IP
forwarding, and a value of 1 means enable IP forwarding.
+.RE
.PP
- \fBoption\fR \fBnon-local-source-routing\fR \fIflag\fR\fB;\fR
+.B option \fBnon-local-source-routing\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies whether the client should configure its IP
layer to allow forwarding of datagrams with non-local source routes
(see Section 3.3.5 of [4] for a discussion of this topic). A value
of 0 means disallow forwarding of such datagrams, and a value of 1
means allow forwarding.
+.RE
.PP
- \fBoption\fR \fBpolicy-filter\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR ... ]\fB;\fR
+.B option \fBpolicy-filter\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies policy filters for non-local source routing.
The filters consist of a list of IP addresses and masks which specify
@@ -253,36 +302,49 @@ Any source routed datagram whose next-hop address does not match one
of the filters should be discarded by the client.
.PP
See STD 3 (RFC1122) for further information.
+.RE
.PP
- \fBoption\fR \fBmax-dgram-reassembly\fR \fIuint16\fR\fB;\fR
+.B option \fBmax-dgram-reassembly\fR \fIuint16\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the maximum size datagram that the client
should be prepared to reassemble. The minimum value legal value is
576.
+.RE
.PP
- \fBoption\fR \fBdefault-ip-ttl\fR \fIuint8;\fR
+.B option \fBdefault-ip-ttl\fR \fIuint8;\fR
+.RS 0.25i
.PP
This option specifies the default time-to-live that the client should
use on outgoing datagrams.
+.RE
.PP
- \fBoption\fR \fBpath-mtu-aging-timeout\fR \fIuint32\fR\fB;\fR
+.B option \fBpath-mtu-aging-timeout\fR \fIuint32\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the timeout (in seconds) to use when aging Path
MTU values discovered by the mechanism defined in RFC 1191.
+.RE
.PP
- \fBoption\fR \fBpath-mtu-plateau-table\fR \fIuint16\fR [\fB,\fR \fIuint16\fR ... ]\fB;\fR
+.B option \fBpath-mtu-plateau-table\fR \fIuint16\fR [\fB,\fR \fIuint16\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies a table of MTU sizes to use when performing
Path MTU Discovery as defined in RFC 1191. The table is formatted as
a list of 16-bit unsigned integers, ordered from smallest to largest.
The minimum MTU value cannot be smaller than 68.
+.RE
.PP
- \fBoption\fR \fBinterface-mtu\fR \fIuint16\fR\fB;\fR
+.B option \fBinterface-mtu\fR \fIuint16\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the MTU to use on this interface. The minimum
legal value for the MTU is 68.
+.RE
.PP
- \fBoption\fR \fBall-subnets-local\fR \fIflag\fR\fB;\fR
+.B option \fBall-subnets-local\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies whether or not the client may assume that all
subnets of the IP network to which the client is connected use the
@@ -290,41 +352,54 @@ same MTU as the subnet of that network to which the client is
directly connected. A value of 1 indicates that all subnets share
the same MTU. A value of 0 means that the client should assume that
some subnets of the directly connected network may have smaller MTUs.
+.RE
.PP
- \fBoption\fR \fBbroadcast-address\fR \fIip-address\fR\fB;\fR
+.B option \fBbroadcast-address\fR \fIip-address\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the broadcast address in use on the client's
subnet. Legal values for broadcast addresses are specified in
section 3.2.1.3 of STD 3 (RFC1122).
+.RE
.PP
- \fBoption\fR \fBperform-mask-discovery\fR \fIflag\fR\fB;\fR
+.B option \fBperform-mask-discovery\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies whether or not the client should perform subnet
mask discovery using ICMP. A value of 0 indicates that the client
should not perform mask discovery. A value of 1 means that the
client should perform mask discovery.
+.RE
.PP
- \fBoption\fR \fBmask-supplier\fR \fIflag\fR\fB;\fR
+.B option \fBmask-supplier\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies whether or not the client should respond to
subnet mask requests using ICMP. A value of 0 indicates that the
client should not respond. A value of 1 means that the client should
respond.
+.RE
.PP
- \fBoption\fR \fBrouter-discovery\fR \fIflag\fR\fB;\fR
+.B option \fBrouter-discovery\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies whether or not the client should solicit
routers using the Router Discovery mechanism defined in RFC 1256.
A value of 0 indicates that the client should not perform
router discovery. A value of 1 means that the client should perform
router discovery.
+.RE
.PP
- \fBoption\fR \fBrouter-solicitation-address\fR \fIip-address\fR\fB;\fR
+.B option \fBrouter-solicitation-address\fR \fIip-address\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the address to which the client should transmit
router solicitation requests.
+.RE
.PP
- \fBoption\fR \fBstatic-routes\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR ... ]\fB;\fR
+.B option \fBstatic-routes\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies a list of static routes that the client should
install in its routing cache. If multiple routes to the same
@@ -339,108 +414,161 @@ The default route (0.0.0.0) is an illegal destination for a static
route. To specify the default route, use the
.B routers
option.
+.RE
.PP
- \fBoption\fR \fBtrailer-encapsulation\fR \fIflag\fR\fB;\fR
+.B option \fBtrailer-encapsulation\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies whether or not the client should negotiate the
use of trailers (RFC 893 [14]) when using the ARP protocol. A value
of 0 indicates that the client should not attempt to use trailers. A
value of 1 means that the client should attempt to use trailers.
+.RE
.PP
- \fBoption\fR \fBarp-cache-timeout\fR \fIuint32\fR\fB;\fR
+.B option \fBarp-cache-timeout\fR \fIuint32\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the timeout in seconds for ARP cache entries.
+.RE
.PP
- \fBoption\fR \fBieee802-3-encapsulation\fR \fIflag\fR\fB;\fR
+.B option \fBieee802-3-encapsulation\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies whether or not the client should use Ethernet
Version 2 (RFC 894) or IEEE 802.3 (RFC 1042) encapsulation if the
interface is an Ethernet. A value of 0 indicates that the client
should use RFC 894 encapsulation. A value of 1 means that the client
should use RFC 1042 encapsulation.
+.RE
.PP
- \fBoption\fR \fBdefault-tcp-ttl\fR \fIuint8\fR\fB;\fR
+.B option \fBdefault-tcp-ttl\fR \fIuint8\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the default TTL that the client should use when
sending TCP segments. The minimum value is 1.
+.RE
.PP
- \fBoption\fR \fBtcp-keepalive-interval\fR \fIuint32\fR\fB;\fR
+.B option \fBtcp-keepalive-interval\fR \fIuint32\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the interval (in seconds) that the client TCP
should wait before sending a keepalive message on a TCP connection.
The time is specified as a 32-bit unsigned integer. A value of zero
indicates that the client should not generate keepalive messages on
connections unless specifically requested by an application.
+.RE
.PP
- \fBoption\fR \fBtcp-keepalive-garbage\fR \fIflag\fR\fB;\fR
+.B option \fBtcp-keepalive-garbage\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the whether or not the client should send TCP
keepalive messages with a octet of garbage for compatibility with
older implementations. A value of 0 indicates that a garbage octet
should not be sent. A value of 1 indicates that a garbage octet
should be sent.
+.RE
.PP
- \fBoption\fR \fBnis-domain\fR \fIstring\fR\fB;\fR
+.B option \fBnis-domain\fR \fIstring\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the name of the client's NIS (Sun Network
Information Services) domain. The domain is formatted as a character
string consisting of characters from the NVT ASCII character set.
+.RE
.PP
- \fBoption\fR \fBnis-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBnis-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies a list of IP addresses indicating NIS servers
available to the client. Servers should be listed in order of
preference.
+.RE
.PP
- \fBoption\fR \fBntp-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBntp-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies a list of IP addresses indicating NTP (RFC 1035)
servers available to the client. Servers should be listed in order
of preference.
+.RE
.PP
- \fBoption\fR \fBnetbios-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBnetbios-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The NetBIOS name server (NBNS) option specifies a list of RFC
1001/1002 NBNS name servers listed in order of preference. NetBIOS
-Name Service is more commonly referred to nowadays as WINS. WINS
+Name Service is currently more commonly referred to as WINS. WINS
servers can be specified using the netbios-name-servers option.
+.RE
.PP
- \fBoption\fR \fBnetbios-dd-server\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBnetbios-dd-server\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The NetBIOS datagram distribution server (NBDD) option specifies a
list of RFC 1001/1002 NBDD servers listed in order of preference.
+.RE
.PP
- \fBoption\fR \fBnetbios-node-type\fR \fIuint8\fR\fB;\fR
+.B option \fBnetbios-node-type\fR \fIuint8\fR\fB;\fR
+.RS 0.25i
.PP
The NetBIOS node type option allows NetBIOS over TCP/IP clients which
are configurable to be configured as described in RFC 1001/1002. The
value is specified as a single octet which identifies the client type.
-A value of 1 corresponds to a NetBIOS B-node; a value of 2 corresponds
-to a P-node; a value of 4 corresponds to an M-node; a value of 8
-corresponds to an H-node.
.PP
- \fBoption\fR \fBnetbios-scope\fR \fIstring\fR\fB;\fR
+Possible node types are:
+.PP
+.TP 5
+.I 1
+B-node: Broadcast - no WINS
+.TP
+.I 2
+P-node: Peer - WINS only.
+.TP
+.I 4
+M-node: Mixed - broadcast, then WINS
+.TP
+.I 8
+H-node: Hybrid - WINS, then broadcast
+.RE
+.PP
+.B option
+.B netbios-scope
+.I string\fB;\fR
+.RS 0.25i
.PP
The NetBIOS scope option specifies the NetBIOS over TCP/IP scope
parameter for the client as specified in RFC 1001/1002. See RFC1001,
RFC1002, and RFC1035 for character-set restrictions.
+.RE
.PP
- \fBoption\fR \fBfont-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBfont-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies a list of X Window System Font servers available
to the client. Servers should be listed in order of preference.
+.RE
.PP
- \fBoption\fR \fBx-display-manager\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBx-display-manager\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies a list of systems that are running the X Window
System Display Manager and are available to the client. Addresses
should be listed in order of preference.
+.RE
.PP
- \fBoption\fR \fBdhcp-client-identifier\fR \fIdata-string\fR\fB;\fR
+.B option \fBdhcp-client-identifier\fR \fIdata-string\fR\fB;\fR
+.RS 0.25i
.PP
This option can be used to specify the a DHCP client identifier in a
host declaration, so that dhcpd can find the host record by matching
against the client identifier.
+.RE
.SH SEE ALSO
dhcpd.conf(5), dhcpd.leases(5), dhclient.conf(5), dhcpd(8),
dhclient(8), RFC2132, RFC2131.
diff --git a/common/dispatch.c b/common/dispatch.c
index ee1f170f..a2b72209 100644
--- a/common/dispatch.c
+++ b/common/dispatch.c
@@ -3,7 +3,7 @@
Network input dispatcher... */
/*
- * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,28 +42,458 @@
#ifndef lint
static char copyright[] =
-"$Id: dispatch.c,v 1.51 1998/10/17 13:35:24 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dispatch.c,v 1.47.2.6 1998/12/23 14:14:48 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
+#include <sys/ioctl.h>
+struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
struct protocol *protocols;
struct timeout *timeouts;
static struct timeout *free_timeouts;
+static int interfaces_invalidated;
+void (*bootp_packet_handler) PROTO ((struct interface_info *,
+ struct dhcp_packet *, int, unsigned int,
+ struct iaddr, struct hardware *));
-int interfaces_invalidated;
+int quiet_interface_discovery;
-#ifdef USE_POLL
-/* Wait for packets to come in using poll(). Anyway, when a packet
- comes in, call receive_packet to receive the packet and possibly
- strip hardware addressing information from it, and then call
- do_packet to try to do something with it.
+/* Use the SIOCGIFCONF ioctl to get a list of all the attached interfaces.
+ For each interface that's of type INET and not the loopback interface,
+ register that interface with the network I/O software, figure out what
+ subnet it's on, and add it to the list of interfaces. */
+
+void discover_interfaces (state)
+ int state;
+{
+ struct interface_info *tmp;
+ struct interface_info *last, *next;
+ char buf [8192];
+ struct ifconf ic;
+ struct ifreq ifr;
+ int i;
+ int sock;
+ int address_count = 0;
+ struct subnet *subnet;
+ struct shared_network *share;
+ struct sockaddr_in foo;
+ int ir;
+#ifdef ALIAS_NAMES_PERMUTED
+ char *s;
+#endif
+
+ /* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
+ if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ error ("Can't create addrlist socket");
+
+ /* Get the interface configuration information... */
+ ic.ifc_len = sizeof buf;
+ ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
+ i = ioctl(sock, SIOCGIFCONF, &ic);
+
+ if (i < 0)
+ error ("ioctl: SIOCGIFCONF: %m");
+
+ /* 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 ||
+ state == DISCOVER_RELAY ||
+ state == DISCOVER_REQUESTED))
+ ir = 0;
+ else if (state == DISCOVER_UNCONFIGURED)
+ ir = INTERFACE_REQUESTED | INTERFACE_AUTOMATIC;
+ else
+ ir = INTERFACE_REQUESTED;
+
+ /* Cycle through the list of interfaces looking for IP addresses. */
+ for (i = 0; i < ic.ifc_len;) {
+ struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
+#ifdef HAVE_SA_LEN
+ if (ifp -> ifr_addr.sa_len)
+ i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
+ else
+#endif
+ i += sizeof *ifp;
- As you can see by comparing this with the code that uses select(),
- below, this is gratuitously complex. Quelle surprise, eh? This is
- SysV we're talking about, after all, and even in the 90's, it
- wouldn't do for SysV to make networking *easy*, would it? Rant,
- rant... */
+#ifdef ALIAS_NAMES_PERMUTED
+ if ((s = strrchr (ifp -> ifr_name, ':'))) {
+ *s = 0;
+ }
+#endif
+
+#ifdef SKIP_DUMMY_INTERFACES
+ if (!strncmp (ifp -> ifr_name, "dummy", 5))
+ continue;
+#endif
+
+
+ /* See if this is the sort of interface we want to
+ deal with. */
+ strcpy (ifr.ifr_name, ifp -> ifr_name);
+ if (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0)
+ error ("Can't get interface flags for %s: %m",
+ ifr.ifr_name);
+
+ /* Skip loopback, point-to-point and down interfaces,
+ except don't skip down interfaces if we're trying to
+ get a list of configurable interfaces. */
+ if ((ifr.ifr_flags & IFF_LOOPBACK) ||
+#ifdef IFF_POINTOPOINT
+ (ifr.ifr_flags & IFF_POINTOPOINT) ||
+#endif
+ (!(ifr.ifr_flags & IFF_UP) &&
+ state != DISCOVER_UNCONFIGURED))
+ continue;
+
+ /* See if we've seen an interface that matches this one. */
+ for (tmp = interfaces; tmp; tmp = tmp -> next)
+ if (!strcmp (tmp -> name, ifp -> ifr_name))
+ break;
+
+ /* If there isn't already an interface by this name,
+ allocate one. */
+ if (!tmp) {
+ tmp = ((struct interface_info *)
+ dmalloc (sizeof *tmp, "discover_interfaces"));
+ if (!tmp)
+ error ("Insufficient memory to %s %s",
+ "record interface", ifp -> ifr_name);
+ strcpy (tmp -> name, ifp -> ifr_name);
+ tmp -> next = interfaces;
+ tmp -> flags = ir;
+ interfaces = tmp;
+ }
+
+ /* If we have the capability, extract link information
+ and record it in a linked list. */
+#ifdef AF_LINK
+ if (ifp -> ifr_addr.sa_family == AF_LINK) {
+ struct sockaddr_dl *foo = ((struct sockaddr_dl *)
+ (&ifp -> ifr_addr));
+ tmp -> hw_address.hlen = foo -> sdl_alen;
+ tmp -> hw_address.htype = HTYPE_ETHER; /* XXX */
+ memcpy (tmp -> hw_address.haddr,
+ LLADDR (foo), foo -> sdl_alen);
+ } else
+#endif /* AF_LINK */
+
+ if (ifp -> ifr_addr.sa_family == AF_INET) {
+ struct iaddr addr;
+
+ /* Get a pointer to the address... */
+ memcpy (&foo, &ifp -> ifr_addr,
+ sizeof ifp -> ifr_addr);
+
+ /* We don't want the loopback interface. */
+ if (foo.sin_addr.s_addr == htonl (INADDR_LOOPBACK))
+ continue;
+
+
+ /* If this is the first real IP address we've
+ found, keep a pointer to ifreq structure in
+ which we found it. */
+ if (!tmp -> ifp) {
+ struct ifreq *tif;
+#ifdef HAVE_SA_LEN
+ int len = ((sizeof ifp -> ifr_name) +
+ ifp -> ifr_addr.sa_len);
+#else
+ int len = sizeof *ifp;
+#endif
+ tif = (struct ifreq *)malloc (len);
+ if (!tif)
+ error ("no space to remember ifp.");
+ memcpy (tif, ifp, len);
+ tmp -> ifp = tif;
+ tmp -> primary_address = foo.sin_addr;
+ }
+
+ /* Grab the address... */
+ addr.len = 4;
+ memcpy (addr.iabuf, &foo.sin_addr.s_addr,
+ addr.len);
+
+ /* If there's a registered subnet for this address,
+ connect it together... */
+ if ((subnet = find_subnet (addr))) {
+ /* If this interface has multiple aliases
+ on the same subnet, ignore all but the
+ first we encounter. */
+ if (!subnet -> interface) {
+ subnet -> interface = tmp;
+ subnet -> interface_address = addr;
+ } else if (subnet -> interface != tmp) {
+ warn ("Multiple %s %s: %s %s",
+ "interfaces match the",
+ "same subnet",
+ subnet -> interface -> name,
+ tmp -> name);
+ }
+ share = subnet -> shared_network;
+ if (tmp -> shared_network &&
+ tmp -> shared_network != share) {
+ warn ("Interface %s matches %s",
+ tmp -> name,
+ "multiple shared networks");
+ } else {
+ tmp -> shared_network = share;
+ }
+
+ if (!share -> interface) {
+ share -> interface = tmp;
+ } else if (share -> interface != tmp) {
+ warn ("Multiple %s %s: %s %s",
+ "interfaces match the",
+ "same shared network",
+ share -> interface -> name,
+ tmp -> name);
+ }
+ }
+ }
+ }
+
+#if defined (LINUX_SLASHPROC_DISCOVERY)
+ /* On Linux, interfaces that don't have IP addresses don't show up
+ in the SIOCGIFCONF syscall. We got away with this prior to
+ Linux 2.1 because we would give each interface an IP address of
+ 0.0.0.0 before trying to boot, but that doesn't work after 2.1
+ because we're using LPF, because we can't configure interfaces
+ with IP addresses of 0.0.0.0 anymore (grumble). This only
+ matters for the DHCP client, of course - the relay agent and
+ server should only care about interfaces that are configured
+ with IP addresses anyway. */
+
+ if (state == DISCOVER_UNCONFIGURED) {
+ int proc_dev;
+ char buffer [256];
+ struct ifreq *tif;
+ int skip = 2;
+
+ proc_dev = open (PROCDEV_DEVICE, O_RDONLY);
+ if (proc_dev < 0)
+ error ("%s: %m", PROCDEV_DEVICE);
+
+ while (read (proc_dev, buffer, 256) == 256) {
+ char *name = buffer;
+ char *sep;
+
+ /* Skip the first two blocks, which are apparently
+ some kind of header. */
+ if (skip) {
+ --skip;
+ continue;
+ }
+
+ /* XXX What if there is no ':'? Does the device put
+ a NUL at the end of the name, I hope? XXX */
+ sep = strrchr (buffer, ':');
+ if (sep)
+ *sep = '\0';
+ while (*name == ' ')
+ name++;
+
+ /* See if we've seen an interface that matches
+ this one. */
+ for (tmp = interfaces; tmp; tmp = tmp -> next)
+ if (!strcmp (tmp -> name, name))
+ break;
+
+ /* If we already found the interface with SIOCGIFCONF,
+ go on to the next. */
+ if (tmp)
+ continue;
+
+ /* Otherwise, allocate one. */
+ tmp = ((struct interface_info *)
+ dmalloc (sizeof *tmp, "discover_interfaces"));
+ if (!tmp)
+ error ("Insufficient memory to %s %s",
+ "record interface", name);
+ memset (tmp, 0, sizeof *tmp);
+ strcpy (tmp -> name, name);
+
+ /* Mock up an ifreq structure. */
+ tif = (struct ifreq *)malloc (sizeof (struct ifreq));
+ if (!tif)
+ error ("no space to remember ifp.");
+ memset (tif, 0, sizeof (struct ifreq));
+ strcpy (tif -> ifr_name, name);
+ tmp -> ifp = tif;
+ tmp -> flags = ir;
+ tmp -> next = interfaces;
+ interfaces = tmp;
+ }
+ close (proc_dev);
+ }
+#endif
+
+ /* Now cycle through all the interfaces we found, looking for
+ hardware addresses. */
+#if defined (SIOCGIFHWADDR) && !defined (AF_LINK)
+ for (tmp = interfaces; tmp; tmp = tmp -> next) {
+ struct ifreq ifr;
+ struct sockaddr sa;
+ int b, sk;
+
+ /* Read the hardware address from this interface. */
+ ifr = *tmp -> ifp;
+ if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
+ continue;
+
+ sa = *(struct sockaddr *)&ifr.ifr_hwaddr;
+
+ switch (sa.sa_family) {
+#ifdef ARPHRD_LOOPBACK
+ case ARPHRD_LOOPBACK:
+ /* ignore loopback interface */
+ break;
+#endif
+
+ case ARPHRD_ETHER:
+ tmp -> hw_address.hlen = 6;
+ tmp -> hw_address.htype = ARPHRD_ETHER;
+ memcpy (tmp -> hw_address.haddr, sa.sa_data, 6);
+ break;
+
+#ifndef ARPHRD_IEEE802
+# define ARPHRD_IEEE802 HTYPE_IEEE802
+#endif
+ case ARPHRD_IEEE802:
+ tmp -> hw_address.hlen = 6;
+ tmp -> hw_address.htype = ARPHRD_IEEE802;
+ memcpy (tmp -> hw_address.haddr, sa.sa_data, 6);
+ break;
+
+#ifndef ARPHRD_FDDI
+# define ARPHRD_FDDI HTYPE_FDDI
+#endif
+ case ARPHRD_FDDI:
+ tmp -> hw_address.hlen = 16;
+ tmp -> hw_address.htype = HTYPE_FDDI; /* XXX */
+ memcpy (tmp -> hw_address.haddr, sa.sa_data, 16);
+ break;
+
+#ifdef ARPHRD_METRICOM
+ case ARPHRD_METRICOM:
+ tmp -> hw_address.hlen = 6;
+ tmp -> hw_address.htype = ARPHRD_METRICOM;
+ memcpy (tmp -> hw_address.haddr, sa.sa_data, 6);
+ break;
+#endif
+
+ default:
+ error ("%s: unknown hardware address type %d",
+ ifr.ifr_name, sa.sa_family);
+ }
+ }
+#endif /* defined (SIOCGIFHWADDR) && !defined (AF_LINK) */
+
+ /* If we're just trying to get a list of interfaces that we might
+ be able to configure, we can quit now. */
+ if (state == DISCOVER_UNCONFIGURED)
+ return;
+
+ /* Weed out the interfaces that did not have IP addresses. */
+ last = (struct interface_info *)0;
+ for (tmp = interfaces; tmp; tmp = next) {
+ next = tmp -> next;
+ if ((tmp -> flags & INTERFACE_AUTOMATIC) &&
+ state == DISCOVER_REQUESTED)
+ tmp -> flags &= ~(INTERFACE_AUTOMATIC |
+ INTERFACE_REQUESTED);
+ if (!tmp -> ifp || !(tmp -> flags & INTERFACE_REQUESTED)) {
+ if ((tmp -> flags & INTERFACE_REQUESTED) != ir)
+ error ("%s: not found", tmp -> name);
+ if (!last)
+ interfaces = interfaces -> next;
+ else
+ last -> next = tmp -> next;
+
+ /* Remember the interface in case we need to know
+ about it later. */
+ tmp -> next = dummy_interfaces;
+ dummy_interfaces = tmp;
+ continue;
+ }
+ last = tmp;
+
+ memcpy (&foo, &tmp -> ifp -> ifr_addr,
+ sizeof tmp -> ifp -> ifr_addr);
+
+ /* We must have a subnet declaration for each interface. */
+ if (!tmp -> shared_network && (state == DISCOVER_SERVER))
+ error ("No subnet declaration for %s (%s).",
+ tmp -> name, inet_ntoa (foo.sin_addr));
+
+ /* Find subnets that don't have valid interface
+ addresses... */
+ for (subnet = (tmp -> shared_network
+ ? tmp -> shared_network -> subnets
+ : (struct subnet *)0);
+ subnet; subnet = subnet -> next_sibling) {
+ if (!subnet -> interface_address.len) {
+ /* Set the interface address for this subnet
+ to the first address we found. */
+ subnet -> interface_address.len = 4;
+ memcpy (subnet -> interface_address.iabuf,
+ &foo.sin_addr.s_addr, 4);
+ }
+ }
+
+ /* Register the interface... */
+ if_register_receive (tmp);
+ if_register_send (tmp);
+ }
+
+ /* Now register all the remaining interfaces as protocols. */
+ for (tmp = interfaces; tmp; tmp = tmp -> next)
+ add_protocol (tmp -> name, tmp -> rfdesc, got_one, tmp);
+
+ close (sock);
+
+ maybe_setup_fallback ();
+}
+
+struct interface_info *setup_fallback ()
+{
+ fallback_interface =
+ ((struct interface_info *)
+ dmalloc (sizeof *fallback_interface, "discover_interfaces"));
+ if (!fallback_interface)
+ error ("Insufficient memory to record fallback interface.");
+ memset (fallback_interface, 0, sizeof *fallback_interface);
+ strcpy (fallback_interface -> name, "fallback");
+ fallback_interface -> shared_network =
+ new_shared_network ("parse_statement");
+ if (!fallback_interface -> shared_network)
+ error ("No memory for shared subnet");
+ memset (fallback_interface -> shared_network, 0,
+ sizeof (struct shared_network));
+ fallback_interface -> shared_network -> name = "fallback-net";
+ return fallback_interface;
+}
+
+void reinitialize_interfaces ()
+{
+ struct interface_info *ip;
+
+ for (ip = interfaces; ip; ip = ip -> next) {
+ if_reinitialize_receive (ip);
+ if_reinitialize_send (ip);
+ }
+
+ if (fallback_interface)
+ if_reinitialize_send (fallback_interface);
+
+ interfaces_invalidated = 1;
+}
+
+#ifdef USE_POLL
+/* Wait for packets to come in using poll(). When a packet comes in,
+ call receive_packet to receive the packet and possibly strip hardware
+ addressing information from it, and then call through the
+ bootp_packet_handler hook to try to do something with it. */
void dispatch ()
{
@@ -151,8 +581,8 @@ void dispatch ()
#else
/* Wait for packets to come in using select(). When one does, call
receive_packet to receive the packet and possibly strip hardware
- addressing information from it, and then call do_packet to try to
- do something with it. */
+ addressing information from it, and then call through the
+ bootp_packet_handler hook to try to do something with it. */
void dispatch ()
{
@@ -218,6 +648,38 @@ void dispatch ()
}
#endif /* USE_POLL */
+void got_one (l)
+ struct protocol *l;
+{
+ struct sockaddr_in from;
+ struct hardware hfrom;
+ struct iaddr ifrom;
+ int result;
+ union {
+ unsigned char packbuf [4095]; /* Packet input buffer.
+ Must be as large as largest
+ possible MTU. */
+ struct dhcp_packet packet;
+ } u;
+ struct interface_info *ip = l -> local;
+
+ if ((result =
+ receive_packet (ip, u.packbuf, sizeof u, &from, &hfrom)) < 0) {
+ warn ("receive_packet failed on %s: %m", ip -> name);
+ return;
+ }
+ if (result == 0)
+ return;
+
+ if (bootp_packet_handler) {
+ ifrom.len = 4;
+ memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len);
+
+ (*bootp_packet_handler) (ip, &u.packet, result,
+ from.sin_port, ifrom, &hfrom);
+ }
+}
+
int locate_network (packet)
struct packet *packet;
{
@@ -331,7 +793,7 @@ void cancel_timeout (where, what)
}
/* Add a protocol to the list of protocols... */
-struct protocol *add_protocol (name, fd, handler, local)
+void add_protocol (name, fd, handler, local)
char *name;
int fd;
void (*handler) PROTO ((struct protocol *));
@@ -349,7 +811,6 @@ struct protocol *add_protocol (name, fd, handler, local)
p -> next = protocols;
protocols = p;
- return p;
}
void remove_protocol (proto)
diff --git a/common/dlpi.c b/common/dlpi.c
index 7d02ec0b..bf75c438 100644
--- a/common/dlpi.c
+++ b/common/dlpi.c
@@ -222,6 +222,9 @@ int if_register_dlpi (info)
case DL_ETHER:
info -> hw_address.htype = HTYPE_ETHER;
break;
+ case DL_FDDI:
+ info -> hw_address.htype = HTYPE_FDDI;
+ break;
default:
error ("%s: unknown DLPI MAC type %d",
info -> name,
@@ -460,6 +463,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
int saplen;
int rslt;
+ if (!strcmp (interface -> name, "fallback"))
+ return send_fallback (interface, packet, raw,
+ len, from, to, hto);
+
dbuflen = 0;
/* Assemble the headers... */
@@ -478,8 +485,8 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
rslt = write (interface -> wfdesc, dbuf, dbuflen);
#else
/* XXX: Assumes ethernet, with two byte SAP */
- sap [0] = 0; /* ETHERTYPE_IP, high byte */
- sap [1] = 0x80; /* ETHERTYPE_IP, low byte */
+ sap [0] = 0x08; /* ETHERTYPE_IP, high byte */
+ sap [1] = 0x0; /* ETHERTYPE_IP, low byte */
saplen = -2; /* -2 indicates a two byte SAP at the end
of the address */
@@ -1226,4 +1233,19 @@ static void sigalrm (sig)
}
#endif /* !defined (USE_POLL) */
+int can_unicast_without_arp ()
+{
+ return 1;
+}
+
+void maybe_setup_fallback ()
+{
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ if_register_fallback (fbi);
+ add_protocol ("fallback", fallback_interface -> wfdesc,
+ fallback_discard, fallback_interface);
+ }
+}
#endif /* USE_DLPI */
diff --git a/common/dns.c b/common/dns.c
deleted file mode 100644
index 391e3fc7..00000000
--- a/common/dns.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/* dns.c
-
- Domain Name Service subroutines. */
-
-/*
- * Copyright (C) 1992 by Ted Lemon.
- * Copyright (c) 1997, 1998 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file is based on software written in 1992 by Ted Lemon for
- * a portable network boot loader. That original code base has been
- * substantially modified for use in the Internet Software Consortium
- * DHCP suite.
- *
- * These later modifications were done on behalf of the Internet
- * Software Consortium by Ted Lemon <mellon@fugue.com> in cooperation
- * with Vixie Enterprises. To learn more about the Internet Software
- * Consortium, see ``http://www.vix.com/isc''. To learn more about
- * Vixie Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: dns.c,v 1.9 1998/03/17 06:09:59 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include "arpa/nameser.h"
-
-int dns_protocol_initialized;
-int dns_protocol_fd;
-
-static int addlabel PROTO ((u_int8_t *, char *));
-static int skipname PROTO ((u_int8_t *));
-static int copy_out_name PROTO ((u_int8_t *, u_int8_t *, char *));
-static int nslookup PROTO ((u_int8_t, char *, int, u_int16_t, u_int16_t));
-static int zonelookup PROTO ((u_int8_t, char *, int, u_int16_t));
-u_int16_t dns_port;
-
-#define DNS_QUERY_HASH_SIZE 293
-struct dns_query *dns_query_hash [DNS_QUERY_HASH_SIZE];
-
-/* Initialize the DNS protocol. */
-
-void dns_startup ()
-{
- struct servent *srv;
- struct sockaddr_in from;
-
- /* Only initialize icmp once. */
- if (dns_protocol_initialized)
- error ("attempted to reinitialize dns protocol");
- dns_protocol_initialized = 1;
-
- /* Get the protocol number (should be 1). */
- srv = getservbyname ("domain", "tcp");
- if (srv)
- dns_port = srv -> s_port;
- else
- dns_port = htons (53);
-
- /* Get a socket for the DNS protocol. */
- dns_protocol_fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (dns_protocol_fd < 0)
- error ("unable to create dns socket: %m");
-
- first_name_server ();
-
- add_protocol ("dns", dns_protocol_fd, dns_packet, 0);
-}
-
-/* Label manipulation stuff; see RFC1035, page 28 section 4.1.2 and
- page 30, section 4.1.4. */
-
-/* addlabel copies a label into the specified buffer, putting the length of
- the label in the first character, the contents of the label in subsequent
- characters, and returning the length of the conglomeration. */
-
-static int addlabel (buf, label)
- u_int8_t *buf;
- char *label;
-{
- *buf = strlen (label);
- memcpy (buf + 1, label, *buf);
- return *buf + 1;
-}
-
-/* skipname skips over all of the labels in a single domain name,
- returning the length of the domain name. */
-
-static int skipname (label)
- u_int8_t *label;
-{
- if (*label & INDIR_MASK)
- return 2;
- if (*label == 0)
- return 1;
- return *label + 1 + skipname (label + *label + 1);
-}
-
-/* copy_out_name copies out the name appearing at the specified location
- into a string, stored as fields seperated by dots rather than lengths
- and labels. The length of the label-formatted name is returned. */
-
-static int copy_out_name (base, name, buf)
- u_int8_t *base;
- u_int8_t *name;
- char *buf;
-{
- if (*name & INDIR_MASK) {
- int offset = (*name & ~INDIR_MASK) + (*name + 1);
- return copy_out_name (base, base + offset, buf);
- }
- if (!*name) {
- *buf = 0;
- return 1;
- }
- memcpy (buf, name + 1, *name);
- *(buf + *name) = '.';
- return (*name + 1
- + copy_out_name (base, name + *name + 1, buf + *name + 1));
-}
-
-/* Compute a hash on the question. */
-
-static INLINE u_int32_t dns_hash_question (struct dns_question *question)
-{
- u_int32_t sum;
- u_int32_t remainder;
- u_int32_t *p = (u_int32_t *)question;
- u_int8_t *s;
-
- /* First word. */
- sum = *p++;
- s = (u_int8_t *)p;
-
- remainder = 0;
- while (s [0]) {
- remainder = s [0];
- if (s [1]) {
- remainder = (remainder << 8) + s [1];
- if (s [2]) {
- remainder = (remainder << 8) + s [2];
- if (s [3])
- remainder = (remainder << 8) + s [3];
- else
- goto done;
- } else
- goto done;
- } else {
- done:
- sum += remainder;
- break;
- }
- if ((sum & 0x80000000) && (remainder & 0x80000000))
- ++sum;
- sum += remainder;
- s += 4;
- }
-
- while (sum > DNS_QUERY_HASH_SIZE) {
- remainder = sum / DNS_QUERY_HASH_SIZE;
- sum = sum % DNS_QUERY_HASH_SIZE;
- while (remainder) {
- sum += remainder % DNS_QUERY_HASH_SIZE;
- remainder /= DNS_QUERY_HASH_SIZE;
- }
- }
-
- return sum;
-}
-
-/* Find a query that matches the specified name. If one can't be
- found, and new is nonzero, allocate one, hash it in, and save the
- question. Otherwise, if new is nonzero, free() the question.
- Return the query if one was found or allocated. */
-
-struct dns_query *find_dns_query (question, new)
- struct dns_question *question;
- int new;
-{
- int hash = dns_hash_question (question);
- struct dns_query *q;
-
- for (q = dns_query_hash [hash]; q; q = q -> next) {
- if (q -> question -> type == question -> type &&
- q -> question -> class == question -> class &&
- !strcmp ((char *)q -> question -> data,
- (char *)question -> data))
- break;
- }
- if (q || !new) {
- if (new)
- free (question);
- return q;
- }
-
- /* Allocate and zap a new query. */
- q = (struct dns_query *)malloc (sizeof (struct dns_query));
- memset (q, 0, sizeof *q);
-
- /* All we need to set up is the question and the hash. */
- q -> question = question;
- q -> next = dns_query_hash [hash];
- dns_query_hash [hash] = q;
- q -> hash = hash;
- return q;
-}
-
-/* Free up all memory associated with a DNS query and remove it from the
- query hash. */
-
-void destroy_dns_query (query)
- struct dns_query *query;
-{
- struct dns_query *q;
-
- /* Free up attached free data. */
- if (query -> question)
- free (query -> question);
- if (query -> answer)
- free (query -> answer);
- if (query -> query)
- free (query -> query);
-
- /* Remove query from hash table. */
- if (dns_query_hash [query -> hash] == query)
- dns_query_hash [query -> hash] = query -> next;
- else {
- for (q = dns_query_hash [query -> hash];
- q -> next && q -> next != query; q = q -> next)
- ;
- if (q -> next)
- q -> next = query -> next;
- }
-
- /* Free the query structure. */
- free (query);
-}
-
-/* ns_inaddr_lookup constructs a PTR lookup query for an internet address -
- e.g., 1.200.9.192.in-addr.arpa. It then passes it on to ns_query for
- completion. */
-
-struct dns_query *ns_inaddr_lookup (inaddr, wakeup)
- struct iaddr inaddr;
- struct dns_wakeup *wakeup;
-{
- unsigned char query [512];
- unsigned char *s;
- unsigned char *label;
- int i;
- unsigned char c;
- struct dns_question *question;
-
- /* First format the query in the internal format. */
- sprintf ((char *)query, "%d.%d.%d.%d.in-addr.arpa.",
- inaddr.iabuf [0], inaddr.iabuf [1],
- inaddr.iabuf [2], inaddr.iabuf [3]);
-
- question = (struct dns_question *)malloc (strlen ((char *)query) +
- sizeof *question);
- if (!question)
- return (struct dns_query *)-1;
- question -> type = T_PTR;
- question -> class = C_IN;
- strcpy ((char *)question -> data, (char *)query);
-
- /* Now format the query for the name server. */
- s = query;
-
- /* Copy out the digits. */
- for (i = 3; i >= 0; --i) {
- label = s++;
- sprintf ((char *)s, "%d", inaddr.iabuf [i]);
- *label = strlen ((char *)s);
- s += *label;
- }
- s += addlabel (s, "in-addr");
- s += addlabel (s, "arpa");
- *s++ = 0;
-
- /* Set the query type. */
- putUShort (s, T_PTR);
- s += sizeof (u_int16_t);
-
- /* Set the query class. */
- putUShort (s, C_IN);
- s += sizeof (u_int16_t);
-
- return ns_query (question, query, s - query, wakeup);
-}
-
-/* Try to satisfy a query out of the local cache. If no answer has
- been cached, and if there isn't already a query pending on this
- question, send it. If the query can be immediately satisfied,
- a pointer to the dns_query structure is returned. If the query
- can't even be made for some reason, (struct dns_query *)-1 is
- returned. Otherwise, the null pointer is returned, indicating that
- a wakeup will be performed later when the answer comes back. */
-
-struct dns_query *ns_query (question, formatted_query, len, wakeup)
- struct dns_question *question;
- unsigned char *formatted_query;
- int len;
- struct dns_wakeup *wakeup;
-{
- HEADER *hdr;
- struct dns_query *query;
- unsigned char *s;
- unsigned char buf [512];
-
- /* If the query won't fit, don't bother setting it up. */
- if (len > 255) {
- free (question);
- return (struct dns_query *)-1;
- }
-
- /* See if there's already a query for this name, and allocate a
- query if none exists. */
- query = find_dns_query (question, 1);
-
- /* If we can't allocate a query, report that the query failed. */
- if (!query)
- return (struct dns_query *)-1;
-
- /* If the query has already been answered, return it. */
- if (query -> expiry > cur_time)
- return query;
-
- /* The query hasn't yet been answered, so we have to wait, one
- way or another. Put the wakeup on the list. */
- if (wakeup) {
- wakeup -> next = query -> wakeups;
- query -> wakeups = wakeup;
- }
-
- /* If the query has already been sent, but we don't yet have
- an answer, we're done. */
- if (query -> sent)
- return (struct dns_query *)0;
-
- /* Construct a header... */
- hdr = (HEADER *)buf;
- memset (hdr, 0, sizeof *hdr);
- hdr -> id = query -> id;
- hdr -> rd = 1;
- hdr -> opcode = QUERY;
- hdr -> qdcount = htons (1);
-
- /* Copy the formatted name into the buffer. */
- s = (unsigned char *)hdr + 1;
- memcpy (s, formatted_query, len);
-
- /* Figure out how long the whole message is */
- s += len;
- query -> len = s - buf;
-
- /* Save the raw query data. */
- query -> query = malloc (len);
- if (!query -> query) {
- destroy_dns_query (query);
- return (struct dns_query *)-1;
- }
- memcpy (query -> query, buf, query -> len);
-
- /* Flag the query as having been sent. */
- query -> sent = 1;
-
- /* Send the query. */
- dns_timeout (query);
-
- /* No answer yet, obviously. */
- return (struct dns_query *)0;
-}
-
-/* Retransmit a DNS query. */
-
-void dns_timeout (qv)
- void *qv;
-{
- struct dns_query *query = qv;
- int status;
-
- /* Choose the server to send to. */
- if (!query -> next_server)
- query -> next_server = first_name_server ();
-
- /* Send the query. */
- if (query -> next_server)
- status = sendto (dns_protocol_fd,
- (char *)query -> query, query -> len, 0,
- ((struct sockaddr *)&query ->
- next_server -> addr),
- sizeof query -> next_server -> addr);
- else
- status = -1;
-
- /* Look for the next server... */
- query -> next_server = query -> next_server -> next;
-
- /* If this is our first time, backoff one second. */
- if (!query -> backoff)
- query -> backoff = 1;
-
- /* If the send failed, don't advance the backoff. */
- else if (status < 0)
- ;
-
- /* If we haven't run out of servers to try, don't backoff. */
- else if (query -> next_server)
- ;
-
- /* If we haven't backed off enough yet, back off some more. */
- else if (query -> backoff < 30)
- query -> backoff += random() % query -> backoff;
-
- /* Set up the timeout. */
- add_timeout (cur_time + query -> backoff, dns_timeout, query);
-}
-
-/* Process a reply from a name server. */
-
-void dns_packet (protocol)
- struct protocol *protocol;
-{
- HEADER *ns_header;
- struct sockaddr_in from;
- struct dns_wakeup *wakeup;
- unsigned char buf [512];
- union {
- unsigned char u [512];
- struct dns_question q;
- } qbuf;
- unsigned char *base;
- unsigned char *dptr, *name;
- u_int16_t type;
- u_int16_t class;
- TIME ttl;
- u_int16_t rdlength;
- int len, status;
- int i;
- struct dns_query *query;
-
- len = sizeof from;
- status = recvfrom (protocol -> fd, (char *)buf, sizeof buf, 0,
- (struct sockaddr *)&from, &len);
- if (status < 0) {
- warn ("dns_packet: %m");
- return;
- }
-
- /* Response is too long? */
- if (len > 512) {
- warn ("dns_packet: dns message too long (%d)", len);
- return;
- }
-
- ns_header = (HEADER *)buf;
- base = (unsigned char *)(ns_header + 1);
-
- /* Parse the response... */
- dptr = base;
-
- /* If this is a response to a query from us, there should have
- been only one query. */
- if (ntohs (ns_header -> qdcount) != 1) {
- warn ("Bogus DNS answer packet from %s claims %d queries.\n",
- inet_ntoa (from.sin_addr),
- ntohs (ns_header -> qdcount));
- return;
- }
-
- /* Find the start of the name in the query. */
- name = dptr;
-
- /* Skip over the name. */
- dptr += copy_out_name (name, name, (char *)qbuf.q.data);
-
- /* Skip over the query type and query class. */
- qbuf.q.type = getUShort (dptr);
- dptr += sizeof (u_int16_t);
- qbuf.q.class = getUShort (dptr);
- dptr += sizeof (u_int16_t);
-
- /* See if we asked this question. */
- query = find_dns_query (&qbuf.q, 0);
- if (!query) {
-warn ("got answer for question %s from DNS, which we didn't ask.",
-qbuf.q.data);
- return;
- }
-
-note ("got answer for question %s from DNS", qbuf.q.data);
-
- /* Wake up everybody who's waiting. */
- for (wakeup = query -> wakeups; wakeup; wakeup = wakeup -> next) {
- (*wakeup -> func) (query);
- }
-}
diff --git a/common/execute.c b/common/execute.c
deleted file mode 100644
index c69cf9ef..00000000
--- a/common/execute.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* execute.c
-
- Support for executable statements. */
-
-/*
- * Copyright (c) 1998 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises. To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''. To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: execute.c,v 1.1 1998/06/25 03:57:00 mellon Exp $ Copyright (c) 1998 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-int execute_statements (packet, options, statements)
- struct packet *packet;
- struct option_state *options;
- struct executable_statement *statements;
-{
- struct executable_statement *r;
-
- if (!statements)
- return 1;
-
- for (r = statements; r; r = r -> next) {
- switch (r -> op) {
- case if_statement:
- if (!execute_statements
- (packet, options,
- evaluate_boolean_expression (packet,
- r -> data.ie.expr)
- ? r -> data.ie.true : r -> data.ie.false))
- return 0;
- break;
-
- case eval_statement:
- evaluate_boolean_expression (packet, r -> data.eval);
- break;
-
- case add_statement:
- classify (packet, r -> data.add);
- break;
-
- case break_statement:
- return 0;
-
- case supersede_option_statement:
- case default_option_statement:
- case append_option_statement:
- case prepend_option_statement:
- if (r -> data.option -> option -> universe -> set_func)
- (r -> data.option -> option ->
- universe -> set_func) (options,
- r -> data.option,
- r -> op);
- break;
-
- default:
- error ("bogus classification rule type %d\n", r -> op);
- }
- }
-
- return 1;
-}
-
-/* Execute all the statements in a particular scope, and all statements in
- scopes outer from that scope, but if a particular limiting scope is
- reached, do not execute statements in that scope or in scopes outer
- from it. */
-
-void execute_statements_in_scope (packet, options, group, limiting_group)
- struct packet *packet;
- struct option_state *options;
- struct group *group;
- struct group *limiting_group;
-{
- struct group *scope;
-
- for (scope = group;
- scope && scope != limiting_group; scope = scope -> next) {
- execute_statements (packet, options, scope -> statements);
- }
-}
diff --git a/common/hash.c b/common/hash.c
index 0a95635b..8d362cb1 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -3,7 +3,7 @@
Routines for manipulating hash tables... */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: hash.c,v 1.10 1998/03/16 06:11:51 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: hash.c,v 1.9.2.1 1998/06/25 21:11:29 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -65,7 +65,7 @@ static INLINE int do_hash (name, len, size)
int size;
{
register int accum = 0;
- register unsigned char *s = (unsigned char *)name;
+ register unsigned char *s = name;
int i = len;
if (i) {
while (i--) {
@@ -167,8 +167,7 @@ unsigned char *hash_lookup (table, name, len)
}
} else {
for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
- if (!strcmp ((char *)bp -> name,
- (char *)name))
+ if (!strcmp ((char *)bp -> name, (char *)name))
return bp -> value;
}
return (unsigned char *)0;
diff --git a/common/icmp.c b/common/icmp.c
index bfdf8f25..fb6cfad9 100644
--- a/common/icmp.c
+++ b/common/icmp.c
@@ -1,4 +1,4 @@
-/* dhcp.c
+/* icmp.c
ICMP Protocol engine - for sending out pings and receiving
responses. */
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: icmp.c,v 1.11 1998/06/25 22:54:13 mellon Exp $ Copyright (c) 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
+"$Id: icmp.c,v 1.7.2.1 1998/06/25 21:11:29 mellon Exp $ Copyright (c) 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -86,8 +86,8 @@ void icmp_startup (routep, handler)
(char *)&state, sizeof state) < 0)
error ("Unable to disable SO_DONTROUTE on ICMP socket: %m");
- add_protocol ("icmp", icmp_protocol_fd,
- icmp_echoreply, (void *)handler);
+ add_protocol ("icmp", icmp_protocol_fd, icmp_echoreply,
+ (void *)handler);
}
int icmp_echorequest (addr)
@@ -117,7 +117,6 @@ int icmp_echorequest (addr)
#else
icmp.icmp_id = (u_int32_t)addr;
#endif
- memset (&icmp.icmp_dun, 0, sizeof icmp.icmp_dun);
icmp.icmp_cksum = wrapsum (checksum ((unsigned char *)&icmp,
sizeof icmp, 0));
@@ -137,11 +136,10 @@ void icmp_echoreply (protocol)
struct protocol *protocol;
{
struct icmp *icfrom;
- struct ip *ip;
struct sockaddr_in from;
- unsigned char icbuf [1500];
+ u_int8_t icbuf [1500];
int status;
- int len, hlen;
+ int len;
struct iaddr ia;
void (*handler) PROTO ((struct iaddr, u_int8_t *, int));
@@ -153,17 +151,13 @@ void icmp_echoreply (protocol)
return;
}
- /* Find the IP header length... */
- ip = (struct ip *)icbuf;
- hlen = ip -> ip_hl << 2;
-
- /* Short packet? */
- if (status < hlen + (sizeof *icfrom)) {
+ /* Probably not for us. */
+ if (status < (sizeof (struct ip)) + (sizeof *icfrom)) {
return;
}
- len = status - hlen;
- icfrom = (struct icmp *)(icbuf + hlen);
+ len = status - sizeof (struct ip);
+ icfrom = (struct icmp *)(icbuf + sizeof (struct ip));
/* Silently discard ICMP packets that aren't echoreplies. */
if (icfrom -> icmp_type != ICMP_ECHOREPLY) {
@@ -172,7 +166,8 @@ void icmp_echoreply (protocol)
/* If we were given a second-stage handler, call it. */
if (protocol -> local) {
- handler = ((void (*) PROTO ((struct iaddr, u_int8_t *, int)))
+ handler = ((void (*) PROTO ((struct iaddr,
+ u_int8_t *, int)))
protocol -> local);
memcpy (ia.iabuf, &from.sin_addr, sizeof from.sin_addr);
ia.len = sizeof from.sin_addr;
diff --git a/common/inet_addr.c b/common/inet_addr.c
index 97667bd2..b00a72c4 100644
--- a/common/inet_addr.c
+++ b/common/inet_addr.c
@@ -43,7 +43,7 @@ static char rcsid[] = "$NetBSD: inet_addr.c,v 1.6 1996/02/02 15:22:23 mrg Exp $"
#ifndef lint
static char copyright[] =
-"$Id: inet_addr.c,v 1.2 1997/03/29 10:37:51 mellon Exp $ Copyright (c) 1983, 1990, 1993 The Regents of the University of California. All rights reserved.\n";
+"$Id: inet_addr.c,v 1.2.2.1 1998/06/26 20:51:35 mellon Exp $ Copyright (c) 1983, 1990, 1993 The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -58,7 +58,7 @@ static char copyright[] =
*/
int
inet_aton(cp, addr)
- char *cp;
+ const char *cp;
struct in_addr *addr;
{
register u_long val;
diff --git a/common/interact.c b/common/interact.c
deleted file mode 100644
index 561af874..00000000
--- a/common/interact.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* interact.c
-
- Text interactor for dhcp servers. */
-
-/*
- * Copyright (c) 1998 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software was written for the Internet Software Consortium by
- * Ted Lemon <mellon@fugue.com> in cooperation with Vixie Enterprises.
- * To learn more about the Internet Software Consortium, see
- * ``http://www.vix.com/isc''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: interact.c,v 1.1 1998/04/09 05:18:56 mellon Exp $ Copyright (c) 1998 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-int interact_initialized;
-int interact_fd;
-static struct interact_client *interact_clients;
-
-void interact_startup ()
-{
- struct sockaddr_un name;
- static int once;
- int len;
- mode_t m;
-
- /* Only initialize interact once. */
- if (interact_initialized)
- error ("attempted to reinitialize interact protocol");
- interact_initialized = 1;
-
- /* Make a socket... */
- interact_fd = socket (AF_UNIX, SOCK_STREAM, 0);
- if (interact_fd < 0)
- error ("unable to create interact socket: %m");
-
- /* XXX for now... */
- name.sun_family = PF_UNIX;
- strcpy (name.sun_path, "/var/run/dhcpctl");
-#if defined (HAVE_SA_LEN)
- name.sun_len =
-#endif
- len = ((sizeof name) - (sizeof name.sun_path) +
- strlen (name.sun_path));
- unlink (name.sun_path);
-
- /* interact socket should be accessible only by root. */
- m = umask (0700);
-
- /* Bind to it... */
- if (bind (interact_fd, (struct sockaddr *)&name, len) < 0) {
- warn ("can't bind to interact socket: %m");
- close (interact_fd);
- umask (m);
- return;
- }
- umask (m);
-
- /* Listen for connections... */
- if (listen (interact_fd, 1) < 0) {
- warn ("can't listen on interact socket: %m");
- close (interact_fd);
- unlink (name.sun_path);
- return;
- }
-
- add_protocol ("interact", interact_fd, new_interact_connection, 0);
-}
-
-void new_interact_connection (proto)
- struct protocol *proto;
-{
- struct sockaddr_un name;
- int namelen;
- struct interact_client *tmp;
- int new_fd;
- int arg;
-
- tmp = (struct interact_client *)malloc (sizeof *tmp);
- if (!tmp)
- error ("Can't find memory for new client!");
- memset (tmp, 0, sizeof *tmp);
-
- namelen = sizeof name;
- new_fd = accept (proto -> fd, (struct sockaddr *)&name, &namelen);
- if (new_fd < 0) {
- warn ("accept: %m");
- free (tmp);
- return;
- }
-
- if ((arg = fcntl (new_fd, F_GETFL, 0)) < 0) {
- bad_flag:
- warn ("Can't set flags on new interactive client: %m");
- close (new_fd);
- free (tmp);
- return;
- }
- arg |= O_NONBLOCK;
- if (fcntl (new_fd, F_SETFL, arg) < 0)
- goto bad_flag;
-
- tmp -> next = interact_clients;
- tmp -> fd = new_fd;
- interact_clients = tmp;
- tmp -> cur_node_actions = top_level_actions;
-
- tmp -> proto = add_protocol ("aclient", new_fd,
- interact_client_input, tmp);
-}
-
-void interact_client_input (proto)
- struct protocol *proto;
-{
- int status;
- char *eobuf;
- struct interact_client *client = proto -> local;
-
- status = read (proto -> fd, &client -> ibuf [client -> ibuflen],
- (sizeof client -> ibuf) - client -> ibuflen);
- if (status < 0) {
- warn ("interact_client_input: %m");
- blow:
- close (proto -> fd);
- remove_protocol (proto);
- free (client);
- return;
- }
- /* EOF: get lost. */
- if (status == 0)
- goto blow;
-
- client -> ibuflen += status;
- eobuf = memchr (client -> ibuf, '\n', client -> ibuflen);
- if (!eobuf) {
- if (client -> ibuflen == sizeof client -> ibuf) {
- warn ("interact_client_input: buffer overflow.");
- goto blow;
- }
- return;
- }
-
- /* NUL terminate and blow away newline. */
- *eobuf = 0;
-
- if (!strcmp (client -> ibuf, "ls"))
- (*client -> cur_node_actions.ls) (client);
- else if (!strncmp (client -> ibuf, "print ", 6))
- (*client -> cur_node_actions.print) (client,
- &client -> ibuf [6]);
- else if (!strncmp (client -> ibuf, "set ", 4))
- (*client -> cur_node_actions.set) (client,
- &client -> ibuf [4]);
- else if (!strncmp (client -> ibuf, "rm ", 3))
- (*client -> cur_node_actions.rm) (client,
- &client -> ibuf [3]);
- else if (!strcmp (client -> ibuf, "cd .."))
- (*client -> cur_node_actions.cdup) (client);
- else if (!strncmp (client -> ibuf, "cd ", 3))
- (*client -> cur_node_actions.cd) (client,
- &client -> ibuf [3]);
- else if (!strcmp (client -> ibuf, "exit")) {
- interact_client_write (client, "done.", 1);
- goto blow;
- } else
- interact_client_write (client, "invalid command", 1);
-
- /* In case the client wrote more than one command. */
- if (client -> ibuflen -= eobuf - &client -> ibuf [0] + 1)
- memmove (client -> ibuf, eobuf, client -> ibuflen);
-}
-
-int interact_client_write (client, string, lastp)
- struct interact_client *client;
- char *string;
- int lastp;
-{
- static char *obuf;
- static int obufmax;
- char *bp;
-
- /* Unlikely to loop, but why not be sure? */
- if (obufmax < strlen (string)) {
- if (obuf)
- free (obuf);
- obufmax = (strlen (string) + 1025) & ~1023;
- obuf = malloc (obufmax);
- if (!obuf) {
- warn ("interact_client_write: out of memory");
- blow:
- close (client -> proto -> fd);
- remove_protocol (client -> proto);
- free (client);
- return 0;
- }
- }
-
- bp = obuf;
- if (!lastp)
- *bp++ = '-';
- strcpy (bp, string);
- bp += strlen (bp);
- *bp++ = '\n';
- if (write (client -> fd, obuf, bp - obuf) < 0)
- return 0;
-
- return 1;
-}
diff --git a/common/lpf.c b/common/lpf.c
new file mode 100644
index 00000000..7069c321
--- /dev/null
+++ b/common/lpf.c
@@ -0,0 +1,252 @@
+/* lpf.c
+
+ Linux packet filter code, contributed by Brian Murrel at Interlinx
+ Support Services in Vancouver, B.C. */
+
+/*
+ * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"$Id: lpf.c,v 1.1 1998/12/22 22:34:54 mellon Exp $ Copyright (c) 1995, 1996, 1998 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+#if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+
+#include <net/bpf.h>
+#include <netinet/in_systm.h>
+#include "includes/netinet/ip.h"
+#include "includes/netinet/udp.h"
+#include "includes/netinet/if_ether.h"
+
+/* Reinitializes the specified interface after an address change. This
+ is not required for packet-filter APIs. */
+
+#ifdef USE_LPF_SEND
+void if_reinitialize_send (info)
+ struct interface_info *info;
+{
+}
+#endif
+
+#ifdef USE_LPF_RECEIVE
+void if_reinitialize_receive (info)
+ struct interface_info *info;
+{
+}
+#endif
+
+/* Called by get_interface_list for each interface that's discovered.
+ Opens a packet filter for each interface and adds it to the select
+ mask. */
+
+int if_register_lpf (info)
+ struct interface_info *info;
+{
+ int sock;
+ char filename[50];
+ int b;
+ struct sockaddr sa;
+
+ /* Make an LPF socket. */
+ if ((sock = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0)
+ error("Open a socket for LPF: %m");
+
+ /* Bind to the interface name */
+ memset (&sa, 0, sizeof sa);
+ sa.sa_family = AF_INET;
+ strncpy (sa.sa_data, (const char *)info -> ifp, sizeof sa.sa_data);
+ if (bind (sock, &sa, sizeof sa))
+ error("Bind socket to interface: %m");
+
+ return sock;
+}
+#endif /* USE_LPF_SEND || USE_LPF_RECEIVE */
+
+#ifdef USE_LPF_SEND
+void if_register_send (info)
+ struct interface_info *info;
+{
+ /* If we're using the lpf API for sending and receiving,
+ we don't need to register this interface twice. */
+#ifndef USE_LPF_RECEIVE
+ info -> wfdesc = if_register_lpf (info, interface);
+#else
+ info -> wfdesc = info -> rfdesc;
+#endif
+ if (!quiet_interface_discovery)
+ note ("Sending on LPF/%s/%s/%s",
+ info -> name,
+ print_hw_addr (info -> hw_address.htype,
+ info -> hw_address.hlen,
+ info -> hw_address.haddr),
+ (info -> shared_network ?
+ info -> shared_network -> name : "unattached"));
+}
+#endif /* USE_LPF_SEND */
+
+#ifdef USE_LPF_RECEIVE
+/* Defined in bpf.c. We can't extern these in dhcpd.h without pulling
+ in bpf includes... */
+extern struct bpf_insn dhcp_bpf_filter [];
+extern int dhcp_bpf_filter_len;
+
+void if_register_receive (info)
+ struct interface_info *info;
+{
+ /* Open a LPF device and hang it on this interface... */
+ info -> rfdesc = if_register_lpf (info);
+
+ /* Set up the bpf filter program structure. This is defined in
+ bpf.c */
+ p.bf_len = dhcp_bpf_filter_len;
+ p.bf_insns = dhcp_bpf_filter;
+
+ /* Patch the server port into the LPF program...
+ XXX changes to filter program may require changes
+ to the insn number(s) used below! XXX */
+ dhcp_bpf_filter [8].k = ntohs (local_port);
+
+ if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
+ sizeof p) < 0)
+ error ("Can't install packet filter program: %m");
+ if (!quiet_interface_discovery)
+ note ("Listening on LPF/%s/%s/%s",
+ info -> name,
+ print_hw_addr (info -> hw_address.htype,
+ info -> hw_address.hlen,
+ info -> hw_address.haddr),
+ (info -> shared_network ?
+ info -> shared_network -> name : "unattached"));
+}
+#endif /* USE_LPF_RECEIVE */
+
+#ifdef USE_LPF_SEND
+ssize_t send_packet (interface, packet, raw, len, from, to, hto)
+ struct interface_info *interface;
+ struct packet *packet;
+ struct dhcp_packet *raw;
+ size_t len;
+ struct in_addr from;
+ struct sockaddr_in *to;
+ struct hardware *hto;
+{
+ int bufp = 0;
+ unsigned char buf [1500];
+
+ 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,
+ to -> sin_addr.s_addr, to -> sin_port,
+ (unsigned char *)raw, len);
+ memcpy (buf + bufp, raw, len);
+ return send (interface -> wfdesc, buf, bufp + len, 0);
+}
+#endif /* USE_LPF_SEND */
+
+#ifdef USE_LPF_RECEIVE
+ssize_t receive_packet (interface, buf, len, from, hfrom)
+ struct interface_info *interface;
+ unsigned char *buf;
+ size_t len;
+ struct sockaddr_in *from;
+ struct hardware *hfrom;
+{
+ int nread;
+ int length = 0;
+ int offset = 0;
+ unsigned char ibuf [1500 + sizeof (struct enstamp)];
+ int bufix = 0;
+
+ length = read (interface -> rfdesc, ibuf, sizeof ibuf);
+ if (length <= 0)
+ return length;
+
+ bufix = sizeof (struct enstamp);
+ /* Decode the physical header... */
+ offset = decode_hw_header (interface, ibuf, bufix, hfrom);
+
+ /* If a physical layer checksum failed (dunno of any
+ physical layer that supports this, but WTH), skip this
+ packet. */
+ if (offset < 0) {
+ return 0;
+ }
+
+ bufix += offset;
+ length -= offset;
+
+ /* Decode the IP and UDP headers... */
+ offset = decode_udp_ip_header (interface, ibuf, bufix,
+ from, (unsigned char *)0, length);
+
+ /* If the IP or UDP checksum was bad, skip the packet... */
+ if (offset < 0)
+ return 0;
+
+ bufix += offset;
+ length -= offset;
+
+ /* Copy out the data in the packet... */
+ memcpy (buf, &ibuf [bufix], length);
+ return length;
+}
+
+int can_unicast_without_arp ()
+{
+ return 1;
+}
+
+void maybe_setup_fallback ()
+{
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ if_register_fallback (fbi);
+ add_protocol ("fallback", fallback_interface -> wfdesc,
+ fallback_discard, fallback_interface);
+ }
+}
+#endif
diff --git a/common/memory.c b/common/memory.c
index eb52d815..871fe077 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: memory.c,v 1.40 1998/06/25 02:59:15 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: memory.c,v 1.35.2.3 1998/11/24 22:32:43 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -56,12 +56,14 @@ static struct hash_table *lease_ip_addr_hash;
static struct hash_table *lease_hw_addr_hash;
static struct lease *dangling_leases;
+static struct hash_table *vendor_class_hash;
+static struct hash_table *user_class_hash;
+
void enter_host (hd)
struct host_decl *hd;
{
struct host_decl *hp = (struct host_decl *)0;
struct host_decl *np = (struct host_decl *)0;
- struct executable_statement *esp;
hd -> n_ipaddr = (struct host_decl *)0;
@@ -91,37 +93,23 @@ void enter_host (hd)
np -> n_ipaddr = hd;
}
- /* See if there's a statement that sets the client identifier.
- This is a kludge - the client identifier really shouldn't be
- set with an executable statement. */
- for (esp = hd -> group -> statements; esp; esp = esp -> next) {
- if (esp -> op == supersede_option_statement &&
- esp -> data.option &&
- (esp -> data.option -> option -> universe ==
- &dhcp_universe) &&
- (esp -> data.option -> option -> code ==
- DHO_DHCP_CLIENT_IDENTIFIER)) {
- hd -> client_identifier =
- evaluate_data_expression
- ((struct packet *)0,
- esp -> data.option -> expression);
- break;
- }
- }
-
- /* If we got a client identifier, hash this entry by
- client identifier. */
- if (hd -> client_identifier.len) {
+ if (hd -> group -> options [DHO_DHCP_CLIENT_IDENTIFIER]) {
+ if (!tree_evaluate (hd -> group -> options
+ [DHO_DHCP_CLIENT_IDENTIFIER]))
+ return;
+
/* If there's no uid hash, make one; otherwise, see if
there's already an entry in the hash for this host. */
if (!host_uid_hash) {
host_uid_hash = new_hash ();
hp = (struct host_decl *)0;
} else
- hp = ((struct host_decl *)
- hash_lookup (host_uid_hash,
- hd -> client_identifier.data,
- hd -> client_identifier.len));
+ hp = (struct host_decl *) hash_lookup
+ (host_uid_hash,
+ hd -> group -> options
+ [DHO_DHCP_CLIENT_IDENTIFIER] -> value,
+ hd -> group -> options
+ [DHO_DHCP_CLIENT_IDENTIFIER] -> len);
/* If there's already a host declaration for this
client identifier, add this one to the end of the
@@ -136,8 +124,10 @@ void enter_host (hd)
}
} else {
add_hash (host_uid_hash,
- hd -> client_identifier.data,
- hd -> client_identifier.len,
+ hd -> group -> options
+ [DHO_DHCP_CLIENT_IDENTIFIER] -> value,
+ hd -> group -> options
+ [DHO_DHCP_CLIENT_IDENTIFIER] -> len,
(unsigned char *)hd);
}
}
@@ -182,20 +172,14 @@ struct subnet *find_host_for_network (host, addr, share)
struct subnet *subnet;
struct iaddr ip_address;
struct host_decl *hp;
- struct data_string fixed_addr;
for (hp = *host; hp; hp = hp -> n_ipaddr) {
- if (!hp -> fixed_addr)
- continue;
- fixed_addr = (evaluate_data_expression
- ((struct packet *)0,
- hp -> fixed_addr -> expression));
- if (!fixed_addr.len)
+ if (!hp -> fixed_addr || !tree_evaluate (hp -> fixed_addr))
continue;
- for (i = 0; i < fixed_addr.len; i += 4) {
+ for (i = 0; i < hp -> fixed_addr -> len; i += 4) {
ip_address.len = 4;
memcpy (ip_address.iabuf,
- fixed_addr.data + i, 4);
+ hp -> fixed_addr -> value + i, 4);
subnet = find_grouped_subnet (share, ip_address);
if (subnet) {
*addr = ip_address;
@@ -217,6 +201,8 @@ void new_address_range (low, high, subnet, dynamic)
int min, max, i;
char lowbuf [16], highbuf [16], netbuf [16];
struct shared_network *share = subnet -> shared_network;
+ struct hostent *h;
+ struct in_addr ia;
/* All subnets should have attached shared network structures. */
if (!share) {
@@ -287,6 +273,23 @@ void new_address_range (low, high, subnet, dynamic)
address_range [i].shared_network = share;
address_range [i].flags = dynamic ? DYNAMIC_BOOTP_OK : 0;
+ memcpy (&ia, address_range [i].ip_addr.iabuf, 4);
+
+ if (subnet -> group -> get_lease_hostnames) {
+ h = gethostbyaddr ((char *)&ia, sizeof ia, AF_INET);
+ if (!h)
+ warn ("No hostname for %s", inet_ntoa (ia));
+ else {
+ address_range [i].hostname =
+ malloc (strlen (h -> h_name) + 1);
+ if (!address_range [i].hostname)
+ error ("no memory for hostname %s.",
+ h -> h_name);
+ strcpy (address_range [i].hostname,
+ h -> h_name);
+ }
+ }
+
/* Link this entry into the list. */
address_range [i].next = share -> leases;
address_range [i].prev = (struct lease *)0;
@@ -354,36 +357,59 @@ struct subnet *find_grouped_subnet (share, addr)
return (struct subnet *)0;
}
+int subnet_inner_than (subnet, scan, warnp)
+ struct subnet *subnet, *scan;
+ int warnp;
+{
+ if (addr_eq (subnet_number (subnet -> net, scan -> netmask),
+ scan -> net) ||
+ addr_eq (subnet_number (scan -> net, subnet -> netmask),
+ subnet -> net)) {
+ char n1buf [16];
+ int i, j;
+ for (i = 0; i < 32; i++)
+ if (subnet -> netmask.iabuf [3 - (i >> 3)]
+ & (1 << (i & 7)))
+ break;
+ for (j = 0; j < 32; j++)
+ if (scan -> netmask.iabuf [3 - (j >> 3)] &
+ (1 << (j & 7)))
+ break;
+ strcpy (n1buf, piaddr (subnet -> net));
+ if (warnp)
+ warn ("%ssubnet %s/%d conflicts with subnet %s/%d",
+ "Warning: ", n1buf, 32 - i,
+ piaddr (scan -> net), 32 - j);
+ if (i < j)
+ return 1;
+ }
+ return 0;
+}
+
/* Enter a new subnet into the subnet list. */
void enter_subnet (subnet)
struct subnet *subnet;
{
- struct subnet *scan;
+ struct subnet *scan, *prev = (struct subnet *)0;
/* Check for duplicates... */
for (scan = subnets; scan; scan = scan -> next_subnet) {
- if (addr_eq (subnet_number (subnet -> net, scan -> netmask),
- scan -> net) ||
- addr_eq (subnet_number (scan -> net, subnet -> netmask),
- subnet -> net)) {
- char n1buf [16];
- int i, j;
- for (i = 0; i < 32; i++)
- if (subnet -> netmask.iabuf [3 - (i >> 3)]
- & (1 << (i & 7)))
- break;
- for (j = 0; j < 32; j++)
- if (scan -> netmask.iabuf [3 - (j >> 3)]
- & (1 << (j & 7)))
- break;
- strcpy (n1buf, piaddr (subnet -> net));
- error ("subnet %s/%d conflicts with subnet %s/%d",
- n1buf, i, piaddr (scan -> net), j);
+ /* When we find a conflict, make sure that the
+ subnet with the narrowest subnet mask comes
+ first. */
+ if (subnet_inner_than (subnet, scan, 1)) {
+ if (prev) {
+ prev -> next_subnet = subnet;
+ } else
+ subnets = subnet;
+ subnet -> next_subnet = scan;
+ return;
}
+ prev = scan;
}
- /* XXX Sort the nets into a balanced tree to make searching quicker. */
+ /* XXX use the BSD radix tree code instead of a linked list. */
subnet -> next_subnet = subnets;
subnets = subnet;
}
@@ -623,8 +649,10 @@ void release_lease (lease)
struct lease lt;
lt = *lease;
- lt.ends = cur_time;
- supersede_lease (lease, &lt, 1);
+ if (lt.ends > cur_time) {
+ lt.ends = cur_time;
+ supersede_lease (lease, &lt, 1);
+ }
}
/* Abandon the specified lease (set its timeout to infinity and its
@@ -638,7 +666,7 @@ void abandon_lease (lease, message)
lease -> flags |= ABANDONED_LEASE;
lt = *lease;
- lt.ends = cur_time; /* XXX */
+ lt.ends = cur_time;
warn ("Abandoning IP address %s: %s",
piaddr (lease -> ip_addr), message);
lt.hardware_addr.htype = 0;
@@ -648,24 +676,6 @@ void abandon_lease (lease, message)
supersede_lease (lease, &lt, 1);
}
-/* Abandon the specified lease (set its timeout to infinity and its
- particulars to zero, and re-hash it as appropriate. */
-
-void dissociate_lease (lease)
- struct lease *lease;
-{
- struct lease lt;
-
- lt = *lease;
- if (lt.ends > cur_time)
- lt.ends = cur_time;
- lt.hardware_addr.htype = 0;
- lt.hardware_addr.hlen = 0;
- lt.uid = (unsigned char *)0;
- lt.uid_len = 0;
- supersede_lease (lease, &lt, 1);
-}
-
/* Locate the lease associated with a given IP address... */
struct lease *find_lease_by_ip_addr (addr)
@@ -831,6 +841,49 @@ void hw_hash_delete (lease)
lease -> n_hw = (struct lease *)0;
}
+
+struct class *add_class (type, name)
+ int type;
+ char *name;
+{
+ struct class *class = new_class ("add_class");
+ char *tname = (char *)malloc (strlen (name) + 1);
+
+ if (!vendor_class_hash)
+ vendor_class_hash = new_hash ();
+ if (!user_class_hash)
+ user_class_hash = new_hash ();
+
+ if (!tname || !class || !vendor_class_hash || !user_class_hash)
+ return (struct class *)0;
+
+ memset (class, 0, sizeof *class);
+ strcpy (tname, name);
+ class -> name = tname;
+
+ if (type)
+ add_hash (user_class_hash,
+ (unsigned char *)tname, strlen (tname),
+ (unsigned char *)class);
+ else
+ add_hash (vendor_class_hash,
+ (unsigned char *)tname, strlen (tname),
+ (unsigned char *)class);
+ return class;
+}
+
+struct class *find_class (type, name, len)
+ int type;
+ unsigned char *name;
+ int len;
+{
+ struct class *class =
+ (struct class *)hash_lookup (type
+ ? user_class_hash
+ : vendor_class_hash, name, len);
+ return class;
+}
+
struct group *clone_group (group, caller)
struct group *group;
char *caller;
@@ -868,16 +921,21 @@ void dump_subnets ()
struct shared_network *s;
struct subnet *n;
+ note ("Subnets:");
+ for (n = subnets; n; n = n -> next_subnet) {
+ debug (" Subnet %s", piaddr (n -> net));
+ debug (" netmask %s",
+ piaddr (n -> netmask));
+ }
+ note ("Shared networks:");
for (s = shared_networks; s; s = s -> next) {
- for (n = subnets; n; n = n -> next_sibling) {
- debug ("Subnet %s", piaddr (n -> net));
- debug (" netmask %s",
- piaddr (n -> netmask));
- }
+ note (" %s", s -> name);
for (l = s -> leases; l; l = l -> next) {
print_lease (l);
}
- debug ("Last Lease:");
- print_lease (s -> last_lease);
+ if (s -> last_lease) {
+ debug (" Last Lease:");
+ print_lease (s -> last_lease);
+ }
}
}
diff --git a/common/nit.c b/common/nit.c
index 0633f1d3..1801bb9f 100644
--- a/common/nit.c
+++ b/common/nit.c
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: nit.c,v 1.15 1997/10/20 21:47:13 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: nit.c,v 1.15.2.1 1998/12/20 18:27:44 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -264,6 +264,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
int hw_end;
struct sockaddr_in foo;
+ if (!strcmp (interface -> name, "fallback"))
+ return send_fallback (interface, packet, raw,
+ len, from, to, hto);
+
/* Start with the sockaddr struct... */
junk = (struct sockaddr *)&buf [0];
bufp = ((unsigned char *)&junk -> sa_data [0]) - &buf [0];
@@ -344,4 +348,20 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
memcpy (buf, &ibuf [bufix], length);
return length;
}
+
+int can_unicast_without_arp ()
+{
+ return 1;
+}
+
+void maybe_setup_fallback ()
+{
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ if_register_fallback (fbi);
+ add_protocol ("fallback", fallback_interface -> wfdesc,
+ fallback_discard, fallback_interface);
+ }
+}
#endif
diff --git a/common/options.c b/common/options.c
index 89257b6e..9d6b7f46 100644
--- a/common/options.c
+++ b/common/options.c
@@ -3,7 +3,7 @@
DHCP options parsing and reassembly. */
/*
- * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,16 +42,12 @@
#ifndef lint
static char copyright[] =
-"$Id: options.c,v 1.32 1998/06/25 03:02:50 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: options.c,v 1.26.2.3 1998/06/25 21:11:30 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#define DHCP_OPTION_DATA
#include "dhcpd.h"
-static void do_option_set PROTO ((struct option_cache **,
- struct option_cache *,
- enum statement_op));
-
/* Parse all available options out of the specified packet. */
void parse_options (packet)
@@ -75,15 +71,15 @@ void parse_options (packet)
if (packet -> options_valid
&& packet -> options [DHO_DHCP_OPTION_OVERLOAD].data) {
if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 1)
- parse_option_buffer
- (packet,
- (unsigned char *)packet -> raw -> file,
- sizeof packet -> raw -> file);
+ parse_option_buffer (packet,
+ (unsigned char *)
+ packet -> raw -> file,
+ sizeof packet -> raw -> file);
if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 2)
- parse_option_buffer
- (packet,
- (unsigned char *)packet -> raw -> sname,
- sizeof packet -> raw -> sname);
+ parse_option_buffer (packet,
+ (unsigned char *)
+ packet -> raw -> sname,
+ sizeof packet -> raw -> sname);
}
}
@@ -120,18 +116,9 @@ void parse_option_buffer (packet, buffer, length)
packet -> options_valid = 0;
return;
}
-
- /* If this is a Relay Agent Information option, we must
- handle it specially. */
- if (code == DHO_DHCP_AGENT_OPTIONS) {
- if (!parse_agent_information_option (packet,
- len, &s [2])) {
- warn ("malformed agent information option.");
- }
-
/* If we haven't seen this option before, just make
space for it and copy it there. */
- } else if (!packet -> options [code].data) {
+ if (!packet -> options [code].data) {
if (!(t = (unsigned char *)malloc (len + 1)))
error ("Can't allocate storage for option %s.",
dhcp_options [code].name);
@@ -166,64 +153,14 @@ void parse_option_buffer (packet, buffer, length)
packet -> options_valid = 1;
}
-/* Parse a Relay Agent Information option and put it at the end of the
- list of such options on the specified packet. */
-
-int parse_agent_information_option (packet, len, data)
- struct packet *packet;
- int len;
- u_int8_t *data;
-{
- struct agent_options *a, **tail;
- struct option_tag *t, *oth = 0, **ott = &oth;
- u_int8_t *op = data, *max = data + len;
-
- /* Parse the agent information option suboptions. */
- while (op < max) {
- /* Check for overflow. */
- if (op + 1 == max || op + op [1] + 2 > max)
- return 0;
- /* Make space for this suboption. */
- t = (struct option_tag *)malloc (op [1] + 1 + sizeof *t);
- if (!t)
- error ("can't allocate space for option tag data.");
-
- /* Link it in at the tail of the list. */
- t -> next = (struct option_tag *)0;
- *ott = t;
- ott = &t -> next;
-
- /* Copy the option data in in its raw form. */
- memcpy (t -> data, op, op [1] + 2);
- op += op [1] + 2;
- }
-
- /* Make an agent options structure to put on the list. */
- a = (struct agent_options *)malloc (sizeof *a);
- if (!a)
- error ("can't allocate space for agent option structure.");
-
- /* Find the tail of the list. */
- for (tail = &packet -> agent_options; *tail; tail = &((*tail) -> next))
- ;
- *tail = a;
- a -> next = (struct agent_options *)0;
- a -> first = oth;
- a -> length = len;
-
- return 1;
-}
-
/* cons options into a big buffer, and then split them out into the
three seperate buffers if needed. This allows us to cons up a set
of vendor options using the same routine. */
-int cons_options (inpacket, outpacket, mms, options,
- overload, terminate, bootpp)
+int cons_options (inpacket, outpacket, options, overload, terminate, bootpp)
struct packet *inpacket;
struct dhcp_packet *outpacket;
- int mms;
- struct option_state *options;
+ struct tree_cache **options;
int overload; /* Overload flags that may be set. */
int terminate;
int bootpp;
@@ -232,47 +169,30 @@ int cons_options (inpacket, outpacket, mms, options,
int priority_len;
unsigned char buffer [4096]; /* Really big buffer... */
int main_buffer_size;
- int mainbufix, bufix, agentix;
+ int mainbufix, bufix;
int option_size;
int length;
- /* If there's a Maximum Message Size option in the incoming packet
- and no alternate maximum message size has been specified, take the
- one in the packet. */
-
- if (!mms &&
- inpacket && inpacket -> options [DHO_DHCP_MAX_MESSAGE_SIZE].data) {
- mms = getUShort (inpacket ->
- options [DHO_DHCP_MAX_MESSAGE_SIZE].data);
- }
-
/* If the client has provided a maximum DHCP message size,
use that; otherwise, if it's BOOTP, only 64 bytes; otherwise
use up to the minimum IP MTU size (576 bytes). */
/* XXX if a BOOTP client specifies a max message size, we will
honor it. */
-
- if (mms) {
- main_buffer_size = mms - DHCP_FIXED_LEN;
-
+ if (inpacket && inpacket -> options [DHO_DHCP_MAX_MESSAGE_SIZE].data) {
+ main_buffer_size =
+ (getUShort (inpacket -> options
+ [DHO_DHCP_MAX_MESSAGE_SIZE].data)
+ - DHCP_FIXED_LEN);
/* Enforce a minimum packet size... */
if (main_buffer_size < (576 - DHCP_FIXED_LEN))
main_buffer_size = 576 - DHCP_FIXED_LEN;
- } else if (bootpp) {
- if (inpacket) {
- main_buffer_size =
- inpacket -> packet_length - DHCP_FIXED_LEN;
- if (main_buffer_size < 64)
- main_buffer_size = 64;
- } else
- main_buffer_size = 64;
- } else
+ if (main_buffer_size > sizeof buffer)
+ main_buffer_size = sizeof buffer;
+ } else if (bootpp)
+ main_buffer_size = 64;
+ else
main_buffer_size = 576 - DHCP_FIXED_LEN;
- /* Set a hard limit at the size of the output buffer. */
- if (main_buffer_size > sizeof buffer)
- main_buffer_size = sizeof buffer;
-
/* Preload the option priority list with mandatory options. */
priority_len = 0;
priority_list [priority_len++] = DHO_DHCP_MESSAGE_TYPE;
@@ -307,8 +227,7 @@ int cons_options (inpacket, outpacket, mms, options,
(main_buffer_size - 7 +
((overload & 1) ? DHCP_FILE_LEN : 0) +
((overload & 2) ? DHCP_SNAME_LEN : 0)),
- options -> dhcp_options,
- priority_list, priority_len,
+ options, priority_list, priority_len,
main_buffer_size,
(main_buffer_size +
((overload & 1) ? DHCP_FILE_LEN : 0)),
@@ -326,12 +245,9 @@ int cons_options (inpacket, outpacket, mms, options,
memcpy (&outpacket -> options [mainbufix],
buffer, option_size);
mainbufix += option_size;
- if (mainbufix < main_buffer_size) {
- agentix = mainbufix;
+ if (mainbufix < main_buffer_size)
outpacket -> options [mainbufix++]
= DHO_END;
- } else
- agentix = mainbufix;
length = DHCP_FIXED_NON_UDP + mainbufix;
} else {
outpacket -> options [mainbufix++] =
@@ -344,10 +260,8 @@ int cons_options (inpacket, outpacket, mms, options,
memcpy (&outpacket -> options [mainbufix],
buffer, main_buffer_size - mainbufix);
- length = DHCP_FIXED_NON_UDP + main_buffer_size;
- agentix = main_buffer_size;
-
bufix = main_buffer_size - mainbufix;
+ length = DHCP_FIXED_NON_UDP + mainbufix;
if (overload & 1) {
if (option_size - bufix <= DHCP_FILE_LEN) {
memcpy (outpacket -> file,
@@ -378,38 +292,6 @@ int cons_options (inpacket, outpacket, mms, options,
= DHO_PAD;
}
}
-
- /* We tack any agent options onto the end of the packet after
- we've put it together. */
- if (agent_options) {
- int len = 0;
- struct agent_options *a;
- struct option_tag *o;
-
- /* Cycle through the options, appending them to the
- buffer. */
- for (a = options -> agent_options; a; a = a -> next) {
- if (agentix + a -> length + 3 + DHCP_FIXED_LEN <=
- dhcp_max_agent_option_packet_length) {
- outpacket ->
- options [agentix++] = DHO_DHCP_AGENT_OPTIONS;
- outpacket -> options [agentix++] = a -> length;
- for (o = a -> first; o; o = o -> next) {
- memcpy (&outpacket -> options [agentix],
- o -> data, o -> data [1] + 2);
- agentix += o -> data [1] + 2;
- }
- }
- }
-
- /* Reterminate the packet. */
- outpacket -> options [agentix++] = DHO_END;
-
- /* Recompute the length, which may now be higher than the
- client can accept but should be okay for the relay agent. */
- length = agentix + DHCP_FIXED_NON_UDP;
- }
-
return length;
}
@@ -419,7 +301,7 @@ int store_options (buffer, buflen, options, priority_list, priority_len,
first_cutoff, second_cutoff, terminate)
unsigned char *buffer;
int buflen;
- struct option_cache **options;
+ struct tree_cache **options;
unsigned char *priority_list;
int priority_len;
int first_cutoff, second_cutoff;
@@ -430,7 +312,6 @@ int store_options (buffer, buflen, options, priority_list, priority_len,
int i;
int ix;
int tto;
- struct data_string od;
/* Zero out the stored-lengths array. */
memset (option_stored, 0, sizeof option_stored);
@@ -458,13 +339,12 @@ int store_options (buffer, buflen, options, priority_list, priority_len,
option_stored [code] = 1;
/* Find the value of the option... */
- od = evaluate_data_expression ((struct packet *)0,
- options [code] -> expression);
- if (!od.len)
+ if (!tree_evaluate (options [code])) {
continue;
+ }
/* We should now have a constant length for the option. */
- length = od.len;
+ length = options [code] -> len;
/* Do we add a NUL? */
if (terminate && dhcp_options [code].format [0] == 't') {
@@ -509,18 +389,17 @@ int store_options (buffer, buflen, options, priority_list, priority_len,
buffer [bufix + 1] = incr;
if (tto && incr == length) {
memcpy (buffer + bufix + 2,
- od.data + ix, incr - 1);
+ options [code] -> value + ix,
+ incr - 1);
buffer [bufix + 2 + incr - 1] = 0;
} else {
memcpy (buffer + bufix + 2,
- od.data + ix, incr);
+ options [code] -> value + ix, incr);
}
length -= incr;
ix += incr;
bufix += 2 + incr;
}
- if (od.buffer)
- dfree (od.buffer, "store_options");
}
return bufix;
}
@@ -704,6 +583,11 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
{
struct packet tp;
+ if (packet -> hlen > sizeof packet -> chaddr) {
+ note ("Discarding packet with invalid hlen.");
+ return;
+ }
+
memset (&tp, 0, sizeof tp);
tp.raw = packet;
tp.packet_length = len;
@@ -712,10 +596,6 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
tp.interface = interface;
tp.haddr = hfrom;
- if (packet -> hlen > sizeof packet -> chaddr) {
- note ("Discarding packet with bogus hardware address length.");
- return;
- }
parse_options (&tp);
if (tp.options_valid &&
tp.options [DHO_DHCP_MESSAGE_TYPE].data)
@@ -725,137 +605,5 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
dhcp (&tp);
else
bootp (&tp);
-
- /* XXX what about freeing the options ?!? */
}
-struct data_string dhcp_option_lookup (packet, code)
- struct packet *packet;
- int code;
-{
- struct data_string result;
-
- result.len = packet -> options [code].len;
- result.data = packet -> options [code].data;
- result.terminated = 1;
- result.buffer = (unsigned char *)0;
- return result;
-}
-
-struct data_string agent_suboption_lookup (packet, code)
- struct packet *packet;
- int code;
-{
- struct agent_options *ao;
- struct option_tag *t;
- struct data_string result;
-
- memset (&result, 0, sizeof result);
-
- /* Find the last set of agent options and consider it definitive. */
- if (ao) {
- for (ao = packet -> agent_options; ao -> next; ao = ao -> next)
- ;
- for (t = ao -> first; t; t = t -> next)
- if (t -> data [0] == code) {
- result.len = t -> data [1];
- result.data = &t -> data [2];
- break;
- }
- }
- return result;
-}
-
-struct data_string server_option_lookup (packet, code)
- struct packet *packet;
- int code;
-{
- struct data_string result;
-
- result.len = 0;
- result.data = (unsigned char *)0;
- result.terminated = 0;
- result.buffer = (unsigned char *)0;
- return result;
-}
-
-void dhcp_option_set (options, option, op)
- struct option_state *options;
- struct option_cache *option;
- enum statement_op op;
-{
- struct option_cache *thecache;
-
- do_option_set (&options -> server_options
- [option -> option -> code], option, op);
-}
-
-void server_option_set (options, option, op)
- struct option_state *options;
- struct option_cache *option;
- enum statement_op op;
-{
- do_option_set (&options -> server_options
- [option -> option -> code], option, op);
-}
-
-static void do_option_set (thecache, option, op)
- struct option_cache **thecache;
- struct option_cache *option;
- enum statement_op op;
-{
- struct option_cache *oc;
-
- switch (op) {
- case if_statement:
- case add_statement:
- case eval_statement:
- case break_statement:
- default:
- warn ("bogus statement type in do_option_set.");
- break;
-
- case default_option_statement:
- if (*thecache)
- break;
- *thecache = option;
- break;
-
- case supersede_option_statement:
- /* Free any ephemeral state associated with the
- current value. */
- if (*thecache)
- free_oc_ephemeral_state (*thecache);
- *thecache = option;
- break;
-
- case append_option_statement:
- case prepend_option_statement:
- if (!*thecache) {
- *thecache = option;
- break;
- }
- if (((*thecache) -> expression -> flags) & EXPR_EPHEMERAL)
- oc = *thecache;
- else {
- oc = new_option_cache ("do_option_set");
- if (!oc) {
- warn ("can't allocate option cache!");
- break;
- }
- *oc = **thecache;
- }
- if (op == append_option_statement)
- oc -> expression =
- make_concat ((*thecache) -> expression,
- option -> expression);
- else
- oc -> expression =
- make_concat (option -> expression,
- (*thecache) -> expression);
-
- oc -> expression -> flags |= EXPR_EPHEMERAL;
- *thecache = oc;
- break;
- }
-}
diff --git a/common/packet.c b/common/packet.c
index f1725144..069a76b8 100644
--- a/common/packet.c
+++ b/common/packet.c
@@ -3,7 +3,7 @@
Packet assembly code, originally contributed by Archie Cobbs. */
/*
- * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: packet.c,v 1.19 1998/03/16 06:14:08 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: packet.c,v 1.18.2.1 1998/06/26 18:20:44 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -158,7 +158,7 @@ void assemble_udp_ip_header (interface, buf, bufix,
int *bufix;
u_int32_t from;
u_int32_t to;
- u_int32_t port;
+ unsigned int port;
unsigned char *data;
int len;
{
diff --git a/common/parse.c b/common/parse.c
index ece7e700..d750ec53 100644
--- a/common/parse.c
+++ b/common/parse.c
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: parse.c,v 1.7 1998/06/25 03:07:51 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: parse.c,v 1.2.2.3 1998/12/22 22:43:22 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -134,11 +134,7 @@ char *parse_string (cfile)
return s;
}
-/*
- * hostname :== IDENTIFIER
- * | IDENTIFIER DOT
- * | hostname DOT IDENTIFIER
- */
+/* hostname :== identifier | hostname DOT identifier */
char *parse_host_name (cfile)
FILE *cfile;
@@ -153,11 +149,12 @@ char *parse_host_name (cfile)
/* Read a dotted hostname... */
do {
/* Read a token, which should be an identifier. */
- token = peek_token (&val, cfile);
- if (!is_identifier (token) && token != NUMBER)
- break;
token = next_token (&val, cfile);
-
+ if (!is_identifier (token) && token != NUMBER) {
+ parse_warn ("expecting an identifier in hostname");
+ skip_to_semi (cfile);
+ return (char *)0;
+ }
/* Store this identifier... */
if (!(s = (char *)malloc (strlen (val) + 1)))
error ("can't allocate temp space for hostname.");
@@ -191,53 +188,6 @@ char *parse_host_name (cfile)
return s;
}
-/* ip-addr-or-hostname :== ip-address | hostname
- ip-address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
-
- Parse an ip address or a hostname. If uniform is zero, put in
- an expr_substring node to limit hostnames that evaluate to more
- than one IP address. */
-
-struct expression *parse_ip_addr_or_hostname (cfile, uniform)
- FILE *cfile;
- int uniform;
-{
- char *val;
- int token;
- unsigned char addr [4];
- int len = sizeof addr;
- char *name;
- struct expression *rv;
-
- token = peek_token (&val, cfile);
- if (is_identifier (token)) {
- name = parse_host_name (cfile);
- if (!name)
- return (struct expression *)0;
- rv = make_host_lookup (name);
- if (!uniform)
- rv = make_limit (rv, 4);
- } else if (token == NUMBER) {
- if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
- return (struct expression *)0;
- rv = make_const_data (addr, len, 0, 0);
- } else {
- if (token != RBRACE && token != LBRACE)
- token = next_token (&val, cfile);
- parse_warn ("%s (%d): expecting IP address or hostname",
- val, token);
- if (token != SEMI)
- skip_to_semi (cfile);
- return (struct expression *)0;
- }
-
- return rv;
-}
-
-/*
- * ip-address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
- */
-
int parse_ip_addr (cfile, addr)
FILE *cfile;
struct iaddr *addr;
@@ -252,10 +202,8 @@ int parse_ip_addr (cfile, addr)
return 0;
}
-/*
- * hardware-parameter :== HARDWARE hardware-type colon-seperated-hex-list SEMI
- * hardware-type :== ETHERNET | TOKEN_RING
- */
+/* hardware-parameter :== HARDWARE ETHERNET csns SEMI
+ csns :== NUMBER | csns COLON NUMBER */
void parse_hardware_param (cfile, hardware)
FILE *cfile;
@@ -274,6 +222,9 @@ void parse_hardware_param (cfile, hardware)
case TOKEN_RING:
hardware -> htype = HTYPE_IEEE802;
break;
+ case FDDI:
+ hardware -> htype = HTYPE_FDDI;
+ break;
default:
parse_warn ("expecting a network hardware type");
skip_to_semi (cfile);
@@ -299,6 +250,9 @@ void parse_hardware_param (cfile, hardware)
hardware -> hlen = hlen;
memcpy ((unsigned char *)&hardware -> haddr [0],
t, hardware -> hlen);
+ if (hlen < sizeof hardware -> haddr)
+ memset (&hardware -> haddr [hlen], 0,
+ (sizeof hardware -> haddr) - hlen);
free (t);
}
@@ -349,7 +303,8 @@ unsigned char *parse_numeric_aggregate (cfile, buf,
{
char *val;
int token;
- unsigned char *bufp = buf, *s, *t;
+ unsigned char *bufp = buf, *s;
+ char *t;
int count = 0;
pair c = (pair)0;
@@ -395,11 +350,11 @@ unsigned char *parse_numeric_aggregate (cfile, buf,
convert_num (s, val, base, size);
s += size / 8;
} else {
- t = (unsigned char *)malloc (strlen (val) + 1);
+ t = (char *)malloc (strlen (val) + 1);
if (!t)
error ("no temp space for number.");
- strcpy ((char *)t, val);
- c = cons ((caddr_t)t, c);
+ strcpy (t, val);
+ c = cons (t, c);
}
} while (++count != *max);
@@ -532,14 +487,12 @@ void convert_num (buf, str, base, size)
}
}
-/*
- * date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER
- * NUMBER COLON NUMBER COLON NUMBER SEMI
- *
- * Dates are always in GMT; first number is day of week; next is
- * year/month/day; next is hours:minutes:seconds on a 24-hour
- * clock.
- */
+/* date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER
+ NUMBER COLON NUMBER COLON NUMBER SEMI
+
+ Dates are always in GMT; first number is day of week; next is
+ year/month/day; next is hours:minutes:seconds on a 24-hour
+ clock. */
TIME parse_date (cfile)
FILE *cfile;
@@ -569,11 +522,6 @@ TIME parse_date (cfile)
skip_to_semi (cfile);
return (TIME)0;
}
-
- /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
- somebody invents a time machine, I think we can safely disregard
- it. This actually works around a stupid Y2K bug that was present
- in a very early beta release of dhcpd. */
tm.tm_year = atoi (val);
if (tm.tm_year > 1900)
tm.tm_year -= 1900;
@@ -699,946 +647,3 @@ TIME parse_date (cfile)
return guess;
}
-
-/*
- * option-name :== IDENTIFIER |
- IDENTIFIER . IDENTIFIER
- */
-
-struct option *parse_option_name (cfile)
- FILE *cfile;
-{
- char *val;
- int token;
- char *vendor;
- struct universe *universe;
- struct option *option;
-
- token = next_token (&val, cfile);
- if (!is_identifier (token)) {
- parse_warn ("expecting identifier after option keyword.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (struct option *)0;
- }
- vendor = malloc (strlen (val) + 1);
- if (!vendor)
- error ("no memory for vendor information.");
- strcpy (vendor, val);
- token = peek_token (&val, cfile);
- if (token == DOT) {
- /* Go ahead and take the DOT token... */
- token = next_token (&val, cfile);
-
- /* The next token should be an identifier... */
- token = next_token (&val, cfile);
- if (!is_identifier (token)) {
- parse_warn ("expecting identifier after '.'");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (struct option *)0;
- }
-
- /* Look up the option name hash table for the specified
- vendor. */
- universe = ((struct universe *)
- hash_lookup (&universe_hash,
- (unsigned char *)vendor, 0));
- /* If it's not there, we can't parse the rest of the
- declaration. */
- if (!universe) {
- parse_warn ("no vendor named %s.", vendor);
- skip_to_semi (cfile);
- return (struct option *)0;
- }
- } else {
- /* Use the default hash table, which contains all the
- standard dhcp option names. */
- val = vendor;
- universe = &dhcp_universe;
- }
-
- /* Look up the actual option info... */
- option = (struct option *)hash_lookup (universe -> hash,
- (unsigned char *)val, 0);
-
- /* If we didn't get an option structure, it's an undefined option. */
- if (!option) {
- if (val == vendor)
- parse_warn ("no option named %s", val);
- else
- parse_warn ("no option named %s for vendor %s",
- val, vendor);
- skip_to_semi (cfile);
- return (struct option *)0;
- }
-
- /* Free the initial identifier token. */
- free (vendor);
- return option;
-}
-
-/*
- * colon-seperated-hex-list :== NUMBER |
- * NUMBER COLON colon-seperated-hex-list
- */
-
-unsigned char *parse_cshl (cfile, plen)
- FILE *cfile;
- int *plen;
-{
- char ibuf [128];
- int ilen = 0;
- int tlen = 0;
- struct option_tag *sl = (struct option_tag *)0;
- struct option_tag *next, **last = &sl;
- int token;
- char *val;
- unsigned char *rv, *rvp;
-
- do {
- token = next_token (&val, cfile);
- if (token != NUMBER && token != NUMBER_OR_NAME) {
- parse_warn ("expecting hexadecimal number.");
- skip_to_semi (cfile);
- for (; sl; sl = next) {
- next = sl -> next;
- dfree (sl, "parse_cshl");
- }
- return (unsigned char *)0;
- }
- if (ilen == sizeof ibuf) {
- next = (struct option_tag *)
- dmalloc (ilen - 1 +
- sizeof (struct option_tag),
- "parse_cshl");
- if (!next)
- error ("no memory for string list.");
- memcpy (next -> data, ibuf, ilen);
- *last = next;
- last = &next -> next;
- tlen += ilen;
- ilen = 0;
- }
- convert_num (&ibuf [ilen++], val, 16, 8);
-
- token = peek_token (&val, cfile);
- if (token != COLON)
- break;
- token = next_token (&val, cfile);
- } while (1);
-
- rv = dmalloc (tlen + ilen, "parse_cshl");
- if (!rv)
- error ("no memory to store octet data.");
- rvp = rv;
- while (sl) {
- next = sl -> next;
- memcpy (rvp, sl -> data, sizeof ibuf);
- rvp += sizeof ibuf;
- dfree (sl, "parse_cshl");
- sl = next;
- }
-
- memcpy (rvp, ibuf, ilen);
- *plen = ilen + tlen;
- return rv;
-}
-
-/*
- * executable-statements :== executable-statement executable-statements |
- * executable-statement
- *
- * executable-statement :==
- * IF if-statement |
- * ADD class-name SEMI |
- * BREAK SEMI |
- * OPTION option-parameter SEMI |
- * SUPERSEDE option-parameter SEMI |
- * PREPEND option-parameter SEMI |
- * APPEND option-parameter SEMI
- */
-
-struct executable_statement *parse_executable_statements (cfile, lose)
- FILE *cfile;
- int *lose;
-{
- struct executable_statement *head, **next;
-
- next = &head;
- while ((*next = parse_executable_statement (cfile, lose)))
- next = &((*next) -> next);
- if (!lose)
- return head;
- return (struct executable_statement *)0;
-}
-
-struct executable_statement *parse_executable_statement (cfile, lose)
- FILE *cfile;
- int *lose;
-{
- int token;
- char *val;
- struct executable_statement *stmt, base;
- struct class *cta;
- struct option *option;
-
- switch (peek_token (&val, cfile)) {
- case IF:
- stmt = parse_if_statement (cfile, lose);
- return stmt;
- case ADD:
- token = next_token (&val, cfile);
- if (token != STRING) {
- parse_warn ("expecting class name.");
- skip_to_semi (cfile);
- *lose = 1;
- return (struct executable_statement *)0;
- }
- cta = find_class (val);
- if (!cta) {
- parse_warn ("unknown class %s.", val);
- skip_to_semi (cfile);
- *lose = 1;
- return (struct executable_statement *)0;
- }
- if (!parse_semi (cfile)) {
- *lose = 1;
- return (struct executable_statement *)0;
- }
- memset (&base, 0, sizeof base);
- base.op = add_statement;
- base.data.add = cta;
- break;
-
- case BREAK:
- token = next_token (&val, cfile);
- if (!parse_semi (cfile)) {
- *lose = 1;
- return (struct executable_statement *)0;
- }
- memset (&base, 0, sizeof base);
- base.op = break_statement;
- break;
-
- case OPTION:
- token = next_token (&val, cfile);
- option = parse_option_name (cfile);
- if (!option) {
- *lose = 1;
- return (struct executable_statement *)0;
- }
- return parse_option_statement (cfile, 1, option,
- supersede_option_statement);
-
- case DEFAULT:
- token = next_token (&val, cfile);
- option = parse_option_name (cfile);
- if (!option) {
- *lose = 1;
- return (struct executable_statement *)0;
- }
- return parse_option_statement (cfile, 1, option,
- default_option_statement);
-
- case PREPEND:
- token = next_token (&val, cfile);
- option = parse_option_name (cfile);
- if (!option) {
- *lose = 1;
- return (struct executable_statement *)0;
- }
- return parse_option_statement (cfile, 1, option,
- prepend_option_statement);
-
- case APPEND:
- token = next_token (&val, cfile);
- option = parse_option_name (cfile);
- if (!option) {
- *lose = 1;
- return (struct executable_statement *)0;
- }
- return parse_option_statement (cfile, 1, option,
- append_option_statement);
-
- default:
- *lose = 0;
- return (struct executable_statement *)0;
- }
-
- stmt = ((struct executable_statement *)
- dmalloc (sizeof (struct executable_statement),
- "parse_executable_statement"));
- if (!stmt)
- error ("no memory for new statement.");
- *stmt = base;
- return stmt;
-}
-
-/*
- * if-statement :== boolean-expression LBRACE executable-statements RBRACE
- * else-statement
- *
- * else-statement :== <null> |
- * ELSE LBRACE executable-statements RBRACE |
- * ELSE IF if-statement |
- * ELSIF if-statement
- */
-
-struct executable_statement *parse_if_statement (cfile, lose)
- FILE *cfile;
- int *lose;
-{
- int token;
- char *val;
- struct executable_statement *stmt;
- struct expression *if_condition;
- struct executable_statement *true, *false;
-
- token = next_token (&val, cfile);
- if_condition = parse_boolean_expression (cfile, lose);
- if (!if_condition) {
- if (!*lose)
- parse_warn ("boolean expression expected.");
- return (struct executable_statement *)0;
- }
- token = next_token (&val, cfile);
- if (token != LBRACE) {
- parse_warn ("left brace expected.");
- skip_to_semi (cfile);
- *lose = 1;
- return (struct executable_statement *)0;
- }
- true = parse_executable_statements (cfile, lose);
- if (*lose)
- return (struct executable_statement *)0;
- token = next_token (&val, cfile);
- if (token != RBRACE) {
- parse_warn ("right brace expected.");
- skip_to_semi (cfile);
- *lose = 1;
- return (struct executable_statement *)0;
- }
- token = peek_token (&val, cfile);
- if (token == ELSE) {
- token = next_token (&val, cfile);
- token = peek_token (&val, cfile);
- if (token == IF) {
- token = next_token (&val, cfile);
- false = parse_if_statement (cfile, lose);
- if (*lose)
- return (struct executable_statement *)0;
- } else if (token != LBRACE) {
- parse_warn ("left brace or if expected.");
- skip_to_semi (cfile);
- *lose = 1;
- return (struct executable_statement *)0;
- } else {
- token = next_token (&val, cfile);
- false = parse_executable_statement (cfile, lose);
- if (*lose)
- return (struct executable_statement *)0;
- }
- } else if (token == ELSIF) {
- token = next_token (&val, cfile);
- false = parse_if_statement (cfile, lose);
- if (*lose)
- return (struct executable_statement *)0;
- } else
- false = (struct executable_statement *)0;
-
- stmt = ((struct executable_statement *)
- dmalloc (sizeof (struct executable_statement),
- "parse_if_statement"));
- if (!stmt)
- error ("no memory for if statement.");
- memset (stmt, 0, sizeof *stmt);
- stmt -> op = if_statement;
- stmt -> data.ie.expr = if_condition;
- stmt -> data.ie.true = true;
- stmt -> data.ie.false = false;
- return stmt;
-}
-
-/*
- * boolean_expression :== CHECK STRING |
- * NOT boolean-expression |
- * data-expression EQUAL data-expression |
- * boolean-expression AND boolean-expression |
- * boolean-expression OR boolean-expression
- */
-
-
-struct expression *parse_boolean_expression (cfile, lose)
- FILE *cfile;
- int *lose;
-{
- int token;
- char *val;
- struct collection *col;
- struct expression buf, *rv;
- struct expression *left, *right;
-
- token = peek_token (&val, cfile);
-
- /* Check for unary operators... */
- switch (token) {
- case CHECK:
- token = next_token (&val, cfile);
- token = next_token (&val, cfile);
- if (token != STRING) {
- parse_warn ("string expected.");
- skip_to_semi (cfile);
- *lose = 1;
- return (struct expression *)0;
- }
- for (col = collections; col; col = col -> next)
- if (!strcmp (col -> name, val))
- break;
- if (!col) {
- parse_warn ("unknown collection.");
- *lose = 1;
- return (struct expression *)0;
- }
- buf.op = expr_check;
- buf.data.check = col;
- goto have_expr;
-
- case NOT:
- token = next_token (&val, cfile);
- buf.op = expr_not;
- buf.data.not = parse_boolean_expression (cfile, lose);
- if (!buf.data.not) {
- if (!*lose) {
- parse_warn ("match expression expected");
- skip_to_semi (cfile);
- }
- *lose = 1;
- return (struct expression *)0;
- }
- goto have_expr;
- }
-
- /* If we're going to find an expression at this point, it must
- involve a binary operator seperating two subexpressions. */
- left = parse_data_expression (cfile, lose);
- if (!left)
- return left;
- token = peek_token (&val, cfile);
- switch (token) {
- case EQUAL:
- buf.op = expr_equal;
- break;
- case AND:
- buf.op = expr_and;
- break;
- case OR:
- buf.op = expr_or;
- break;
- default:
- parse_warn ("Expecting a boolean expression.");
- skip_to_semi (cfile);
- *lose = 1;
- return (struct expression *)0;
- }
- token = next_token (&val, cfile);
-
- /* Now find the RHS of the expression. */
- right = parse_data_expression (cfile, lose);
- if (!right) {
- if (!*lose) {
- if (buf.op == expr_equal)
- parse_warn ("Expecting a data expression.");
- else
- parse_warn ("Expecting a boolean expression.");
- skip_to_semi (cfile);
- }
- return right;
- }
-
- /* Store the LHS and RHS. */
- buf.data.equal [0] = left;
- buf.data.equal [1] = right;
-
- have_expr:
- rv = new_expression ("parse_boolean_expression");
- if (!rv)
- error ("No memory for boolean expression.");
- *rv = buf;
- return rv;
-}
-
-/*
- * data_expression :== SUBSTRING LPAREN data-expression COMMA
- * numeric-expression COMMA
- * numeric-expression RPAREN |
- * SUFFIX LPAREN data_expression COMMA
- * numeric-expression |
- * OPTION option_name |
- * HARDWARE |
- * PACKET LPAREN numeric-expression COMMA
- * numeric-expression RPAREN |
- * STRING |
- * colon_seperated_hex_list
- */
-
-struct expression *parse_data_expression (cfile, lose)
- FILE *cfile;
- int *lose;
-{
- int token;
- char *val;
- struct collection *col;
- struct expression buf, *rv;
- struct expression *left, *right;
- struct option *option;
-
- token = peek_token (&val, cfile);
-
- switch (token) {
- case SUBSTRING:
- token = next_token (&val, cfile);
- buf.op = expr_substring;
-
- token = next_token (&val, cfile);
- if (token != LPAREN) {
- nolparen:
- parse_warn ("left parenthesis expected.");
- *lose = 1;
- return (struct expression *)0;
- }
-
- rv = parse_data_expression (cfile, lose);
- if (!rv) {
- nodata:
- parse_warn ("expecting data expression.");
- skip_to_semi (cfile);
- *lose = 1;
- return (struct expression *)0;
- }
-
- token = next_token (&val, cfile);
- if (token != COMMA) {
- nocomma:
- parse_warn ("comma expected.");
- *lose = 1;
- return (struct expression *)0;
- }
-
- left = parse_numeric_expression (cfile, lose);
- if (!left) {
- nonum:
- if (!*lose) {
- parse_warn ("expecting numeric expression.");
- skip_to_semi (cfile);
- *lose = 1;
- }
- return (struct expression *)0;
- }
-
- token = next_token (&val, cfile);
- if (token != COMMA)
- goto nocomma;
-
- right = parse_numeric_expression (cfile, lose);
- if (!right)
- goto nonum;
-
- token = next_token (&val, cfile);
- if (token != RPAREN) {
- norparen:
- parse_warn ("right parenthesis expected.");
- *lose = 1;
- return (struct expression *)0;
- }
- return make_substring (rv, left, right);
-
- case SUFFIX:
- token = next_token (&val, cfile);
- buf.op = expr_suffix;
-
- token = next_token (&val, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- buf.data.suffix.expr = parse_data_expression (cfile, lose);
- if (!buf.data.suffix.expr)
- goto nodata;
-
- token = next_token (&val, cfile);
- if (token != COMMA)
- goto nocomma;
-
- buf.data.suffix.len = parse_numeric_expression (cfile, lose);
- if (!buf.data.suffix.len)
- goto nonum;
-
- token = next_token (&val, cfile);
- if (token != RPAREN)
- goto norparen;
- goto have_expr;
-
- case OPTION:
- token = next_token (&val, cfile);
- buf.op = expr_option;
- buf.data.option = parse_option_name (cfile);
- if (!buf.data.option) {
- *lose = 1;
- return (struct expression *)0;
- }
- goto have_expr;
-
- case HARDWARE:
- token = next_token (&val, cfile);
- buf.op = expr_hardware;
- goto have_expr;
-
- case PACKET:
- token = next_token (&val, cfile);
- buf.op = expr_packet;
-
- token = next_token (&val, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- buf.data.packet.offset =
- parse_numeric_expression (cfile, lose);
- if (!buf.data.packet.offset)
- goto nonum;
-
- token = next_token (&val, cfile);
- if (token != COMMA)
- goto nocomma;
-
- buf.data.packet.len =
- parse_numeric_expression (cfile, lose);
- if (!buf.data.substring.len)
- goto nonum;
-
- token = next_token (&val, cfile);
- if (token != RPAREN)
- goto norparen;
- goto have_expr;
-
- case STRING:
- token = next_token (&val, cfile);
- return make_const_data (val, strlen (val), 1, 1);
-
- case NUMBER:
- case NUMBER_OR_NAME:
- buf.op = expr_const_data;
- memset (&buf.data, 0, sizeof buf.data);
- buf.data.const_data.data =
- parse_cshl (cfile, &buf.data.const_data.len);
- goto have_expr;
-
- default:
- return (struct expression *)0;
- }
-
- have_expr:
- rv = (struct expression *)dmalloc (sizeof (struct expression),
- "parse_boolean_expression");
- if (!rv)
- error ("No memory for boolean expression.");
- *rv = buf;
- return rv;
-}
-
-/*
- * numeric-expression :== EXTRACT_INT LPAREN data-expression
- * COMMA number RPAREN |
- * NUMBER
- */
-
-struct expression *parse_numeric_expression (cfile, lose)
- FILE *cfile;
- int *lose;
-{
- int token;
- char *val;
- struct collection *col;
- struct expression buf, *rv;
- struct expression *left, *right;
- struct option *option;
-
- token = peek_token (&val, cfile);
-
- switch (token) {
- case EXTRACT_INT:
- token = next_token (&val, cfile);
-
- token = next_token (&val, cfile);
- if (token != LPAREN) {
- parse_warn ("left parenthesis expected.");
- *lose = 1;
- return (struct expression *)0;
- }
-
- buf.data.extract_int.expr =
- parse_data_expression (cfile, lose);
- if (!buf.data.extract_int.expr) {
- parse_warn ("expecting data expression.");
- skip_to_semi (cfile);
- *lose = 1;
- return (struct expression *)0;
- }
-
- token = next_token (&val, cfile);
- if (token != COMMA) {
- parse_warn ("comma expected.");
- *lose = 1;
- return (struct expression *)0;
- }
-
- token = next_token (&val, cfile);
- if (token != NUMBER) {
- parse_warn ("number expected.");
- *lose = 1;
- return (struct expression *)0;
- }
- buf.data.extract_int.width = (struct expression *)0;
- switch (atoi (val)) {
- case 8:
- buf.op = expr_extract_int8;
- break;
-
- case 16:
- buf.op = expr_extract_int16;
- break;
-
- case 32:
- buf.op = expr_extract_int32;
- break;
-
- default:
- parse_warn ("unsupported integer size %d", atoi (val));
- *lose = 1;
- skip_to_semi (cfile);
- return (struct expression *)0;
- }
-
- token = next_token (&val, cfile);
- if (token != RPAREN) {
- parse_warn ("right parenthesis expected.");
- *lose = 1;
- return (struct expression *)0;
- }
- goto have_expr;
-
- case NUMBER:
- buf.op = expr_const_int;
- buf.data.const_int = atoi (val);
- goto have_expr;
-
- default:
- return (struct expression *)0;
- }
-
- have_expr:
- rv = (struct expression *)dmalloc (sizeof (struct expression),
- "parse_boolean_expression");
- if (!rv)
- error ("No memory for boolean expression.");
- *rv = buf;
- return rv;
-}
-
-/* option-statement :== identifier DOT identifier <syntax> SEMI
- | identifier <syntax> SEMI
-
- Option syntax is handled specially through format strings, so it
- would be painful to come up with BNF for it. However, it always
- starts as above and ends in a SEMI. */
-
-struct executable_statement *parse_option_statement (cfile, lookups,
- option, op)
- FILE *cfile;
- int lookups;
- struct option *option;
- enum statement_op op;
-{
- char *val;
- int token;
- char *fmt;
- struct expression *expr = (struct expression *)0;
- int lose;
- struct executable_statement *stmt;
-
- token = peek_token (&val, cfile);
- if (token == SEMI) {
- /* Eat the semicolon... */
- token = next_token (&val, cfile);
- expr = make_const_data (0, 0, 0, 0);
- goto done;
- }
-
- /* See if there's a data expression, and if so, use it rather than
- the standard format. */
- expr = ((struct expression *)parse_data_expression (cfile, &lose));
-
- /* Found a data expression, but it was bogus? */
- if (lose)
- return (struct executable_statement *)0;
-
- /* We found one. */
- if (expr)
- goto done;
-
- /* Parse the option data... */
- do {
- /* Set a flag if this is an array of a simple type (i.e.,
- not an array of pairs of IP addresses, or something
- like that. */
- int uniform = option -> format [1] == 'A';
-
- for (fmt = option -> format; *fmt; fmt++) {
- if (*fmt == 'A')
- break;
- expr = parse_option_token (cfile, fmt,
- expr, uniform, lookups);
- }
- if (*fmt == 'A') {
- token = peek_token (&val, cfile);
- if (token == COMMA) {
- token = next_token (&val, cfile);
- continue;
- }
- break;
- }
- } while (*fmt == 'A');
-
- done:
- token = next_token (&val, cfile);
- if (token != SEMI) {
- parse_warn ("semicolon expected.");
- skip_to_semi (cfile);
- return (struct executable_statement *)0;
- }
- stmt = ((struct executable_statement *)
- dmalloc (sizeof *stmt, "parse_option_statement"));
- stmt -> op = op;
- stmt -> data.option = option_cache (expr, option);
- return stmt;
-}
-
-struct expression *parse_option_token (cfile, fmt, expr, uniform, lookups)
- FILE *cfile;
- char *fmt;
- struct expression *expr;
- int uniform;
- int lookups;
-{
- char *val;
- int token;
- struct expression *t;
- unsigned char buf [4];
- int len;
- unsigned char *ob;
- struct iaddr addr;
-
- switch (*fmt) {
- case 'X':
- token = peek_token (&val, cfile);
- if (token == NUMBER_OR_NAME || token == NUMBER) {
- ob = parse_cshl (cfile, &len);
- return make_concat (expr,
- make_const_data (ob, len, 0, 0));
- } else if (token == STRING) {
- token = next_token (&val, cfile);
- return make_concat (expr,
- make_const_data ((unsigned char *)
- val,
- strlen (val),
- 1, 1));
- } else {
- parse_warn ("expecting string %s.",
- "or hexadecimal data");
- skip_to_semi (cfile);
- return (struct expression *)0;
- }
- break;
-
- case 't': /* Text string... */
- token = next_token (&val, cfile);
- if (token != STRING && !is_identifier (token)) {
- parse_warn ("expecting string.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (struct expression *)0;
- }
- return make_concat (expr,
- make_const_data ((unsigned char *)
- val, strlen (val), 1, 1));
- break;
-
- case 'I': /* IP address or hostname. */
- if (lookups)
- t = parse_ip_addr_or_hostname (cfile, uniform);
- else {
- if (!parse_ip_addr (cfile, &addr))
- return (struct expression *)0;
- t = make_const_data (addr.iabuf, addr.len, 0, 1);
- }
- if (!t)
- return (struct expression *)0;
- return make_concat (expr, t);
- break;
-
- case 'L': /* Unsigned 32-bit integer... */
- case 'l': /* Signed 32-bit integer... */
- token = next_token (&val, cfile);
- if (token != NUMBER) {
- need_number:
- parse_warn ("expecting number.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (struct expression *)0;
- }
- convert_num (buf, val, 0, 32);
- return make_concat (expr, make_const_data (buf, 4, 0, 1));
- break;
- case 's': /* Signed 16-bit integer. */
- case 'S': /* Unsigned 16-bit integer. */
- token = next_token (&val, cfile);
- if (token != NUMBER)
- goto need_number;
- convert_num (buf, val, 0, 16);
- return make_concat (expr, make_const_data (buf, 2, 0, 1));
- break;
- case 'b': /* Signed 8-bit integer. */
- case 'B': /* Unsigned 8-bit integer. */
- token = next_token (&val, cfile);
- if (token != NUMBER)
- goto need_number;
- convert_num (buf, val, 0, 8);
- return make_concat (expr, make_const_data (buf, 1, 0, 1));
- break;
- case 'f': /* Boolean flag. */
- token = next_token (&val, cfile);
- if (!is_identifier (token)) {
- parse_warn ("expecting identifier.");
- bad_flag:
- if (token != SEMI)
- skip_to_semi (cfile);
- return (struct expression *)0;
- }
- if (!strcasecmp (val, "true")
- || !strcasecmp (val, "on"))
- buf [0] = 1;
- else if (!strcasecmp (val, "false")
- || !strcasecmp (val, "off"))
- buf [0] = 0;
- else {
- parse_warn ("expecting boolean.");
- goto bad_flag;
- }
- return make_concat (expr, make_const_data (buf, 1, 0, 1));
- break;
- default:
- warn ("Bad format %c in parse_option_param.",
- *fmt);
- skip_to_semi (cfile);
- return (struct expression *)0;
- }
-}
diff --git a/common/print.c b/common/print.c
index df5bcd38..4a2b4648 100644
--- a/common/print.c
+++ b/common/print.c
@@ -3,7 +3,7 @@
Turn data structures into printable text. */
/*
- * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: print.c,v 1.17 1998/03/16 06:14:21 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: print.c,v 1.16.2.2 1998/11/24 22:39:35 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -76,26 +76,26 @@ void print_lease (lease)
struct tm *t;
char tbuf [32];
- debug (" Lease %s",
+ debug (" Lease %s",
piaddr (lease -> ip_addr));
t = gmtime (&lease -> starts);
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
- debug (" start %s", tbuf);
+ debug (" start %s", tbuf);
t = gmtime (&lease -> ends);
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
- debug (" end %s", tbuf);
+ debug (" end %s", tbuf);
t = gmtime (&lease -> timestamp);
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
- debug (" stamp %s", tbuf);
+ debug (" stamp %s", tbuf);
- debug (" hardware addr = %s",
+ debug (" hardware addr = %s",
print_hw_addr (lease -> hardware_addr.htype,
lease -> hardware_addr.hlen,
lease -> hardware_addr.haddr));
- debug (" host %s ",
+ debug (" host %s ",
lease -> host ? lease -> host -> name : "<none>");
}
diff --git a/common/resolv.c b/common/resolv.c
deleted file mode 100644
index 30077ba7..00000000
--- a/common/resolv.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* resolv.c
-
- Parser for /etc/resolv.conf file. */
-
-/*
- * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises. To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''. To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: resolv.c,v 1.6 1998/01/12 01:01:44 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include "dhctoken.h"
-
-struct name_server *name_servers;
-struct domain_search_list *domains;
-char path_resolv_conf [] = _PATH_RESOLV_CONF;
-
-void read_resolv_conf (parse_time)
- TIME parse_time;
-{
- FILE *cfile;
- char *val;
- int token;
- int declaration = 0;
- struct name_server *sp, *sl, *ns;
- struct domain_search_list *dp, *dl, *nd;
- struct iaddr *iaddr;
-
- new_parse (path_resolv_conf);
-
- eol_token = 1;
- if ((cfile = fopen (path_resolv_conf, "r")) == NULL) {
- warn ("Can't open %s: %m", path_resolv_conf);
- return;
- }
-
- do {
- token = next_token (&val, cfile);
- if (token == EOF)
- break;
- else if (token == EOL)
- continue;
- else if (token == DOMAIN || token == SEARCH) {
- do {
- struct domain_search_list *nd, **dp;
- char *dn;
-
- dn = parse_host_name (cfile);
- if (!dn)
- break;
-
- dp = &domains;
- for (nd = domains; nd; nd = nd -> next) {
- dp = &nd -> next;
- if (!strcmp (nd -> domain, dn))
- break;
- }
- if (!nd) {
- nd = new_domain_search_list
- ("read_resolv_conf");
- if (!nd)
- error ("No memory for %s", dn);
- nd -> next =
- (struct domain_search_list *)0;
- *dp = nd;
- nd -> domain = dn;
- dn = (char *)0;
- }
- nd -> rcdate = parse_time;
- token = peek_token (&val, cfile);
- } while (token != EOL);
- if (token != EOL) {
- parse_warn ("junk after domain declaration");
- skip_to_semi (cfile);
- }
- token = next_token (&val, cfile);
- } else if (token == NAMESERVER) {
- struct name_server *ns, **sp;
- struct iaddr iaddr;
-
- parse_ip_addr (cfile, &iaddr);
-
- sp = &name_servers;
- for (ns = name_servers; ns; ns = ns -> next) {
- sp = &ns -> next;
- if (!memcmp (&ns -> addr.sin_addr,
- iaddr.iabuf, iaddr.len))
- break;
- }
- if (!ns) {
- ns = new_name_server ("read_resolv_conf");
- if (!ns)
- error ("No memory for nameserver %s",
- piaddr (iaddr));
- ns -> next = (struct name_server *)0;
- *sp = ns;
- memcpy (&ns -> addr.sin_addr,
- iaddr.iabuf, iaddr.len);
-#ifdef HAVE_SA_LEN
- ns -> addr.sin_len = sizeof ns -> addr;
-#endif
- ns -> addr.sin_family = AF_INET;
- ns -> addr.sin_port = htons (53);
- memset (ns -> addr.sin_zero, 0,
- sizeof ns -> addr.sin_zero);
- }
- ns -> rcdate = parse_time;
- skip_to_semi (cfile);
- } else
- skip_to_semi (cfile); /* Ignore what we don't grok. */
- } while (1);
- token = next_token (&val, cfile); /* Clear the peek buffer */
-
- /* Lose servers that are no longer in /etc/resolv.conf. */
- sl = (struct name_server *)0;
- for (sp = name_servers; sp; sp = ns) {
- ns = sp -> next;
- if (sp -> rcdate != parse_time) {
- if (sl)
- sl -> next = sp -> next;
- else
- name_servers = sp -> next;
- /* We can't actually free the name server structure,
- because somebody might be hanging on to it. If
- your /etc/resolv.conf file changes a lot, this
- could be a noticable memory leak. */
- } else
- sl = sp;
- }
-
- /* Lose domains that are no longer in /etc/resolv.conf. */
- dl = (struct domain_search_list *)0;
- for (dp = domains; dp; dp = nd) {
- nd = dp -> next;
- if (dp -> rcdate != parse_time) {
- if (dl)
- dl -> next = dp -> next;
- else
- domains = dp -> next;
- free_domain_search_list (dp, "pick_name_server");
- } else
- dl = dp;
- }
- eol_token = 0;
-}
-
-/* Pick a name server from the /etc/resolv.conf file. */
-
-struct name_server *first_name_server ()
-{
- FILE *rc;
- static TIME rcdate;
- struct stat st;
-
- /* Check /etc/resolv.conf and reload it if it's changed. */
- if (cur_time > rcdate) {
- if (stat (path_resolv_conf, &st) < 0) {
- warn ("Can't stat %s", path_resolv_conf);
- return (struct name_server *)0;
- }
- if (st.st_mtime > rcdate) {
- char rcbuf [512];
- char *s, *t, *u;
- rcdate = cur_time + 1;
-
- read_resolv_conf (rcdate);
- }
- }
-
- return name_servers;
-}
diff --git a/common/socket.c b/common/socket.c
index fbef4321..4cf5366a 100644
--- a/common/socket.c
+++ b/common/socket.c
@@ -50,7 +50,7 @@
#ifndef lint
static char copyright[] =
-"$Id: socket.c,v 1.27 1998/03/15 20:54:20 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: socket.c,v 1.26.2.4 1998/12/22 22:45:05 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -102,7 +102,7 @@ int if_register_socket (info)
int sock;
int flag;
-#ifndef SO_BINDTODEVICE
+#if !defined (SO_BINDTODEVICE) && !defined (USE_FALLBACK)
/* Make sure only one interface is registered. */
if (once)
error ("The standard socket API can only support %s",
@@ -136,9 +136,10 @@ int if_register_socket (info)
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
error ("Can't bind to dhcp address: %m");
-#ifdef SO_BINDTODEVICE
+#if defined (SO_BINDTODEVICE)
/* Bind this socket to this interface. */
- if (setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE,
+ if (info -> ifp &&
+ setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE,
(char *)(info -> ifp), sizeof *(info -> ifp)) < 0) {
error("setting SO_BINDTODEVICE");
}
@@ -224,7 +225,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
int retry = 0;
do {
#endif
- result = recvfrom (interface -> rfdesc, buf, len, 0,
+ result = recvfrom (interface -> rfdesc, (char *)buf, len, 0,
(struct sockaddr *)from, &flen);
#ifdef IGNORE_HOSTUNREACH
} while (result < 0 &&
@@ -236,7 +237,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
}
#endif /* USE_SOCKET_RECEIVE */
-#ifdef USE_SOCKET_FALLBACK
+#ifdef USE_SOCKET_SEND
/* This just reads in a packet and silently discards it. */
void fallback_discard (protocol)
@@ -253,4 +254,26 @@ void fallback_discard (protocol)
if (status < 0)
warn ("fallback_discard: %m");
}
-#endif /* USE_SOCKET_RECEIVE */
+#endif /* USE_SOCKET_SEND */
+
+#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
+int can_unicast_without_arp ()
+{
+ return 0;
+}
+
+/* If we have SO_BINDTODEVICE, set up a fallback interface; otherwise,
+ do not. */
+
+void maybe_setup_fallback ()
+{
+#if defined (SO_BINDTODEVICE)
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ fbi -> wfdesc = if_register_socket (fbi);
+ add_protocol ("fallback", fbi -> rfdesc, got_one, fbi);
+ }
+#endif
+}
+#endif /* USE_SOCKET_SEND && !USE_SOCKET_FALLBACK */
diff --git a/common/sysconf.c b/common/sysconf.c
deleted file mode 100644
index 09146cfa..00000000
--- a/common/sysconf.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* sysconf.c
-
- System status watcher...
-
- !!!Boy, howdy, is this ever not guaranteed not to change!!! */
-
-/*
- * Copyright (c) 1997, 1998 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises. To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''. To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: sysconf.c,v 1.4 1998/03/16 06:14:51 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-int sysconf_initialized;
-int sysconf_fd;
-
-void sysconf_startup (handler)
- void (*handler) PROTO ((struct sysconf_header *, void *));
-{
- struct sockaddr_un name;
- static int once;
- int len;
-
- /* Only initialize sysconf once. */
- if (sysconf_initialized)
- error ("attempted to reinitialize sysconf protocol");
- sysconf_initialized = 1;
-
- sysconf_fd = socket (AF_UNIX, SOCK_STREAM, 0);
- if (sysconf_fd < 0)
- error ("unable to create sysconf socket: %m");
-
- /* XXX for now... */
- name.sun_family = PF_UNIX;
- strcpy (name.sun_path, "/var/run/sysconf");
-#if defined (HAVE_SA_LEN)
- name.sun_len =
-#endif
- len = ((sizeof name) - (sizeof name.sun_path) +
- strlen (name.sun_path));
-
- if (connect (sysconf_fd, (struct sockaddr *)&name, len) < 0) {
- if (!once)
- warn ("can't connect to sysconf socket: %m");
- once = 1;
- close (sysconf_fd);
- sysconf_initialized = 0;
- add_timeout (cur_time + 60, sysconf_restart, (void *)handler);
- } else
- add_protocol ("sysconf", sysconf_fd, sysconf_message,
- (void *)handler);
-}
-
-void sysconf_restart (v)
- void *v;
-{
- void (*handler) PROTO ((struct sysconf_header *, void *)) =
- (void (*) PROTO ((struct sysconf_header *, void *)))v;
-
- sysconf_startup (handler);
-}
-
-void sysconf_message (proto)
- struct protocol *proto;
-{
- struct sysconf_header hdr;
- int status;
- char *buf;
- void (*handler) PROTO ((struct sysconf_header *, void *));
-
- status = read (sysconf_fd, &hdr, sizeof hdr);
- if (status < 0) {
- warn ("sysconf_message: %m");
- lose:
- add_timeout (cur_time + 60, sysconf_restart, proto -> local);
- remove_protocol (proto);
- return;
- }
- if (status < sizeof (hdr)) {
- warn ("sysconf_message: short message");
- goto lose;
- }
-
- if (hdr.length) {
- buf = malloc (hdr.length);
- if (!buf)
- error ("sysconf_message: can't buffer payload");
- status = read (sysconf_fd, buf, hdr.length);
- if (status < 0)
- error ("sysconf_message payload read: %m");
- if (status != hdr.length)
- error ("sysconf_message payload: short read");
- } else
- buf = (char *)0;
-
- /* Call the handler... */
- if ((handler = ((void (*) PROTO ((struct sysconf_header *, void *)))
- proto -> local)))
- (*handler) (&hdr, buf);
-
- if (buf)
- free (buf);
-}
diff --git a/common/tables.c b/common/tables.c
index c95714f1..abbff6f4 100644
--- a/common/tables.c
+++ b/common/tables.c
@@ -3,7 +3,7 @@
Tables of information... */
/*
- * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: tables.c,v 1.16 1998/06/25 03:09:09 mellon Exp $ Copyright (c) 1995, 1996, 1998 The Internet Software Consortium. All rights reserved.\n";
+"$Id: tables.c,v 1.13.2.3 1998/12/22 22:45:44 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -78,7 +78,7 @@ struct option dhcp_options [256] = {
{ "lpr-servers", "IA", &dhcp_universe, 9 },
{ "impress-servers", "IA", &dhcp_universe, 10 },
{ "resource-location-servers", "IA", &dhcp_universe, 11 },
- { "host-name", "t", &dhcp_universe, 12 },
+ { "host-name", "X", &dhcp_universe, 12 },
{ "boot-size", "S", &dhcp_universe, 13 },
{ "merit-dump", "t", &dhcp_universe, 14 },
{ "domain-name", "t", &dhcp_universe, 15 },
@@ -418,7 +418,7 @@ char *hardware_types [] = {
"unknown-5",
"token-ring",
"unknown-7",
- "unknown-8",
+ "fddi",
"unknown-9",
"unknown-10",
"unknown-11",
@@ -667,525 +667,6 @@ char *hardware_types [] = {
"unknown-254",
"unknown-255" };
-struct universe agent_universe;
-struct option agent_options [256] = {
- { "pad", "", &agent_universe, 0 },
- { "circuit-id", "X", &agent_universe, 1 },
- { "remote-id", "X", &agent_universe, 2 },
- { "agent-id", "I", &agent_universe, 3 },
- { "option-4", "X", &agent_universe, 4 },
- { "option-5", "X", &agent_universe, 5 },
- { "option-6", "X", &agent_universe, 6 },
- { "option-7", "X", &agent_universe, 7 },
- { "option-8", "X", &agent_universe, 8 },
- { "option-9", "X", &agent_universe, 9 },
- { "option-10", "X", &agent_universe, 10 },
- { "option-11", "X", &agent_universe, 11 },
- { "option-12", "X", &agent_universe, 12 },
- { "option-13", "X", &agent_universe, 13 },
- { "option-14", "X", &agent_universe, 14 },
- { "option-15", "X", &agent_universe, 15 },
- { "option-16", "X", &agent_universe, 16 },
- { "option-17", "X", &agent_universe, 17 },
- { "option-18", "X", &agent_universe, 18 },
- { "option-19", "X", &agent_universe, 19 },
- { "option-20", "X", &agent_universe, 20 },
- { "option-21", "X", &agent_universe, 21 },
- { "option-22", "X", &agent_universe, 22 },
- { "option-23", "X", &agent_universe, 23 },
- { "option-24", "X", &agent_universe, 24 },
- { "option-25", "X", &agent_universe, 25 },
- { "option-26", "X", &agent_universe, 26 },
- { "option-27", "X", &agent_universe, 27 },
- { "option-28", "X", &agent_universe, 28 },
- { "option-29", "X", &agent_universe, 29 },
- { "option-30", "X", &agent_universe, 30 },
- { "option-31", "X", &agent_universe, 31 },
- { "option-32", "X", &agent_universe, 32 },
- { "option-33", "X", &agent_universe, 33 },
- { "option-34", "X", &agent_universe, 34 },
- { "option-35", "X", &agent_universe, 35 },
- { "option-36", "X", &agent_universe, 36 },
- { "option-37", "X", &agent_universe, 37 },
- { "option-38", "X", &agent_universe, 38 },
- { "option-39", "X", &agent_universe, 39 },
- { "option-40", "X", &agent_universe, 40 },
- { "option-41", "X", &agent_universe, 41 },
- { "option-42", "X", &agent_universe, 42 },
- { "option-43", "X", &agent_universe, 43 },
- { "option-44", "X", &agent_universe, 44 },
- { "option-45", "X", &agent_universe, 45 },
- { "option-46", "X", &agent_universe, 46 },
- { "option-47", "X", &agent_universe, 47 },
- { "option-48", "X", &agent_universe, 48 },
- { "option-49", "X", &agent_universe, 49 },
- { "option-50", "X", &agent_universe, 50 },
- { "option-51", "X", &agent_universe, 51 },
- { "option-52", "X", &agent_universe, 52 },
- { "option-53", "X", &agent_universe, 53 },
- { "option-54", "X", &agent_universe, 54 },
- { "option-55", "X", &agent_universe, 55 },
- { "option-56", "X", &agent_universe, 56 },
- { "option-57", "X", &agent_universe, 57 },
- { "option-58", "X", &agent_universe, 58 },
- { "option-59", "X", &agent_universe, 59 },
- { "option-60", "X", &agent_universe, 60 },
- { "option-61", "X", &agent_universe, 61 },
- { "option-62", "X", &agent_universe, 62 },
- { "option-63", "X", &agent_universe, 63 },
- { "option-64", "X", &agent_universe, 64 },
- { "option-65", "X", &agent_universe, 65 },
- { "option-66", "X", &agent_universe, 66 },
- { "option-67", "X", &agent_universe, 67 },
- { "option-68", "X", &agent_universe, 68 },
- { "option-69", "X", &agent_universe, 69 },
- { "option-70", "X", &agent_universe, 70 },
- { "option-71", "X", &agent_universe, 71 },
- { "option-72", "X", &agent_universe, 72 },
- { "option-73", "X", &agent_universe, 73 },
- { "option-74", "X", &agent_universe, 74 },
- { "option-75", "X", &agent_universe, 75 },
- { "option-76", "X", &agent_universe, 76 },
- { "option-77", "X", &agent_universe, 77 },
- { "option-78", "X", &agent_universe, 78 },
- { "option-79", "X", &agent_universe, 79 },
- { "option-80", "X", &agent_universe, 80 },
- { "option-81", "X", &agent_universe, 81 },
- { "option-82", "X", &agent_universe, 82 },
- { "option-83", "X", &agent_universe, 83 },
- { "option-84", "X", &agent_universe, 84 },
- { "option-85", "X", &agent_universe, 85 },
- { "option-86", "X", &agent_universe, 86 },
- { "option-87", "X", &agent_universe, 87 },
- { "option-88", "X", &agent_universe, 88 },
- { "option-89", "X", &agent_universe, 89 },
- { "option-90", "X", &agent_universe, 90 },
- { "option-91", "X", &agent_universe, 91 },
- { "option-92", "X", &agent_universe, 92 },
- { "option-93", "X", &agent_universe, 93 },
- { "option-94", "X", &agent_universe, 94 },
- { "option-95", "X", &agent_universe, 95 },
- { "option-96", "X", &agent_universe, 96 },
- { "option-97", "X", &agent_universe, 97 },
- { "option-98", "X", &agent_universe, 98 },
- { "option-99", "X", &agent_universe, 99 },
- { "option-100", "X", &agent_universe, 100 },
- { "option-101", "X", &agent_universe, 101 },
- { "option-102", "X", &agent_universe, 102 },
- { "option-103", "X", &agent_universe, 103 },
- { "option-104", "X", &agent_universe, 104 },
- { "option-105", "X", &agent_universe, 105 },
- { "option-106", "X", &agent_universe, 106 },
- { "option-107", "X", &agent_universe, 107 },
- { "option-108", "X", &agent_universe, 108 },
- { "option-109", "X", &agent_universe, 109 },
- { "option-110", "X", &agent_universe, 110 },
- { "option-111", "X", &agent_universe, 111 },
- { "option-112", "X", &agent_universe, 112 },
- { "option-113", "X", &agent_universe, 113 },
- { "option-114", "X", &agent_universe, 114 },
- { "option-115", "X", &agent_universe, 115 },
- { "option-116", "X", &agent_universe, 116 },
- { "option-117", "X", &agent_universe, 117 },
- { "option-118", "X", &agent_universe, 118 },
- { "option-119", "X", &agent_universe, 119 },
- { "option-120", "X", &agent_universe, 120 },
- { "option-121", "X", &agent_universe, 121 },
- { "option-122", "X", &agent_universe, 122 },
- { "option-123", "X", &agent_universe, 123 },
- { "option-124", "X", &agent_universe, 124 },
- { "option-125", "X", &agent_universe, 125 },
- { "option-126", "X", &agent_universe, 126 },
- { "option-127", "X", &agent_universe, 127 },
- { "option-128", "X", &agent_universe, 128 },
- { "option-129", "X", &agent_universe, 129 },
- { "option-130", "X", &agent_universe, 130 },
- { "option-131", "X", &agent_universe, 131 },
- { "option-132", "X", &agent_universe, 132 },
- { "option-133", "X", &agent_universe, 133 },
- { "option-134", "X", &agent_universe, 134 },
- { "option-135", "X", &agent_universe, 135 },
- { "option-136", "X", &agent_universe, 136 },
- { "option-137", "X", &agent_universe, 137 },
- { "option-138", "X", &agent_universe, 138 },
- { "option-139", "X", &agent_universe, 139 },
- { "option-140", "X", &agent_universe, 140 },
- { "option-141", "X", &agent_universe, 141 },
- { "option-142", "X", &agent_universe, 142 },
- { "option-143", "X", &agent_universe, 143 },
- { "option-144", "X", &agent_universe, 144 },
- { "option-145", "X", &agent_universe, 145 },
- { "option-146", "X", &agent_universe, 146 },
- { "option-147", "X", &agent_universe, 147 },
- { "option-148", "X", &agent_universe, 148 },
- { "option-149", "X", &agent_universe, 149 },
- { "option-150", "X", &agent_universe, 150 },
- { "option-151", "X", &agent_universe, 151 },
- { "option-152", "X", &agent_universe, 152 },
- { "option-153", "X", &agent_universe, 153 },
- { "option-154", "X", &agent_universe, 154 },
- { "option-155", "X", &agent_universe, 155 },
- { "option-156", "X", &agent_universe, 156 },
- { "option-157", "X", &agent_universe, 157 },
- { "option-158", "X", &agent_universe, 158 },
- { "option-159", "X", &agent_universe, 159 },
- { "option-160", "X", &agent_universe, 160 },
- { "option-161", "X", &agent_universe, 161 },
- { "option-162", "X", &agent_universe, 162 },
- { "option-163", "X", &agent_universe, 163 },
- { "option-164", "X", &agent_universe, 164 },
- { "option-165", "X", &agent_universe, 165 },
- { "option-166", "X", &agent_universe, 166 },
- { "option-167", "X", &agent_universe, 167 },
- { "option-168", "X", &agent_universe, 168 },
- { "option-169", "X", &agent_universe, 169 },
- { "option-170", "X", &agent_universe, 170 },
- { "option-171", "X", &agent_universe, 171 },
- { "option-172", "X", &agent_universe, 172 },
- { "option-173", "X", &agent_universe, 173 },
- { "option-174", "X", &agent_universe, 174 },
- { "option-175", "X", &agent_universe, 175 },
- { "option-176", "X", &agent_universe, 176 },
- { "option-177", "X", &agent_universe, 177 },
- { "option-178", "X", &agent_universe, 178 },
- { "option-179", "X", &agent_universe, 179 },
- { "option-180", "X", &agent_universe, 180 },
- { "option-181", "X", &agent_universe, 181 },
- { "option-182", "X", &agent_universe, 182 },
- { "option-183", "X", &agent_universe, 183 },
- { "option-184", "X", &agent_universe, 184 },
- { "option-185", "X", &agent_universe, 185 },
- { "option-186", "X", &agent_universe, 186 },
- { "option-187", "X", &agent_universe, 187 },
- { "option-188", "X", &agent_universe, 188 },
- { "option-189", "X", &agent_universe, 189 },
- { "option-190", "X", &agent_universe, 190 },
- { "option-191", "X", &agent_universe, 191 },
- { "option-192", "X", &agent_universe, 192 },
- { "option-193", "X", &agent_universe, 193 },
- { "option-194", "X", &agent_universe, 194 },
- { "option-195", "X", &agent_universe, 195 },
- { "option-196", "X", &agent_universe, 196 },
- { "option-197", "X", &agent_universe, 197 },
- { "option-198", "X", &agent_universe, 198 },
- { "option-199", "X", &agent_universe, 199 },
- { "option-200", "X", &agent_universe, 200 },
- { "option-201", "X", &agent_universe, 201 },
- { "option-202", "X", &agent_universe, 202 },
- { "option-203", "X", &agent_universe, 203 },
- { "option-204", "X", &agent_universe, 204 },
- { "option-205", "X", &agent_universe, 205 },
- { "option-206", "X", &agent_universe, 206 },
- { "option-207", "X", &agent_universe, 207 },
- { "option-208", "X", &agent_universe, 208 },
- { "option-209", "X", &agent_universe, 209 },
- { "option-210", "X", &agent_universe, 210 },
- { "option-211", "X", &agent_universe, 211 },
- { "option-212", "X", &agent_universe, 212 },
- { "option-213", "X", &agent_universe, 213 },
- { "option-214", "X", &agent_universe, 214 },
- { "option-215", "X", &agent_universe, 215 },
- { "option-216", "X", &agent_universe, 216 },
- { "option-217", "X", &agent_universe, 217 },
- { "option-218", "X", &agent_universe, 218 },
- { "option-219", "X", &agent_universe, 219 },
- { "option-220", "X", &agent_universe, 220 },
- { "option-221", "X", &agent_universe, 221 },
- { "option-222", "X", &agent_universe, 222 },
- { "option-223", "X", &agent_universe, 223 },
- { "option-224", "X", &agent_universe, 224 },
- { "option-225", "X", &agent_universe, 225 },
- { "option-226", "X", &agent_universe, 226 },
- { "option-227", "X", &agent_universe, 227 },
- { "option-228", "X", &agent_universe, 228 },
- { "option-229", "X", &agent_universe, 229 },
- { "option-230", "X", &agent_universe, 230 },
- { "option-231", "X", &agent_universe, 231 },
- { "option-232", "X", &agent_universe, 232 },
- { "option-233", "X", &agent_universe, 233 },
- { "option-234", "X", &agent_universe, 234 },
- { "option-235", "X", &agent_universe, 235 },
- { "option-236", "X", &agent_universe, 236 },
- { "option-237", "X", &agent_universe, 237 },
- { "option-238", "X", &agent_universe, 238 },
- { "option-239", "X", &agent_universe, 239 },
- { "option-240", "X", &agent_universe, 240 },
- { "option-241", "X", &agent_universe, 241 },
- { "option-242", "X", &agent_universe, 242 },
- { "option-243", "X", &agent_universe, 243 },
- { "option-244", "X", &agent_universe, 244 },
- { "option-245", "X", &agent_universe, 245 },
- { "option-246", "X", &agent_universe, 246 },
- { "option-247", "X", &agent_universe, 247 },
- { "option-248", "X", &agent_universe, 248 },
- { "option-249", "X", &agent_universe, 249 },
- { "option-250", "X", &agent_universe, 250 },
- { "option-251", "X", &agent_universe, 251 },
- { "option-252", "X", &agent_universe, 252 },
- { "option-253", "X", &agent_universe, 253 },
- { "option-254", "X", &agent_universe, 254 },
- { "option-end", "e", &agent_universe, 255 },
-};
-
-struct universe server_universe;
-struct option server_options [256] = {
- { "pad", "", &server_universe, 0 },
- { "default-lease-time", "L", &server_universe, 1 },
- { "max-lease-time", "L", &server_universe, 2 },
- { "min-lease-time", "L", &server_universe, 3 },
- { "bootp-lease-cutoff", "L", &server_universe, 4 },
- { "bootp-lease-length", "L", &server_universe, 5 },
- { "boot-unknown-clients", "f", &server_universe, 6 },
- { "dynamic-bootp", "f", &server_universe, 7 },
- { "allow-bootp", "f", &server_universe, 8 },
- { "allow-booting", "f", &server_universe, 9 },
- { "one-lease-per-client", "f", &server_universe, 10 },
- { "get-lease-hostnames", "f", &server_universe, 11 },
- { "use-host-decl-names", "f", &server_universe, 12 },
- { "use-lease-addr-for-default-route", "f", &server_universe, 13 },
- { "min-secs", "B", &server_universe, 14 },
- { "filename", "t", &server_universe, 15 },
- { "server-name", "t", &server_universe, 16 },
- { "next-server", "I", &server_universe, 17 },
- { "option-18", "X", &server_universe, 18 },
- { "option-19", "X", &server_universe, 19 },
- { "option-20", "X", &server_universe, 20 },
- { "option-21", "X", &server_universe, 21 },
- { "option-22", "X", &server_universe, 22 },
- { "option-23", "X", &server_universe, 23 },
- { "option-24", "X", &server_universe, 24 },
- { "option-25", "X", &server_universe, 25 },
- { "option-26", "X", &server_universe, 26 },
- { "option-27", "X", &server_universe, 27 },
- { "option-28", "X", &server_universe, 28 },
- { "option-29", "X", &server_universe, 29 },
- { "option-30", "X", &server_universe, 30 },
- { "option-31", "X", &server_universe, 31 },
- { "option-32", "X", &server_universe, 32 },
- { "option-33", "X", &server_universe, 33 },
- { "option-34", "X", &server_universe, 34 },
- { "option-35", "X", &server_universe, 35 },
- { "option-36", "X", &server_universe, 36 },
- { "option-37", "X", &server_universe, 37 },
- { "option-38", "X", &server_universe, 38 },
- { "option-39", "X", &server_universe, 39 },
- { "option-40", "X", &server_universe, 40 },
- { "option-41", "X", &server_universe, 41 },
- { "option-42", "X", &server_universe, 42 },
- { "option-43", "X", &server_universe, 43 },
- { "option-44", "X", &server_universe, 44 },
- { "option-45", "X", &server_universe, 45 },
- { "option-46", "X", &server_universe, 46 },
- { "option-47", "X", &server_universe, 47 },
- { "option-48", "X", &server_universe, 48 },
- { "option-49", "X", &server_universe, 49 },
- { "option-50", "X", &server_universe, 50 },
- { "option-51", "X", &server_universe, 51 },
- { "option-52", "X", &server_universe, 52 },
- { "option-53", "X", &server_universe, 53 },
- { "option-54", "X", &server_universe, 54 },
- { "option-55", "X", &server_universe, 55 },
- { "option-56", "X", &server_universe, 56 },
- { "option-57", "X", &server_universe, 57 },
- { "option-58", "X", &server_universe, 58 },
- { "option-59", "X", &server_universe, 59 },
- { "option-60", "X", &server_universe, 60 },
- { "option-61", "X", &server_universe, 61 },
- { "option-62", "X", &server_universe, 62 },
- { "option-63", "X", &server_universe, 63 },
- { "option-64", "X", &server_universe, 64 },
- { "option-65", "X", &server_universe, 65 },
- { "option-66", "X", &server_universe, 66 },
- { "option-67", "X", &server_universe, 67 },
- { "option-68", "X", &server_universe, 68 },
- { "option-69", "X", &server_universe, 69 },
- { "option-70", "X", &server_universe, 70 },
- { "option-71", "X", &server_universe, 71 },
- { "option-72", "X", &server_universe, 72 },
- { "option-73", "X", &server_universe, 73 },
- { "option-74", "X", &server_universe, 74 },
- { "option-75", "X", &server_universe, 75 },
- { "option-76", "X", &server_universe, 76 },
- { "option-77", "X", &server_universe, 77 },
- { "option-78", "X", &server_universe, 78 },
- { "option-79", "X", &server_universe, 79 },
- { "option-80", "X", &server_universe, 80 },
- { "option-81", "X", &server_universe, 81 },
- { "option-82", "X", &server_universe, 82 },
- { "option-83", "X", &server_universe, 83 },
- { "option-84", "X", &server_universe, 84 },
- { "option-85", "X", &server_universe, 85 },
- { "option-86", "X", &server_universe, 86 },
- { "option-87", "X", &server_universe, 87 },
- { "option-88", "X", &server_universe, 88 },
- { "option-89", "X", &server_universe, 89 },
- { "option-90", "X", &server_universe, 90 },
- { "option-91", "X", &server_universe, 91 },
- { "option-92", "X", &server_universe, 92 },
- { "option-93", "X", &server_universe, 93 },
- { "option-94", "X", &server_universe, 94 },
- { "option-95", "X", &server_universe, 95 },
- { "option-96", "X", &server_universe, 96 },
- { "option-97", "X", &server_universe, 97 },
- { "option-98", "X", &server_universe, 98 },
- { "option-99", "X", &server_universe, 99 },
- { "option-100", "X", &server_universe, 100 },
- { "option-101", "X", &server_universe, 101 },
- { "option-102", "X", &server_universe, 102 },
- { "option-103", "X", &server_universe, 103 },
- { "option-104", "X", &server_universe, 104 },
- { "option-105", "X", &server_universe, 105 },
- { "option-106", "X", &server_universe, 106 },
- { "option-107", "X", &server_universe, 107 },
- { "option-108", "X", &server_universe, 108 },
- { "option-109", "X", &server_universe, 109 },
- { "option-110", "X", &server_universe, 110 },
- { "option-111", "X", &server_universe, 111 },
- { "option-112", "X", &server_universe, 112 },
- { "option-113", "X", &server_universe, 113 },
- { "option-114", "X", &server_universe, 114 },
- { "option-115", "X", &server_universe, 115 },
- { "option-116", "X", &server_universe, 116 },
- { "option-117", "X", &server_universe, 117 },
- { "option-118", "X", &server_universe, 118 },
- { "option-119", "X", &server_universe, 119 },
- { "option-120", "X", &server_universe, 120 },
- { "option-121", "X", &server_universe, 121 },
- { "option-122", "X", &server_universe, 122 },
- { "option-123", "X", &server_universe, 123 },
- { "option-124", "X", &server_universe, 124 },
- { "option-125", "X", &server_universe, 125 },
- { "option-126", "X", &server_universe, 126 },
- { "option-127", "X", &server_universe, 127 },
- { "option-128", "X", &server_universe, 128 },
- { "option-129", "X", &server_universe, 129 },
- { "option-130", "X", &server_universe, 130 },
- { "option-131", "X", &server_universe, 131 },
- { "option-132", "X", &server_universe, 132 },
- { "option-133", "X", &server_universe, 133 },
- { "option-134", "X", &server_universe, 134 },
- { "option-135", "X", &server_universe, 135 },
- { "option-136", "X", &server_universe, 136 },
- { "option-137", "X", &server_universe, 137 },
- { "option-138", "X", &server_universe, 138 },
- { "option-139", "X", &server_universe, 139 },
- { "option-140", "X", &server_universe, 140 },
- { "option-141", "X", &server_universe, 141 },
- { "option-142", "X", &server_universe, 142 },
- { "option-143", "X", &server_universe, 143 },
- { "option-144", "X", &server_universe, 144 },
- { "option-145", "X", &server_universe, 145 },
- { "option-146", "X", &server_universe, 146 },
- { "option-147", "X", &server_universe, 147 },
- { "option-148", "X", &server_universe, 148 },
- { "option-149", "X", &server_universe, 149 },
- { "option-150", "X", &server_universe, 150 },
- { "option-151", "X", &server_universe, 151 },
- { "option-152", "X", &server_universe, 152 },
- { "option-153", "X", &server_universe, 153 },
- { "option-154", "X", &server_universe, 154 },
- { "option-155", "X", &server_universe, 155 },
- { "option-156", "X", &server_universe, 156 },
- { "option-157", "X", &server_universe, 157 },
- { "option-158", "X", &server_universe, 158 },
- { "option-159", "X", &server_universe, 159 },
- { "option-160", "X", &server_universe, 160 },
- { "option-161", "X", &server_universe, 161 },
- { "option-162", "X", &server_universe, 162 },
- { "option-163", "X", &server_universe, 163 },
- { "option-164", "X", &server_universe, 164 },
- { "option-165", "X", &server_universe, 165 },
- { "option-166", "X", &server_universe, 166 },
- { "option-167", "X", &server_universe, 167 },
- { "option-168", "X", &server_universe, 168 },
- { "option-169", "X", &server_universe, 169 },
- { "option-170", "X", &server_universe, 170 },
- { "option-171", "X", &server_universe, 171 },
- { "option-172", "X", &server_universe, 172 },
- { "option-173", "X", &server_universe, 173 },
- { "option-174", "X", &server_universe, 174 },
- { "option-175", "X", &server_universe, 175 },
- { "option-176", "X", &server_universe, 176 },
- { "option-177", "X", &server_universe, 177 },
- { "option-178", "X", &server_universe, 178 },
- { "option-179", "X", &server_universe, 179 },
- { "option-180", "X", &server_universe, 180 },
- { "option-181", "X", &server_universe, 181 },
- { "option-182", "X", &server_universe, 182 },
- { "option-183", "X", &server_universe, 183 },
- { "option-184", "X", &server_universe, 184 },
- { "option-185", "X", &server_universe, 185 },
- { "option-186", "X", &server_universe, 186 },
- { "option-187", "X", &server_universe, 187 },
- { "option-188", "X", &server_universe, 188 },
- { "option-189", "X", &server_universe, 189 },
- { "option-190", "X", &server_universe, 190 },
- { "option-191", "X", &server_universe, 191 },
- { "option-192", "X", &server_universe, 192 },
- { "option-193", "X", &server_universe, 193 },
- { "option-194", "X", &server_universe, 194 },
- { "option-195", "X", &server_universe, 195 },
- { "option-196", "X", &server_universe, 196 },
- { "option-197", "X", &server_universe, 197 },
- { "option-198", "X", &server_universe, 198 },
- { "option-199", "X", &server_universe, 199 },
- { "option-200", "X", &server_universe, 200 },
- { "option-201", "X", &server_universe, 201 },
- { "option-202", "X", &server_universe, 202 },
- { "option-203", "X", &server_universe, 203 },
- { "option-204", "X", &server_universe, 204 },
- { "option-205", "X", &server_universe, 205 },
- { "option-206", "X", &server_universe, 206 },
- { "option-207", "X", &server_universe, 207 },
- { "option-208", "X", &server_universe, 208 },
- { "option-209", "X", &server_universe, 209 },
- { "option-210", "X", &server_universe, 210 },
- { "option-211", "X", &server_universe, 211 },
- { "option-212", "X", &server_universe, 212 },
- { "option-213", "X", &server_universe, 213 },
- { "option-214", "X", &server_universe, 214 },
- { "option-215", "X", &server_universe, 215 },
- { "option-216", "X", &server_universe, 216 },
- { "option-217", "X", &server_universe, 217 },
- { "option-218", "X", &server_universe, 218 },
- { "option-219", "X", &server_universe, 219 },
- { "option-220", "X", &server_universe, 220 },
- { "option-221", "X", &server_universe, 221 },
- { "option-222", "X", &server_universe, 222 },
- { "option-223", "X", &server_universe, 223 },
- { "option-224", "X", &server_universe, 224 },
- { "option-225", "X", &server_universe, 225 },
- { "option-226", "X", &server_universe, 226 },
- { "option-227", "X", &server_universe, 227 },
- { "option-228", "X", &server_universe, 228 },
- { "option-229", "X", &server_universe, 229 },
- { "option-230", "X", &server_universe, 230 },
- { "option-231", "X", &server_universe, 231 },
- { "option-232", "X", &server_universe, 232 },
- { "option-233", "X", &server_universe, 233 },
- { "option-234", "X", &server_universe, 234 },
- { "option-235", "X", &server_universe, 235 },
- { "option-236", "X", &server_universe, 236 },
- { "option-237", "X", &server_universe, 237 },
- { "option-238", "X", &server_universe, 238 },
- { "option-239", "X", &server_universe, 239 },
- { "option-240", "X", &server_universe, 240 },
- { "option-241", "X", &server_universe, 241 },
- { "option-242", "X", &server_universe, 242 },
- { "option-243", "X", &server_universe, 243 },
- { "option-244", "X", &server_universe, 244 },
- { "option-245", "X", &server_universe, 245 },
- { "option-246", "X", &server_universe, 246 },
- { "option-247", "X", &server_universe, 247 },
- { "option-248", "X", &server_universe, 248 },
- { "option-249", "X", &server_universe, 249 },
- { "option-250", "X", &server_universe, 250 },
- { "option-251", "X", &server_universe, 251 },
- { "option-252", "X", &server_universe, 252 },
- { "option-253", "X", &server_universe, 253 },
- { "option-254", "X", &server_universe, 254 },
- { "option-end", "e", &server_universe, 255 },
-};
struct hash_table universe_hash;
@@ -1194,10 +675,7 @@ void initialize_universes()
{
int i;
- /* Set up the DHCP option universe... */
dhcp_universe.name = "dhcp";
- dhcp_universe.lookup_func = dhcp_option_lookup;
- dhcp_universe.set_func = dhcp_option_set;
dhcp_universe.hash = new_hash ();
if (!dhcp_universe.hash)
error ("Can't allocate dhcp option hash table.");
@@ -1207,40 +685,8 @@ void initialize_universes()
(unsigned char *)dhcp_options [i].name, 0,
(unsigned char *)&dhcp_options [i]);
}
-
- /* Set up the Relay Agent Information Option suboption universe... */
- agent_universe.name = "agent";
- agent_universe.lookup_func = agent_suboption_lookup;
- agent_universe.hash = new_hash ();
- if (!agent_universe.hash)
- error ("Can't allocate agent option hash table.");
- for (i = 0; i < 256; i++) {
- agent_universe.options [i] = &agent_options [i];
- add_hash (agent_universe.hash,
- (unsigned char *)agent_options [i].name, 0,
- (unsigned char *)&agent_options [i]);
- }
-
- /* Set up the server option universe... */
- server_universe.name = "server";
- server_universe.lookup_func = server_option_lookup;
- server_universe.set_func = server_option_set;
- server_universe.hash = new_hash ();
- if (!server_universe.hash)
- error ("Can't allocate server option hash table.");
- for (i = 0; i < 256; i++) {
- server_universe.options [i] = &server_options [i];
- add_hash (server_universe.hash,
- (unsigned char *)server_options [i].name, 0,
- (unsigned char *)&server_options [i]);
- }
-
- /* Set up the hash of universes. */
- universe_hash.hash_count = DEFAULT_HASH_SIZE;
- add_hash (&universe_hash, (unsigned char *)dhcp_universe.name, 0,
+ universe_hash.hash_count = DEFAULT_HASH_SIZE;
+ add_hash (&universe_hash,
+ (unsigned char *)dhcp_universe.name, 0,
(unsigned char *)&dhcp_universe);
- add_hash (&universe_hash, (unsigned char *)agent_universe.name, 0,
- (unsigned char *)&agent_universe);
- add_hash (&universe_hash, (unsigned char *)server_universe.name, 0,
- (unsigned char *)&server_universe);
}
diff --git a/common/tree.c b/common/tree.c
index 6f1f0383..ac83d670 100644
--- a/common/tree.c
+++ b/common/tree.c
@@ -3,7 +3,7 @@
Routines for manipulating parse trees... */
/*
- * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,12 +42,17 @@
#ifndef lint
static char copyright[] =
-"$Id: tree.c,v 1.12 1998/06/25 03:10:32 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
+"$Id: tree.c,v 1.10 1997/05/09 08:14:57 mellon Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
-static struct data_string do_host_lookup PROTO ((struct dns_host_entry *));
+static TIME tree_evaluate_recurse PROTO ((int *, unsigned char **, int *,
+ struct tree *));
+static TIME do_host_lookup PROTO ((int *, unsigned char **, int *,
+ struct dns_host_entry *));
+static void do_data_copy PROTO ((int *, unsigned char **, int *,
+ unsigned char *, int));
pair cons (car, cdr)
caddr_t car;
@@ -61,15 +66,30 @@ pair cons (car, cdr)
return foo;
}
-struct expression *make_host_lookup (name)
+struct tree_cache *tree_cache (tree)
+ struct tree *tree;
+{
+ struct tree_cache *tc;
+
+ tc = new_tree_cache ("tree_cache");
+ if (!tc)
+ return 0;
+ tc -> value = (unsigned char *)0;
+ tc -> len = tc -> buf_size = 0;
+ tc -> timeout = 0;
+ tc -> tree = tree;
+ return tc;
+}
+
+struct tree *tree_host_lookup (name)
char *name;
{
- struct expression *nt;
- nt = new_expression ("make_host_lookup");
+ struct tree *nt;
+ nt = new_tree ("tree_host_lookup");
if (!nt)
error ("No memory for host lookup tree node.");
- nt -> op = expr_host_lookup;
- nt -> data.host_lookup = enter_dns_host (name);
+ nt -> op = TREE_HOST_LOOKUP;
+ nt -> data.host_lookup.host = enter_dns_host (name);
return nt;
}
@@ -79,50 +99,37 @@ struct dns_host_entry *enter_dns_host (name)
struct dns_host_entry *dh;
if (!(dh = (struct dns_host_entry *)dmalloc
- (sizeof (struct dns_host_entry), "enter_dns_host")))
+ (sizeof (struct dns_host_entry), "enter_dns_host"))
+ || !(dh -> hostname = dmalloc (strlen (name) + 1,
+ "enter_dns_host")))
error ("Can't allocate space for new host.");
- memset (dh, 0, sizeof *dh);
-
- dh -> hostname = dmalloc (strlen (name) + 1, "enter_dns_host");
strcpy (dh -> hostname, name);
+ dh -> data = (unsigned char *)0;
+ dh -> data_len = 0;
+ dh -> buf_len = 0;
+ dh -> timeout = 0;
return dh;
}
-struct expression *make_const_data (data, len, terminated, allocate)
+struct tree *tree_const (data, len)
unsigned char *data;
int len;
- int terminated;
- int allocate;
{
- struct expression *nt;
- if (!(nt = new_expression ("tree_const")))
+ struct tree *nt;
+ if (!(nt = new_tree ("tree_const"))
+ || !(nt -> data.const_val.data =
+ (unsigned char *)dmalloc (len, "tree_const")))
error ("No memory for constant data tree node.");
- memset (nt, 0, sizeof *nt);
- if (len) {
- if (allocate) {
- if (!(nt -> data.const_data.data =
- (unsigned char *)dmalloc (len + terminated,
- "tree_const")))
- error ("No memory for const_data node.");
- memcpy (nt -> data.const_data.data,
- data, len + terminated);
- nt -> data.const_data.buffer =
- nt -> data.const_data.data;
- } else
- nt -> data.const_data.data = data;
- nt -> data.const_data.terminated = terminated;
- } else
- nt -> data.const_data.data = 0;
-
- nt -> op = expr_const_data;
- nt -> data.const_data.len = len;
+ nt -> op = TREE_CONST;
+ memcpy (nt -> data.const_val.data, data, len);
+ nt -> data.const_val.len = len;
return nt;
}
-struct expression *make_concat (left, right)
- struct expression *left, *right;
+struct tree *tree_concat (left, right)
+ struct tree *left, *right;
{
- struct expression *nt;
+ struct tree *nt;
/* If we're concatenating a null tree to a non-null tree, just
return the non-null tree; if both trees are null, return
@@ -132,149 +139,157 @@ struct expression *make_concat (left, right)
if (!right)
return left;
- /* If both expressions are constant, combine them. */
- if (left -> op == expr_const_data &&
- right -> op == expr_const_data) {
- unsigned char *buf =
- dmalloc (left -> data.const_data.len
- + right -> data.const_data.len
- + right -> data.const_data.terminated,
- "tree_concat");
+ /* If both trees are constant, combine them. */
+ if (left -> op == TREE_CONST && right -> op == TREE_CONST) {
+ unsigned char *buf = dmalloc (left -> data.const_val.len
+ + right -> data.const_val.len,
+ "tree_concat");
if (!buf)
error ("No memory to concatenate constants.");
- memcpy (buf, left -> data.const_data.data,
- left -> data.const_data.len);
- memcpy (buf + left -> data.const_data.len,
- right -> data.const_data.data,
- right -> data.const_data.len);
- if (left -> data.const_data.buffer)
- dfree (left -> data.const_data.buffer, "make_concat");
- if (right -> data.const_data.buffer)
- dfree (right -> data.const_data.buffer, "make_concat");
- left -> data.const_data.data = buf;
- left -> data.const_data.buffer = buf;
- left -> data.const_data.len += right -> data.const_data.len;
- free_expression (right, "make_concat");
+ memcpy (buf, left -> data.const_val.data,
+ left -> data.const_val.len);
+ memcpy (buf + left -> data.const_val.len,
+ right -> data.const_val.data,
+ right -> data.const_val.len);
+ dfree (left -> data.const_val.data, "tree_concat");
+ dfree (right -> data.const_val.data, "tree_concat");
+ left -> data.const_val.data = buf;
+ left -> data.const_val.len += right -> data.const_val.len;
+ free_tree (right, "tree_concat");
return left;
}
/* Otherwise, allocate a new node to concatenate the two. */
- if (!(nt = new_expression ("make_concat")))
- error ("No memory for concatenation expression node.");
- nt -> op = expr_concat;
- nt -> data.concat [0] = left;
- nt -> data.concat [1] = right;
+ if (!(nt = new_tree ("tree_concat")))
+ error ("No memory for data tree concatenation node.");
+ nt -> op = TREE_CONCAT;
+ nt -> data.concat.left = left;
+ nt -> data.concat.right = right;
return nt;
}
-struct expression *make_substring (expr, offset, length)
- struct expression *expr;
- struct expression *offset;
- struct expression *length;
+struct tree *tree_limit (tree, limit)
+ struct tree *tree;
+ int limit;
{
- struct expression *rv;
-
- /* If the expression we're limiting is constant, limit it now. */
- if (expr -> op == expr_const_data &&
- offset -> op == expr_const_int &&
- length -> op == expr_const_int) {
- int off = offset -> data.const_int;
- int len = length -> data.const_int;
- if (expr -> data.const_data.len > off) {
- expr -> data.const_data.data += off;
- expr -> data.const_data.len -= off;
- if (expr -> data.const_data.len > len) {
- expr -> data.const_data.len = len;
- expr -> data.const_data.terminated = 0;
- }
- } else {
- expr -> data.const_data.len = 0;
- expr -> data.const_data.terminated = 0;
- }
+ struct tree *rv;
- free_expression (offset, "make_substring");
- free_expression (length, "make_substring");
- return expr;
+ /* If the tree we're limiting is constant, limit it now. */
+ if (tree -> op == TREE_CONST) {
+ if (tree -> data.const_val.len > limit)
+ tree -> data.const_val.len = limit;
+ return tree;
}
/* Otherwise, put in a node which enforces the limit on evaluation. */
- rv = new_expression ("make_substring");
+ rv = new_tree ("tree_limit");
if (!rv)
- error ("no memory for substring expression.");
- memset (rv, 0, sizeof *rv);
- rv -> op = expr_substring;
- rv -> data.substring.expr = expr;
- rv -> data.substring.offset = offset;
- rv -> data.substring.len = length;
+ return (struct tree *)0;
+ rv -> op = TREE_LIMIT;
+ rv -> data.limit.tree = tree;
+ rv -> data.limit.limit = limit;
return rv;
}
-struct expression *make_limit (expr, limit)
- struct expression *expr;
- int limit;
+int tree_evaluate (tree_cache)
+ struct tree_cache *tree_cache;
{
- struct expression *rv;
-
- /* If the expression we're limiting is constant, limit it now. */
- if (expr -> op == expr_const_data) {
- if (expr -> data.const_data.len > limit) {
- expr -> data.const_data.len = limit;
- expr -> data.const_data.terminated = 0;
- }
- return expr;
+ unsigned char *bp = tree_cache -> value;
+ int bc = tree_cache -> buf_size;
+ int bufix = 0;
+
+ /* If there's no tree associated with this cache, it evaluates
+ to a constant and that was detected at startup. */
+ if (!tree_cache -> tree)
+ return 1;
+
+ /* Try to evaluate the tree without allocating more memory... */
+ tree_cache -> timeout = tree_evaluate_recurse (&bufix, &bp, &bc,
+ tree_cache -> tree);
+
+ /* No additional allocation needed? */
+ if (bufix <= bc) {
+ tree_cache -> len = bufix;
+ return 1;
}
- /* Otherwise, put in a node which enforces the limit on evaluation. */
- rv = new_expression ("make_limit 1");
- if (!rv)
- error ("no memory for limit expression");
- memset (rv, 0, sizeof *rv);
- rv -> op = expr_substring;
- rv -> data.substring.expr = expr;
-
- /* Offset is a constant 0. */
- rv -> data.substring.offset = new_expression ("make_limit 2");
- if (!rv -> data.substring.offset)
- error ("no memory for limit offset expression");
- memset (rv -> data.substring.offset, 0, sizeof *rv);
- rv -> data.substring.offset -> op = expr_const_int;
- rv -> data.substring.offset -> data.const_int = 0;
-
- /* Length is a constant: the specified limit. */
- rv -> data.substring.len = new_expression ("make_limit 2");
- if (!rv -> data.substring.len)
- error ("no memory for limit length expression");
- memset (rv -> data.substring.len, 0, sizeof *rv);
- rv -> data.substring.offset -> op = expr_const_int;
- rv -> data.substring.offset -> data.const_int = limit;
+ /* If we can't allocate more memory, return with what we
+ have (maybe nothing). */
+ if (!(bp = (unsigned char *)dmalloc (bufix, "tree_evaluate")))
+ return 0;
- return rv;
+ /* Record the change in conditions... */
+ bc = bufix;
+ bufix = 0;
+
+ /* Note that the size of the result shouldn't change on the
+ second call to tree_evaluate_recurse, since we haven't
+ changed the ``current'' time. */
+ tree_evaluate_recurse (&bufix, &bp, &bc, tree_cache -> tree);
+
+ /* Free the old buffer if needed, then store the new buffer
+ location and size and return. */
+ if (tree_cache -> value)
+ dfree (tree_cache -> value, "tree_evaluate");
+ tree_cache -> value = bp;
+ tree_cache -> len = bufix;
+ tree_cache -> buf_size = bc;
+ return 1;
}
-struct option_cache *option_cache (expr, option)
- struct expression *expr;
- struct option *option;
+static TIME tree_evaluate_recurse (bufix, bufp, bufcount, tree)
+ int *bufix;
+ unsigned char **bufp;
+ int *bufcount;
+ struct tree *tree;
{
- struct option_cache *oc = new_option_cache ("option_cache");
- if (!oc) {
- warn ("no memory for option cache.");
- return (struct option_cache *)0;
+ int limit;
+ TIME t1, t2;
+
+ switch (tree -> op) {
+ case TREE_CONCAT:
+ t1 = tree_evaluate_recurse (bufix, bufp, bufcount,
+ tree -> data.concat.left);
+ t2 = tree_evaluate_recurse (bufix, bufp, bufcount,
+ tree -> data.concat.right);
+ if (t1 > t2)
+ return t2;
+ return t1;
+
+ case TREE_HOST_LOOKUP:
+ return do_host_lookup (bufix, bufp, bufcount,
+ tree -> data.host_lookup.host);
+
+ case TREE_CONST:
+ do_data_copy (bufix, bufp, bufcount,
+ tree -> data.const_val.data,
+ tree -> data.const_val.len);
+ t1 = MAX_TIME;
+ return t1;
+
+ case TREE_LIMIT:
+ limit = *bufix + tree -> data.limit.limit;
+ t1 = tree_evaluate_recurse (bufix, bufp, bufcount,
+ tree -> data.limit.tree);
+ *bufix = limit;
+ return t1;
+
+ default:
+ warn ("Bad node id in tree: %d.");
+ t1 = MAX_TIME;
+ return t1;
}
- memset (oc, 0, sizeof *oc);
- oc -> expression = expr;
- oc -> option = option;
- return oc;
}
-static struct data_string do_host_lookup (dns)
+static TIME do_host_lookup (bufix, bufp, bufcount, dns)
+ int *bufix;
+ unsigned char **bufp;
+ int *bufcount;
struct dns_host_entry *dns;
{
struct hostent *h;
int i;
int new_len;
- struct data_string result;
-
- memset (&result, 0, sizeof result);
#ifdef DEBUG_EVAL
debug ("time: now = %d dns = %d %d diff = %d",
@@ -284,15 +299,13 @@ static struct data_string do_host_lookup (dns)
/* If the record hasn't timed out, just copy the data and return. */
if (cur_time <= dns -> timeout) {
#ifdef DEBUG_EVAL
- debug ("easy copy: %x %d %s",
- dns -> data, dns -> data.len,
- dns -> data.data
- ? inet_ntoa (*(struct in_addr *)(dns -> data.data))
- : 0);
+ debug ("easy copy: %x %d %x",
+ dns -> data, dns -> data_len,
+ dns -> data ? *(int *)(dns -> data) : 0);
#endif
- result.data = dns -> buffer;
- result.len = dns -> data_len;
- return result;
+ do_data_copy (bufix, bufp, bufcount,
+ dns -> data, dns -> data_len);
+ return dns -> timeout;
}
#ifdef DEBUG_EVAL
debug ("Looking up %s", dns -> hostname);
@@ -322,13 +335,12 @@ static struct data_string do_host_lookup (dns)
#endif /* !NO_H_ERRNO */
/* Okay to try again after a minute. */
- dns -> timeout = cur_time + 60;
- return result;
+ return cur_time + 60;
}
#ifdef DEBUG_EVAL
- debug ("Lookup succeeded; first address is %s",
- inet_ntoa (h -> h_addr_list [0]));
+ debug ("Lookup succeeded; first address is %x",
+ h -> h_addr_list [0]);
#endif
/* Count the number of addresses we got... */
@@ -345,12 +357,12 @@ static struct data_string do_host_lookup (dns)
new_len = dns -> buf_len;
if (!dns -> buf_len) {
dns -> timeout = cur_time + 60;
- return result;
+ return dns -> timeout;
}
} else {
- if (dns -> buffer)
- dfree (dns -> buffer, "do_host_lookup");
- dns -> buffer = buf;
+ if (dns -> data)
+ dfree (dns -> data, "do_host_lookup");
+ dns -> data = buf;
dns -> buf_len = new_len;
}
}
@@ -358,12 +370,12 @@ static struct data_string do_host_lookup (dns)
/* Addresses are conveniently stored one to the buffer, so we
have to copy them out one at a time... :'( */
for (i = 0; i < new_len / h -> h_length; i++) {
- memcpy (dns -> buffer + h -> h_length * i,
+ memcpy (dns -> data + h -> h_length * i,
h -> h_addr_list [i], h -> h_length);
}
#ifdef DEBUG_EVAL
debug ("dns -> data: %x h -> h_addr_list [0]: %x",
- *(int *)(dns -> buffer), h -> h_addr_list [0]);
+ *(int *)(dns -> data), h -> h_addr_list [0]);
#endif
dns -> data_len = new_len;
@@ -375,386 +387,26 @@ static struct data_string do_host_lookup (dns)
debug ("hard copy: %x %d %x",
dns -> data, dns -> data_len, *(int *)(dns -> data));
#endif
- result.data = dns -> buffer;
- result.len = dns -> data_len;
- return result;
+ do_data_copy (bufix, bufp, bufcount, dns -> data, dns -> data_len);
+ return dns -> timeout;
}
-int evaluate_boolean_expression (packet, expr)
- struct packet *packet;
- struct expression *expr;
-{
- struct data_string left, right;
- int result;
-
- switch (expr -> op) {
- case expr_check:
- return check_collection (packet, expr -> data.check);
-
- case expr_equal:
- left = evaluate_data_expression (packet,
- expr -> data.equal [0]);
- right = evaluate_data_expression (packet,
- expr -> data.equal [1]);
- if (left.len == right.len && !memcmp (left.data,
- right.data, left.len))
- result = 1;
- else
- result = 0;
- if (left.buffer)
- dfree ("evaluate_boolean_expression", left.buffer);
- if (right.buffer)
- dfree ("evaluate_boolean_expression", right.buffer);
- return result;
-
- case expr_and:
- return (evaluate_boolean_expression (packet,
- expr -> data.and [0]) &&
- evaluate_boolean_expression (packet,
- expr -> data.and [1]));
-
- case expr_or:
- return (evaluate_boolean_expression (packet,
- expr -> data.or [0]) ||
- evaluate_boolean_expression (packet,
- expr -> data.or [1]));
-
- case expr_not:
- return (!evaluate_boolean_expression (packet,
- expr -> data.not));
-
- case expr_substring:
- case expr_suffix:
- case expr_option:
- case expr_hardware:
- case expr_const_data:
- case expr_packet:
- case expr_concat:
- case expr_host_lookup:
- warn ("Data opcode in evaluate_boolean_expression: %d",
- expr -> op);
- return 0;
-
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- case expr_const_int:
- warn ("Numeric opcode in evaluate_boolean_expression: %d",
- expr -> op);
- return 0;
- }
-
- warn ("Bogus opcode in evaluate_boolean_expression: %d", expr -> op);
- return 0;
-}
-
-struct data_string evaluate_data_expression (packet, expr)
- struct packet *packet;
- struct expression *expr;
-{
- struct data_string result, data, other;
- int offset, len;
-
- switch (expr -> op) {
- /* Extract N bytes starting at byte M of a data string. */
- case expr_substring:
- data = evaluate_data_expression (packet,
- expr -> data.substring.expr);
-
- /* Evaluate the offset and length. */
- offset = evaluate_numeric_expression
- (packet, expr -> data.substring.offset);
- len = evaluate_numeric_expression
- (packet, expr -> data.substring.len);
-
- /* If the offset is after end of the string, return
- an empty string. */
- if (data.len <= offset) {
- if (data.buffer)
- dfree ("expr_substring", data.buffer);
- memset (&result, 0, sizeof result);
- return result;
- }
-
- /* Otherwise, do the adjustments and return what's left. */
- data.len -= offset;
- if (data.len > len) {
- data.len = len;
- data.terminated = 0;
- }
- data.data += offset;
- return data;
-
- /* Extract the last N bytes of a data string. */
- case expr_suffix:
- data = evaluate_data_expression (packet,
- expr -> data.suffix.expr);
-
- /* Evaluate the length. */
- len = evaluate_numeric_expression
- (packet, expr -> data.substring.len);
-
- /* If we are returning the last N bytes of a string whose
- length is <= N, just return the string. */
- if (data.len <= len)
- return data;
- data.data += data.len - len;
- data.len = len;
- return data;
-
- /* Extract an option. */
- case expr_option:
- return ((*expr -> data.option -> universe -> lookup_func)
- (packet, expr -> data.option -> code));
-
- /* Combine the hardware type and address. */
- case expr_hardware:
- result.len = packet -> raw -> hlen + 1;
- result.buffer = dmalloc (result.len,
- "expr_hardware");
- if (!result.buffer) {
- warn ("no memory for expr_hardware");
- result.len = 0;
- } else {
- result.buffer [0] = packet -> raw -> htype;
- memcpy (&result.buffer [1], packet -> raw -> chaddr,
- packet -> raw -> hlen);
- }
- result.data = result.buffer;
- result.terminated = 0;
- return result;
-
- /* Extract part of the raw packet. */
- case expr_packet:
- len = evaluate_numeric_expression (packet,
- expr -> data.packet.len);
- offset = evaluate_numeric_expression (packet,
- expr -> data.packet.len);
- if (offset > packet -> packet_length) {
- warn ("expr_packet on %s: length %d + offset %d > %d",
- print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr),
- len, offset, packet -> packet_length);
- memset (&result, 0, sizeof result);
- return result;
- }
- if (offset + len > packet -> packet_length)
- result.len = packet -> packet_length - offset;
- else
- result.len = len;
- result.data = ((unsigned char *)(packet -> raw)) + offset;
- result.buffer = (unsigned char *)0;
- result.terminated = 0;
- return result;
-
- /* Some constant data... */
- case expr_const_data:
- return expr -> data.const_data;
-
- /* Hostname lookup... */
- case expr_host_lookup:
- return do_host_lookup (expr -> data.host_lookup);
- break;
-
- /* Concatenation... */
- case expr_concat:
- data = evaluate_data_expression (packet,
- expr -> data.concat [0]);
- other = evaluate_data_expression (packet,
- expr -> data.concat [1]);
-
- memset (&result, 0, sizeof result);
- result.buffer = dmalloc (data.len + other.len +
- other.terminated, "expr_concat");
- if (!result.buffer) {
- warn ("out of memory doing concatenation.");
- return result;
- }
-
- result.len = (data.len + other.len);
- result.data = result.buffer;
- memcpy (result.data, data.data, data.len);
- memcpy (&result.data [data.len], other.data,
- other.len + other.terminated);
- if (data.buffer)
- dfree (data.buffer, "expr_concat");
- if (other.buffer)
- dfree (other.buffer, "expr_concat");
- return result;
- break;
-
- case expr_check:
- case expr_equal:
- case expr_and:
- case expr_or:
- case expr_not:
- warn ("Boolean opcode in evaluate_data_expression: %d",
- expr -> op);
- goto null_return;
-
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- case expr_const_int:
- warn ("Numeric opcode in evaluate_data_expression: %d",
- expr -> op);
- goto null_return;
- }
-
- warn ("Bogus opcode in evaluate_data_expression: %d", expr -> op);
- null_return:
- memset (&result, 0, sizeof result);
- return result;
-}
-
-unsigned long evaluate_numeric_expression (packet, expr)
- struct packet *packet;
- struct expression *expr;
-{
- struct data_string data;
- unsigned long result;
-
- switch (expr -> op) {
- case expr_check:
- case expr_equal:
- case expr_and:
- case expr_or:
- case expr_not:
- warn ("Boolean opcode in evaluate_numeric_expression: %d",
- expr -> op);
- return 0;
-
- case expr_substring:
- case expr_suffix:
- case expr_option:
- case expr_hardware:
- case expr_const_data:
- case expr_packet:
- case expr_concat:
- case expr_host_lookup:
- warn ("Data opcode in evaluate_numeric_expression: %d",
- expr -> op);
- return 0;
-
- case expr_extract_int8:
- data = evaluate_data_expression (packet,
- expr ->
- data.extract_int.expr);
- if (data.len < 1)
- return 0;
- result = data.data [0];
- if (data.buffer)
- dfree (data.buffer, "expr_extract_int8");
- return result;
-
- case expr_extract_int16:
- data = evaluate_data_expression (packet,
- expr ->
- data.extract_int.expr);
- if (data.len < 2)
- return 0;
- result = getUShort (data.data);
- if (data.buffer)
- dfree (data.buffer, "expr_extract_int16");
- return result;
-
- case expr_extract_int32:
- data = evaluate_data_expression (packet,
- expr ->
- data.extract_int.expr);
- if (data.len < 4)
- return 0;
- result = getULong (data.data);
- if (data.buffer)
- dfree (data.buffer, "expr_extract_int32");
- return result;
-
- case expr_const_int:
- return expr -> data.const_int;
- }
-
- warn ("Bogus opcode in evaluate_numeric_expression: %d", expr -> op);
- return 0;
-}
-
-void free_oc_ephemeral_state (oc)
- struct option_cache *oc;
-{
- if (free_ephemeral_outer_tree (expr))
- free_option_cache (oc, "free_oc_ephemeral_state");
-}
-
-/* Recursively free any ephemeral subexpressions of the passed expression,
- and then free that expression. */
-
-int free_ephemeral_outer_tree (expr)
- struct expression *expr;
+static void do_data_copy (bufix, bufp, bufcount, data, len)
+ int *bufix;
+ unsigned char **bufp;
+ int *bufcount;
+ unsigned char *data;
+ int len;
{
- /* If this expression isn't ephemeral, notify the caller. */
- if (!(expr -> flags & EXPR_EPHEMERAL))
- return 0;
+ int space = *bufcount - *bufix;
- /* Free any ephemeral subexpressions... */
- switch (expr -> op) {
- /* All the binary operators can be handled the same way. */
- case expr_equal:
- case expr_concat:
- case expr_and:
- case expr_or:
- free_ephemeral_outer_tree (expr -> data.equal [0]);
- free_ephemeral_outer_tree (expr -> data.equal [1]);
- break;
-
- case expr_substring:
- free_ephemeral_outer_tree (expr -> data.substring.expr);
- free_ephemeral_outer_tree (expr -> data.substring.offset);
- free_ephemeral_outer_tree (expr -> data.substring.len);
- break;
-
- case expr_suffix:
- free_ephemeral_outer_tree (expr -> data.suffix.expr);
- free_ephemeral_outer_tree (expr -> data.suffix.len);
- break;
-
- case expr_not:
- free_ephemeral_outer_tree (expr -> data.not);
- break;
-
- case expr_packet:
- free_ephemeral_outer_tree (expr -> data.packet.offset);
- free_ephemeral_outer_tree (expr -> data.packet.len);
- break;
-
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- free_ephemeral_outer_tree (expr -> data.extract_int.expr);
- free_ephemeral_outer_tree (expr -> data.extract_int.width);
- break;
-
- /* No subexpressions. */
- case expr_const_int:
- case expr_check:
- case expr_host_lookup:
- case expr_option:
- case expr_const_data:
- case expr_hardware:
- break;
+ /* If there's more space than we need, use only what we need. */
+ if (space > len)
+ space = len;
- default:
- break;
- }
-
- free_expression (expr, "free_expr_outer_tree");
- return 1;
+ /* Copy as much data as will fit, then increment the buffer index
+ by the amount we actually had to copy, which could be more. */
+ if (space > 0)
+ memcpy (*bufp + *bufix, data, space);
+ *bufix += len;
}
-
-/* Free all of the state in an option state buffer. The buffer itself is
- not freed, since these buffers are always contained in other structures. */
-
-void free_option_state (state)
- struct option_state *state;
-{
- int i;
- struct agent_option *ao;
diff --git a/common/upf.c b/common/upf.c
index 498b6e6c..7da9aff6 100644
--- a/common/upf.c
+++ b/common/upf.c
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: upf.c,v 1.3 1997/10/20 21:47:15 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: upf.c,v 1.3.2.1 1998/12/20 18:29:48 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -232,6 +232,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
unsigned char buf [256];
struct iovec iov [2];
+ 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,
@@ -295,4 +299,20 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
memcpy (buf, &ibuf [bufix], length);
return length;
}
+
+int can_unicast_without_arp ()
+{
+ return 1;
+}
+
+void maybe_setup_fallback ()
+{
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ if_register_fallback (fbi);
+ add_protocol ("fallback", fallback_interface -> wfdesc,
+ fallback_discard, fallback_interface);
+ }
+}
#endif
diff --git a/configure b/configure
index 7d5fe371..8858d31a 100755
--- a/configure
+++ b/configure
@@ -74,9 +74,9 @@ fi
echo "System Type: $sysname"
-for foo in . client server relay statmsg sysconfd common dhcpctl; do
+for foo in . client server relay common; do
(sed -e "/^##--${sysname}--/,/^##--${sysname}--/s/^#//" \
- <Makefile.conf; cat site.conf; cat $foo/Makefile.dist) \
+ <Makefile.conf; cat $foo/Makefile.dist) \
>$foo/Makefile
done
diff --git a/doc/IANA-arp-parameters b/doc/IANA-arp-parameters
deleted file mode 100644
index 9fa8f115..00000000
--- a/doc/IANA-arp-parameters
+++ /dev/null
@@ -1,145 +0,0 @@
-
-
-ADDRESS RESOLUTION PROTOCOL PARAMETERS
-
-The Address Resolution Protocol (ARP) specified in [RFC826] has
-several parameters. The assigned values for these parameters are
-listed here.
-
-REVERSE ADDRESS RESOLUTION PROTOCOL OPERATION CODES
-
-The Reverse Address Resolution Protocol (RARP) specified in [RFC903]
-uses the "Reverse" codes below.
-
-DYNAMIC REVERSE ARP
-
-The Dynamic Reverse Address Resolution Protocol (DRARP) uses the
-"DRARP" codes below. For further information, contact: David Brownell
-(suneast!helium!db@Sun.COM).
-
-INVERSE ADDRESS RESOULUTION PROTOCOL
-
-The Inverse Address Resolution Protocol (IARP) specified in [RFC1293]
-uses the "InARP" codes below.
-
-Assignments:
-
-Number Operation Code (op) References
------- -------------------------- ----------
- 1 REQUEST [RFC826]
- 2 REPLY [RFC826]
- 3 request Reverse [RFC903]
- 4 reply Reverse [RFC903]
- 5 DRARP-Request [David Brownell]
- 6 DRARP-Reply [David Brownell]
- 7 DRARP-Error [David Brownell]
- 8 InARP-Request [RFC1293]
- 9 InARP-Reply [RFC1293]
- 10 ARP-NAK [RFC1577]
- 11 MARS-Request [Armitage]
- 12 MARS-Multi [Armitage]
- 13 MARS-MServ [Armitage]
- 14 MARS-Join [Armitage]
- 15 MARS-Leave [Armitage]
- 16 MARS-NAK [Armitage]
- 17 MARS-Unserv [Armitage]
- 18 MARS-SJoin [Armitage]
- 19 MARS-SLeave [Armitage]
- 20 MARS-Grouplist-Request [Armitage]
- 21 MARS-Grouplist-Reply [Armitage]
- 22 MARS-Redirect-Map [Armitage]
- 23 MAPOS-UNARP [Maruyama]
-
-
-Number Hardware Type (hrd) References
------- ----------------------------------- ----------
- 1 Ethernet (10Mb) [JBP]
- 2 Experimental Ethernet (3Mb) [JBP]
- 3 Amateur Radio AX.25 [PXK]
- 4 Proteon ProNET Token Ring [Doria]
- 5 Chaos [GXP]
- 6 IEEE 802 Networks [JBP]
- 7 ARCNET [JBP]
- 8 Hyperchannel [JBP]
- 9 Lanstar [TU]
- 10 Autonet Short Address [MXB1]
- 11 LocalTalk [JKR1]
- 12 LocalNet (IBM PCNet or SYTEK LocalNET) [JXM]
- 13 Ultra link [RXD2]
- 14 SMDS [GXC1]
- 15 Frame Relay [AGM]
- 16 Asynchronous Transmission Mode (ATM) [JXB2]
- 17 HDLC [JBP]
- 18 Fibre Channel [Yakov Rekhter]
- 19 Asynchronous Transmission Mode (ATM) [RFC1577]
- 20 Serial Line [JBP]
- 21 Asynchronous Transmission Mode (ATM) [MXB1]
- 22 MIL-STD-188-220 [Jensen]
- 23 Metricom [Stone]
- 24 IEEE 1394.1995 [Hattig]
- 25 MAPOS [Maruyama]
-
-Protocol Type (pro)
-
-Use the same codes as listed in the section called "Ethernet Numbers
-of Interest" (all hardware types use this code set for the protocol
-type).
-
-
-REFERENCES
-
-[RFC826] Plummer, D., "An Ethernet Address Resolution Protocol or
- Converting Network Protocol Addresses to 48-bit Ethernet
- Addresses for Transmission on Ethernet Hardware", STD 37, RFC
- 826, MIT-LCS, November 1982.
-
-[RFC903] Finlayson, R., Mann, T., Mogul, J., and M. Theimer, "A
- Reverse Address Resolution Protocol", STD 38, RFC 903,
- Stanford University, June 1984.
-
-[RFC1293] Bradley, T., and C. Brown, "Inverse Address Resolution
- Protocol", RFC 1293, Wellfleet Communications, Inc.,
- January 1992.
-
-
-PEOPLE
-
-[Armitage] Grenville Armitage, <gja@thumper.belcore.com>, April 1995.
-
-[AGM] Andy Malis <malis_a@timeplex.com>
-
-[GXC1] George Clapp <meritec!clapp@bellcore.bellcore.com>
-
-[Doria] Avri Doria <avri@peoteon.com> December 1994.
-
-[GXP] Gill Pratt <gill%mit-ccc@MC.LCS.MIT.EDU>
-
-[Jensen] Herb Jensen, <hwjensen@itt.com>, February 1995.
-
-[JBP] Jon Postel <postel@isi.edu>
-
-[JKR1] Joyce K. Reynolds <jkrey@isi.edu>
-
-[JXM] Joseph Murdock <---none--->
-
-[Hattig] Myron Hattig, <Myron_Hattig@ccm.jf.intel.com>, February 1997.
-
-[Maruyama] Mitsuru Maruyama, <mitsuru@ntt-20.ecl.net>, March 1997.
-
-[MXB1] Mike Burrows <burrows@SRC.DEC.COM>
-
-[PXK] Philip Koch <Philip.Koch@DARTMOUTH.EDU>
-
-[RXD2] Rajiv Dhingra <rajiv@ULTRA.COM>
-
-[Stone] Jonathan Stone, <jonathan@DSG.Stanford.edu>, May 1996.
-
-[TU] Tom Unger <tom@CITI.UMICH>
-
-[David Brownell]
-
-[Mark Laubach]
-
-[Yakov Rekhter] <Yakov@IBM.COM>
-
-[]
diff --git a/doc/draft-ietf-dhc-authentication-03.txt b/doc/draft-ietf-dhc-authentication-03.txt
deleted file mode 100644
index 5be03584..00000000
--- a/doc/draft-ietf-dhc-authentication-03.txt
+++ /dev/null
@@ -1,446 +0,0 @@
-
-Network Working Group R. Droms, Editor
-INTERNET DRAFT Bucknell University
-Obsoletes: draft-ietf-dhc-authentication-02.txt November 1996
- Expires May 1997
-
-
- Authentication for DHCP Messages
- <draft-ietf-dhc-authentication-03.txt>
-
-Status of this memo
-
- This document is an Internet-Draft. Internet-Drafts are working
- documents of the Internet Engineering Task Force (IETF), its areas,
- and its working groups. Note that other groups may also distribute
- working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as ``work in progress.''
-
- To learn the current status of any Internet-Draft, please check the
- ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
- Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
- munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
- ftp.isi.edu (US West Coast).
-
-Abstract
-
- The Dynamic Host Configuration Protocol (DHCP) [1] provides a
- framework for passing configuration information to hosts on a TCP/IP
- network. In some situations, network administrators may wish to
- constrain the allocation of addresses to authorized hosts.
- Additionally, some network administrators may wish to provide for
- authentication of the source and contents of DHCP messages. This
- document defines a new DHCP option through which authorization
- tickets can be easily generated and newly attached hosts with proper
- authorization can be automatically configured from an authenticated
- DHCP server.
-
-1. Introduction
-
- DHCP transports protocol stack configuration parameters from
- centrally administered servers to TCP/IP hosts. Among those
- parameters are an IP address. DHCP servers can be configured to
- dynamically allocate addresses from a pool of addresses, eliminating
- a manual step in configuration of TCP/IP hosts.
-
-
-
-
-Droms [Page 1]
-
-DRAFT Authentication for DHCP Messages November 1996
-
-
- Some network administrators may wish to provide authentication of the
- source and contents of DHCP messages. For example, clients may be
- subject to denial of service attacks through the use of bogus DHCP
- servers, or may simply be misconfigured due to unintentionally
- instantiated DHCP servers. Network administrators may wish to
- constrain the allocation of addresses to authorized hosts to avoid
- denial of service attacks in "hostile" environments where the network
- medium is not physically secured, such as wireless networks or
- college residence halls.
-
- This document defines a technique that can provide both entity
- authentication and message authentication.
-
-1.1 Requirements
-
- Throughout this document, the words that are used to define the
- significance of particular requirements are capitalized. These words
- are:
-
- o "MUST"
-
- This word or the adjective "REQUIRED" means that the
- item is an absolute requirement of this specification.
-
- o "MUST NOT"
-
- This phrase means that the item is an absolute prohibition
- of this specification.
-
- o "SHOULD"
-
- This word or the adjective "RECOMMENDED" means that there
- may exist valid reasons in particular circumstances to ignore
- this item, but the full implications should be understood and
- the case carefully weighed before choosing a different course.
-
- o "SHOULD NOT"
-
- This phrase means that there may exist valid reasons in
- particular circumstances when the listed behavior is acceptable
- or even useful, but the full implications should be understood
- and the case carefully weighed before implementing any behavior
- described with this label.
-
-
-
-
-
-
-
-
-Droms [Page 2]
-
-DRAFT Authentication for DHCP Messages November 1996
-
-
- o "MAY"
-
- This word or the adjective "OPTIONAL" means that this item is
- truly optional. One vendor may choose to include the item
- because a particular marketplace requires it or because it
- enhances the product, for example; another vendor may omit the
- same item.
-
-1.2 Terminology
-
- This document uses the following terms:
-
- o "DHCP client"
-
- A DHCP client or "client" is an Internet host using DHCP to obtain
- configuration parameters such as a network address.
-
- o "DHCP server"
-
- A DHCP server of "server"is an Internet host that returns
- configuration parameters to DHCP clients.
-
-2. Format of the authentication option
-
- The following diagram defines the format of the DHCP
- authentication option:
-
-
- +----------+----------+----------+
- | Code | Length | Protocol |
- +----------+----------+----------+-----------+---
- | Authentication information ...
- +----------+----------+----------+-----------+---
-
-
- The code for the authentication option is TBD, and the length field
- contains the length of the protocol and authentication information
- fields in octets. The protocol field defines the particular
- technique for authentication used in the option.
-
- This document defines two protocols in sections 3 and 4, encoded with
- protocol field values 0 and 1. Protocol field values 2-254 are
- reserved for future use. Other protocols may be defined according to
- the procedure described in section 5.
-
-3. Protocol 0
-
- If the protocol field is 0, the authentication information field
-
-
-
-Droms [Page 3]
-
-DRAFT Authentication for DHCP Messages November 1996
-
-
- holds a simple authentication token:
-
-
- +----------+----------+----------+
- | Code | n+1 | 0 |
- +----------+----------+----------+-----------+------
- | Authentication token (n octets) ...
- +----------+----------+----------+-----------+------
-
-
- The authentication token is an opaque, unencoded value known to both
- the sender and receiver. The sender inserts the authentication token
- in the DHCP message and the receiver matches the token from the
- message to the shared token. If the authentication option is present
- and the token from the message does not match the shared token, the
- receiver MUST discard the message.
-
- Protocol 0 may be used to pass a plain-text password and provides
- only weak entity authentication and no message authentication. This
- protocol is useful for rudimentary protection against, e.g.,
- inadvertently instantiated DHCP servers.
-
- DISCUSSION:
-
- The intent here is to pass a constant, non-computed token such as
- a plain-text password. Other types of entity authentication using
- computed tokens such as Kerberos tickets or one-time passwords
- will be defined as separate protocols.
-
-
-4. Protocol 1
-
- If the protocol field is 1, the authentication information contains
- an encrypted value generated by the source as a message
- authentication code (MAC) to provide message authentication and
- entity authentication.
-
- This technique is based on the HMAC protocol [3] using the MD5 hash
- {2].
-
-
-
-
-
-
-
-
-
-
-
-
-Droms [Page 4]
-
-DRAFT Authentication for DHCP Messages November 1996
-
-
-4.1 Format
-
- The format of the authentication information for protocol 1 is:
-
-
- +----------+----------+----------+
- | Code | n | 1 |
- +----------+----------+----------+----------+-
- | Counter (8 octets) ...
- +----------+----------+----------+----------+-
- | MAC ...
- +----------+----------+----------+----------+-
-
- The following definitions will be used in the description of the
- authentication information for protocol 1:
-
- K - a secret value shared between the source and destination
- of the message
- Counter - the value of a 64-bit monotonically increasing counter
- HMAC-MD5 - the MAC generating function as defined by [3] and [2]
-
- The sender computes the MAC as described in [3]. The 'counter' field
- of the authentication option MUST be set to the value of a
- monotonically increasing counter and the 'MAC' field of the
- authentication option MUST be set to all 0s for the computation of
- the MAC. Because a DHCP relay agent may alter the values of the
- 'giaddr' and 'hops' fields in the DHCP message, the contents of those
- two fields MUST also be set to zero for the computation of the
- message digest. Using a counter value such as the current time of
- day (e.g., an NTP-format timestamp [4]) can reduce the danger of
- replay attacks.
-
- DISCUSSION:
-
- Protocol 1 specifies the use of HMAC-MD5. Use of a different
- technique, such as HMAC-SHA, will be specified as a separate
- protocol.
-
-4.2 Message validation
-
- To validate an incoming message, the receiver checks the 'counter'
- field and computes the MAC as described in [3]. If the 'counter'
- field does not contain a value larger than the last value of
- 'counter' used by the sender, the receiver MUST discard the incoming
- message. The receiver MUST set the 'MAC' field of the authentication
- option to all 0s for computation of the MAC. Because a DHCP relay
- agent may alter the values of the 'giaddr' and 'hops' fields in the
- DHCP message, the contents of those two fields MUST also be set to
-
-
-
-Droms [Page 5]
-
-DRAFT Authentication for DHCP Messages November 1996
-
-
- zero for the computation of the MAC. If the MAC computed by the
- receiver does not match the MAC contained in the authentication
- option, the receiver MUST discard the DHCP message.
-
-4.3 Key utilization
-
- Each DHCP client has a key, K. The client uses its key to encode any
- messages it sends to the server and to authenticate and verify any
- messages it receives from the server. The client's key must be
- initially distributed to the client through some out-of-band
- mechanism, and must be stored locally on the client for use in all
- authenticated DHCP messages. Once the client has been given its key,
- it may use that key for all transactions even if the client's
- configuration changes; e.g., if the client is assigned a new network
- address.
-
- Each DHCP server must know the keys for all authorized clients. If
- all clients use the same key, clients can perform both entity and
- message authentication for all messages received from servers.
- Servers will be able to perform message authentication. To
- authenticate the identity of individual clients, each client must be
- configured with a unique key. Appendix A describes a technique for
- key management.
-
-5. Definition of new authentication protocols
-
- The author of a new DHCP option will follow these steps to obtain
- acceptance of the option as a part of the DHCP Internet Standard:
-
- 1. The author devises the new authentication protocol.
- 2. The author documents the new protocol as an Internet Draft.
- 3. The author submits the Internet Draft for review through the IETF
- standards process as defined in "Internet Official Protocol
- Standards" (STD 1). The new protocol will be submitted for
- eventual acceptance as an Internet Standard.
- 4. The new protocol progresses through the IETF standards process;
- the new option will be reviewed by the Dynamic Host Configuration
- Working Group (if that group still exists), or as an Internet
- Draft not submitted by an IETF working group.
-
- This procedure for defining new authentication protocols will ensure
- that:
-
- * new options are reviewed for technical correctness and
- appropriateness, and
- * documentation for new options is complete and published.
-
-
-
-
-
-Droms [Page 6]
-
-DRAFT Authentication for DHCP Messages November 1996
-
-
-6. References
-
- [1] Droms, R., "Dynamic Host Configuration Protocol", RFC 1541,
- Bucknell University, October 1993.
-
- [2] Rivest, R., "The MD5 Message-Digest Algorithm",
- RFC-1321, April 1992.
-
- [3] Krawczyk H., M. Bellare and R. Canetti, "HMAC: Keyed-Hashing for
- Message Authentication" <draft-ietf-ipsec-hmac-md5-01.txt> (work in
- progress), August 1996.
-
- [4] Mills, D., "Network Time Protocol (Version 3)", RFC-1305, March
- 1992.
-
-7. Acknowledgments
-
- Jeff Schiller and Christian Huitema developed this scheme during a
- terminal room BOF at the Dallas IETF meeting, December 1995. The
- author transcribed the notes from that discussion, which form the
- basis for this document. The editor appreciates Jeff's and
- Christian's patience in reviewing this document and its earlier
- drafts.
-
- Thanks also to John Wilkins, Ran Atkinson and Shawn Mamros for
- reviewing this document, and to Thomas Narten for reviewing earlier
- drafts of this document.
-
-8. Security considerations
-
- This document describes authentication and verification mechanisms
- for DHCP.
-
-9. Author's address
-
- Ralph Droms
- Computer Science Department
- 323 Dana Engineering
- Bucknell University
- Lewisburg, PA 17837
-
- Phone: (717) 524-1145
- EMail: droms@bucknell.edu
-
-
-
-
-
-
-
-
-Droms [Page 7]
-
-DRAFT Authentication for DHCP Messages November 1996
-
-
- Appendix A - Key Management Technique
-
- To avoid centralized management of a list of random keys, suppose K for
- each client is generated from the pair (client identifier, subnet
- address), which must be unique to that client. That is, K = MD5(MK,
- unique-id), where MK is a secret master key and MD5 is some encoding
- function.
-
- Without knowledge of the master key MK, an unauthorized client cannot
- generate its own key K. The server can quickly validate an incoming
- message from a new client by regenerating K from the client-id. For known
- clients, the server can choose to recover the client's K dynamically from
- the client-id in the DHCP message, or can choose to precompute and cache
- all of the Ks a priori.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Droms [Page 8]
-
diff --git a/doc/draft-ietf-dhc-dhcp-09.txt b/doc/draft-ietf-dhc-dhcp-09.txt
deleted file mode 100644
index 399e2de3..00000000
--- a/doc/draft-ietf-dhc-dhcp-09.txt
+++ /dev/null
@@ -1,2519 +0,0 @@
-
-
-Network Working Group R. Droms
-INTERNET DRAFT Bucknell University
-Obsoletes: draft-ietf-dhc-dhcp-08.txt December 1996
- Expires June 1997
-
-
- Dynamic Host Configuration Protocol
- <draft-ietf-dhc-dhcp-09.txt>
-
-Status of this memo
-
- This document is an Internet-Draft. Internet-Drafts are working
- documents of the Internet Engineering Task Force (IETF), its areas,
- and its working groups. Note that other groups may also distribute
- working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as ``work in progress.''
-
- To learn the current status of any Internet-Draft, please check the
- ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
- Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
- munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
- ftp.isi.edu (US West Coast).
-
-Abstract
-
- The Dynamic Host Configuration Protocol (DHCP) provides a framework
- for passing configuration information to hosts on a TCP/IP network.
- DHCP is based on the Bootstrap Protocol (BOOTP) [7], adding the
- capability of automatic allocation of reusable network addresses and
- additional configuration options [19]. DHCP captures the behavior of
- BOOTP relay agents [7, 21], and DHCP participants can interoperate
- with BOOTP participants [9].
-
-
-Table of Contents
-
- 1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . 2
- 1.1 Changes to RFC1541. . . . . . . . . . . . . . . . . . . . . . 4
- 1.2 Related Work. . . . . . . . . . . . . . . . . . . . . . . . . 4
- 1.3 Problem definition and issues . . . . . . . . . . . . . . . . 5
- 1.4 Requirements. . . . . . . . . . . . . . . . . . . . . . . . . 5
- 1.5 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 6
- 1.6 Design goals. . . . . . . . . . . . . . . . . . . . . . . . . 6
- 2. Protocol Summary. . . . . . . . . . . . . . . . . . . . . . . 8
-
-
-
-Droms [Page 1]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- 2.1 Configuration parameters repository . . . . . . . . . . . . . 11
- 2.2 Dynamic allocation of network addresses . . . . . . . . . . . 12
- 3. The Client-Server Protocol. . . . . . . . . . . . . . . . . . 13
- 3.1 Client-server interaction - allocating a network address. . . 13
- 3.2 Client-server interaction - reusing a previously allocated
- network address . . . . . . . . . . . . . . . . . . . . . . . 17
- 3.3 Interpretation and representation of time values. . . . . . . 20
- 3.4 Obtaining parameters with externally configured network
- address . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
- 3.5 Client parameters in DHCP . . . . . . . . . . . . . . . . . . 20
- 3.6 Use of DHCP in clients with multiple interfaces . . . . . . . 22
- 3.7 When clients should use DHCP. . . . . . . . . . . . . . . . . 22
- 4. Specification of the DHCP client-server protocol. . . . . . . 22
- 4.1 Constructing and sending DHCP messages. . . . . . . . . . . . 22
- 4.2 DHCP server administrative controls . . . . . . . . . . . . . 25
- 4.3 DHCP server behavior. . . . . . . . . . . . . . . . . . . . . 26
- 4.4 DHCP client behavior. . . . . . . . . . . . . . . . . . . . . 33
- 5. Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . .40
- 6. References . . . . . . . . . . . . . . . . . . . . . . . . . .41
- 7. Security Considerations. . . . . . . . . . . . . . . . . . . .42
- 8. Author's Address . . . . . . . . . . . . . . . . . . . . . . .43
- A. Host Configuration Parameters . . . . . . . . . . . . . . . .44
-
-List of Figures
-
- 1. Format of a DHCP message . . . . . . . . . . . . . . . . . . . 9
- 2. Format of the 'flags' field. . . . . . . . . . . . . . . . . . 11
- 3. Timeline diagram of messages exchanged between DHCP client and
- servers when allocating a new network address. . . . . . . . . 15
- 4. Timeline diagram of messages exchanged between DHCP client and
- servers when reusing a previously allocated network address. . 18
- 5. State-transition diagram for DHCP clients. . . . . . . . . . . 34
-
-List of Tables
-
- 1. Description of fields in a DHCP message. . . . . . . . . . . . 10
- 2. DHCP messages. . . . . . . . . . . . . . . . . . . . . . . . . 14
- 3. Fields and options used by DHCP servers. . . . . . . . . . . . 28
- 4. Client messages from various states. . . . . . . . . . . . . . 33
- 5. Fields and options used by DHCP clients. . . . . . . . . . . . 37
-
-1. Introduction
-
- The Dynamic Host Configuration Protocol (DHCP) provides configuration
- parameters to Internet hosts. DHCP consists of two components: a
- protocol for delivering host-specific configuration parameters from a
- DHCP server to a host and a mechanism for allocation of network
- addresses to hosts.
-
-
-
-Droms [Page 2]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- DHCP is built on a client-server model, where designated DHCP server
- hosts allocate network addresses and deliver configuration parameters
- to dynamically configured hosts. Throughout the remainder of this
- document, the term "server" refers to a host providing initialization
- parameters through DHCP, and the term "client" refers to a host
- requesting initialization parameters from a DHCP server.
-
- A host should not act as a DHCP server unless explicitly configured
- to do so by a system administrator. The diversity of hardware and
- protocol implementations in the Internet would preclude reliable
- operation if random hosts were allowed to respond to DHCP requests.
- For example, IP requires the setting of many parameters within the
- protocol implementation software. Because IP can be used on many
- dissimilar kinds of network hardware, values for those parameters
- cannot be guessed or assumed to have correct defaults. Also,
- distributed address allocation schemes depend on a polling/defense
- mechanism for discovery of addresses that are already in use. IP
- hosts may not always be able to defend their network addresses, so
- that such a distributed address allocation scheme cannot be
- guaranteed to avoid allocation of duplicate network addresses.
-
- DHCP supports three mechanisms for IP address allocation. In
- "automatic allocation", DHCP assigns a permanent IP address to a
- client. In "dynamic allocation", DHCP assigns an IP address to a
- client for a limited period of time (or until the client explicitly
- relinquishes the address). In "manual allocation", a client's IP
- address is assigned by the network administrator, and DHCP is used
- simply to convey the assigned address to the client. A particular
- network will use one or more of these mechanisms, depending on the
- policies of the network administrator.
-
- Dynamic allocation is the only one of the three mechanisms that
- allows automatic reuse of an address that is no longer needed by the
- client to which it was assigned. Thus, dynamic allocation is
- particularly useful for assigning an address to a client that will be
- connected to the network only temporarily or for sharing a limited
- pool of IP addresses among a group of clients that do not need
- permanent IP addresses. Dynamic allocation may also be a good choice
- for assigning an IP address to a new client being permanently
- connected to a network where IP addresses are sufficiently scarce
- that it is important to reclaim them when old clients are retired.
- Manual allocation allows DHCP to be used to eliminate the error-prone
- process of manually configuring hosts with IP addresses in
- environments where (for whatever reasons) it is desirable to manage
- IP address assignment outside of the DHCP mechanisms.
-
- The format of DHCP messages is based on the format of BOOTP messages,
- to capture the BOOTP relay agent behavior described as part of the
-
-
-
-Droms [Page 3]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- BOOTP specification [7, 21] and to allow interoperability of existing
- BOOTP clients with DHCP servers. Using BOOTP relay agents eliminates
- the necessity of having a DHCP server on each physical network
- segment.
-
-1.1 Changes to RFC 1541
-
- This document updates the DHCP protocol specification that appears in
- RFC1541. A new DHCP message type, DHCPINFORM, has been added; see
- section 3.4, 4.3 and 4.4 for details. The classing mechanism for
- identifying DHCP clients to DHCP servers has been extended to include
- "vendor" classes as defined in sections 4.2 and 4.3. The minimum
- lease time restriction has been removed. Finally, many editorial
- changes have been made to clarify the text as a result of experience
- gained in DHCP interoperability tests.
-
-1.2 Related Work
-
- There are several Internet protocols and related mechanisms that
- address some parts of the dynamic host configuration problem. The
- Reverse Address Resolution Protocol (RARP) [10] (through the
- extensions defined in the Dynamic RARP (DRARP) [5]) explicitly
- addresses the problem of network address discovery, and includes an
- automatic IP address assignment mechanism. The Trivial File Transfer
- Protocol (TFTP) [20] provides for transport of a boot image from a
- boot server. The Internet Control Message Protocol (ICMP) [16]
- provides for informing hosts of additional routers via "ICMP
- redirect" messages. ICMP also can provide subnet mask information
- through the "ICMP mask request" message and other information through
- the (obsolete) "ICMP information request" message. Hosts can locate
- routers through the ICMP router discovery mechanism [8].
-
- BOOTP is a transport mechanism for a collection of configuration
- information. BOOTP is also extensible, and official extensions [17]
- have been defined for several configuration parameters. Morgan has
- proposed extensions to BOOTP for dynamic IP address assignment [15].
- The Network Information Protocol (NIP), used by the Athena project at
- MIT, is a distributed mechanism for dynamic IP address assignment
- [19]. The Resource Location Protocol RLP [1] provides for location
- of higher level services. Sun Microsystems diskless workstations use
- a boot procedure that employs RARP, TFTP and an RPC mechanism called
- "bootparams" to deliver configuration information and operating
- system code to diskless hosts. (Sun Microsystems, Sun Workstation
- and SunOS are trademarks of Sun Microsystems, Inc.) Some Sun
- networks also use DRARP and an auto-installation mechanism to
- automate the configuration of new hosts in an existing network.
-
- In other related work, the path minimum transmission unit (MTU)
-
-
-
-Droms [Page 4]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- discovery algorithm can determine the MTU of an arbitrary internet
- path [14]. The Address Resolution Protocol (ARP) has been proposed
- as a transport protocol for resource location and selection [6].
- Finally, the Host Requirements RFCs [3, 4] mention specific
- requirements for host reconfiguration and suggest a scenario for
- initial configuration of diskless hosts.
-
-1.3 Problem definition and issues
-
- DHCP is designed to supply DHCP clients with the configuration
- parameters defined in the Host Requirements RFCs. After obtaining
- parameters via DHCP, a DHCP client should be able to exchange packets
- with any other host in the Internet. The TCP/IP stack parameters
- supplied by DHCP are listed in Appendix A.
-
- Not all of these parameters are required for a newly initialized
- client. A client and server may negotiate for the transmission of
- only those parameters required by the client or specific to a
- particular subnet.
-
- DHCP allows but does not require the configuration of client
- parameters not directly related to the IP protocol. DHCP also does
- not address registration of newly configured clients with the Domain
- Name System (DNS) [12, 13].
-
- DHCP is not intended for use in configuring routers.
-
-1.4 Requirements
-
- Throughout this document, the words that are used to define the
- significance of particular requirements are capitalized. These words
- are:
-
- o "MUST"
-
- This word or the adjective "REQUIRED" means that the
- item is an absolute requirement of this specification.
-
- o "MUST NOT"
-
- This phrase means that the item is an absolute prohibition
- of this specification.
-
-
-
-
-
-
-
-
-
-Droms [Page 5]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- o "SHOULD"
-
- This word or the adjective "RECOMMENDED" means that there
- may exist valid reasons in particular circumstances to ignore
- this item, but the full implications should be understood and
- the case carefully weighed before choosing a different course.
-
- o "SHOULD NOT"
-
- This phrase means that there may exist valid reasons in
- particular circumstances when the listed behavior is acceptable
- or even useful, but the full implications should be understood
- and the case carefully weighed before implementing any behavior
- described with this label.
-
- o "MAY"
-
- This word or the adjective "OPTIONAL" means that this item is
- truly optional. One vendor may choose to include the item
- because a particular marketplace requires it or because it
- enhances the product, for example; another vendor may omit the
- same item.
-
-1.5 Terminology
-
- This document uses the following terms:
-
- o "DHCP client"
-
- A DHCP client is an Internet host using DHCP to obtain
- configuration parameters such as a network address.
-
- o "DHCP server"
-
- A DHCP server is an Internet host that returns configuration
- parameters to DHCP clients.
-
- o "BOOTP relay agent"
-
- A BOOTP relay agent or relay agent is an Internet host or router that
- passes DHCP messages between DHCP clients and DHCP servers. DHCP is
- designed to use the same relay agent behavior as specified in
- the BOOTP protocol specification.
-
-
-
-
-
-
-
-
-Droms [Page 6]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- o "binding"
-
- A binding is a collection of configuration parameters, including
- at least an IP address, associated with or "bound to" a DHCP
- client. Bindings are managed by DHCP servers.
-
-1.6 Design goals
-
- The following list gives general design goals for DHCP.
-
- o DHCP should be a mechanism rather than a policy. DHCP must
- allow local system administrators control over configuration
- parameters where desired; e.g., local system administrators
- should be able to enforce local policies concerning allocation
- and access to local resources where desired.
-
- o Clients should require no manual configuration. Each client should
- be able to discover appropriate local configuration parameters
- without user intervention and incorporate those parameters into
- its own configuration.
-
- o Networks should require no manual configuration for individual
- clients. Under normal circumstances, the network manager should
- not have to enter any per-client configuration parameters.
-
- o DHCP should not require a server on each subnet. To allow for
- scale and economy, DHCP must work across routers or through the
- intervention of BOOTP relay agents.
-
- o A DHCP client must be prepared to receive multiple responses to a
- request for configuration parameters. Some installations may
- include multiple, overlapping DHCP servers to enhance
- reliability and increase performance.
-
- o DHCP must coexist with statically configured, non-participating
- hosts and with existing network protocol implementations.
-
- o DHCP must interoperate with the BOOTP relay agent behavior as
- described by RFC 951 and by RFC 1542 [21].
-
- o DHCP must provide service to existing BOOTP clients.
-
- The following list gives design goals specific to the transmission of
- the network layer parameters. DHCP must:
-
-
-
-
-
-
-
-Droms [Page 7]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- o Guarantee that any specific network address will not be in
- use by more than one DHCP client at a time,
-
- o Retain DHCP client configuration across DHCP client reboot. A DHCP
- client should, whenever possible, be assigned the same configuration
- parameters (e.g., network address) in response to each request,
-
- o Retain DHCP client configuration across server reboots, and, whenever
- possible, a DHCP client should be assigned the same configuration
- parameters despite restarts of the DHCP mechanism,
-
- o Allow automated assignment of configuration parameters to new
- clients to avoid hand configuration for new clients,
-
- o Support fixed or permanent allocation of configuration
- parameters to specific clients.
-
-2. Protocol Summary
-
- From the client's point of view, DHCP is an extension of the BOOTP
- mechanism. This behavior allows existing BOOTP clients to
- interoperate with DHCP servers without requiring any change to the
- clients' initialization software. RFC 1542 [2] details the
- interactions between BOOTP and DHCP clients and servers [9]. There
- are some new, optional transactions that optimize the interaction
- between DHCP clients and servers that are described in sections 3 and
- 4.
-
- Figure 1 gives the format of a DHCP message and table 1 describes
- each of the fields in the DHCP message. The numbers in parentheses
- indicate the size of each field in octets. The names for the fields
- given in the figure will be used throughout this document to refer to
- the fields in DHCP messages.
-
- There are two primary differences between DHCP and BOOTP. First,
- DHCP defines mechanisms through which clients can be assigned a
- network address for a finite lease, allowing for serial reassignment
- of network addresses to different clients. Second, DHCP provides the
- mechanism for a client to acquire all of the IP configuration
- parameters that it needs in order to operate.
-
- DHCP introduces a small change in terminology intended to clarify the
- meaning of one of the fields. What was the "vendor extensions" field
- in BOOTP has been re-named the "options" field in DHCP. Similarly,
- the tagged data items that were used inside the BOOTP "vendor
- extensions" field, which were formerly referred to as "vendor
- extensions," are now termed simply "options."
-
-
-
-
-Droms [Page 8]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | op (1) | htype (1) | hlen (1) | hops (1) |
- +---------------+---------------+---------------+---------------+
- | xid (4) |
- +-------------------------------+-------------------------------+
- | secs (2) | flags (2) |
- +-------------------------------+-------------------------------+
- | ciaddr (4) |
- +---------------------------------------------------------------+
- | yiaddr (4) |
- +---------------------------------------------------------------+
- | siaddr (4) |
- +---------------------------------------------------------------+
- | giaddr (4) |
- +---------------------------------------------------------------+
- | |
- | chaddr (16) |
- | |
- | |
- +---------------------------------------------------------------+
- | |
- | sname (64) |
- +---------------------------------------------------------------+
- | |
- | file (128) |
- +---------------------------------------------------------------+
- | |
- | options (variable) |
- +---------------------------------------------------------------+
-
- Figure 1: Format of a DHCP message
-
- DHCP defines a new 'client identifier' option that is used to pass an
- explicit client identifier to a DHCP server. This change eliminates
- the overloading of the 'chaddr' field in BOOTP messages, where
- 'chaddr' is used both as a hardware address for transmission of BOOTP
- reply messages and as a client identifier. The 'client identifier'
- is an opaque key, not to be interpreted by the server; for example,
- the 'client identifier' may contain a hardware address, identical to
- the contents of the 'chaddr' field, or it may contain another type of
- identifier, such as a DNS name. The 'client identifier' chosen by a
- DHCP client MUST be unique to that client within the subnet to which
- the client is attached. If the client uses a 'client identifier' in
- one message, it MUST use that same identifier in all subsequent
- messages, to ensure that all servers correctly identify the client.
-
-
-
-
-Droms [Page 9]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- DHCP clarifies the interpretation of the 'siaddr' field as the
- address of the server to use in the next step of the client's
- bootstrap process. A DHCP server may return its own address in the
- 'siaddr' field, if the server is prepared to supply the next
- bootstrap service (e.g., delivery of an operating system executable
- image). A DHCP server always returns its own address in the 'server
- identifier' option.
-
- FIELD OCTETS DESCRIPTION
- ----- ------ -----------
-
- op 1 Message op code / message type.
- 1 = BOOTREQUEST, 2 = BOOTREPLY
- htype 1 Hardware address type, see ARP section in "Assigned
- Numbers" RFC; e.g., '1' = 10mb ethernet.
- hlen 1 Hardware address length (e.g. '6' for 10mb
- ethernet).
- hops 1 Client sets to zero, optionally used by relay agents
- when booting via a relay agent.
- xid 4 Transaction ID, a random number chosen by the
- client, used by the client and server to associate
- messages and responses between a client and a
- server.
- secs 2 Filled in by client, seconds elapsed since client
- began address acquisition or renewal process.
- flags 2 Flags (see figure 2).
- ciaddr 4 Client IP address; only filled in if client is in
- BOUND, RENEW or REBINDING state and can respond to ARP
- requests.
- yiaddr 4 'your' (client) IP address.
- siaddr 4 IP address of next server to use in bootstrap;
- returned in DHCPOFFER, DHCPACK by server.
- giaddr 4 Relay agent IP address, used in booting via a
- relay agent.
- chaddr 16 Client hardware address.
- sname 64 Optional server host name, null terminated string.
- file 128 Boot file name, null terminated string; "generic"
- name or null in DHCPDISCOVER, fully qualified
- directory-path name in DHCPOFFER.
- options var Optional parameters field. See the options
- documents for a list of defined options.
-
- Table 1: Description of fields in a DHCP message
-
- The 'options' field is now variable length. A DHCP client must be
- prepared to receive DHCP messages with an 'options' field of at least
- length 312 octets. This requirement implies that a DHCP client must
- be prepared to receive a message of up to 576 octets, the minimum IP
-
-
-
-Droms [Page 10]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- datagram size an IP host must be prepared to accept [3]. DHCP
- clients may negotiate the use of larger DHCP messages through the
- 'maximum DHCP message size' option. The options field may be further
- extended into the 'file' and 'sname' fields.
-
- In the case of a client using DHCP for initial configuration (before
- the client's TCP/IP software has been completely configured), DHCP
- requires creative use of the client's TCP/IP software and liberal
- interpretation of RFC 1122. The TCP/IP software SHOULD accept and
- forward to the IP layer any IP packets delivered to the client's
- hardware address before the IP address is configured; DHCP servers
- and BOOTP relay agents may not be able to deliver DHCP messages to
- clients that cannot accept hardware unicast datagrams before the
- TCP/IP software is configured.
-
-
-
- To work around some clients that cannot accept IP unicast datagrams
- before the TCP/IP software is configured as discussed in the previous
- paragraph, DHCP uses the 'flags' field [21]. The leftmost bit is
- defined as the BROADCAST (B) flag. The semantics of this flag are
- discussed in section 4.1 of this document. The remaining bits of the
- flags field are reserved for future use. They MUST be set to zero by
- clients and ignored by servers and relay agents. Figure 2 gives the
- format of the 'flags' field.
-
- 1 1 1 1 1 1
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |B| MBZ |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
- B: BROADCAST flag
-
- MBZ: MUST BE ZERO (reserved for future use)
-
- Figure 2: Format of the 'flags' field
-
-
-2.1 Configuration parameters repository
-
- The first service provided by DHCP is to provide persistent storage
- of network parameters for network clients. The model of DHCP
- persistent storage is that the DHCP service stores a key-value entry
- for each client, where the key is some unique identifier (for
- example, an IP subnet number and a unique identifier within the
- subnet) and the value contains the configuration parameters for the
- client.
-
-
-
-Droms [Page 11]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- For example, the key might be the pair (IP-subnet-number, hardware-
- address) (note that the "hardware-address" should be typed by the
- type of hardware to accommodate possible duplication of hardware
- addresses resulting from bit-ordering problems in a mixed-media,
- bridged network) allowing for serial or concurrent reuse of a
- hardware address on different subnets, and for hardware addresses
- that may not be globally unique. Alternately, the key might be the
- pair (IP-subnet-number, hostname), allowing the server to assign
- parameters intelligently to a DHCP client that has been moved to a
- different subnet or has changed hardware addresses (perhaps because
- the network interface failed and was replaced). The protocol defines
- that the key will be (IP-subnet-number, hardware-address) unless the
- client explicitly supplies an identifier using the 'client
- identifier' option.
-
- A client can query the DHCP service to retrieve its configuration
- parameters. The client interface to the configuration parameters
- repository consists of protocol messages to request configuration
- parameters and responses from the server carrying the configuration
- parameters.
-
-2.2 Dynamic allocation of network addresses
-
- The second service provided by DHCP is the allocation of temporary or
- permanent network (IP) addresses to clients. The basic mechanism for
- the dynamic allocation of network addresses is simple: a client
- requests the use of an address for some period of time. The
- allocation mechanism (the collection of DHCP servers) guarantees not
- to reallocate that address within the requested time and attempts to
- return the same network address each time the client requests an
- address. In this document, the period over which a network address
- is allocated to a client is referred to as a "lease" [11]. The
- client may extend its lease with subsequent requests. The client may
- issue a message to release the address back to the server when the
- client no longer needs the address. The client may ask for a
- permanent assignment by asking for an infinite lease. Even when
- assigning "permanent" addresses, a server may choose to give out
- lengthy but non-infinite leases to allow detection of the fact that
- the client has been retired.
-
- In some environments it will be necessary to reassign network
- addresses due to exhaustion of available addresses. In such
- environments, the allocation mechanism will reuse addresses whose
- lease has expired. The server should use whatever information is
- available in the configuration information repository to choose an
- address to reuse. For example, the server may choose the least
- recently assigned address. As a consistency check, the allocating
- server SHOULD probe the reused address before allocating the address,
-
-
-
-Droms [Page 12]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- e.g., with an ICMP echo request, and the client SHOULD probe the
- newly received address, e.g., with ARP.
-
-
-3. The Client-Server Protocol
-
- DHCP uses the BOOTP message format defined in RFC 951 and given in
- table 1 and figure 1. The 'op' field of each DHCP message sent from
- a client to a server contains BOOTREQUEST. BOOTREPLY is used in the
- 'op' field of each DHCP message sent from a server to a client.
-
- The first four octets of the 'options' field of the DHCP message
- contain the (decimal) values 99, 130, 83 and 99, respectively (this
- is the same magic cookie as is defined in RFC 1497 [17]). The
- remainder of the 'options' field consists of a list of tagged
- parameters that are called "options". All of the "vendor extensions"
- listed in RFC 1497 are also DHCP options. RFC 1533 gives the
- complete set of options defined for use with DHCP.
-
- Several options have been defined so far. One particular option -
- the "DHCP message type" option - must be included in every DHCP
- message. This option defines the "type" of the DHCP message.
- Additional options may be allowed, required, or not allowed,
- depending on the DHCP message type.
-
- Throughout this document, DHCP messages that include a 'DHCP message
- type' option will be referred to by the type of the message; e.g., a
- DHCP message with 'DHCP message type' option type 1 will be referred
- to as a "DHCPDISCOVER" message.
-
-3.1 Client-server interaction - allocating a network address
-
- The following summary of the protocol exchanges between clients and
- servers refers to the DHCP messages described in table 2. The
- timeline diagram in figure 3 shows the timing relationships in a
- typical client-server interaction. If the client already knows its
- address, some steps may be omitted; this abbreviated interaction is
- described in section 3.2.
-
- 1. The client broadcasts a DHCPDISCOVER message on its local physical
- subnet. The DHCPDISCOVER message MAY include options that suggest
- values for the network address and lease duration. BOOTP relay
- agents may pass the message on to DHCP servers not on the same
- physical subnet.
-
-
-
-
-
-
-
-Droms [Page 13]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- 2. Each server may respond with a DHCPOFFER message that includes an
- available network address in the 'yiaddr' field (and other
- configuration parameters in DHCP options). Servers need not
- reserve the offered network address, although the protocol will
- work more efficiently if the server avoids allocating the offered
- network address to another client. When allocating a new address,
- servers SHOULD check that the offered network address is not
- already in use; e.g., the server may probe the offered address
- with an ICMP Echo Request. Servers SHOULD be implemented so that
- network administrators MAY choose to disable probes of newly
- allocated addresses. The server transmits the DHCPOFFER message
- to the client, using the BOOTP relay agent if necessary.
-
- Message Use
- ------- ---
-
- DHCPDISCOVER - Client broadcast to locate available servers.
-
- DHCPOFFER - Server to client in response to DHCPDISCOVER with
- offer of configuration parameters.
-
- DHCPREQUEST - Client message to servers either (a) requesting
- offered parameters from one server and implicitly
- declining offers from all others, (b) confirming
- correctness of previously allocated address after,
- e.g., system reboot, or (c) extending the lease on a
- particular network address.
-
- DHCPACK - Server to client with configuration parameters,
- including committed network address.
-
- DHCPNAK - Server to client indicating client's notion of network
- address is incorrect (e.g., client has moved to new
- subnet) or client's lease as expired
-
- DHCPDECLINE - Client to server indicating network address is already
- in use.
-
- DHCPRELEASE - Client to server relinquishing network address and
- cancelling remaining lease.
-
- DHCPINFORM - Client to server, asking only for local configuration
- parameters; client already has externally configured
- network address.
-
- Table 2: DHCP messages
-
-
-
-
-
-Droms [Page 14]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- Server Client Server
- (not selected) (selected)
-
- v v v
- | | |
- | Begins initialization |
- | | |
- | _____________/|\_____________ |
- |/ DHCPDISCOVER | DHCPDISCOVER \|
- | | |
- Determines | Determines
- configuration | configuration
- | | |
- |\ | ____________/|
- | \_________ | /DHCPOFFER |
- | DHCPOFFER\ |/ |
- | \ | |
- | Collects replies |
- | \| |
- | Selects configuration |
- | | |
- | _____________/|\_____________ |
- |/ DHCPREQUEST | DHCPREQUEST \|
- | | |
- | | Commits configuration
- | | |
- | | _____________/|
- | |/ DHCPACK |
- | | |
- | Initialization complete |
- | | |
- . . .
- . . .
- | | |
- | Graceful shutdown |
- | | |
- | |\_____________ |
- | | DHCPRELEASE \|
- | | |
- | | Discards lease
- | | |
- v v v
- Figure 3: Timeline diagram of messages exchanged between DHCP
- client and servers when allocating a new network address
-
-
-
-
-
-
-
-Droms [Page 15]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- 3. The client receives one or more DHCPOFFER messages from one or more
- servers. The client may choose to wait for multiple responses.
- The client chooses one server from which to request configuration
- parameters, based on the configuration parameters offered in the
- DHCPOFFER messages. The client broadcasts a DHCPREQUEST message
- that MUST include the 'server identifier' option to indicate which
- server it has selected, and that MAY include other options
- specifying desired configuration values. The 'requested IP
- address' option MUST be set to the value of 'yiaddr' in the
- DHCPOFFER message from the server. This DHCPREQUEST message is
- broadcast and relayed through DHCP/BOOTP relay agents. To help
- ensure that any BOOTP relay agents forward the DHCPREQUEST message
- to the same set of DHCP servers that received the original
- DHCPDISCOVER message, the DHCPREQUEST message MUST use the same
- value in the DHCP message header's 'secs' field and be sent to the
- same IP broadcast address as the original DHCPDISCOVER message.
- The client times out and retransmits the DHCPDISCOVER message if
- the client receives no DHCPOFFER messages.
-
- 4. The servers receive the DHCPREQUEST broadcast from the client.
- Those servers not selected by the DHCPREQUEST message use the
- message as notification that the client has declined that server's
- offer. The server selected in the DHCPREQUEST message commits the
- binding for the client to persistent storage and responds with a
- DHCPACK message containing the configuration parameters for the
- requesting client. The combination of 'client identifier' or
- 'chaddr' and assigned network address constitute a unique
- identifier for the client's lease and are used by both the client
- and server to identify a lease referred to in any DHCP messages.
- Any configuration parameters in the DHCPACK message SHOULD NOT
- conflict with those in the earlier DHCPOFFER message to which the
- client is responding. The server SHOULD NOT check the offered
- network address at this point. The 'yiaddr' field in the DHCPACK
- messages is filled in with the selected network address.
-
- If the selected server is unable to satisfy the DHCPREQUEST message
- (e.g., the requested network address has been allocated), the
- server SHOULD respond with a DHCPNAK message.
-
- A server MAY choose to mark addresses offered to clients in
- DHCPOFFER messages as unavailable. The server SHOULD mark an
- address offered to a client in a DHCPOFFER message as available if
- the server receives no DHCPREQUEST message from that client.
-
- 5. The client receives the DHCPACK message with configuration
- parameters. The client SHOULD perform a final check on the
- parameters (e.g., ARP for allocated network address), and notes the
- duration of the lease specified in the DHCPACK message. At this
-
-
-
-Droms [Page 16]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- point, the client is configured. If the client detects that the
- address is already in use (e.g., through the use of ARP), the
- client MUST send a DHCPDECLINE message to the server and restarts
- the configuration process. The client SHOULD wait a minimum of ten
- seconds before restarting the configuration process to avoid
- excessive network traffic in case of looping.
-
- If the client receives a DHCPNAK message, the client restarts the
- configuration process.
-
- The client times out and retransmits the DHCPREQUEST message if the
- client receives neither a DHCPACK or a DHCPNAK message. The client
- retransmits the DHCPREQUEST according to the retransmission
- algorithm in section 4.1. The client should choose to retransmit
- the DHCPREQUEST enough times to give adequate probability of
- contacting the server without causing the client (and the user of
- that client) to wait overly long before giving up; e.g., a client
- retransmitting as described in section 4.1 might retransmit the
- DHCPREQUEST message four times, for a total delay of 60 seconds,
- before restarting the initialization procedure. If the client
- receives neither a DHCPACK or a DHCPNAK message after employing the
- retransmission algorithm, the client reverts to INIT state and
- restarts the initialization process. The client SHOULD notify the
- user that the initialization process has failed and is restarting.
-
- 6. The client may choose to relinquish its lease on a network address
- by sending a DHCPRELEASE message to the server. The client
- identifies the lease to be released with its 'client identifier',
- or 'chaddr' and network address in the DHCPRELEASE message. If the
- client used a 'client identifier' when it obtained the lease, it
- MUST use the same 'client identifier' in the DHCPRELEASE message.
-
-3.2 Client-server interaction - reusing a previously allocated network
- address
-
- If a client remembers and wishes to reuse a previously allocated
- network address, a client may choose to omit some of the steps
- described in the previous section. The timeline diagram in figure 4
- shows the timing relationships in a typical client-server interaction
- for a client reusing a previously allocated network address.
-
- 1. The client broadcasts a DHCPREQUEST message on its local subnet.
- The message includes the client's network address in the
- 'requested IP address' option. As the client has not received its
- network address, it MUST NOT fill in the 'ciaddr' field. BOOTP
- relay agents pass the message on to DHCP servers not on the same
- subnet. If the client used a 'client identifier' to obtain its
- address, the client MUST use the same 'client identifier' in the
-
-
-
-Droms [Page 17]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- DHCPREQUEST message.
-
- 2. Servers with knowledge of the client's configuration parameters
- respond with a DHCPACK message to the client. Servers SHOULD NOT
- check that the client's network address is already in use; the
- client may respond to ICMP Echo Request messages at this point.
-
- Server Client Server
-
- v v v
- | | |
- | Begins |
- | initialization |
- | | |
- | /|\ |
- | ___________/ | \___________ |
- | /DHCPREQUEST | DHCPREQUEST\ |
- |/ | \|
- | | |
- Locates | Locates
- configuration | configuration
- | | |
- |\ | /|
- | \ | ___________/ |
- | \ | / DHCPACK |
- | \_______ |/ |
- | DHCPACK\ | |
- | Initialization |
- | complete |
- | \| |
- | | |
- | (Subsequent |
- | DHCPACKS |
- | ignored) |
- | | |
- | | |
- v v v
-
- Figure 4: Timeline diagram of messages exchanged between DHCP
- client and servers when reusing a previously allocated
- network address
-
-
- If the client's request is invalid (e.g., the client has moved
- to a new subnet), servers SHOULD respond with a DHCPNAK message to
- the client. Servers SHOULD NOT respond if their information is not
- guaranteed to be accurate. For example, a server that identifies a
- request for an expired binding that is owned by another server SHOULD
-
-
-
-Droms [Page 18]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- NOT respond with a DHCPNAK unless the servers are using an explicit
- mechanism to maintain coherency among the servers.
-
- If 'giaddr' is 0x0 in the DHCPREQUEST message, the client is on
- the same subnet as the server. The server MUST
- broadcast the DHCPNAK message to the 0xffffffff broadcast address
- because the client may not have a correct network address or subnet
- mask, and the client may not be answering ARP requests.
- Otherwise, the server MUST send the DHCPNAK message to the IP
- address of the BOOTP relay agent, as recorded in 'giaddr'. The
- relay agent will, in turn, forward the message directly to the
- client's hardware address, so that the DHCPNAK can be delivered even
- if the client has moved to a new network.
-
- 3. The client receives the DHCPACK message with configuration
- parameters. The client performs a final check on the parameters
- (as in section 3.1), and notes the duration of the lease specified
- in the DHCPACK message. The specific lease is implicitly identified
- by the 'client identifier' or 'chaddr' and the network address. At
- this point, the client is configured.
-
- If the client detects that the IP address in the DHCPACK message
- is already in use, the client MUST send a DHCPDECLINE message to the
- server and restarts the configuration process by requesting a
- new network address. This action corresponds to the client
- moving to the INIT state in the DHCP state diagram, which is
- described in section 4.4.
-
- If the client receives a DHCPNAK message, it cannot reuse its
- remembered network address. It must instead request a new
- address by restarting the configuration process, this time
- using the (non-abbreviated) procedure described in section
- 3.1. This action also corresponds to the client moving to
- the INIT state in the DHCP state diagram.
-
- The client times out and retransmits the DHCPREQUEST message if
- the client receives neither a DHCPACK nor a DHCPNAK message. The
- client retransmits the DHCPREQUEST according to the retransmission
- algorithm in section 4.1. The client should choose to retransmit
- the DHCPREQUEST enough times to give adequate probability of
- contacting the server without causing the client (and the user of
- that client) to wait overly long before giving up; e.g., a client
- retransmitting as described in section 4.1 might retransmit the
- DHCPREQUEST message four times, for a total delay of 60 seconds,
- before restarting the initialization procedure. If the client
- receives neither a DHCPACK or a DHCPNAK message after employing
- the retransmission algorithm, the client MAY choose to use the
- previously allocated network address and configuration parameters
-
-
-
-Droms [Page 19]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- for the remainder of the unexpired lease. This corresponds to
- moving to BOUND state in the client state transition diagram shown
- in figure 5.
-
- 4. The client may choose to relinquish its lease on a network
- address by sending a DHCPRELEASE message to the server. The
- client identifies the lease to be released with its
- 'client identifier', or 'chaddr' and network address in the
- DHCPRELEASE message.
-
- Note that in this case, where the client retains its network
- address locally, the client will not normally relinquish its
- lease during a graceful shutdown. Only in the case where the
- client explicitly needs to relinquish its lease, e.g., the client
- is about to be moved to a different subnet, will the client send
- a DHCPRELEASE message.
-
-3.3 Interpretation and representation of time values
-
- A client acquires a lease for a network address for a fixed period of
- time (which may be infinite). Throughout the protocol, times are to
- be represented in units of seconds. The time value of 0xffffffff is
- reserved to represent "infinity".
-
- As clients and servers may not have synchronized clocks, times are
- represented in DHCP messages as relative times, to be interpreted
- with respect to the client's local clock. Representing relative
- times in units of seconds in an unsigned 32 bit word gives a range of
- relative times from 0 to approximately 100 years, which is sufficient
- for the relative times to be measured using DHCP.
-
- The algorithm for lease duration interpretation given in the previous
- paragraph assumes that client and server clocks are stable relative
- to each other. If there is drift between the two clocks, the server
- may consider the lease expired before the client does. To
- compensate, the server may return a shorter lease duration to the
- client than the server commits to its local database of client
- information.
-
-3.4 Obtaining parameters with externally configured network address
-
- If a client has obtained a network address through some other means
- (e.g., manual configuration), it may use a DHCPINFORM request message
- to obtain other local configuration parameters. Servers receiving a
- DHCPINFORM message construct a DHCPACK message with any local
- configuration parameters appropriate for the client without:
- allocating a new address, checking for an existing binding, filling
- in 'yiaddr' or including lease time parameters. The servers SHOULD
-
-
-
-Droms [Page 20]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- unicast the DHCPACK reply to the address given in the 'ciaddr' field
- of the DHCPINFORM message.
-
- The server SHOULD check the network address in a DHCPINFORM message
- for consistency, but MUST NOT check for an existing lease. The
- server forms a DHCPACK message containing the configuration
- parameters for the requesting client and sends the DHCPACK message
- directly to the client.
-
-3.5 Client parameters in DHCP
-
- Not all clients require initialization of all parameters listed in
- Appendix A. Two techniques are used to reduce the number of
- parameters transmitted from the server to the client. First, most of
- the parameters have defaults defined in the Host Requirements RFCs;
- if the client receives no parameters from the server that override
- the defaults, a client uses those default values. Second, in its
- initial DHCPDISCOVER or DHCPREQUEST message, a client may provide the
- server with a list of specific parameters the client is interested
- in. If the client includes a list of parameters in a DHCPDISCOVER
- message, it MUST include that list in any subsequent DHCPREQUEST
- messages.
-
- The client SHOULD include the 'maximum DHCP message size' option to
- let the server know how large the server may make its DHCP messages.
- The parameters returned to a client may still exceed the space
- allocated to options in a DHCP message. In this case, two additional
- options flags (which must appear in the 'options' field of the
- message) indicate that the 'file' and 'sname' fields are to be used
- for options.
-
- The client can inform the server which configuration parameters the
- client is interested in by including the 'parameter request list'
- option. The data portion of this option explicitly lists the options
- requested by tag number.
-
- In addition, the client may suggest values for the network address
- and lease time in the DHCPDISCOVER message. The client may include
- the 'requested IP address' option to suggest that a particular IP
- address be assigned, and may include the 'IP address lease time'
- option to suggest the lease time it would like. Other options
- representing "hints" at configuration parameters are allowed in a
- DHCPDISCOVER or DHCPREQUEST message. However, additional options may
- be ignored by servers, and multiple servers may, therefore, not
- return identical values for some options. The 'requested IP address'
- option is to be filled in only in a DHCPREQUEST message when the
- client is verifying network parameters obtained previously. The
- client fills in the 'ciaddr' field only when correctly configured
-
-
-
-Droms [Page 21]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- with an IP address in BOUND, RENEWING or REBINDING state.
-
- If a server receives a DHCPREQUEST message with an invalid 'requested
- IP address', the server SHOULD respond to the client with a DHCPNAK
- message and may choose to report the problem to the system
- administrator. The server may include an error message in the
- 'message' option.
-
-3.6 Use of DHCP in clients with multiple interfaces
-
- A client with multiple network interfaces must use DHCP through each
- interface independently to obtain configuration information
- parameters for those separate interfaces.
-
-3.7 When clients should use DHCP
-
- A client SHOULD use DHCP to reacquire or verify its IP address and
- network parameters whenever the local network parameters may have
- changed; e.g., at system boot time or after a disconnection from the
- local network, as the local network configuration may change without
- the client's or user's knowledge.
-
- If a client has knowledge of a previous network address and is unable
- to contact a local DHCP server, the client may continue to use the
- previous network address until the lease for that address expires.
- If the lease expires before the client can contact a DHCP server, the
- client must immediately discontinue use of the previous network
- address and may inform local users of the problem.
-
-4. Specification of the DHCP client-server protocol
-
- In this section, we assume that a DHCP server has a block of network
- addresses from which it can satisfy requests for new addresses. Each
- server also maintains a database of allocated addresses and leases in
- local permanent storage.
-
-4.1 Constructing and sending DHCP messages
-
- DHCP clients and servers both construct DHCP messages by filling in
- fields in the fixed format section of the message and appending
- tagged data items in the variable length option area. The options
- area includes first a four-octet 'magic cookie' (which was described
- in section 3), followed by the options. The last option must always
- be the 'end' option.
-
- DHCP uses UDP as its transport protocol. DHCP messages from a client
- to a server are sent to the 'DHCP server' port (67), and DHCP
- messages from a server to a client are sent to the 'DHCP client' port
-
-
-
-Droms [Page 22]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- (68). A server with multiple network address (e.g., a multi-homed
- host) MAY use any of its network addresses in outgoing DHCP messages.
-
- The 'server identifier' field is used both to identify a DHCP server
- in a DHCP message and as a destination address from clients to
- servers. A server with multiple network addresses MUST be prepared
- to to accept any of its network addresses as identifying that server
- in a DHCP message. To accommodate potentially incomplete network
- connectivity, a server MUST choose an address as a 'server
- identifier' that, to the best of the server's knowledge, is reachable
- from the client. For example, if the DHCP server and the DHCP client
- are connected to the same subnet (i.e., the 'giaddr' field in the
- message from the client is zero), the server SHOULD select the IP
- address the server is using for communication on that subnet as the
- 'server identifier'. If the server is using multiple IP addresses on
- that subnet, any such address may be used. If the server has
- received a message through a DHCP relay agent, the server SHOULD
- choose an address from the interface on which the message was
- recieved as the 'server identifier' (unless the server has other,
- better information on which to make its choice). DHCP clients MUST
- use the IP address provided in the 'server identifier' option for any
- unicast requests to the DHCP server.
-
- DHCP messages broadcast by a client prior to that client obtaining
- its IP address must have the source address field in the IP header
- set to 0.
-
- If the 'giaddr' field in a DHCP message from a client is non-zero,
- the server sends any return messages to the 'DHCP server' port on the
- BOOTP relay agent whose address appears in 'giaddr'. If the 'giaddr'
- field is zero and the 'ciaddr' field is nonzero, then the server
- unicasts DHCPOFFER and DHCPACK messages to the address in 'ciaddr'.
- If 'giaddr' is zero and 'ciaddr' is zero, and the broadcast bit is
- set, then the server broadcasts DHCPOFFER and DHCPACK messages to
- 0xffffffff. If the broadcast bit is not set and 'giaddr' is zero and
- 'ciaddr' is zero, then the server unicasts DHCPOFFER and DHCPACK
- messages to the client's hardware address and 'yiaddr' address. In
- all cases, when 'giaddr' is zero, the server broadcasts any DHCPNAK
- messages to 0xffffffff.
-
- If the options in a DHCP message extend into the 'sname' and 'file'
- fields, the 'option overload' option MUST appear in the 'options'
- field, with value 1, 2 or 3, as specified in RFC 1533. If the
- 'option overload' option is present in the 'options' field, the
- options in the 'options' field MUST be terminated by an 'end' option,
- and MAY contain one or more 'pad' options to fill the options field.
- The options in the 'sname' and 'file' fields (if in use as indicated
- by the 'options overload' option) MUST begin with the first octet of
-
-
-
-Droms [Page 23]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- the field, MUST be terminated by an 'end' option, and MUST be
- followed by 'pad' options to fill the remainder of the field. Any
- individual option in the 'options', 'sname' and 'file' fields MUST be
- entirely contained in that field. The options in the 'options' field
- MUST be interpreted first, so that any 'option overload' options may
- be interpreted. The 'file' field MUST be interpreted next (if the
- 'option overload' option indicates that the 'file' field contains
- DHCP options), followed by the 'sname' field.
-
- The values to be passed in an 'option' tag may be too long to fit in
- the 255 octets available to a single option (e.g., a list of routers
- in a 'router' option [21]). Options may appear only once, unless
- otherwise specified in the options document. The client concatenates
- the values of multiple instances of the same option into a single
- parameter list for configuration.
-
- DHCP clients are responsible for all message retransmission. The
- client MUST adopt a retransmission strategy that incorporates a
- randomized exponential backoff algorithm to determine the delay
- between retransmissions. The delay between retransmissions SHOULD be
- chosen to allow sufficient time for replies from the server to be
- delivered based on the characteristics of the internetwork between
- the client and the server. For example, in a 10Mb/sec Ethernet
- internetwork, the delay before the first retransmission SHOULD be 4
- seconds randomized by the value of a uniform random number chosen
- from the range -1 to +1. Clients with clocks that provide resolution
- granularity of less than one second may choose a non-integer
- randomization value. The delay before the next retransmission SHOULD
- be 8 seconds randomized by the value of a uniform number chosen from
- the range -1 to +1. The retransmission delay SHOULD be doubled with
- subsequent retransmissions up to a maximum of 64 seconds. The client
- MAY provide an indication of retransmission attempts to the user as
- an indication of the progress of the configuration process.
-
- The 'xid' field is used by the client to match incoming DHCP messages
- with pending requests. A DHCP client MUST choose 'xid's in such a
- way as to minimize the chance of using an 'xid' identical to one used
- by another client. For example, a client may choose a different,
- random initial 'xid' each time the client is rebooted, and
- subsequently use sequential 'xid's until the next reboot. Selecting
- a new 'xid' for each retransmission is an implementation decision. A
- client may choose to reuse the same 'xid' or select a new 'xid' for
- each retransmitted message.
-
- Normally, DHCP servers and BOOTP relay agents attempt to deliver
- DHCPOFFER, DHCPACK and DHCPNAK messages directly to the client using
- unicast delivery. The IP destination address (in the IP header) is
- set to the DHCP 'yiaddr' address and the link-layer destination
-
-
-
-Droms [Page 24]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- address is set to the DHCP 'chaddr' address. Unfortunately, some
- client implementations are unable to receive such unicast IP
- datagrams until the implementation has been configured with a valid
- IP address (leading to a deadlock in which the client's IP address
- cannot be delivered until the client has been configured with an IP
- address).
-
- A client that cannot receive unicast IP datagrams until its protocol
- software has been configured with an IP address SHOULD set the
- BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
- DHCPREQUEST messages that client sends. The BROADCAST bit will
- provide a hint to the DHCP server and BOOTP relay agent to broadcast
- any messages to the client on the client's subnet. A client that can
- receive unicast IP datagrams before its protocol software has been
- configured SHOULD clear the BROADCAST bit to 0. The BOOTP
- clarifications document discusses the ramifications of the use of the
- BROADCAST bit [21].
-
- A server or relay agent sending or relaying a DHCP message directly
- to a DHCP client (i.e., not to a relay agent specified in the
- 'giaddr' field) SHOULD examine the BROADCAST bit in the 'flags'
- field. If this bit is set to 1, the DHCP message SHOULD be sent as
- an IP broadcast using an IP broadcast address (preferably 0xffffffff)
- as the IP destination address and the link-layer broadcast address as
- the link-layer destination address. If the BROADCAST bit is cleared
- to 0, the message SHOULD be sent as an IP unicast to the IP address
- specified in the 'yiaddr' field and the link-layer address specified
- in the 'chaddr' field. If unicasting is not possible, the message
- MAY be sent as an IP broadcast using an IP broadcast address
- (preferably 0xffffffff) as the IP destination address and the link-
- layer broadcast address as the link-layer destination address.
-
-4.2 DHCP server administrative controls
-
- DHCP servers are not required to respond to every DHCPDISCOVER and
- DHCPREQUEST message they receive. For example, a network
- administrator, to retain stringent control over the clients attached
- to the network, may choose to configure DHCP servers to respond only
- to clients that have been previously registered through some external
- mechanism. The DHCP specification describes only the interactions
- between clients and servers when the clients and servers choose to
- interact; it is beyond the scope of the DHCP specification to
- describe all of the administrative controls that system
- administrators might want to use. Specific DHCP server
- implementations may incorporate any controls or policies desired by a
- network administrator.
-
- In some environments, a DHCP server will have to consider the values
-
-
-
-Droms [Page 25]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- of the vendor class options included in DHCPDISCOVER or DHCPREQUEST
- messages when determining the correct parameters for a particular
- client.
-
- A DHCP server needs to use some unique identifier to associate a
- client with its lease. The client MAY choose to explicitly provide
- the identifier through the 'client identifier' option. If the client
- supplies a 'client identifier', the client MUST use the same 'client
- identifier' in all subsequent messages, and the server MUST use that
- identifier to identify the client. If the client does not provide a
- 'client identifier' option, the server MUST use the contents of the
- 'chaddr' field to identify the client. It is crucial for a DHCP
- client to use an identifier unique within the subnet to which the
- client is attached in the 'client identifier' option. Use of
- 'chaddr' as the client's unique identifier may cause unexpected
- results, as that identifier may be associated with a hardware
- interface that could be moved to a new client. Some sites may choose
- to use a manufacturer's serial number as the 'client identifier', to
- avoid unexpected changes in a clients network address due to transfer
- of hardware interfaces among computers. Sites may also choose to use
- a DNS name as the 'client identifier', causing address leases to be
- associated with the DNS name rather than a specific hardware box.
-
- DHCP clients are free to use any strategy in selecting a DHCP server
- among those from which the client receives a DHCPOFFER message. The
- client implementation of DHCP SHOULD provide a mechanism for the user
- to select directly the 'vendor class identifier' values.
-
-4.3 DHCP server behavior
-
- A DHCP server processes incoming DHCP messages from a client based on
- the current state of the binding for that client. A DHCP server can
- receive the following messages from a client:
-
- o DHCPDISCOVER
-
- o DHCPREQUEST
-
- o DHCPDECLINE
-
- o DHCPRELEASE
-
- o DHCPINFORM
-
- Table 3 gives the use of the fields and options in a DHCP message by
- a server. The remainder of this section describes the action of the
- DHCP server for each possible incoming message.
-
-
-
-
-Droms [Page 26]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
-4.3.1 DHCPDISCOVER message
-
- When a server receives a DHCPDISCOVER message from a client, the
- server chooses a network address for the requesting client. If no
- address is available, the server may choose to report the problem to
- the system administrator. If an address is available, the new address
- SHOULD be chosen as follows:
-
- o The client's current address as recorded in the client's current
- binding, ELSE
-
- o The client's previous address as recorded in the client's (now
- expired or released) binding, if that address is in the server's
- pool of available addresses and not already allocated, ELSE
-
- o The address requested in the 'Requested IP Address' option, if that
- address is valid and not already allocated, ELSE
-
- o A new address allocated from the server's pool of available
- addresses; the address is selected based on the subnet from which
- the message was received (if 'giaddr' is 0) or on the address of
- the relay agent that forwarded the message ('giaddr' when not 0).
-
- As described in section 4.2, a server MAY, for administrative
- reasons, assign an address other than the one requested, or may
- refuse to allocate an address to a particular client even though free
- addresses are available.
-
- Note that, in some network architectures (e.g., internets with more
- than one IP subnet assigned to a physical network segment), it may be
- the case that the DHCP client should be assigned an address from a
- different subnet than the address recorded in 'giaddr'. Thus, DHCP
- does not require that the client be assigned as address from the
- subnet in 'giaddr'. A server is free to choose some other subnet,
- and it is beyond the scope of the DHCP specification to describe ways
- in which the assigned IP address might be chosen.
-
- While not required for correct operation of DHCP, the server SHOULD
- NOT reuse the selected network address before the client responds to
- the server's DHCPOFFER message. The server may choose to record the
- address as offered to the client.
-
- The server must also choose an expiration time for the lease, as
- follows:
-
- o IF the client has not requested a specific lease in the
- DHCPDISCOVER message and the client already has an assigned network
- address, the server returns the lease expiration time previously
-
-
-
-Droms [Page 27]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- assigned to that address (note that the client must explicitly
- request a specific lease to extend the expiration time on a
- previously assigned address), ELSE
-
- o IF the client has not requested a specific lease in the
- DHCPDISCOVER message and the client does not have an assigned
- network address, the server assigns a locally configured default
- lease time, ELSE
-
- o IF the client has requested a specific lease in the DHCPDISCOVER
- message (regardless of whether the client has an assigned network
- address), the server may choose either to return the requested
- lease (if the lease is acceptable to local policy) or select
- another lease.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Droms [Page 28]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- Field DHCPOFFER DHCPACK DHCPNAK
- ----- --------- ------- -------
- 'op' BOOTREPLY BOOTREPLY BOOTREPLY
- 'htype' (From "Assigned Numbers" RFC)
- 'hlen' (Hardware address length in octets)
- 'hops' 0 0 0
- 'xid' 'xid' from client 'xid' from client 'xid' from client
- DHCPDISCOVER DHCPREQUEST DHCPREQUEST
- message message message
- 'secs' 0 0 0
- 'ciaddr' 0 'ciaddr' from 0
- DHCPREQUEST or 0
- 'yiaddr' IP address offered IP address 0
- to client assigned to client
- 'siaddr' IP address of next IP address of next 0
- bootstrap server bootstrap server
- 'flags' 'flags' from 'flags' from 'flags' from
- client DHCPDISCOVER client DHCPREQUEST client DHCPREQUEST
- message message message
- 'giaddr' 'giaddr' from 'giaddr' from 'giaddr' from
- client DHCPDISCOVER client DHCPREQUEST client DHCPREQUEST
- message message message
- 'chaddr' 'chaddr' from 'chaddr' from 'chaddr' from
- client DHCPDISCOVER client DHCPREQUEST client DHCPREQUEST
- message message message
- 'sname' Server host name Server host name (unused)
- or options or options
- 'file' Client boot file Client boot file (unused)
- name or options name or options
- 'options' options options
-
- Option DHCPOFFER DHCPACK DHCPNAK
- ------ --------- ------- -------
- Requested IP address MUST NOT MUST NOT MUST NOT
- IP address lease time MUST MUST (DHCPREQUEST) MUST NOT
- MUST NOT (DHCPINFORM)
- Use 'file'/'sname' fields MAY MAY MUST NOT
- DHCP message type DHCPOFFER DHCPACK DHCPNAK
- Parameter request list MUST NOT MUST NOT MUST NOT
- Message SHOULD SHOULD SHOULD
- Client identifier MUST NOT MUST NOT MAY
- Vendor class identifier MAY MAY MAY
- Server identifier MUST MUST MUST
- Maximum message size MUST NOT MUST NOT MUST NOT
- All others MAY MAY MUST NOT
-
- Table 3: Fields and options used by DHCP servers
-
-
-
-
-Droms [Page 29]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- Once the network address and lease have been determined, the server
- constructs a DHCPOFFER message with the offered configuration
- parameters. It is important for all DHCP servers to return the same
- parameters (with the possible exception of a newly allocated network
- address) to ensure predictable client behavior regardless of which
- server the client selects. The configuration parameters MUST be
- selected by applying the following rules in the order given below.
- The network administrator is responsible for configuring multiple
- DHCP servers to ensure uniform responses from those servers. The
- server MUST return to the client:
-
- o The client's network address, as determined by the rules given
- earlier in this section,
-
- o The expiration time for the client's lease, as determined by the
- rules given earlier in this section,
-
- o Parameters requested by the client, according to the following
- rules:
-
- -- IF the server has been explicitly configured with a default
- value for the parameter, the server MUST include that value
- in an appropriate option in the 'option' field, ELSE
-
- -- IF the server recognizes the parameter as a parameter
- defined in the Host Requirements Document, the server MUST
- include the default value for that parameter as given in the
- Host Requirements Document in an appropriate option in the
- 'option' field, ELSE
-
- -- The server MUST NOT return a value for that parameter,
-
- The server MUST supply as many of the requested parameters as
- possible and MUST omit any parameters it cannot provide. The
- server MUST include each requested parameter only once unless
- explicitly allowed in the DHCP Options and BOOTP Vendor
- Extensions document.
-
- o Any parameters from the existing binding that differ from the Host
- Requirements Document defaults,
-
- o Any parameters specific to this client (as identified by
- the contents of 'chaddr' or 'client identifier' in the DHCPDISCOVER
- or DHCPREQUEST message), e.g., as configured by the network
- administrator,
-
-
-
-
-
-
-Droms [Page 30]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- o Any parameters specific to this client's class (as identified
- by the contents of the 'vendor class identifier'
- option in the DHCPDISCOVER or DHCPREQUEST message),
- e.g., as configured by the network administrator; the parameters
- MUST be identified by an exact match between the client's vendor
- class identifiers and the client's classes identified in the
- server,
-
- o Parameters with non-default values on the client's subnet.
-
- The server MAY choose to return the 'vendor class identifier' used to
- determine the parameters in the DHCPOFFER message to assist the
- client in selecting which DHCPOFFER to accept. The server inserts
- the 'xid' field from the DHCPDISCOVER message into the 'xid' field of
- the DHCPOFFER message and sends the DHCPOFFER message to the
- requesting client.
-
-4.3.2 DHCPREQUEST message
-
- A DHCPREQUEST message may come from a client responding to a
- DHCPOFFER message from a server, from a client verifying a previously
- allocated IP address or from a client extending the lease on a
- network address. If the DHCPREQUEST message contains a 'server
- identifier' option, the message is in response to a DHCPOFFER
- message. Otherwise, the message is a request to verify or extend an
- existing lease. If the client uses a 'client identifier' in a
- DHCPREQUEST message, it MUST use that same 'client identifier' in all
- subsequent messages. If the client included a list of requested
- parameters in a DHCPDISCOVER message, it MUST include that list in
- all subsequent messages.
-
- Any configuration parameters in the DHCPACK message SHOULD NOT
- conflict with those in the earlier DHCPOFFER message to which the
- client is responding. The client SHOULD use the parameters in the
- DHCPACK message for configuration.
-
- Clients send DHCPREQUEST messages as follows:
-
- o DHCPREQUEST generated during SELECTING state:
-
- Client inserts the address of the selected server in 'server
- identifier', 'ciaddr' MUST be zero, 'requested IP address' MUST be
- filled in with the yiaddr value from the chosen DHCPOFFER.
-
- Note that the client may choose to collect several DHCPOFFER
- messages and select the "best" offer. The client indicates its
- selection by identifying the offering server in the DHCPREQUEST
- message. If the client receives no acceptable offers, the client
-
-
-
-Droms [Page 31]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- may choose to try another DHCPDISCOVER message. Therefore, the
- servers may not receive a specific DHCPREQUEST from which they can
- decide whether or not the client has accepted the offer. Because
- the servers have not committed any network address assignments on
- the basis of a DHCPOFFER, servers are free to reuse offered network
- addresses in response to subsequent requests. As an implementation
- detail, servers SHOULD NOT reuse offered addresses and may use an
- implementation-specific timeout mechanism to decide when to reuse
- an offered address.
-
- o DHCPREQUEST generated during INIT-REBOOT state:
-
- 'server identifier' MUST NOT be filled in, 'requested IP address'
- option MUST be filled in with client's notion of its previously
- assigned address. 'ciaddr' MUST be zero. The client is seeking to
- verify a previously allocated, cached configuration. Server SHOULD
- send a DHCPNAK message to the client if the 'requested IP address'
- is incorrect, or is on the wrong network.
-
- Determining whether a client in the INIT-REBOOT state is on the
- correct network is done by examining the contents of 'giaddr', the
- 'requested IP address' option, and a database lookup. If the DHCP
- server detects that the client is on the wrong net (i.e., the
- result of applying the local subnet mask or remote subnet mask (if
- 'giaddr' is not zero) to 'requested IP address' option value
- doesn't match reality), then the server SHOULD send a DHCPNAK
- message to the client.
-
- If the network is correct, then the DHCP server should check if the
- client's notion of its IP address is correct. If not, then the
- server SHOULD send a DHCPNAK message to the client. If the DHCP
- server has no record of this client, then it MUST remain silent,
- and MAY output a warning to the network administrator. This
- behavior is necessary for peaceful coexistence of non-communicating
- DHCP servers on the same wire.
-
- If 'giaddr' is 0x0 in the DHCPREQUEST message, the client is on the
- same subnet as the server. The server MUST broadcast the DHCPNAK
- message to the 0xffffffff broadcast address because the client may
- not have a correct network address or subnet mask, and the client
- may not be answering ARP requests.
-
- If 'giaddr' is set in the DHCPREQUEST message, the client is on a
- different subnet. The server MUST set the broadcast bit in the
- DHCPNAK, so that the relay agent will broadcast the DHCPNAK to the
- client, because the client may not have a correct network address
- or subnet mask, and the client may not be answering ARP requests.
-
-
-
-
-Droms [Page 32]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- o DHCPREQUEST generated during RENEWING state:
-
- 'server identifier' MUST NOT be filled in, 'requested IP address'
- option MUST NOT be filled in, 'ciaddr' MUST be filled in with
- client's IP address. In this situation, the client is completely
- configured, and is trying to extend its lease. This message will be
- unicast, so no relay agents will be involved in its transmission.
- Because 'giaddr' is therefore not filled in, the DHCP server will
- trust the value in 'ciaddr', and use it when replying to the
- client.
-
- A client MAY choose to renew or extend its lease prior to T1. The
- server may choose not to extend the lease (as a policy decision by
- the network administrator), but should return a DHCPACK message
- regardless.
-
- o DHCPREQUEST generated during REBINDING state:
-
- 'server identifier' MUST NOT be filled in, 'requested IP address'
- option MUST NOT be filled in, 'ciaddr' MUST be filled in with
- client's IP address. In this situation, the client is completely
- configured, and is trying to extend its lease. This message MUST be
- broadcast to the 0xffffffff IP broadcast address. The DHCP server
- SHOULD check 'ciaddr' for correctness before replying to the
- DHCPREQUEST.
-
- The DHCPREQUEST from a REBINDING client is intended to accommodate
- sites that have multiple DHCP servers and a mechanism for
- maintaining consistency among leases managed by multiple servers.
- A DHCP server MAY extend a client's lease only if it has local
- administrative authority to do so.
-
-4.3.3 DHCPDECLINE message
-
- If the server receives a DHCPDECLINE message, the client has
- discovered through some other means that the suggested network
- address is already in use. The server MUST mark the network address
- as not available and SHOULD notify the local system administrator of
- a possible configuration problem.
-
-4.3.4 DHCPRELEASE message
-
- Upon receipt of a DHCPRELEASE message, the server marks the network
- address as not allocated. The server SHOULD retain a record of the
- client's initialization parameters for possible reuse in response to
- subsequent requests from the client.
-
-4.3.5 DHCPINFORM message
-
-
-
-Droms [Page 33]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- The server responds to a DHCPINFORM message by sending a DHCPACK
- message directly to the address given in the 'ciaddr' field of the
- DHCPINFORM message. The server MUST NOT send a lease expiration time
- to the client and SHOULD NOT fill in 'yiaddr'. The server includes
- other parameters in the DHCPACK message as defined in section 4.3.1.
-
-4.3.6 Client messages
-
- Table 4 details the differences between messages from clients in
- various states.
-
- ---------------------------------------------------------------------
- | |INIT-REBOOT |SELECTING |RENEWING |REBINDING |
- ---------------------------------------------------------------------
- |broad/unicast |broadcast |broadcast |unicast |broadcast |
- |server-ip |MUST NOT |MUST |MUST NOT |MUST NOT |
- |requested-ip |MUST |MUST |MUST NOT |MUST NOT |
- |ciaddr |zero |zero |IP address |IP address|
- ---------------------------------------------------------------------
-
- Table 4: Client messages from different states
-
-4.4 DHCP client behavior
-
- Figure 5 gives a state-transition diagram for a DHCP client. A
- client can receive the following messages from a server:
-
- o DHCPOFFER
-
- o DHCPACK
-
- o DHCPNAK
-
- The DHCPINFORM message is not shown in figure 5. A client simply
- sends the DHCPINFORM and waits for DHCPACK messages. Once the client
- has selected its parameters, it has completed the configuration
- process.
-
- Table 5 gives the use of the fields and options in a DHCP message by
- a client. The remainder of this section describes the action of the
- DHCP client for each possible incoming message. The description in
- the following section corresponds to the full configuration procedure
- previously described in section 3.1, and the text in the subsequent
- section corresponds to the abbreviated configuration procedure
- described in section 3.2.
-
-
-
-
-
-
-Droms [Page 34]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- -------- -------
-| | +-------------------------->| |<-------------------+
-| INIT- | | +-------------------->| INIT | |
-| REBOOT |DHCPNAK/ +---------->| |<---+ |
-| |Restart| | ------- | |
- -------- | DHCPNAK/ | | |
- | Discard offer | -/Send DHCPDISCOVER |
--/Send DHCPREQUEST | | |
- | | | DHCPACK v | |
- ----------- | (not accept.)/ ----------- | |
-| | | Send DHCPDECLINE | | |
-| REBOOTING | | | | SELECTING |<----+ |
-| | | / | | |DHCPOFFER/ |
- ----------- | / ----------- | |Collect |
- | | / | | | replies |
-DHCPACK/ | / +----------------+ +-------+ |
-Record lease, set| | v Select offer/ |
-timers T1, T2 ------------ send DHCPREQUEST | |
- | +----->| | DHCPNAK, Lease expired/ |
- | | | REQUESTING | Halt network |
- DHCPOFFER/ | | | |
- Discard ------------ | |
- | | | | ----------- |
- | +--------+ DHCPACK/ | | |
- | Record lease, set -----| REBINDING | |
- | timers T1, T2 / | | |
- | | DHCPACK/ ----------- |
- | v Record lease, set ^ |
- +----------------> ------- /timers T1,T2 | |
- +----->| |<---+ | |
- | | BOUND |<---+ | |
- DHCPOFFER, DHCPACK, | | | T2 expires/ DHCPNAK/
- DHCPNAK/Discard ------- | Broadcast Halt network
- | | | | DHCPREQUEST |
- +-------+ | DHCPACK/ | |
- T1 expires/ Record lease, set | |
- Send DHCPREQUEST timers T1, T2 | |
- to leasing server | | |
- | ---------- | |
- | | |------------+ |
- +->| RENEWING | |
- | |----------------------------+
- ----------
- Figure 5: State-transition diagram for DHCP clients
-
-
-
-
-
-
-
-Droms [Page 35]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
-4.4.1 Initialization and allocation of network address
-
- The client begins in INIT state and forms a DHCPDISCOVER message.
- The client SHOULD wait a random time between one and ten seconds to
- desynchronize the use of DHCP at startup. The client sets 'ciaddr'
- to 0x00000000. The client MAY request specific parameters by
- including the 'parameter request list' option. The client MAY
- suggest a network address and/or lease time by including the
- 'requested IP address' and 'IP address lease time' options. The
- client MUST include its hardware address in the 'chaddr' field, if
- necessary for delivery of DHCP reply messages. The client MAY
- include a different unique identifier in the 'client identifier'
- option, as discussed in section 4.2. If the client included a list
- of requested parameters in a DHCPDISCOVER message, it MUST include
- that list in all subsequent messages.
-
- The client generates and records a random transaction identifier and
- inserts that identifier into the 'xid' field. The client records its
- own local time for later use in computing the lease expiration. The
- client then broadcasts the DHCPDISCOVER on the local hardware
- broadcast address to the 0xffffffff IP broadcast address and 'DHCP
- server' UDP port.
-
- If the 'xid' of an arriving DHCPOFFER message does not match the
- 'xid' of the most recent DHCPDISCOVER message, the DHCPOFFER message
- must be silently discarded. Any arriving DHCPACK messages must be
- silently discarded.
-
- The client collects DHCPOFFER messages over a period of time, selects
- one DHCPOFFER message from the (possibly many) incoming DHCPOFFER
- messages (e.g., the first DHCPOFFER message or the DHCPOFFER message
- from the previously used server) and extracts the server address from
- the 'server identifier' option in the DHCPOFFER message. The time
- over which the client collects messages and the mechanism used to
- select one DHCPOFFER are implementation dependent.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Droms [Page 36]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- Field DHCPDISCOVER DHCPREQUEST DHCPDECLINE,
- DHCPINFORM DHCPRELEASE
- ----- ------------ ----------- -----------
- 'op' BOOTREQUEST BOOTREQUEST BOOTREQUEST
- 'htype' (From "Assigned Numbers" RFC)
- 'hlen' (Hardware address length in octets)
- 'hops' 0 0 0
- 'xid' selected by client 'xid' from server selected by
- DHCPOFFER message client
- 'secs' 0 or seconds since 0 or seconds since 0
- DHCP process started DHCP process started
- 'flags' Set 'BROADCAST' Set 'BROADCAST' 0
- flag if client flag if client
- requires broadcast requires broadcast
- reply reply
- 'ciaddr' 0 (DHCPDISCOVER) 0 or client's 0 (DHCPDECLINE)
- client's network address client's network
- network address (BOUND/RENEW/REBIND) address
- (DHCPINFORM) (DHCPRELEASE)
- 'yiaddr' 0 0 0
- 'siaddr' 0 0 0
- 'giaddr' 0 0 0
- 'chaddr' client's hardware client's hardware client's hardware
- address address address
- 'sname' options, if options, if (unused)
- indicated in indicated in
- 'sname/file' 'sname/file'
- option; otherwise option; otherwise
- unused unused
- 'file' options, if options, if (unused)
- indicated in indicated in
- 'sname/file' 'sname/file'
- option; otherwise option; otherwise
- unused unused
- 'options' options options (unused)
-
- Option DHCPDISCOVER DHCPREQUEST DHCPDECLINE,
- DHCPINFORM DHCPRELEASE
- ------ ------------ ----------- -----------
- Requested IP address MAY MUST (in MUST
- (DISCOVER) SELECTING or (DHCPDECLINE),
- MUST NOT INIT-REBOOT) MUST NOT
- (INFORM) MUST NOT (in (DHCPRELEASE)
- BOUND or
- RENEWING)
- IP address lease time MAY MAY MUST NOT
- (DISCOVER)
- MUST NOT
-
-
-
-Droms [Page 37]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- (INFORM)
- Use 'file'/'sname' fields MAY MAY MAY
- DHCP message type DHCPDISCOVER/ DHCPREQUEST DHCPDECLINE/
- DHCPINFORM DHCPRELEASE
- Client identifier MAY MAY MAY
- Vendor class identifier MAY MAY MUST NOT
- Server identifier MUST NOT MUST (after MUST
- SELECTING)
- MUST NOT (after
- INIT-REBOOT,
- BOUND, RENEWING
- or REBINDING)
- Parameter request list MAY MAY MUST NOT
- Maximum message size MAY MAY MUST NOT
- Message SHOULD NOT SHOULD NOT SHOULD
- Site-specific MAY MAY MUST NOT
- All others MAY MAY MUST NOT
-
- Table 5: Fields and options used by DHCP clients
-
- If the parameters are acceptable, the client records the address of
- the server that supplied the parameters from the 'server identifier'
- field and sends that address in the 'server identifier' field of a
- DHCPREQUEST broadcast message. Once the DHCPACK message from the
- server arrives, the client is initialized and moves to BOUND state.
- The DHCPREQUEST message contains the same 'xid' as the DHCPOFFER
- message. The client records the lease expiration time as the sum of
- the time at which the original request was sent and the duration of
- the lease from the DHCPACK message. The client SHOULD perform a
- check on the suggested address to ensure that the address is not
- already in use. For example, if the client is on a network that
- supports ARP, the client may issue an ARP request for the suggested
- request. When broadcasting an ARP request for the suggested address,
- the client must fill in its own hardware address as the sender's
- hardware address, and 0 as the sender's IP address, to avoid
- confusing ARP caches in other hosts on the same subnet. If the
- network address appears to be in use, the client MUST send a
- DHCPDECLINE message to the server. The client SHOULD broadcast an ARP
- reply to announce the client's new IP address and clear any outdated
- ARP cache entries in hosts on the client's subnet.
-
-4.4.2 Initialization with known network address
-
- The client begins in INIT-REBOOT state and sends a DHCPREQUEST
- message. The client MUST insert its known network address as a
- 'requested IP address' option in the DHCPREQUEST message. The client
- may request specific configuration parameters by including the
- 'parameter request list' option. The client generates and records a
-
-
-
-Droms [Page 38]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- random transaction identifier and inserts that identifier into the
- 'xid' field. The client records its own local time for later use in
- computing the lease expiration. The client MUST NOT include a
- 'server identifier' in the DHCPREQUEST message. The client then
- broadcasts the DHCPREQUEST on the local hardware broadcast address to
- the 'DHCP server' UDP port.
-
- Once a DHCPACK message with an 'xid' field matching that in the
- client's DHCPREQUEST message arrives from any server, the client is
- initialized and moves to BOUND state. The client records the lease
- expiration time as the sum of the time at which the DHCPREQUEST
- message was sent and the duration of the lease from the DHCPACK
- message.
-
-4.4.3 Initialization with an externally assigned network address
-
- The client sends a DHCPINFORM message. The client may request
- specific configuration parameters by including the 'parameter request
- list' option. The client generates and records a random transaction
- identifier and inserts that identifier into the 'xid' field. The
- client places its own network address in the 'ciaddr' field. The
- client SHOULD NOT request lease time parameters.
-
- The client then unicasts the DHCPINFORM to the DHCP server if it
- knows the server's address, otherwise it broadcasts the message to
- the limited (all 1s) broadcast address. DHCPINFORM messages MUST be
- directed to the 'DHCP server' UDP port.
-
- Once a DHCPACK message with an 'xid' field matching that in the
- client's DHCPINFORM message arrives from any server, the client is
- initialized.
-
- If the client does not receive a DHCPACK within a reasonable period
- of time (60 seconds or 4 tries if using timeout suggested in section
- 4.1), then it SHOULD display a message informing the user of the
- problem, and then SHOULD begin network processing using suitable
- defaults as per Appendix A.
-
-4.4.4 Use of broadcast and unicast
-
- The DHCP client broadcasts DHCPDISCOVER, DHCPREQUEST and DHCPINFORM
- messages, unless the client knows the address of a DHCP server. The
- client unicasts DHCPRELEASE messages to the server. Because the
- client is declining the use of the IP address supplied by the server,
- the client broadcasts DHCPDECLINE messages.
-
- When the DHCP client knows the address of a DHCP server, in either
- INIT or REBOOTING state, the client may use that address in the
-
-
-
-Droms [Page 39]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- DHCPDISCOVER or DHCPREQUEST rather than the IP broadcast address.
- The client may also use unicast to send DHCPINFORM messages to a
- known DHCP server. If the client receives no response to DHCP
- messages sent to the IP address of a known DHCP server, the DHCP
- client reverts to using the IP broadcast address.
-
-4.4.5 Reacquisition and expiration
-
- The client maintains two times, T1 and T2, that specify the times at
- which the client tries to extend its lease on its network address.
- T1 is the time at which the client enters the RENEWING state and
- attempts to contact the server that originally issued the client's
- network address. T2 is the time at which the client enters the
- REBINDING state and attempts to contact any server. T1 MUST be
- earlier than T2, which, in turn, MUST be earlier than the time at
- which the client's lease will expire.
-
- To avoid the need for synchronized clocks, T1 and T2 are expressed in
- options as relative times [2].
-
- At time T1 the client moves to RENEWING state and sends (via unicast)
- a DHCPREQUEST message to the server to extend its lease. The client
- sets the 'ciaddr' field in the DHCPREQUEST to its current network
- address. The client records the local time at which the DHCPREQUEST
- message is sent for computation of the lease expiration time. The
- client MUST NOT include a 'server identifier' in the DHCPREQUEST
- message.
-
- Any DHCPACK messages that arrive with an 'xid' that does not match
- the 'xid' of the client's DHCPREQUEST message are silently discarded.
- When the client receives a DHCPACK from the server, the client
- computes the lease expiration time as the sum of the time at which
- the client sent the DHCPREQUEST message and the duration of the lease
- in the DHCPACK message. The client has successfully reacquired its
- network address, returns to BOUND state and may continue network
- processing.
-
- If no DHCPACK arrives before time T2, the client moves to REBINDING
- state and sends (via broadcast) a DHCPREQUEST message to extend its
- lease. The client sets the 'ciaddr' field in the DHCPREQUEST to its
- current network address. The client MUST NOT include a 'server
- identifier' in the DHCPREQUEST message.
-
- Times T1 and T2 are configurable by the server through options. T1
- defaults to (0.5 * duration_of_lease). T2 defaults to (0.875 *
- duration_of_lease). Times T1 and T2 SHOULD be chosen with some
- random "fuzz" around a fixed value, to avoid synchronization of
- client reacquisition.
-
-
-
-Droms [Page 40]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- A client MAY choose to renew or extend its lease prior to T1. The
- server MAY choose to extend the client's lease according to policy
- set by the network administrator. The server SHOULD return T1 and
- T2, and their values SHOULD be adjusted from their original values to
- take account of the time remaining on the lease.
-
- In both RENEWING and REBINDING states, if the client receives no
- response to its DHCPREQUEST message, the client SHOULD wait one-half
- of the remaining time until T2 (in RENEWING state) and one-half of
- the remaining lease time (in REBINDING state), down to a minimum of
- 60 seconds, before retransmitting the DHCPREQUEST message.
-
- If the lease expires before the client receives a DHCPACK, the client
- moves to INIT state, MUST immediately stop any other network
- processing and requests network initialization parameters as if the
- client were uninitialized. If the client then receives a DHCPACK
- allocating that client its previous network address, the client
- SHOULD continue network processing. If the client is given a new
- network address, it MUST NOT continue using the previous network
- address and SHOULD notify the local users of the problem.
-
-4.4.6 DHCPRELEASE
-
- If the client no longer requires use of its assigned network address
- (e.g., the client is gracefully shut down), the client sends a
- DHCPRELEASE message to the server. Note that the correct operation
- of DHCP does not depend on the transmission of DHCPRELEASE messages.
-
-5. Acknowledgments
-
- The author thanks the many (and too numerous to mention!) members of
- the DHC WG for their tireless and ongoing efforts in the development
- of DHCP and this document.
-
-
- The efforts of J Allard, Mike Carney, Dave Lapp, Fred Lien and John
- Mendonca in organizing DHCP interoperability testing sessions are
- gratefully acknowledged.
-
- The development of this document was supported in part by grants from
- the Corporation for National Research Initiatives (CNRI), Bucknell
- University and Sun Microsystems.
-
-
-
-
-
-
-
-
-
-Droms [Page 41]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
-6. References
-
- [1] Acetta, M., "Resource Location Protocol", RFC 887, CMU, December
- 1983.
-
- [2] Alexander, S., and R. Droms, "DHCP Options and BOOTP Vendor
- Extensions", RFC 1533, Lachman Technology, Inc., Bucknell
- University, October 1993.
-
- [3] Braden, R., Editor, "Requirements for Internet Hosts --
- Communication Layers", STD 3, RFC 1122, USC/Information Sciences
- Institute, October 1989.
-
- [4] Braden, R., Editor, "Requirements for Internet Hosts --
- Application and Support, STD 3, RFC 1123, USC/Information
- Sciences Institute, October 1989.
-
- [5] Brownell, D, "Dynamic Reverse Address Resolution Protocol
- (DRARP)", Work in Progress.
-
- [6] Comer, D., and R. Droms, "Uniform Access to Internet Directory
- Services", Proc. of ACM SIGCOMM '90 (Special issue of Computer
- Communications Review), 20(4):50--59, 1990.
-
- [7] Croft, B., and J. Gilmore, "Bootstrap Protocol (BOOTP)", RFC 951,
- Stanford and SUN Microsystems, September 1985.
-
- [8] Deering, S., "ICMP Router Discovery Messages", RFC 1256, Xerox
- PARC, September 1991.
-
- [9] Droms, D., "Interoperation between DHCP and BOOTP", RFC 1534,
- Bucknell University, October 1993.
-
- [10] Finlayson, R., Mann, T., Mogul, J., and M. Theimer, "A Reverse
- Address Resolution Protocol", RFC 903, Stanford, June 1984.
-
- [11] Gray C., and D. Cheriton, "Leases: An Efficient Fault-Tolerant
- Mechanism for Distributed File Cache Consistency", In Proc. of
- the Twelfth ACM Symposium on Operating Systems Design, 1989.
-
- [12] Mockapetris, P., "Domain Names -- Concepts and Facilities", STD
- 13, RFC 1034, USC/Information Sciences Institute, November 1987.
-
- [13] Mockapetris, P., "Domain Names -- Implementation and
- Specification", STD 13, RFC 1035, USC/Information Sciences
- Institute, November 1987.
-
-
-
-
-
-Droms [Page 42]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
- [14] Mogul J., and S. Deering, "Path MTU Discovery", RFC 1191,
- November 1990.
-
- [15] Morgan, R., "Dynamic IP Address Assignment for Ethernet Attached
- Hosts", Work in Progress.
-
- [16] Postel, J., "Internet Control Message Protocol", STD 5, RFC 792,
- USC/Information Sciences Institute, September 1981.
-
- [17] Reynolds, J., "BOOTP Vendor Information Extensions", RFC 1497,
- USC/Information Sciences Institute, August 1993.
-
- [18] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1340,
- USC/Information Sciences Institute, July 1992.
-
- [19] Jeffrey Schiller and Mark Rosenstein. A Protocol for the Dynamic
- Assignment of IP Addresses for use on an Ethernet. (Available
- from the Athena Project, MIT), 1989.
-
- [20] Sollins, K., "The TFTP Protocol (Revision 2)", RFC 783, NIC,
- June 1981.
-
- [21] Wimer, W., "Clarifications and Extensions for the Bootstrap
- Protocol", RFC 1542, Carnegie Mellon University, October 1993.
-
-7. Security Considerations
-
- DHCP is built directly on UDP and IP which are as yet inherently
- insecure. Furthermore, DHCP is generally intended to make
- maintenance of remote and/or diskless hosts easier. While perhaps
- not impossible, configuring such hosts with passwords or keys may be
- difficult and inconvenient. Therefore, DHCP in its current form is
- quite insecure.
-
- Unauthorized DHCP servers may be easily set up. Such servers can
- then send false and potentially disruptive information to clients
- such as incorrect or duplicate IP addresses, incorrect routing
- information (including spoof routers, etc.), incorrect domain
- nameserver addresses (such as spoof nameservers), and so on.
- Clearly, once this seed information is in place, an attacker can
- further compromise affected systems.
-
- Malicious DHCP clients could masquerade as legitimate clients and
- retrieve information intended for those legitimate clients. Where
- dynamic allocation of resources is used, a malicious client could
- claim all resources for itself, thereby denying resources to
- legitimate clients.
-
-
-
-
-Droms [Page 43]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
-8. Author's Address
-
- Ralph Droms
- Computer Science Department
- 323 Dana Engineering
- Bucknell University
- Lewisburg, PA 17837
-
- Phone: (717) 524-1145
- EMail: droms@bucknell.edu
-
- This document will expire on May 30, 1996.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Droms [Page 44]
-
-DRAFT Dynamic Host Configuration Protocol December 1996
-
-
-A. Host Configuration Parameters
-
- IP-layer_parameters,_per_host:_
-
- Be a router on/off HRC 3.1
- Non-local source routing on/off HRC 3.3.5
- Policy filters for
- non-local source routing (list) HRC 3.3.5
- Maximum reassembly size integer HRC 3.3.2
- Default TTL integer HRC 3.2.1.7
- PMTU aging timeout integer MTU 6.6
- MTU plateau table (list) MTU 7
- IP-layer_parameters,_per_interface:_
- IP address (address) HRC 3.3.1.6
- Subnet mask (address mask) HRC 3.3.1.6
- MTU integer HRC 3.3.3
- All-subnets-MTU on/off HRC 3.3.3
- Broadcast address flavor 0x00000000/0xffffffff HRC 3.3.6
- Perform mask discovery on/off HRC 3.2.2.9
- Be a mask supplier on/off HRC 3.2.2.9
- Perform router discovery on/off RD 5.1
- Router solicitation address (address) RD 5.1
- Default routers, list of:
- router address (address) HRC 3.3.1.6
- preference level integer HRC 3.3.1.6
- Static routes, list of:
- destination (host/subnet/net) HRC 3.3.1.2
- destination mask (address mask) HRC 3.3.1.2
- type-of-service integer HRC 3.3.1.2
- first-hop router (address) HRC 3.3.1.2
- ignore redirects on/off HRC 3.3.1.2
- PMTU integer MTU 6.6
- perform PMTU discovery on/off MTU 6.6
-
- Link-layer_parameters,_per_interface:_
- Trailers on/off HRC 2.3.1
- ARP cache timeout integer HRC 2.3.2.1
- Ethernet encapsulation (RFC 894/RFC 1042) HRC 2.3.3
-
- TCP_parameters,_per_host:_
- TTL integer HRC 4.2.2.19
- Keep-alive interval integer HRC 4.2.3.6
- Keep-alive data size 0/1 HRC 4.2.3.6
-
-Key:
-
- MTU = Path MTU Discovery (RFC 1191, Proposed Standard)
- RD = Router Discovery (RFC 1256, Proposed Standard)
-
-
-
-Droms [Page 45]
-
diff --git a/doc/draft-ietf-dhc-dhcp-dns-02.txt b/doc/draft-ietf-dhc-dhcp-dns-02.txt
deleted file mode 100644
index b85ed12e..00000000
--- a/doc/draft-ietf-dhc-dhcp-dns-02.txt
+++ /dev/null
@@ -1,356 +0,0 @@
-
-
-Network Working Group Yakov Rekhter
-Internet Draft Cisco Systems
-Expiration Date: April 1997 October 1996
-
-
- Interaction between DHCP and DNS
- draft-ietf-dhc-dhcp-dns-02.txt
-
-
-1. Status of this Memo
-
- This document is an Internet-Draft. Internet-Drafts are working
- documents of the Internet Engineering Task Force (IETF), its areas,
- and its working groups. Note that other groups may also distribute
- working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as ``work in progress.''
-
- To learn the current status of any Internet-Draft, please check the
- ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
- Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
- munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
- ftp.isi.edu (US West Coast).
-
-
-2. Abstract
-
- DHCP provides a powerful mechanism for IP host autoconfiguration.
- However, the autoconfiguration provided by DHCP does not include
- updating DNS, and specifically updating the name to address and
- address to name mappings maintained by DNS.
-
- This document specifies how DHCP clients and servers should use the
- Dynamic DNS Updates mechanism to update the DNS name to address and
- address to name mapping, so that the mappings for DHCP clients would
- be consistent with the IP addresses that the clients acquire via
- DHCP.
-
-
-
-
-
-
-
-
-
-
-
-Yakov Rekhter [Page 1]
-
-
-
-
-
-Internet Draft draft-ietf-dhc-dhcp-dns-02.txt October 1996
-
-
-3. Interaction between DHCP and DNS
-
- DNS [RFC1034, RFC1035] maintains (among other things) the information
- about mapping between hosts' Fully Qualified Domain Names (FQDNs)
- [RFC1594] and IP addresses assigned to the hosts. The information is
- maintained in two types of Resource Records (RRs): A and PTR. The A
- RR contains mapping from a FQDN to an IP address; the PTR RR contains
- mapping from an IP address to a FQDN.
-
- DHCP [RFC1541] provides a mechanism by which a host (a DHCP client)
- could acquire certain configuration information, and specifically its
- IP address(es). However, DHCP does not provide any mechanisms to
- update the DNS RRs that contain the information about mapping between
- the host's FQDN and its IP address(es) (A and PTR RRs). Thus the
- information maintained by DNS for a DHCP client may be incorrect - a
- host (the client) could acquire its address by using DHCP, but the A
- RR for the host's FQDN wouldn't reflect the address that the host
- acquired, and the PTR RR for the acquired address wouldn't reflect
- the host's FQDN.
-
- Dynamic DNS Updates [DynDNS] is a mechanism that enables DNS
- information to be updated DNS over a network.
-
- The Dynamic DNS Update protocol can be used to maintain consistency
- between the information stored in the A and PTR RRs and the actual
- address assignment done via DHCP. When a host with a particular FQDN
- acquires its IP address via DHCP, the A RR associated with the host's
- FQDN would be updated (by using the Dynamic DNS Updates protocol) to
- reflect the new address. Likewise, when an IP address gets assigned
- to a host with a particular FQDN, the PTR RR associated with this
- address would be updated (using the Dynamic DNS Updates protocol) to
- reflect the new FQDN.
-
-
-4. Models of operations
-
- When a DHCP client acquires a new address, both the A RR (for the
- client's FQDN) and the PTR RR (for the acquired address) have to be
- updated. Therefore, we have two separate Dynamic DNS Update
- transactions. Acquiring an address via DHCP involves two entities: a
- DHCP client and a DHCP server. In principle each of these entities
- could perform none, one, or both of the transactions. However, upon
- some introspection one could realize that not all permutations make
- sense. This document covers the possible design permutations:
-
- (1) DHCP client updates the A RR, DHCP server updates the PTR
- RR
-
-
-
-
-Yakov Rekhter [Page 2]
-
-
-
-
-
-Internet Draft draft-ietf-dhc-dhcp-dns-02.txt October 1996
-
-
- (2) DHCP server updates both the A and the PTR RRs
-
- One could observe that the only difference between these two cases is
- whether the FQDN to IP address mapping is updated by a DHCP client or
- by a DHCP server. The IP address to FQDN mapping is updated by a DHCP
- server in both cases.
-
-
-4.1. Client FQDN Option
-
- To update the IP address to FQDN mapping a DHCP server needs to know
- FQDN of the client to which the server leases the address. To allow
- the client to convey its FQDN to the server this document defines a
- new option, called "Client FQDN".
-
- The code for this option is 81. Its minimum length is 4.
-
-
-
- Code Len Flags RCODE1 RCODE2 Domain Name
- +------+------+------+------+------+------+--
- | TBD | n | 0/1 | | | ...
- +------+------+------+------+------+------+--
-
-
-
- The Flags field allows a DHCP client to indicate to a DHCP server
- whether the client wants the server to be responsible for updating
- the FQDN to IP address mapping (if Flags is set to 1), or whether the
- client wants to take this responsibility (if Flags is set to 0).
-
- The RCODE1 and RCODE2 fields are used by a DHCP server to indicate to
- a DHCP client the Response Code from Dynamic DNS Updates.
-
- The Domain Name part of the option carries FQDN of a client.
-
-
-
-4.2. DHCP Client behavior
-
- If a client wants to be responsible for updating the FQDN to IP
- address mapping for the FQDN and address(es) used by the client, then
- the client shall include the Client FQDN option in the DHCPREQUEST
- message originated by the client. The Flags field in the option shall
- be set to 0. Once the client's DHCP configuration is completed (the
- client receives a DHCPACK message, and successfully completed a final
- check on the parameters passed in the message), the client shall
- originate an update for the A RR (associated with the client's FQDN).
-
-
-
-Yakov Rekhter [Page 3]
-
-
-
-
-
-Internet Draft draft-ietf-dhc-dhcp-dns-02.txt October 1996
-
-
- The update shall be originated following the procedures described in
- [DynDNS].
-
-
- If a client does not want to be responsible for updating the FQDN to
- IP address mapping for the FQDN and address(es) used by the client,
- then the client shall include the Client FQDN option in the
- DHCPREQUEST message originated by the client. The Flags field in the
- option shall be set to 1.
-
-
- A client should set the RCODE1 and RCODE2 fields in the Client FQDN
- option to 0 when sending the option.
-
- Whether the client wants to be responsible for updating the FQDN to
- IP address mapping, or whether the client wants to delegate this
- responsibility to a server is a local to the client matter. The
- choice between the two alternatives may be based on a particular
- security model that is used with the Dynamic DNS Update protocol
- (e.g., only a client may have sufficient credentials to perform
- updates to the FQDN to IP address mapping for its FQDN).
-
- If a client releases its address lease prior to the lease expiration
- time, and the client is responsible for updating its A RR(s), the
- client should delete the A RR (following the procedures described in
- [DynDNS]) associated with the leased address before sending DHCP
- RELEASE message.
-
-
-4.3. DHCP Server behavior
-
- When a server receives a DHCPREQUEST message from a client, if the
- message contains the Client FQDN option, and the server replies to
- the message with a DHCPACK message, the server shall originate an
- update for the PTR RR (associated with the address leased to the
- client). The server shall originate the update before the server
- sends the DHCPACK message to the client. The update shall be
- originated following the procedures described in [DynDNS]. The RCODE
- from the update [DynDNS] should be carried to the client in the
- RCODE1 field of the Client FQDN option in the DHCPACK message. The
- RCODE2 field should be set to 0.
-
- In addition, if the Client FQDN option carried in the DHCPREQUEST
- message has its Flags field set to 1, then the server shall originate
- an update for the A RR (associated with the FQDN carried in the
- option). The server shall originate the update before the server
- sends the DHCPACK message to the client. The update shall be
- originated following the procedures described in [DynDNS]. The RCODE
-
-
-
-Yakov Rekhter [Page 4]
-
-
-
-
-
-Internet Draft draft-ietf-dhc-dhcp-dns-02.txt October 1996
-
-
- from the update [DynDNS] should be carried to the client in the
- RCODE2 field of the Client FQDN option in the DHCPACK message.
-
- When a server receives a DHCPREQUEST message from a client, and the
- message contains the Client FQDN option, the server shall ignore the
- value carried in the RCODE1 and RCODE2 fields of the option.
-
- When a DHCP server sends the Client FQDN option to a client in the
- DHCPACK message, the server should copy the Flags and the Domain Name
- fields from the Client FQDN option that the client sent to the server
- in the DHCPREQUEST message.
-
-
- If a server originates updates for both the A and PTR RRs, then the
- order in which the updates are generated is not significant.
-
-
- If a server detects that a lease on an address that the server leases
- to a client expires, the server should delete the PTR RR associated
- with the address. In addition, if the client authorized the server to
- update its A RR, the server should also delete the A RR. The deletion
- should follow the procedures described in [DynDNS].
-
- If a server terminates a lease on an address prior to the lease
- expiration time, the server should delete the PTR RR associated with
- the address. In addition, if the client (that leased the address)
- authorized the server to update its A RR, the server should also
- delete the A RR. The deletion should follow the procedures described
- in [DynDNS].
-
-
-5. Updating other RRs
-
- The procedures described in this document cover updates only to the A
- and PTR RRs. Updating other types of RRs is outside the scope of this
- document.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Yakov Rekhter [Page 5]
-
-
-
-
-
-Internet Draft draft-ietf-dhc-dhcp-dns-02.txt October 1996
-
-
-6. Security Considerations
-
- Security issues are not discussed in this document.
-
-
-7. References
-
- [RFC1034] P. Mockapetris, "Domain names - concepts and facilities",
- RFC1034, 11/01/1987
-
- [RFC1035] P. Mockapetris, "Domain names - implementation and
- specification", RFC1035, 11/01/1987
-
- [RFC1541] R. Droms, "Dynamic Host Configuration Protocol", RFC1541,
- 10/27/1993
-
- [RFC1594] A. Marine, J. Reynolds, G. Malkin, "FYI on Questions and
- Answer Answers to Commonly asked ``New Internet User'' Questions",
- RFC1594, 03/11/1994
-
- [DynDNS] P. Vixie, S. Thomson, Y. Rekhter, J. Bound, "Dynamic Updates
- in the Domain Name System (DNS UPDATE)", draft-ietf-dnsind-dynDNS-
- 09.txt
-
-
-
-8. Acknowledgements
-
- Many thanks to Mark Beyer (Tandem), Jim Bound (DEC), Ralph Droms
- (Bucknell University), Edie Gunter (IBM), Michael Lewis (Chevron),
- and Michael Patton (BBN) for their review and comments.
-
-
-9. Author Information
-
-
- Yakov Rekhter
- cisco Systems, Inc.
- 170 Tasman Dr.
- San Jose, CA 95134
- Phone: (914) 528-0090
- email: yakov@cisco.com
-
-
-
-
-
-
-
-
-
-Yakov Rekhter [Page 6]
-
-
diff --git a/doc/draft-ietf-dhc-new-options-00.txt b/doc/draft-ietf-dhc-new-options-00.txt
deleted file mode 100644
index adf332a5..00000000
--- a/doc/draft-ietf-dhc-new-options-00.txt
+++ /dev/null
@@ -1,110 +0,0 @@
-
-Network Working Group R. Droms
-INTERNET DRAFT Bucknell University
-Obsoletes: February 1996
- Expires August 1996
-
-
- Procedure for Defining New DHCP Options
- <draft-ietf-dhc-new-options-00.txt>
-
-Status of this memo
-
- This document is an Internet-Draft. Internet-Drafts are working
- documents of the Internet Engineering Task Force (IETF), its areas,
- and its working groups. Note that other groups may also distribute
- working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as ``work in progress.''
-
- To learn the current status of any Internet-Draft, please check the
- ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
- Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
- munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
- ftp.isi.edu (US West Coast).
-
-Abstract
-
- The Dynamic Host Configuration Protocol (DHCP) provides a
- framework for passing configuration information to hosts on a TCP/IP
- network. Configuration parameters and other control information are
- carried in tagged data items that are stored in the 'options' field
- of the DHCP message. The data items themselves are also called
- "options."
-
- This document describes the procedure for defining new DHCP options.
- The procedure will guarantee that:
-
- * allocation of new option numbers is coordinated from a single
- authority,
- * new options are reviewed for technical correctness and
- appropriateness, and
- * documentation for new options is complete and published.
-
-
-
-
-
-
-
-Droms [Page 1]
-
-DRAFT Procedure for Defining New DHCP Options February 1996
-
-
-Procedure
-
- The author of a new DHCP option will follow these steps to obtain
- acceptance of the option as a part of the DHCP Internet Standard:
-
- 1. The author devises the new option.
- 2. The author requests a number for the new option from IANA.
- 3. The author documents the new option, using the newly obtained
- option number, as an Internet Draft.
- 4. The author submits the Internet Draft for review through the IETF
- standards process as defined in "Internet Official Protocol
- Standards" (STD 1). The new option will be submitted for eventual
- acceptance as an Internet Standard.
- 5. The new option progresses through the IETF standards process; the
- new option will be reviewed by the Dynamic Host Configuration
- Working Group (if that group still exists), or as an Internet
- Draft not submitted by an IETF working group.
- 6. If the new option fails to gain acceptance as an Internet
- Standard, the assigned option number will be returned to IANA for
- reassignment.
-
-Acceptance and publication
-
- If this procedure is accepted, it will be added to the DHCP options
- specification as an Appendix.
-
-Security Considerations
-
- Security issues are not discussed in this memo.
-
-Author's Address
-
- Ralph Droms
- Computer Science Department
- 323 Dana Engineering
- Bucknell University
- Lewisburg, PA 17837
-
- Phone: (717) 524-1145
- EMail: droms@bucknell.edu
-
-
-
-
-
-
-
-
-
-
-
-Droms [Page 2]
-
diff --git a/doc/draft-ietf-dhc-options-1533update-06.txt b/doc/draft-ietf-dhc-options-1533update-06.txt
deleted file mode 100644
index f62107ae..00000000
--- a/doc/draft-ietf-dhc-options-1533update-06.txt
+++ /dev/null
@@ -1,2127 +0,0 @@
-
-
-Network Working Group S. Alexander
-INTERNET DRAFT Silicon Graphics, Inc.
-Obsoletes: draft-ietf-dhc-options-1533update-05.txt R. Droms
- Bucknell University
- December 1996
- Expires June 1997
-
-
- DHCP Options and BOOTP Vendor Extensions
- <draft-ietf-dhc-options-1533update-06.txt>
-
-Status of this memo
-
- This document is an Internet-Draft. Internet-Drafts are working
- documents of the Internet Engineering Task Force (IETF), its areas,
- and its working groups. Note that other groups may also distribute
- working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as ``work in progress.''
-
- To learn the current status of any Internet-Draft, please check the
- ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
- Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
- munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
- ftp.isi.edu (US West Coast).
-
-Abstract
-
- The Dynamic Host Configuration Protocol (DHCP) [1] provides a
- framework for passing configuration information to hosts on a TCP/IP
- network. Configuration parameters and other control information are
- carried in tagged data items that are stored in the 'options' field
- of the DHCP message. The data items themselves are also called
- "options."
-
- This document specifies the current set of DHCP options. Future
- options will be specified in separate RFCs. The current list of
- valid options is also available in
- ftp://ftp.isi.edu/in-notes/iana/assignments [22].
-
- All of the vendor information extensions defined in RFC 1497 [2] may
- be used as DHCP options. The definitions given in RFC 1497 are
- included in this document, which supersedes RFC 1497. All of the
- DHCP options defined in this document, except for those specific to
- DHCP as defined in section 9, may be used as BOOTP vendor information
-
-
-
-Alexander & Droms [Page 1]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
- extensions.
-
-Table of Contents
-
- 1. Introduction .............................................. 2
- 2. BOOTP Extension/DHCP Option Field Format .................. 4
- 3. RFC 1497 Vendor Extensions ................................ 5
- 4. IP Layer Parameters per Host .............................. 12
- 5. IP Layer Parameters per Interface ........................ 15
- 6. Link Layer Parameters per Interface ....................... 19
- 7. TCP Parameters ............................................ 20
- 8. Application and Service Parameters ........................ 21
- 9. DHCP Extensions ........................................... 29
- 10. Defining new extensions ................................... 35
- 11. Acknowledgements .......................................... 35
- 12. References ................................................ 36
- 13. Security Considerations ................................... 37
- 14. Authors' Addresses ........................................ 37
-
-1. Introduction
-
- This document specifies options for use with both the Dynamic Host
- Configuration Protocol and the Bootstrap Protocol.
-
- The full description of DHCP packet formats may be found in the DHCP
- specification document [1], and the full description of BOOTP packet
- formats may be found in the BOOTP specification document [3]. This
- document defines the format of information in the last field of DHCP
- packets ('options') and of BOOTP packets ('vend'). The remainder of
- this section defines a generalized use of this area for giving
- information useful to a wide class of machines, operating systems and
- configurations. Sites with a single DHCP or BOOTP server that is
- shared among heterogeneous clients may choose to define other, site-
- specific formats for the use of the 'options' field.
-
- Section 2 of this memo describes the formats of DHCP options and
- BOOTP vendor extensions. Section 3 describes options defined in
- previous documents for use with BOOTP (all may also be used with
- DHCP). Sections 4-8 define new options intended for use with both
- DHCP and BOOTP. Section 9 defines options used only in DHCP.
-
- References further describing most of the options defined in sections
- 2-6 can be found in section 12. The use of the options defined in
- section 9 is described in the DHCP specification [1].
-
- Information on registering new options is contained in section 10.
-
- This document updates the definition of DHCP/BOOTP options that
-
-
-
-Alexander & Droms [Page 2]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
- appears in RFC1533. The classing mechanism has been extended to
- include vendor classes as described in section 8.4 and 9.13. The new
- procedure for defining new DHCP/BOOTP options in described in section
- 10. Several new options, including NIS+ domain and servers, Mobile
- IP home agent, SMTP server, TFTP server and Bootfile server, have
- been added. Text giving definitions used throughout the document has
- been added in section 1.1. Text emphasizing the need for uniqueness
- of client-identifiers has been added to section 9.14.
-
-1.1 Requirements
-
- Throughout this document, the words that are used to define the
- significance of particular requirements are capitalized. These words
- are:
-
- o "MUST"
-
- This word or the adjective "REQUIRED" means that the
- item is an absolute requirement of this specification.
-
- o "MUST NOT"
-
- This phrase means that the item is an absolute prohibition
- of this specification.
-
- o "SHOULD"
-
- This word or the adjective "RECOMMENDED" means that there
- may exist valid reasons in particular circumstances to ignore
- this item, but the full implications should be understood and
- the case carefully weighed before choosing a different course.
-
- o "SHOULD NOT"
-
- This phrase means that there may exist valid reasons in
- particular circumstances when the listed behavior is acceptable
- or even useful, but the full implications should be understood
- and the case carefully weighed before implementing any behavior
- described with this label.
-
- o "MAY"
-
- This word or the adjective "OPTIONAL" means that this item is
- truly optional. One vendor may choose to include the item
- because a particular marketplace requires it or because it
- enhances the product, for example; another vendor may omit the
- same item.
-
-
-
-
-Alexander & Droms [Page 3]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-1.2 Terminology
-
- This document uses the following terms:
-
- o "DHCP client"
-
- A DHCP client or "client" is an Internet host using DHCP to obtain
- configuration parameters such as a network address.
-
- o "DHCP server"
-
- A DHCP server of "server"is an Internet host that returns
- configuration parameters to DHCP clients.
-
- o "binding"
-
- A binding is a collection of configuration parameters, including
- at least an IP address, associated with or "bound to" a DHCP
- client. Bindings are managed by DHCP servers.
-
-2. BOOTP Extension/DHCP Option Field Format
-
- DHCP options have the same format as the BOOTP 'vendor extensions'
- defined in RFC 1497 [2]. Options may be fixed length or variable
- length. All options begin with a tag octet, which uniquely
- identifies the option. Fixed-length options without data consist of
- only a tag octet. Only options 0 and 255 are fixed length. All
- other options are variable-length with a length octet following the
- tag octet. The value of the length octet does not include the two
- octets specifying the tag and length. The length octet is followed
- by "length" octets of data.
- Options containing NVT ASCII data SHOULD NOT include a trailing NULL;
- however, the receiver of such options MUST be prepared to delete
- trailing nulls if they exist.
- The receiver MUST NOT
- require that a trailing null be included in the data. In the case
- of some variable-length
- options the length field is a constant but must still be specified.
-
- Any options defined subsequent to this document MUST contain a
- length octet even if the length is fixed or zero.
-
- All multi-octet quantities are in network byte-order.
-
- When used with BOOTP, the first four octets of the vendor information
- field have been assigned to the "magic cookie" (as suggested in RFC
- 951). This field identifies the mode in which the succeeding data is
- to be interpreted. The value of the magic cookie is the 4 octet
-
-
-
-Alexander & Droms [Page 4]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
- dotted decimal 99.130.83.99 (or hexadecimal number 63.82.53.63) in
- network byte order.
-
- All of the "vendor extensions" defined in RFC 1497 are also DHCP
- options.
-
- Option codes 128 to 254 (decimal) are reserved for site-specific
- options.
-
- Except for the options in section 9, all options may be used with
- either DHCP or BOOTP.
-
- Many of these options have their default values specified in other
- documents. In particular, RFC 1122 [4] specifies default values for
- most IP and TCP configuration parameters.
-
- Many options supply one or more 32-bit IP address. Use of IP
- addresses rather than fully-qualified Domain Names (FQDNs) may make
- future renumbering of IP hosts more difficult. Use of these addresses
- is discouraged at sites that may require renumbering.
-
-3. RFC 1497 Vendor Extensions
-
- This section lists the vendor extensions as defined in RFC
- 1497. They are defined here for completeness.
-
-3.1. Pad Option
-
- The pad option can be used to cause subsequent fields to align on
- word boundaries.
-
- The code for the pad option is 0, and its length is 1 octet.
-
- Code
- +-----+
- | 0 |
- +-----+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 5]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-3.2. End Option
-
- The end option marks the end of valid information in the vendor
- field. Subsequent octets should be filled with pad options.
-
- The code for the end option is 255, and its length is 1 octet.
-
- Code
- +-----+
- | 255 |
- +-----+
-
-3.3. Subnet Mask
-
- The subnet mask option specifies the client's subnet mask as per RFC
- 950 [5].
-
- If both the subnet mask and the router option are specified in a DHCP
- reply, the subnet mask option MUST be first.
-
- The code for the subnet mask option is 1, and its length is 4 octets.
-
- Code Len Subnet Mask
- +-----+-----+-----+-----+-----+-----+
- | 1 | 4 | m1 | m2 | m3 | m4 |
- +-----+-----+-----+-----+-----+-----+
-
-3.4. Time Offset
-
- The time offset field specifies the offset of the client's subnet in
- seconds from Coordinated Universal Time (UTC). The offset is
- expressed as a two's complement 32-bit integer. A positive offset
- indicates a location east of the zero meridian and a negative offset
- indicates a location west of the zero meridian.
-
- The code for the time offset option is 2, and its length is 4 octets.
-
- Code Len Time Offset
- +-----+-----+-----+-----+-----+-----+
- | 2 | 4 | n1 | n2 | n3 | n4 |
- +-----+-----+-----+-----+-----+-----+
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 6]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-3.5. Router Option
-
- The router option specifies a list of IP addresses for routers on the
- client's subnet. Routers SHOULD be listed in order of preference.
-
- The code for the router option is 3. The minimum length for the
- router option is 4 octets, and the length MUST always be a multiple
- of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 3 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-3.6. Time Server Option
-
- The time server option specifies a list of RFC 868 [6] time servers
- available to the client. Servers SHOULD be listed in order of
- preference.
-
- The code for the time server option is 4. The minimum length for
- this option is 4 octets, and the length MUST always be a multiple of
- 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 4 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-3.7. Name Server Option
-
- The name server option specifies a list of IEN 116 [7] name servers
- available to the client. Servers SHOULD be listed in order of
- preference.
-
- The code for the name server option is 5. The minimum length for
- this option is 4 octets, and the length MUST always be a multiple of
- 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 5 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 7]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-3.8. Domain Name Server Option
-
- The domain name server option specifies a list of Domain Name System
- (STD 13, RFC 1035 [8]) name servers available to the client. Servers
- SHOULD be listed in order of preference.
-
- The code for the domain name server option is 6. The minimum length
- for this option is 4 octets, and the length MUST always be a multiple
- of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 6 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-3.9. Log Server Option
-
- The log server option specifies a list of MIT-LCS UDP log servers
- available to the client. Servers SHOULD be listed in order of
- preference.
-
- The code for the log server option is 7. The minimum length for this
- option is 4 octets, and the length MUST always be a multiple of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 7 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-3.10. Cookie Server Option
-
- The cookie server option specifies a list of RFC 865 [9] cookie
- servers available to the client. Servers SHOULD be listed in order
- of preference.
-
- The code for the log server option is 8. The minimum length for this
- option is 4 octets, and the length MUST always be a multiple of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 8 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 8]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-3.11. LPR Server Option
-
- The LPR server option specifies a list of RFC 1179 [10] line printer
- servers available to the client. Servers SHOULD be listed in order
- of preference.
-
- The code for the LPR server option is 9. The minimum length for this
- option is 4 octets, and the length MUST always be a multiple of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 9 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-3.12. Impress Server Option
-
- The Impress server option specifies a list of Imagen Impress servers
- available to the client. Servers SHOULD be listed in order of
- preference.
-
- The code for the Impress server option is 10. The minimum length for
- this option is 4 octets, and the length MUST always be a multiple of
- 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 10 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-3.13. Resource Location Server Option
-
- This option specifies a list of RFC 887 [11] Resource Location
- servers available to the client. Servers SHOULD be listed in order
- of preference.
-
- The code for this option is 11. The minimum length for this option
- is 4 octets, and the length MUST always be a multiple of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 11 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 9]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-3.14. Host Name Option
-
- This option specifies the name of the client. The name may or may
- not be qualified with the local domain name (see section 3.17 for the
- preferred way to retrieve the domain name). See RFC 1035 for
- character set restrictions.
-
- The code for this option is 12, and its minimum length is 1.
-
- Code Len Host Name
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 12 | n | h1 | h2 | h3 | h4 | h5 | h6 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-3.15. Boot File Size Option
-
- This option specifies the length in 512-octet blocks of the default
- boot image for the client. The file length is specified as an
- unsigned 16-bit integer.
-
- The code for this option is 13, and its length is 2.
-
- Code Len File Size
- +-----+-----+-----+-----+
- | 13 | 2 | l1 | l2 |
- +-----+-----+-----+-----+
-
-3.16. Merit Dump File
-
- This option specifies the path-name of a file to which the client's
- core image should be dumped in the event the client crashes. The
- path is formatted as a character string consisting of characters from
- the NVT ASCII character set.
-
- The code for this option is 14. Its minimum length is 1.
-
- Code Len Dump File Pathname
- +-----+-----+-----+-----+-----+-----+---
- | 14 | n | n1 | n2 | n3 | n4 | ...
- +-----+-----+-----+-----+-----+-----+---
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 10]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-3.17. Domain Name
-
- This option specifies the domain name that client should use when
- resolving hostnames via the Domain Name System.
-
- The code for this option is 15. Its minimum length is 1.
-
- Code Len Domain Name
- +-----+-----+-----+-----+-----+-----+--
- | 15 | n | d1 | d2 | d3 | d4 | ...
- +-----+-----+-----+-----+-----+-----+--
-
-3.18. Swap Server
-
- This specifies the IP address of the client's swap server.
-
- The code for this option is 16 and its length is 4.
-
- Code Len Swap Server Address
- +-----+-----+-----+-----+-----+-----+
- | 16 | n | a1 | a2 | a3 | a4 |
- +-----+-----+-----+-----+-----+-----+
-
-3.19. Root Path
-
- This option specifies the path-name that contains the client's root
- disk. The path is formatted as a character string consisting of
- characters from the NVT ASCII character set.
-
- The code for this option is 17. Its minimum length is 1.
-
- Code Len Root Disk Pathname
- +-----+-----+-----+-----+-----+-----+---
- | 17 | n | n1 | n2 | n3 | n4 | ...
- +-----+-----+-----+-----+-----+-----+---
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 11]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-3.20. Extensions Path
-
- A string to specify a file, retrievable via TFTP, which contains
- information which can be interpreted in the same way as the 64-octet
- vendor-extension field within the BOOTP response, with the following
- exceptions:
-
- - the length of the file is unconstrained;
- - all references to Tag 18 (i.e., instances of the
- BOOTP Extensions Path field) within the file are
- ignored.
-
- The code for this option is 18. Its minimum length is 1.
-
- Code Len Extensions Pathname
- +-----+-----+-----+-----+-----+-----+---
- | 18 | n | n1 | n2 | n3 | n4 | ...
- +-----+-----+-----+-----+-----+-----+---
-
-4. IP Layer Parameters per Host
-
- This section details the options that affect the operation of the IP
- layer on a per-host basis.
-
-4.1. IP Forwarding Enable/Disable Option
-
- This option specifies whether the client should configure its IP
- layer for packet forwarding. A value of 0 means disable IP
- forwarding, and a value of 1 means enable IP forwarding.
-
- The code for this option is 19, and its length is 1.
-
- Code Len Value
- +-----+-----+-----+
- | 19 | 1 | 0/1 |
- +-----+-----+-----+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 12]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-4.2. Non-Local Source Routing Enable/Disable Option
-
- This option specifies whether the client should configure its IP
- layer to allow forwarding of datagrams with non-local source routes
- (see Section 3.3.5 of [4] for a discussion of this topic). A value
- of 0 means disallow forwarding of such datagrams, and a value of 1
- means allow forwarding.
-
- The code for this option is 20, and its length is 1.
-
- Code Len Value
- +-----+-----+-----+
- | 20 | 1 | 0/1 |
- +-----+-----+-----+
-
-4.3. Policy Filter Option
-
- This option specifies policy filters for non-local source routing.
- The filters consist of a list of IP addresses and masks which specify
- destination/mask pairs with which to filter incoming source routes.
-
- Any source routed datagram whose next-hop address does not match one
- of the filters should be discarded by the client.
-
- See [4] for further information.
-
- The code for this option is 21. The minimum length of this option is
- 8, and the length MUST be a multiple of 8.
-
- Code Len Address 1 Mask 1
- +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
- | 21 | n | a1 | a2 | a3 | a4 | m1 | m2 | m3 | m4 |
- +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
- Address 2 Mask 2
- +-----+-----+-----+-----+-----+-----+-----+-----+---
- | a1 | a2 | a3 | a4 | m1 | m2 | m3 | m4 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+---
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 13]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-4.4. Maximum Datagram Reassembly Size
-
- This option specifies the maximum size datagram that the client
- should be prepared to reassemble. The size is specified as a 16-bit
- unsigned integer. The minimum value legal value is 576.
-
- The code for this option is 22, and its length is 2.
-
- Code Len Size
- +-----+-----+-----+-----+
- | 22 | 2 | s1 | s2 |
- +-----+-----+-----+-----+
-
-4.5. Default IP Time-to-live
-
- This option specifies the default time-to-live that the client should
- use on outgoing datagrams. The TTL is specified as an octet with a
- value between 1 and 255.
-
- The code for this option is 23, and its length is 1.
-
- Code Len TTL
- +-----+-----+-----+
- | 23 | 1 | ttl |
- +-----+-----+-----+
-
-4.6. Path MTU Aging Timeout Option
-
- This option specifies the timeout (in seconds) to use when aging Path
- MTU values discovered by the mechanism defined in RFC 1191 [12]. The
- timeout is specified as a 32-bit unsigned integer.
-
- The code for this option is 24, and its length is 4.
-
- Code Len Timeout
- +-----+-----+-----+-----+-----+-----+
- | 24 | 4 | t1 | t2 | t3 | t4 |
- +-----+-----+-----+-----+-----+-----+
-
-
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 14]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-4.7. Path MTU Plateau Table Option
-
- This option specifies a table of MTU sizes to use when performing
- Path MTU Discovery as defined in RFC 1191. The table is formatted as
- a list of 16-bit unsigned integers, ordered from smallest to largest.
- The minimum MTU value cannot be smaller than 68.
-
- The code for this option is 25. Its minimum length is 2, and the
- length MUST be a multiple of 2.
-
- Code Len Size 1 Size 2
- +-----+-----+-----+-----+-----+-----+---
- | 25 | n | s1 | s2 | s1 | s2 | ...
- +-----+-----+-----+-----+-----+-----+---
-
-5. IP Layer Parameters per Interface
-
- This section details the options that affect the operation of the IP
- layer on a per-interface basis. It is expected that a client can
- issue multiple requests, one per interface, in order to configure
- interfaces with their specific parameters.
-
-5.1. Interface MTU Option
-
- This option specifies the MTU to use on this interface. The MTU is
- specified as a 16-bit unsigned integer. The minimum legal value for
- the MTU is 68.
-
- The code for this option is 26, and its length is 2.
-
- Code Len MTU
- +-----+-----+-----+-----+
- | 26 | 2 | m1 | m2 |
- +-----+-----+-----+-----+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 15]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-5.2. All Subnets are Local Option
-
- This option specifies whether or not the client may assume that all
- subnets of the IP network to which the client is connected use the
- same MTU as the subnet of that network to which the client is
- directly connected. A value of 1 indicates that all subnets share
- the same MTU. A value of 0 means that the client should assume that
- some subnets of the directly connected network may have smaller MTUs.
-
- The code for this option is 27, and its length is 1.
-
- Code Len Value
- +-----+-----+-----+
- | 27 | 1 | 0/1 |
- +-----+-----+-----+
-
-5.3. Broadcast Address Option
-
- This option specifies the broadcast address in use on the client's
- subnet. Legal values for broadcast addresses are specified in
- section 3.2.1.3 of [4].
-
- The code for this option is 28, and its length is 4.
-
- Code Len Broadcast Address
- +-----+-----+-----+-----+-----+-----+
- | 28 | 4 | b1 | b2 | b3 | b4 |
- +-----+-----+-----+-----+-----+-----+
-
-5.4. Perform Mask Discovery Option
-
- This option specifies whether or not the client should perform subnet
- mask discovery using ICMP. A value of 0 indicates that the client
- should not perform mask discovery. A value of 1 means that the
- client should perform mask discovery.
-
- The code for this option is 29, and its length is 1.
-
- Code Len Value
- +-----+-----+-----+
- | 29 | 1 | 0/1 |
- +-----+-----+-----+
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 16]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-5.5. Mask Supplier Option
-
- This option specifies whether or not the client should respond to
- subnet mask requests using ICMP. A value of 0 indicates that the
- client should not respond. A value of 1 means that the client should
- respond.
-
- The code for this option is 30, and its length is 1.
-
- Code Len Value
- +-----+-----+-----+
- | 30 | 1 | 0/1 |
- +-----+-----+-----+
-
-5.6. Perform Router Discovery Option
-
- This option specifies whether or not the client should solicit
- routers using the Router Discovery mechanism defined in RFC 1256
- [13]. A value of 0 indicates that the client should not perform
- router discovery. A value of 1 means that the client should perform
- router discovery.
-
- The code for this option is 31, and its length is 1.
-
- Code Len Value
- +-----+-----+-----+
- | 31 | 1 | 0/1 |
- +-----+-----+-----+
-
-5.7. Router Solicitation Address Option
-
- This option specifies the address to which the client should transmit
- router solicitation requests.
-
- The code for this option is 32, and its length is 4.
-
- Code Len Address
- +-----+-----+-----+-----+-----+-----+
- | 32 | 4 | a1 | a2 | a3 | a4 |
- +-----+-----+-----+-----+-----+-----+
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 17]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-5.8. Static Route Option
-
- This option specifies a list of static routes that the client should
- install in its routing cache. If multiple routes to the same
- destination are specified, they are listed in descending order of
- priority.
-
- The routes consist of a list of IP address pairs. The first address
- is the destination address, and the second address is the router for
- the destination.
-
- The default route (0.0.0.0) is an illegal destination for a static
- route. See section 3.5 for information about the router option.
-
- The code for this option is 33. The minimum length of this option is
- 8, and the length MUST be a multiple of 8.
-
- Code Len Destination 1 Router 1
- +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
- | 33 | n | d1 | d2 | d3 | d4 | r1 | r2 | r3 | r4 |
- +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
- Destination 2 Router 2
- +-----+-----+-----+-----+-----+-----+-----+-----+---
- | d1 | d2 | d3 | d4 | r1 | r2 | r3 | r4 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+---
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 18]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-6. Link Layer Parameters per Interface
-
- This section lists the options that affect the operation of the data
- link layer on a per-interface basis.
-
-6.1. Trailer Encapsulation Option
-
- This option specifies whether or not the client should negotiate the
- use of trailers (RFC 893 [14]) when using the ARP protocol. A value
- of 0 indicates that the client should not attempt to use trailers. A
- value of 1 means that the client should attempt to use trailers.
-
- The code for this option is 34, and its length is 1.
-
- Code Len Value
- +-----+-----+-----+
- | 34 | 1 | 0/1 |
- +-----+-----+-----+
-
-6.2. ARP Cache Timeout Option
-
- This option specifies the timeout in seconds for ARP cache entries.
- The time is specified as a 32-bit unsigned integer.
-
- The code for this option is 35, and its length is 4.
-
- Code Len Time
- +-----+-----+-----+-----+-----+-----+
- | 35 | 4 | t1 | t2 | t3 | t4 |
- +-----+-----+-----+-----+-----+-----+
-
-6.3. Ethernet Encapsulation Option
-
- This option specifies whether or not the client should use Ethernet
- Version 2 (RFC 894 [15]) or IEEE 802.3 (RFC 1042 [16]) encapsulation
- if the interface is an Ethernet. A value of 0 indicates that the
- client should use RFC 894 encapsulation. A value of 1 means that the
- client should use RFC 1042 encapsulation.
-
- The code for this option is 36, and its length is 1.
-
- Code Len Value
- +-----+-----+-----+
- | 36 | 1 | 0/1 |
- +-----+-----+-----+
-
-
-
-
-
-
-Alexander & Droms [Page 19]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-7. TCP Parameters
-
- This section lists the options that affect the operation of the TCP
- layer on a per-interface basis.
-
-7.1. TCP Default TTL Option
-
- This option specifies the default TTL that the client should use when
- sending TCP segments. The value is represented as an 8-bit unsigned
- integer. The minimum value is 1.
-
- The code for this option is 37, and its length is 1.
-
- Code Len TTL
- +-----+-----+-----+
- | 37 | 1 | n |
- +-----+-----+-----+
-
-7.2. TCP Keepalive Interval Option
-
- This option specifies the interval (in seconds) that the client TCP
- should wait before sending a keepalive message on a TCP connection.
- The time is specified as a 32-bit unsigned integer. A value of zero
- indicates that the client should not generate keepalive messages on
- connections unless specifically requested by an application.
-
- The code for this option is 38, and its length is 4.
-
- Code Len Time
- +-----+-----+-----+-----+-----+-----+
- | 38 | 4 | t1 | t2 | t3 | t4 |
- +-----+-----+-----+-----+-----+-----+
-
-7.3. TCP Keepalive Garbage Option
-
- This option specifies the whether or not the client should send TCP
- keepalive messages with a octet of garbage for compatibility with
- older implementations. A value of 0 indicates that a garbage octet
- should not be sent. A value of 1 indicates that a garbage octet
- should be sent.
-
- The code for this option is 39, and its length is 1.
-
- Code Len Value
- +-----+-----+-----+
- | 39 | 1 | 0/1 |
- +-----+-----+-----+
-
-
-
-
-Alexander & Droms [Page 20]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-8. Application and Service Parameters
-
- This section details some miscellaneous options used to configure
- miscellaneous applications and services.
-
-8.1. Network Information Service Domain Option
-
- This option specifies the name of the client's NIS [17] domain. The
- domain is formatted as a character string consisting of characters
- from the NVT ASCII character set.
-
- The code for this option is 40. Its minimum length is 1.
-
- Code Len NIS Domain Name
- +-----+-----+-----+-----+-----+-----+---
- | 40 | n | n1 | n2 | n3 | n4 | ...
- +-----+-----+-----+-----+-----+-----+---
-
-8.2. Network Information Servers Option
-
- This option specifies a list of IP addresses indicating NIS servers
- available to the client. Servers SHOULD be listed in order of
- preference.
-
- The code for this option is 41. Its minimum length is 4, and the
- length MUST be a multiple of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 41 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-8.3. Network Time Protocol Servers Option
-
- This option specifies a list of IP addresses indicating NTP [18]
- servers available to the client. Servers SHOULD be listed in order
- of preference.
-
- The code for this option is 42. Its minimum length is 4, and the
- length MUST be a multiple of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 42 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-
-
-
-
-
-Alexander & Droms [Page 21]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-8.4. Vendor Specific Information
-
- This option is used by clients and servers to exchange vendor-
- specific information. The information is an opaque object of n
- octets, presumably interpreted by vendor-specific code on the clients
- and servers. The definition of this information is vendor specific.
- The vendor is indicated in the vendor class identifier option.
- Servers not equipped to interpret the vendor-specific information
- sent by a client MUST ignore it (although it may be reported).
- Clients which do not receive desired vendor-specific information
- SHOULD make an attempt to operate without it, although they may do so
- (and announce they are doing so) in a degraded mode.
-
- If a vendor potentially encodes more than one item of information in
- this option, then the vendor SHOULD encode the option using
- "Encapsulated vendor-specific options" as described below:
-
- The Encapsulated vendor-specific options field SHOULD be encoded as a
- sequence of code/length/value fields of identical syntax to the DHCP
- options field with the following exceptions:
-
- 1) There SHOULD NOT be a "magic cookie" field in the encapsulated
- vendor-specific extensions field.
-
- 2) Codes other than 0 or 255 MAY be redefined by the vendor within
- the encapsulated vendor-specific extensions field, but SHOULD
- conform to the tag-length-value syntax defined in section 2.
-
- 3) Code 255 (END), if present, signifies the end of the
- encapsulated vendor extensions, not the end of the vendor
- extensions field. If no code 255 is present, then the end of
- the enclosing vendor-specific information field is taken as the
- end of the encapsulated vendor-specific extensions field.
-
- The code for this option is 43 and its minimum length is 1.
-
- Code Len Vendor-specific information
- +-----+-----+-----+-----+---
- | 43 | n | i1 | i2 | ...
- +-----+-----+-----+-----+---
-
- When encapsulated vendor-specific extensions are used, the
- information bytes 1-n have the following format:
-
- Code Len Data item Code Len Data item Code
- +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
- | T1 | n | d1 | d2 | ... | T2 | n | D1 | D2 | ... | ... |
- +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
-
-
-
-Alexander & Droms [Page 22]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-8.5. NetBIOS over TCP/IP Name Server Option
-
- The NetBIOS name server (NBNS) option specifies a list of RFC
- 1001/1002 [19] [20] NBNS name servers listed in order of preference.
-
- The code for this option is 44. The minimum length of the option is
- 4 octets, and the length must always be a multiple of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
- | 44 | n | a1 | a2 | a3 | a4 | b1 | b2 | b3 | b4 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
-
-8.6. NetBIOS over TCP/IP Datagram Distribution Server Option
-
- The NetBIOS datagram distribution server (NBDD) option specifies a
- list of RFC 1001/1002 NBDD servers listed in order of preference. The
- code for this option is 45. The minimum length of the option is 4
- octets, and the length must always be a multiple of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
- | 45 | n | a1 | a2 | a3 | a4 | b1 | b2 | b3 | b4 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
-
-8.7. NetBIOS over TCP/IP Node Type Option
-
- The NetBIOS node type option allows NetBIOS over TCP/IP clients which
- are configurable to be configured as described in RFC 1001/1002. The
- value is specified as a single octet which identifies the client type
- as follows:
-
- Value Node Type
- ----- ---------
- 0x1 B-node
- 0x2 P-node
- 0x4 M-node
- 0x8 H-node
-
- In the above chart, the notation '0x' indicates a number in base-16
- (hexadecimal).
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 23]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
- The code for this option is 46. The length of this option is always
- 1.
-
- Code Len Node Type
- +-----+-----+-----------+
- | 46 | 1 | see above |
- +-----+-----+-----------+
-
-8.8. NetBIOS over TCP/IP Scope Option
-
- The NetBIOS scope option specifies the NetBIOS over TCP/IP scope
- parameter for the client as specified in RFC 1001/1002. See [19],
- [20], and [8] for character-set restrictions.
-
- The code for this option is 47. The minimum length of this option is
- 1.
-
- Code Len NetBIOS Scope
- +-----+-----+-----+-----+-----+-----+----
- | 47 | n | s1 | s2 | s3 | s4 | ...
- +-----+-----+-----+-----+-----+-----+----
-
-8.9. X Window System Font Server Option
-
- This option specifies a list of X Window System [21] Font servers
- available to the client. Servers SHOULD be listed in order of
- preference.
-
- The code for this option is 48. The minimum length of this option is
- 4 octets, and the length MUST be a multiple of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+---
- | 48 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+---
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 24]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-8.10. X Window System Display Manager Option
-
- This option specifies a list of IP addresses of systems that are
- running the X Window System Display Manager and are available to the
- client.
-
- Addresses SHOULD be listed in order of preference.
-
- The code for the this option is 49. The minimum length of this option
- is 4, and the length MUST be a multiple of 4.
-
- Code Len Address 1 Address 2
-
- +-----+-----+-----+-----+-----+-----+-----+-----+---
- | 49 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+---
-
-8.11. Network Information Service+ Domain Option
-
- This option specifies the name of the client's NIS+ [17] domain. The
- domain is formatted as a character string consisting of characters
- from the NVT ASCII character set.
-
- The code for this option is 64. Its minimum length is 1.
-
- Code Len NIS Client Domain Name
- +-----+-----+-----+-----+-----+-----+---
- | 64 | n | n1 | n2 | n3 | n4 | ...
- +-----+-----+-----+-----+-----+-----+---
-
-8.12. Network Information Service+ Servers Option
-
- This option specifies a list of IP addresses indicating NIS+ servers
- available to the client. Servers SHOULD be listed in order of
- preference.
-
- The code for this option is 65. Its minimum length is 4, and the
- length MUST be a multiple of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 65 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 25]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-8.13. Mobile IP Home Agent option
-
- This option specifies a list of IP addresses indicating mobile IP
- home agents available to the client. Agents SHOULD be listed in
- order of preference.
-
- The code for this option is 68. Its minimum length is 0 (indicating
- no home agents are available) and the length MUST be a multiple of 4.
- It is expected that the usual length will be four octets, containing
- a single home agent's address.
-
- Code Len Home Agent Addresses (zero or more)
- +-----+-----+-----+-----+-----+-----+--
- | 68 | n | a1 | a2 | a3 | a4 | ...
- +-----+-----+-----+-----+-----+-----+--
-
-8.14. Simple Mail Transport Protocol (SMTP) Server Option
-
- The SMTP server option specifies a list of SMTP servers available to
- the client. Servers SHOULD be listed in order of preference.
-
- The code for the SMTP server option is 69. The minimum length for
- this option is 4 octets, and the length MUST always be a multiple of
- 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 69 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-8.15. Post Office Protocol (POP3) Server Option
-
- The POP3 server option specifies a list of POP3 available to the
- client. Servers SHOULD be listed in order of preference.
-
- The code for the POP3 server option is 70. The minimum length for
- this option is 4 octets, and the length MUST always be a multiple of
- 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 70 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 26]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-8.16. Network News Transport Protocol (NNTP) Server Option
-
- The NNTP server option specifies a list of NNTP available to the
- client. Servers SHOULD be listed in order of preference.
-
- The code for the NNTP server option is 71. The minimum length for
- this option is 4 octets, and the length MUST always be a multiple of
- 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 71 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-8.17. Default World Wide Web (WWW) Server Option
-
- The WWW server option specifies a list of WWW available to the
- client. Servers SHOULD be listed in order of preference.
-
- The code for the WWW server option is 72. The minimum length for
- this option is 4 octets, and the length MUST always be a multiple of
- 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 72 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-8.18. Default Finger Server Option
-
- The Finger server option specifies a list of Finger available to the
- client. Servers SHOULD be listed in order of preference.
-
- The code for the Finger server option is 73. The minimum length for
- this option is 4 octets, and the length MUST always be a multiple of
- 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 73 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 27]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-8.19. Default Internet Relay Chat (IRC) Server Option
-
- The IRC server option specifies a list of IRC available to the
- client. Servers SHOULD be listed in order of preference.
-
- The code for the IRC server option is 74. The minimum length for
- this option is 4 octets, and the length MUST always be a multiple of
- 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 74 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-8.20. StreetTalk Server Option
-
- The StreetTalk server option specifies a list of StreetTalk servers
- available to the client. Servers SHOULD be listed in order of
- preference.
-
- The code for the StreetTalk server option is 75. The minimum length
- for this option is 4 octets, and the length MUST always be a multiple
- of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 75 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-8.21. StreetTalk Directory Assistance (STDA) Server Option
-
- The StreetTalk Directory Assistance (STDA) server option specifies a
- list of STDA servers available to the client. Servers SHOULD be
- listed in order of preference.
-
- The code for the StreetTalk Directory Assistance server option is 76.
- The minimum length for this option is 4 octets, and the length MUST
- always be a multiple of 4.
-
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 76 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 28]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-9. DHCP Extensions
-
- This section details the options that are specific to DHCP.
-
-9.1. Requested IP Address
-
- This option is used in a client request (DHCPDISCOVER) to allow the
- client to request that a particular IP address be assigned.
-
- The code for this option is 50, and its length is 4.
-
- Code Len Address
- +-----+-----+-----+-----+-----+-----+
- | 50 | 4 | a1 | a2 | a3 | a4 |
- +-----+-----+-----+-----+-----+-----+
-
-9.2. IP Address Lease Time
-
- This option is used in a client request (DHCPDISCOVER or DHCPREQUEST)
- to allow the client to request a lease time for the IP address. In a
- server reply (DHCPOFFER), a DHCP server uses this option to specify
- the lease time it is willing to offer.
-
- The time is in units of seconds, and is specified as a 32-bit
- unsigned integer.
-
- The code for this option is 51, and its length is 4.
-
- Code Len Lease Time
- +-----+-----+-----+-----+-----+-----+
- | 51 | 4 | t1 | t2 | t3 | t4 |
- +-----+-----+-----+-----+-----+-----+
-
-9.3. Option Overload
-
- This option is used to indicate that the DHCP 'sname' or 'file'
- fields are being overloaded by using them to carry DHCP options. A
- DHCP server inserts this option if the returned parameters will
- exceed the usual space allotted for options.
-
- If this option is present, the client interprets the specified
- additional fields after it concludes interpretation of the standard
- option fields.
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 29]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
- The code for this option is 52, and its length is 1. Legal values
- for this option are:
-
- Value Meaning
- ----- --------
- 1 the 'file' field is used to hold options
- 2 the 'sname' field is used to hold options
- 3 both fields are used to hold options
-
- Code Len Value
- +-----+-----+-----+
- | 52 | 1 |1/2/3|
- +-----+-----+-----+
-
-9.4 TFTP server name
-
- This option is used to identify a TFTP server when the 'sname'
- field in the DHCP header has been used for DHCP options.
-
- The code for this option is 66, and its minimum length is 1.
-
- Code Len TFTP server
- +-----+-----+-----+-----+-----+---
- | 66 | n | c1 | c2 | c3 | ...
- +-----+-----+-----+-----+-----+---
-
-9.5 Bootfile name
-
- This option is used to identify a bootfile when the 'file' field in
- the DHCP header has been used for DHCP options.
-
- The code for this option is 67, and its minimum length is 1.
-
- Code Len Bootfile name
- +-----+-----+-----+-----+-----+---
- | 67 | n | c1 | c2 | c3 | ...
- +-----+-----+-----+-----+-----+---
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 30]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-9.6. DHCP Message Type
-
- This option is used to convey the type of the DHCP message. The code
- for this option is 53, and its length is 1. Legal values for this
- option are:
-
- Value Message Type
- ----- ------------
- 1 DHCPDISCOVER
- 2 DHCPOFFER
- 3 DHCPREQUEST
- 4 DHCPDECLINE
- 5 DHCPACK
- 6 DHCPNAK
- 7 DHCPRELEASE
- 8 DHCPINFORM
-
- Code Len Type
- +-----+-----+-----+
- | 53 | 1 | 1-9 |
- +-----+-----+-----+
-
-9.7. Server Identifier
-
- This option is used in DHCPOFFER and DHCPREQUEST messages, and may
- optionally be included in the DHCPACK and DHCPNAK messages. DHCP
- servers include this option in the DHCPOFFER in order to allow the
- client to distinguish between lease offers. DHCP clients use the
- contents of the 'server identifier' field as the destination address
- for any DHCP messages unicast to the DHCP server. DHCP clients also
- indicate which of several lease offers is being accepted by including
- this option in a DHCPREQUEST message.
-
- The identifier is the IP address of the selected server.
-
- The code for this option is 54, and its length is 4.
-
- Code Len Address
- +-----+-----+-----+-----+-----+-----+
- | 54 | 4 | a1 | a2 | a3 | a4 |
- +-----+-----+-----+-----+-----+-----+
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 31]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-9.8. Parameter Request List
-
- This option is used by a DHCP client to request values for specified
- configuration parameters. The list of requested parameters is
- specified as n octets, where each octet is a valid DHCP option code
- as defined in this document.
-
- The client MAY list the options in order of preference. The DHCP
- server is not required to return the options in the requested order,
- but MUST try to insert the requested options in the order requested
- by the client.
-
- The code for this option is 55. Its minimum length is 1.
-
- Code Len Option Codes
- +-----+-----+-----+-----+---
- | 55 | n | c1 | c2 | ...
- +-----+-----+-----+-----+---
-
-9.9. Message
-
- This option is used by a DHCP server to provide an error message to a
- DHCP client in a DHCPNAK message in the event of a failure. A client
- may use this option in a DHCPDECLINE message to indicate the why the
- client declined the offered parameters. The message consists of n
- octets of NVT ASCII text, which the client may display on an
- available output device.
-
- The code for this option is 56 and its minimum length is 1.
-
- Code Len Text
- +-----+-----+-----+-----+---
- | 56 | n | c1 | c2 | ...
- +-----+-----+-----+-----+---
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 32]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-9.10. Maximum DHCP Message Size
-
- This option specifies the maximum length DHCP message that it is
- willing to accept. The length is specified as an unsigned 16-bit
- integer. A client may use the maximum DHCP message size option in
- DHCPDISCOVER or DHCPREQUEST messages, but should not use the option
- in DHCPDECLINE messages.
-
- The code for this option is 57, and its length is 2. The minimum
- legal value is 576 octets.
-
- Code Len Length
- +-----+-----+-----+-----+
- | 57 | 2 | l1 | l2 |
- +-----+-----+-----+-----+
-
-9.11. Renewal (T1) Time Value
-
- This option specifies the time interval from address assignment until
- the client transitions to the RENEWING state.
-
- The value is in units of seconds, and is specified as a 32-bit
- unsigned integer.
-
- The code for this option is 58, and its length is 4.
-
- Code Len T1 Interval
- +-----+-----+-----+-----+-----+-----+
- | 58 | 4 | t1 | t2 | t3 | t4 |
- +-----+-----+-----+-----+-----+-----+
-
-9.12. Rebinding (T2) Time Value
-
- This option specifies the time interval from address assignment until
- the client transitions to the REBINDING state.
-
- The value is in units of seconds, and is specified as a 32-bit
- unsigned integer.
-
- The code for this option is 59, and its length is 4.
-
- Code Len T2 Interval
- +-----+-----+-----+-----+-----+-----+
- | 59 | 4 | t1 | t2 | t3 | t4 |
- +-----+-----+-----+-----+-----+-----+
-
-
-
-
-
-
-Alexander & Droms [Page 33]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
-9.13. Vendor class identifier
-
- This option is used by DHCP clients to optionally identify the vendor
- type and configuration of a DHCP client. The information is a string
- of n octets, interpreted by servers. Vendors may choose to define
- specific vendor class identifiers to convey particular configuration
- or other identification information about a client. For example, the
- identifier may encode the client's hardware configuration. Servers
- not equipped to interpret the class-specific information sent by a
- client MUST ignore it (although it may be reported). Servers that
- respond SHOULD only use option 43 to return the vendor-specific
- information to the client.
-
- The code for this option is 60, and its minimum length is 1.
-
- Code Len Vendor class Identifier
- +-----+-----+-----+-----+---
- | 60 | n | i1 | i2 | ...
- +-----+-----+-----+-----+---
-
-9.14. Client-identifier
-
- This option is used by DHCP clients to specify their unique
- identifier. DHCP servers use this value to index their database of
- address bindings. This value is expected to be unique for all
- clients in an administrative domain.
-
- Identifiers SHOULD be treated as opaque objects by DHCP servers.
-
- The client identifier MAY consist of type-value pairs similar to the
- 'htype'/'chaddr' fields defined in [3]. For instance, it MAY consist
- of a hardware type and hardware address. In this case the type field
- SHOULD be one of the ARP hardware types defined in STD2 [22]. A
- hardware type of 0 (zero) should be used when the value field
- contains an identifier other than a hardware address (e.g. a fully
- qualified domain name).
-
- For correct identification of clients, each client's client-
- identifier MUST be unique among the client-identifiers used on the
- subnet to which the client is attached. Vendors and system
- administrators are responsible for choosing client-identifiers that
- meet this requirement for uniqueness.
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 34]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
- The code for this option is 61, and its minimum length is 2.
-
- Code Len Type Client-Identifier
- +-----+-----+-----+-----+-----+---
- | 61 | n | t1 | i1 | i2 | ...
- +-----+-----+-----+-----+-----+---
-
-
-10. Defining new extensions
-
- The author of a new DHCP option will follow these steps to obtain
- acceptance of the option as a part of the DHCP Internet Standard:
-
- 1. The author devises the new option.
- 2. The author requests a number for the new option from IANA by
- contacting:
- Internet Assigned Numbers Authority (IANA)
- USC/Information Sciences Institute
- 4676 Admiralty Way
- Marina del Rey, California 90292-6695
-
- or by email as: iana@isi.edu
-
- 3. The author documents the new option, using the newly obtained
- option number, as an Internet Draft.
- 4. The author submits the Internet Draft for review through the IETF
- standards process as defined in "Internet Official Protocol
- Standards" (STD 1). The new option will be submitted for eventual
- acceptance as an Internet Standard.
- 5. The new option progresses through the IETF standards process; the
- new option will be reviewed by the Dynamic Host Configuration
- Working Group (if that group still exists), or as an Internet
- Draft not submitted by an IETF working group.
- 6. If the new option fails to gain acceptance as an Internet
- Standard, the assigned option number will be returned to IANA for
- reassignment.
-
- This procedure for defining new extensions will ensure that:
-
- * allocation of new option numbers is coordinated from a single
- authority,
- * new options are reviewed for technical correctness and
- appropriateness, and
- * documentation for new options is complete and published.
-
-11. Acknowledgements
-
- The author thanks the many (and too numerous to mention!)
-
-
-
-Alexander & Droms [Page 35]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
- members of the DHC WG for their tireless and ongoing efforts in
- the development of DHCP and this document.
-
-
- The efforts of J Allard, Mike Carney, Dave Lapp, Fred Lien and
- John Mendonca in organizing DHCP interoperability testing
- sessions are gratefully acknowledged.
-
- The development of this document was supported in part by grants
- from the Corporation for National Research Initiatives (CNRI),
- Bucknell University and Sun Microsystems.
-
-
-12. References
-
- [1] Droms, R., "Dynamic Host Configuration Protocol", RFC 1531,
- Bucknell University, October 1993.
-
- [2] Reynolds, J., "BOOTP Vendor Information Extensions", RFC 1497,
- USC/Information Sciences Institute, August 1993.
-
- [3] Croft, W., and J. Gilmore, "Bootstrap Protocol", RFC 951,
- Stanford University and Sun Microsystems, September 1985.
-
- [4] Braden, R., Editor, "Requirements for Internet Hosts -
- Communication Layers", STD 3, RFC 1122, USC/Information Sciences
- Institute, October 1989.
-
- [5] Mogul, J., and J. Postel, "Internet Standard Subnetting
- Procedure", STD 5, RFC 950, USC/Information Sciences Institute,
- August 1985.
-
- [6] Postel, J., and K. Harrenstien, "Time Protocol", STD 26, RFC
- 868, USC/Information Sciences Institute, SRI, May 1983.
-
- [7] Postel, J., "Name Server", IEN 116, USC/Information Sciences
- Institute, August 1979.
-
- [8] Mockapetris, P., "Domain Names - Implementation and
- Specification", STD 13, RFC 1035, USC/Information Sciences
- Institute, November 1987.
-
- [9] Postel, J., "Quote of the Day Protocol", STD 23, RFC 865,
- USC/Information Sciences Institute, May 1983.
-
- [10] McLaughlin, L., "Line Printer Daemon Protocol", RFC 1179, The
- Wollongong Group, August 1990.
-
-
-
-
-Alexander & Droms [Page 36]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
- [11] Accetta, M., "Resource Location Protocol", RFC 887, CMU,
- December 1983.
-
- [12] Mogul, J. and S. Deering, "Path MTU Discovery", RFC 1191,
- DECWRL, Stanford University, November 1990.
-
- [13] Deering, S., "ICMP Router Discovery Messages", RFC 1256,
- Xerox PARC, September 1991.
-
- [14] Leffler, S. and M. Karels, "Trailer Encapsulations", RFC 893,
- U. C. Berkeley, April 1984.
-
- [15] Hornig, C., "Standard for the Transmission of IP Datagrams over
- Ethernet Networks", RFC 894, Symbolics, April 1984.
-
- [16] Postel, J. and J. Reynolds, "Standard for the Transmission of
- IP Datagrams Over IEEE 802 Networks", RFC 1042, USC/Information
- Sciences Institute, February 1988.
-
- [17] Sun Microsystems, "System and Network Administration", March
- 1990.
-
- [18] Mills, D., "Internet Time Synchronization: The Network Time
- Protocol", RFC 1305, UDEL, March 1992.
-
- [19] NetBIOS Working Group, "Protocol Standard for a NetBIOS Service
- on a TCP/UDP transport: Concepts and Methods", STD 19, RFC 1001,
- March 1987.
-
- [20] NetBIOS Working Group, "Protocol Standard for a NetBIOS Service
- on a TCP/UDP transport: Detailed Specifications", STD 19, RFC
- 1002, March 1987.
-
- [21] Scheifler, R., "FYI On the X Window System", FYI 6, RFC 1198,
- MIT Laboratory for Computer Science, January 1991.
-
- [22] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1700,
- USC/Information Sciences Institute, July 1992.
-
-13. Security Considerations
-
- Security issues are not discussed in this memo.
-
-14. Authors' Addresses
-
- Steve Alexander
- Silicon Graphics, Inc.
- 2011 N. Shoreline Boulevard
-
-
-
-Alexander & Droms [Page 37]
-
-DRAFT DHCP Options and BOOTP Vendor Extensions December 1996
-
-
- Mailstop 510
- Mountain View, CA 94043-1389
-
- Phone: (415) 933-6172
- EMail: sca@engr.sgi.com
-
- Ralph Droms
- Bucknell University
- Lewisburg, PA 17837
-
- Phone: (717) 524-1145
- EMail: droms@bucknell.edu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Alexander & Droms [Page 38]
-
diff --git a/doc/draft-ietf-dhc-options-opt127-02.txt b/doc/draft-ietf-dhc-options-opt127-02.txt
deleted file mode 100644
index d42a33ea..00000000
--- a/doc/draft-ietf-dhc-options-opt127-02.txt
+++ /dev/null
@@ -1,167 +0,0 @@
-
-
-Network Working Group R. Droms
-INTERNET DRAFT Bucknell University
-Obsoletes: draft-ietf-dhc-options-opt127-01.txt April 1996
- Expires October 1996
-
-
- An Extension to the DHCP Option Codes
- <draft-ietf-dhc-options-opt127-02.txt>
-
-Status of this memo
-
- This document is an Internet-Draft. Internet-Drafts are working
- documents of the Internet Engineering Task Force (IETF), its areas,
- and its working groups. Note that other groups may also distribute
- working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as ``work in progress.''
-
- To learn the current status of any Internet-Draft, please check the
- ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
- Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
- munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
- ftp.isi.edu (US West Coast).
-
-Abstract
-
- The Dynamic Host Configuration Protocol (DHCP) provides a framework
- for passing configuration information to hosts on a TCP/IP network.
- This document defines a new option to extend the available option
- codes.
-
-Introduction
-
- The Dynamic Host Configuration Protocol (DHCP) [1] provides a
- framework for passing configuration information to hosts on a TCP/IP
- network. Configuration parameters and other control information are
- carried in tagged data items that are stored in the 'options' field
- of the DHCP message. The data items themselves are also called
- "options."
-
- Each option is assigned a one-octet option code. Options 128-254 are
- reserved for local use and at this time over half of the available
- options in the range 0-127 and option 255 have been assigned. This
- document defines a new option to extend the available option codes
- and new option to request the parameters represented by those new
-
-
-
-Droms [Page 1]
-
-DRAFT An extension to the DHCP Option Codes April 1996
-
-
- option codes.
-
-Definition of option 127
-
- Option code 127 indicates that the DHCP option has a two-octet
- extended option code. The format of these options is:
-
- Extended
- Code Len option code Data...
- +-----+-----+-----+-----+-----+-----+----
- | 127 | XXX | oh | ol | d1 | d2 | ...
- +-----+-----+-----+-----+-----+-----+----
-
- Other than the two-octet extended option code, these options are
- encoded and carried in DHCP messages identically to the options
- defined in RFC 1533 [2]. The high-order and low-order octets of the
- extended option code are stored in 'oh' and 'ol', respectively. The
- number of octets given in the 'len' field includes the two-octet
- extended option code.
-
- The two-octet extended option codes will be assigned through the
- mechanisms defined for the assignment of new options [3] after the
- current one-octet option codes have been exhausted.
-
-Definition of option 126
-
- This option is used by a DHCP client to request values for specified
- configuration paramaters that are identified by extended option codes
- as defined above. The list of n requested parameters is specified as
- 2n octets, where each pair of octets is a valid extended option code.
-
- The client MAY list the options in order of preference. The DHCP
- server is not required to return the options in the requested order,
- but MUST try to insert the requested options in the order requested
- by the client.
-
- The code for this option is 126. Its minimum length is 2.
-
- Extended
- Code Len option codes
- +-----+-----+-----+-----+-----+-----+----
- | 126 | XXX | c1h | c1l | c2h | c2l | ...
- +-----+-----+-----+-----+-----+-----+----
-
-
-
-
-
-
-
-
-Droms [Page 2]
-
-DRAFT An extension to the DHCP Option Codes April 1996
-
-
-References
-
- [1] Droms, R., "Dynamic Host Configuration Protocol", RFC 1531,
- Bucknell University, October 1993.
-
- [2] Alexander, S. and R. Droms, "DHCP Options and BOOTP Vendor
- Extensions", RFC 1533, Lachman Associates, October 1993.
-
- [3] Droms, R., "Procedure for Defining New DHCP Options", Work in
- progress, February, 1996.
-
-Security Considerations
-
- Security issues are not discussed in this document.
-
-Author's Address
-
- Ralph Droms
- Computer Science Department
- 323 Dana Engineering
- Bucknell University
- Lewisburg, PA 17837
-
- Phone: (717) 524-1145
- EMail: droms@bucknell.edu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Droms [Page 3]
-
diff --git a/doc/draft-ietf-dhc-renumbering-00.txt b/doc/draft-ietf-dhc-renumbering-00.txt
deleted file mode 100644
index c0f00843..00000000
--- a/doc/draft-ietf-dhc-renumbering-00.txt
+++ /dev/null
@@ -1,390 +0,0 @@
-
-
-INTERNET-DRAFT Lowell Gilbert
-DHC Working Group Epilogue Technology Corporation
-Network Area April 1996
- Expires October 1996
-
-
- Graceful renumbering of networks with DHCP
- <draft-ietf-dhc-renumbering-00.txt>
-
-Status of this memo
-
- This document is an Internet-Draft. Internet-Drafts are working
- documents of the Internet Engineering Task Force (IETF), its areas,
- and its working groups. Note that other groups may also distribute
- working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as ``work in progress.''
-
- To learn the current status of any Internet-Draft, please check the
- ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
- Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
- munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
- ftp.isi.edu (US West Coast).
-
-
-Abstract
-
- This document proposes a method for improving the ability of the
- Dynamic Host Configuration Protocol (DHCP) to assist in renumbering
- an internet. DHCP is already capable of supporting host renumbering
- by assigning a new address when a client attempts to renegotiate an
- existing lease, but this proposal makes host renumbering more
- graceful by providing for a transition period in which the client can
- use both addresses.
-
-
-
-
-
-
-
-Gilbert [Page 1]
-
-DRAFT Graceful renumbering of networks with DHCP April 1996
-
-
-Introduction
-
- This document proposes a method for improving the ability of the
- Dynamic Host Configuration Protocol (DHCP) to assist in renumbering an
- internet. DHCP is already capable of supporting host renumbering by
- assigning a new address when a client attempts to renegotiate an
- existing lease, but this proposal makes host renumbering more graceful
- by providing for a transition period in which the client can use both
- addresses. This enables the client to avoid disruption of existing
- communications that may have already bound themselves to the original
- address. This also enables the client to avoid disruption of new
- communications (when the existing address would no longer be valid) by
- ensuring they are bound to the new address.
-
- This proposal adds to the core DHC protocol a mechanism by which a
- DHCP client may acquire an additional IP address to eventually replace
- one already in use. A new option is defined for the server to start
- this process in the client. Significant modifications to the
- protocol's state machine are avoided by starting up a whole new state
- machine for handling the new address.
-
-
-Motivations
-
- Host addresses may need to change for a number of reasons. For
- example, if the address assignment scheme is based on CIDR
- guidelines, when a site changes its provider hosts within the site
- may need to change their addresses.
-
- The intention of the mechanism described here is to allow system
- administrators to specify a graceful transition period during
- renumbering to minimize disruption caused by address changes,
- particularly for hosts for which continuous availability is an
- important factor.
-
-
-
-
-
-
-
-
-
-
-Gilbert [Page 2]
-
-DRAFT Graceful renumbering of networks with DHCP April 1996
-
-
-Document Independence
-
- The most important point to note about this proposal is that it can
- be issued as a separate document from the protocol specification.
- There are three factors that make this practical:
-
- * the graceful renumbering support is optional,
-
- * the graceful renumbering support will be completely impossible
- for some existing platforms (i.e. those which aren't capable of
- having multiple addresses at one time anyway),
-
- * the graceful renumbering support doesn't in any way affect the
- operation of hosts or servers that don't implement it.
- Therefore, there's no good reason that it can't be split out on
- its own, to progress on its own (separate) merits.
-
-
-Design Goals
-
- * full backward compatibility with DHCP implementations compliant
- with RFC1541. This is essential for acceptance of new
- implementations with the new functionality.
-
- * no changes to relay agents. This is the key to the general DHCP
- migration strategy. The simpler a relay agent is, the more
- likely it is to be included in other network devices.
-
- * minimal impact upon the standards status (and advancement) of the
- base DHCP protocol. Acceptance of the core protocol is a
- prerequisite for acceptance of this one.
-
-
-Terminology:
-
-
- Use of the terms MUST, SHOULD, or SHOULD NOT in this document implies
- the usual meanings with respect to implementing this specification.
- However, none of this specification need be implemented for an
- implementation to be considered compliant with DHCP (for which
- compliance with RFC 1541 is necessary and sufficient).
-
-
-
-Gilbert [Page 3]
-
-DRAFT Graceful renumbering of networks with DHCP April 1996
-
-
-Requirements
-
- This proposal requires that any client be capable of binding more
- than one address to an interface at a time, and also that the client
- be able to distinguish among these addresses for the purpose of
- binding existing and new transport connections. It also requires
- that any server be able to track multiple bindings per client. If
- these requirements cannot be met, then the host in question can still
- implement DHCP, but won't be able to implement graceful renumbering
- support.
-
- A new option (the "renumbering" option) is defined for use in DHCPACK
- and DHCPDISCOVER messages. The length of this option is 4 octets.
- The presence of this option in a DHCPACK indicates that the client
- should initialize a new DHCP state machine for a new address. The
- option shall contain a "magic cookie" value which the server can use
- in tracking requests for new addresses; the client MUST NOT attempt
- to interpret the value.
-
- This proposal assumes that a DHCP Server would have to be configured
- with the new (post-renumbering) addresses, prior to the
- reconfiguration of any of the Relay Agents that point to that Server.
- Once the Server is configured with the new addresses, the Relay
- Agents that point to that server could be reconfigured on their own,
- without requiring any coordination with the Server. Under those
- conditions, this proposal can accommodate a situation where a client
- would receive a DHCPACK with the "renumbering" option, but the Relay
- Agent that serves the client would not be configured (yet) with a new
- (post-renumbering) address.
-
-
-Protocol Summary
-
-
- A renumbering option in a DHCPACK packet requests the client to begin
- trying to get a post-renumbering address. The post-renumbering
- address has its own DHCP state machine, which runs in parallel with
- the one for the pre-renumbering address (with both addresses active
- on the interface) until the lease runs out on the pre-renumbering
- address. Then the original state machine dies a quiet death.
-
-
-
-
-Gilbert [Page 4]
-
-DRAFT Graceful renumbering of networks with DHCP April 1996
-
-
-Client behaviour
-
-
- When a client receives the renumbering option in a DHCPACK packet, it
- MUST immediately initialize a new state machine for handling the new
- address. The old state machine SHOULD NOT attempt to renegotiate the
- lease after this point, and may terminate at any time thereafter, up
- to and including the termination of the lease. When the lease
- expires, the client MUST stop using that address and SHOULD release
- all resources related to that address.
-
- When the new state machine is initialized, it starts in the INIT
- state. Once it starts, it is responsible for acquiring a post-
- renumbering address and keeping this address on the interface; the
- responsibilities of the old state machine are now limited to deciding
- when to terminate.
-
- The renumbering option MUST be returned in the client's DHCPINIT
- message exactly as it was included in the DHCPACK message. The state
- machine then proceeds as normal, completely separate from the
- original state machine. When it receives a DHCPACK (for the *new*
- address), it SHOULD, if possible, arrange that the new address will
- be the address used by default on that particular interface. This
- means that any new transport connections should be bound to the new
- address, and that datagram protocols should switch to the new address
- as soon as practical.
-
-
- When a client receives the renumbering option in a DHCPACK packet,
- the client does the following:
-
- (1) If the received DHCPACK packet causes the DHCP state machine
- transition from Requesting to Bound state, then the client checks
- whether it has another DHCP state machine. If such a machine
- exists, then the client sends a DHCPRELEASE on the new machine,
- and terminates the new machine. The old machine continues to
- operate according to the normal DHCP operations. If no such (old)
- machine exists, then the new machine starts to operate according
- to the normal DHCP operations.
-
- (2) If the DHCPACK packet is received when the state machine is
-
-
-
-Gilbert [Page 5]
-
-DRAFT Graceful renumbering of networks with DHCP April 1996
-
-
- already in Bound, or Renewing, or Rebinding state, then the client
- marks the state machine as "deprecated" and immediately initiates
- another state machine. When the new state machine is initialized,
- it starts in the INIT state. The renumbering option MUST be
- returned in the client's DHCPINIT message exactly as it was
- included in the DHCPACK message. The state machine then proceeds
- as normal, completely separate from the original state machine.
- Once the new state machine starts, it attempts to acquire a post-
- renumbering address. If the attempt is successful, the client
- assigns this address on the interface; the responsibilities of the
- old state machine at that point would become limited to deciding
- when to terminate.
-
- When a client receives a DHCPACK packet without the renumbering
- option the client does the following:
-
- (1) If the received DHCPACK causes the DHCP state machine to
- transition into the Bound state, the client checks if it has
- another state machine which is marked as "deprecated". If yes,
- then the client SHOULD start using the newly acquired address for
- all the new transport connections, and that datagram protocols
- SHOULD switch to the new address as soon as practical. The
- existing connections are still bound to the old address (the
- address associated with the "deprecated" state machine). The
- "deprecated" machine SHOULD NOT attempt to renegotiate the lease
- after this point, and may terminate at any time thereafter, up to
- and including the termination of the lease. When the lease on the
- address associated with the "deprecated" state machine expires,
- the client MUST stop using that address and SHOULD release all
- resources related to that address.
-
- (2) In all other cases the client follows the standard DHCP
- procedures.
-
-
-
-Server behaviour
-
-
- As part of its database of addresses, a DHCP server MUST maintain
- state information for every address (or block of addresses)
-
-
-
-Gilbert [Page 6]
-
-DRAFT Graceful renumbering of networks with DHCP April 1996
-
-
- indicating whether that address is deprecated. When a DHCPREQUEST
- arrives, the server MUST check this state information.
-
- If the address being requested is not deprecated, the server
- continues as provided in RFC 1541. If, however, the address has been
- deprecated the server prepares a DHCPACK using the remainder of the
- available lease time, and in addition adds a renumbering option. The
- method of choosing a value for the renumbering option is an
- implentation decision. The server should be prepared to handle
- further negotiations on the deprecated address, even though the
- client is expected to stop such negotiations once it attempts to
- acquire a replacement address.
-
- If the server has no post-renumbering addresses available to offer to
- the client, it SHOULD offer the previous, deprecated address, in
- order to signal the problem to the client.
-
-
-
-Relay Agent behaviour
-
-
- The only requirement that this proposal places on relay agents is
- that they MUST place a "new" (i.e., post-renumbering) address for
- itself in the 'giaddr' field when passing on a DHCP message. Since
- this can, in the worst case, be accomplished by hand-configuration,
- modifications to relay agent software are not absolutely necessary.
-
-
-
-Discussion
-
-
- The option's cookie can be used for anything that the server wants.
- Two obvious possibilities are that it could be common across the
- whole renumbering, and that it could represent a binding to a
- particular client. Because the client's new state machine starts in
- INIT, the server will be able to gather subnet information from the
- broadcast DHCPDISCOVER.
-
- The idea behind using a new option to tell the client to initiate
-
-
-
-Gilbert [Page 7]
-
-DRAFT Graceful renumbering of networks with DHCP April 1996
-
-
- this process is that it avoids all of the problems that I saw in
- (Yakov Rekhter's) original version of this proposal. Those had to do
- with figuring out when to shut down a new state machine, and with the
- extra traffic from sending an extra DHCPDISCOVER every time you went
- back into the BOUND state.
-
-
-Acknowledgements
-
-
- This document owes a great deal to Yakov Rekhter's initial
- suggestions on the same subject. Input from both him and Ralph Droms
- had significant further effect on the document.
-
-
-References
-
-
- [1] Droms, R., "Dynamic Host Configuration Protocol", RFC 1531,
- Bucknell University, October 1993.
-
-Security Considerations
-
-
- Security issues are not discussed in this document.
-
-Author's Address
-
- Lowell Gilbert
- Lowell@Epilogue.Com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Gilbert [Page 8]
diff --git a/includes/cf/freebsd.h b/includes/cf/freebsd.h
index 965d3323..032d52c2 100644
--- a/includes/cf/freebsd.h
+++ b/includes/cf/freebsd.h
@@ -3,7 +3,8 @@
System dependencies for FreeBSD... */
/*
- * Copyright (c) 1996 The Internet Software Consortium. All rights reserved.
+ * Copyright (c) 1996, 1998 The Internet Software Consortium.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -53,7 +54,10 @@ extern int h_errno;
#include <net/if.h>
#include <net/if_dl.h>
-#define INADDR_LOOPBACK ((u_int32_t)0x7f000001)
+#include <net/if_arp.h>
+#if !defined (INADDR_LOOPBACK)
+# define INADDR_LOOPBACK ((u_int32_t)0x7f000001)
+#endif
/* Varargs stuff... */
#include <stdarg.h>
diff --git a/includes/cf/linux.h b/includes/cf/linux.h
index 4386a7e2..11bf1e61 100644
--- a/includes/cf/linux.h
+++ b/includes/cf/linux.h
@@ -63,7 +63,7 @@ extern int h_errno;
#include <net/if.h>
#include <net/route.h>
-#if defined (LINUX_1_X)
+#if LINUX_MAJOR == 1
# include <linux/if_arp.h>
# include <linux/time.h> /* also necessary */
#else
@@ -103,8 +103,14 @@ extern int h_errno;
#define GET_TIME(x) time ((x))
#if defined (USE_DEFAULT_NETWORK)
+# if (LINUX_MAJOR >= 2) && (LINUX_MINOR >= 1)
+# define USE_LPF
+# define LINUX_SLASHPROC_DISCOVERY
+# define PROCDEV_DEVICE "/proc/net/dev"
+# else
# define USE_SOCKETS
# define IGNORE_HOSTUNREACH
+# endif
#endif
#define ALIAS_NAMES_PERMUTED
diff --git a/includes/cf/sco.h b/includes/cf/sco.h
index 89c5f31c..e8be0903 100644
--- a/includes/cf/sco.h
+++ b/includes/cf/sco.h
@@ -83,9 +83,7 @@ extern int h_errno;
#define _PATH_DHCRELAY_PID "/etc/dhcrelay.pid"
#endif
-#if !defined (INADDR_LOOPBACK)
#define INADDR_LOOPBACK ((u_int32_t)0x7f000001)
-#endif
/* Varargs stuff: use stdarg.h instead ... */
#include <stdarg.h>
diff --git a/includes/cf/sunos5-5.h b/includes/cf/sunos5-5.h
index a5b7cd85..6917cd5b 100644
--- a/includes/cf/sunos5-5.h
+++ b/includes/cf/sunos5-5.h
@@ -117,12 +117,13 @@ extern int h_errno;
#define NEED_INET_ATON
-/* By default, use the DLPI API for receiving and sending packets. */
+/* By default, use BSD Socket API for receiving and sending packets.
+ This actually works pretty well on Solaris, which doesn't censor
+ the all-ones broadcast address. */
#if defined (USE_DEFAULT_NETWORK)
# define USE_DLPI
-# define USE_DLPI_RAW
+/* # define USE_DLPI_RAW */
# define USE_DLPI_PFMOD
-# define DLPI_FIRST_SEND_WAIT 6
#endif
#define USE_POLL
@@ -137,11 +138,7 @@ extern int h_errno;
#define TIME time_t
#define GET_TIME(x) time ((x))
-/* Solaris prior to 2.5 didn't have random(). Rather than being clever and
- using random() only on versions >2.5, always use rand() and srand(). */
-
#define random() rand()
-#define srandom(x) srand(x)
/* Solaris doesn't provide an endian.h, so we have to do it. */
diff --git a/includes/cf/ultrix.h b/includes/cf/ultrix.h
index 76662b28..da7c35c6 100644
--- a/includes/cf/ultrix.h
+++ b/includes/cf/ultrix.h
@@ -65,7 +65,6 @@ extern int h_errno;
#define int8_t char
#define int16_t short
#define int32_t long
-#define ssize_t long
#define u_int8_t unsigned char /* Not quite POSIX... */
#define u_int16_t unsigned short
@@ -87,7 +86,6 @@ extern int h_errno;
#define VA_start(list, last) va_start (list)
#define vsnprintf(buf, size, fmt, list) vsprintf (buf, fmt, list)
#define NO_SNPRINTF
-#define NEED_INET_ATON
#define INADDR_LOOPBACK ((u_int32_t)0x7f000001)
#define EOL '\n'
diff --git a/includes/dhcp.h b/includes/dhcp.h
index 840c86d6..b96ec3d0 100644
--- a/includes/dhcp.h
+++ b/includes/dhcp.h
@@ -84,6 +84,7 @@ struct dhcp_packet {
/* Possible values for hardware type (htype) field... */
#define HTYPE_ETHER 1 /* Ethernet 10Mbps */
#define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
+#define HTYPE_FDDI 8 /* FDDI... */
/* Magic cookie validating dhcp options field (and bootp vendor
extensions field). */
@@ -154,7 +155,6 @@ struct dhcp_packet {
#define DHO_DHCP_CLASS_IDENTIFIER 60
#define DHO_DHCP_CLIENT_IDENTIFIER 61
#define DHO_DHCP_USER_CLASS_ID 77
-#define DHO_DHCP_AGENT_OPTIONS 82
#define DHO_END 255
/* DHCP message types. */
@@ -166,8 +166,3 @@ struct dhcp_packet {
#define DHCPNAK 6
#define DHCPRELEASE 7
#define DHCPINFORM 8
-
-/* Relay Agent Information option subtypes: */
-#define RAI_CIRCUIT_ID 1
-#define RAI_REMOTE_ID 2
-#define RAI_AGENT_ID 3
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index c91320ba..b78e6e8d 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -63,12 +63,16 @@
#include "cdefs.h"
#include "osdep.h"
#include "dhcp.h"
-#include "statement.h"
#include "tree.h"
#include "hash.h"
#include "inet.h"
#include "sysconf.h"
+struct option_data {
+ int len;
+ u_int8_t *data;
+};
+
struct string_list {
struct string_list *next;
char string [1];
@@ -88,32 +92,6 @@ struct domain_search_list {
TIME rcdate;
};
-/* Option tag structures are used to build chains of option tags, for
- when we're sure we're not going to have enough of them to justify
- maintaining an array. */
-
-struct option_tag {
- struct option_tag *next;
- u_int8_t data [1];
-};
-
-/* An agent option structure. We need a special structure for the
- Relay Agent Information option because if more than one appears in
- a message, we have to keep them seperate. */
-
-struct agent_options {
- struct agent_options *next;
- int length;
- struct option_tag *first;
-};
-
-/* The data associated with a given option in an array of options. */
-
-struct option_data {
- int len;
- u_int8_t *data;
-};
-
/* A dhcp packet and the pointers to its option values. */
struct packet {
struct dhcp_packet *raw;
@@ -128,17 +106,8 @@ struct packet {
of local sender (maybe gateway). */
struct shared_network *shared_network;
struct option_data options [256];
- struct agent_options *agent_options; /* Received agent options. */
-
-#if !defined (PACKET_MAX_CLASSES)
-# define PACKET_MAX_CLASSES 5
-#endif
- int class_count;
- struct class *classes [PACKET_MAX_CLASSES];
};
-/* A network interface's MAC address. */
-
struct hardware {
u_int8_t htype;
u_int8_t hlen;
@@ -177,12 +146,6 @@ struct lease {
struct lease_state *state;
};
-struct option_state {
- struct option_cache *dhcp_options [256];
- struct option_cache *server_options [256];
- struct agent_options *agent_options;
-};
-
struct lease_state {
struct lease_state *next;
@@ -190,10 +153,12 @@ struct lease_state {
TIME offered_expiry;
- struct option_state options;
- int max_message_size;
+ struct tree_cache *options [256];
u_int32_t expiry, renewal, rebind;
- struct data_string filename, server_name;
+ char filename [DHCP_FILE_LEN];
+ char *server_name;
+
+ struct iaddr from;
u_int32_t xid;
u_int16_t secs;
@@ -219,45 +184,31 @@ struct lease_state {
#define DISCOVER_RELAY 3
#define DISCOVER_REQUESTED 4
-/* Server option names. */
-
-#define SV_DEFAULT_LEASE_TIME 1
-#define SV_MAX_LEASE_TIME 2
-#define SV_MIN_LEASE_TIME 3
-#define SV_BOOTP_LEASE_CUTOFF 4
-#define SV_BOOTP_LEASE_LENGTH 5
-#define SV_BOOT_UNKNOWN_CLIENTS 6
-#define SV_DYNAMIC_BOOTP 7
-#define SV_ALLOW_BOOTP 8
-#define SV_ALLOW_BOOTING 9
-#define SV_ONE_LEASE_PER_CLIENT 10
-#define SV_GET_LEASE_HOSTNAMES 11
-#define SV_USE_HOST_DECL_NAMES 12
-#define SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE 13
-#define SV_MIN_SECS 14
-#define SV_FILENAME 15
-#define SV_SERVER_NAME 16
-#define SV_NEXT_SERVER 17
-
-#if !defined (DEFAULT_DEFAULT_LEASE_TIME)
-# define DEFAULT_DEFAULT_LEASE_TIME 43200
-#endif
-
-#if !defined (DEFAULT_MIN_LEASE_TIME)
-# define DEFAULT_MIN_LEASE_TIME 43200
-#endif
-
-#if !defined (DEFAULT_MAX_LEASE_TIME)
-# define DEFAULT_MAX_LEASE_TIME 86400
-#endif
-
/* Group of declarations that share common parameters. */
struct group {
struct group *next;
struct subnet *subnet;
struct shared_network *shared_network;
- struct executable_statement *statements;
+
+ TIME default_lease_time;
+ TIME max_lease_time;
+ TIME bootp_lease_cutoff;
+ TIME bootp_lease_length;
+
+ char *filename;
+ char *server_name;
+ struct iaddr next_server;
+
+ int boot_unknown_clients;
+ int dynamic_bootp;
+ int allow_bootp;
+ int allow_booting;
+ int one_lease_per_client;
+ int get_lease_hostnames;
+ int use_host_decl_names;
+
+ struct tree_cache *options [256];
};
/* A dhcp host declaration structure. */
@@ -265,8 +216,7 @@ struct host_decl {
struct host_decl *n_ipaddr;
char *name;
struct hardware interface;
- struct data_string client_identifier;
- struct option_cache *fixed_addr;
+ struct tree_cache *fixed_addr;
struct group *group;
};
@@ -294,25 +244,10 @@ struct subnet {
struct group *group;
};
-struct collection {
- struct collection *next;
-
- char *name;
- struct class *classes;
-};
-
struct class {
- struct class *nic; /* Next in collection. */
- char *name; /* Optional... */
+ char *name;
- struct hash_table *hash;
- struct expression *expr;
- struct expression *spawn;
-
struct group *group;
-
- /* Statements to execute if class matches. */
- struct executable_statement *statements;
};
/* DHCP client lease structure... */
@@ -453,77 +388,6 @@ struct protocol {
void *local;
};
-struct dns_query; /* forward */
-
-struct dns_wakeup {
- struct dns_wakeup *next; /* Next wakeup in chain. */
- void (*func) PROTO ((struct dns_query *));
-};
-
-struct dns_question {
- u_int16_t type; /* Type of query. */
- u_int16_t class; /* Class of query. */
- unsigned char data [1]; /* Query data. */
-};
-
-struct dns_answer {
- u_int16_t type; /* Type of answer. */
- u_int16_t class; /* Class of answer. */
- int count; /* Number of answers. */
- unsigned char *answers[1]; /* Pointers to answers. */
-};
-
-struct dns_query {
- struct dns_query *next; /* Next query in hash bucket. */
- u_int32_t hash; /* Hash bucket index. */
- TIME expiry; /* Query expiry time (zero if not yet
- answered. */
- u_int16_t id; /* Query ID (also hash table index) */
- caddr_t waiters; /* Pointer to list of things waiting
- on this query. */
-
- struct dns_question *question; /* Question, internal format. */
- struct dns_answer *answer; /* Answer, internal format. */
-
- unsigned char *query; /* Query formatted for DNS server. */
- int len; /* Length of entire query. */
- int sent; /* The query has been sent. */
- struct dns_wakeup *wakeups; /* Wakeups to call if this query is
- answered. */
- struct name_server *next_server; /* Next server to try. */
- int backoff; /* Current backoff, in seconds. */
-};
-
-struct interact_client; /* forward */
-
-/* Actions that can be taken by an interactive connection to the dhcp server
- or client. */
-
-struct interact_actions {
- void (*ls) PROTO ((struct interact_client *));
- void (*print) PROTO ((struct interact_client *, char *));
- void (*set) PROTO ((struct interact_client *, char *));
- void (*rm) PROTO ((struct interact_client *, char *));
- void (*cd) PROTO ((struct interact_client *, char *));
- void (*cdup) PROTO ((struct interact_client *));
- void * (*next) PROTO ((struct interact_client *, void *));
-};
-
-/* Interactive connection state. */
-
-struct interact_client {
- struct interact_client *next;
- int fd;
- struct interact_actions cur_node_actions;
- void *cur_node;
- int cur_node_classp;
- int last_input;
- struct protocol *proto;
-
- char ibuf [1024];
- int ibuflen;
-};
-
/* Bitmask of dhcp option codes. */
typedef unsigned char option_mask [16];
@@ -591,23 +455,15 @@ typedef unsigned char option_mask [16];
void parse_options PROTO ((struct packet *));
void parse_option_buffer PROTO ((struct packet *, unsigned char *, int));
-int parse_agent_information_option PROTO ((struct packet *, int, u_int8_t *));
-int cons_options PROTO ((struct packet *, struct dhcp_packet *, int,
- struct option_state *, int, int, int));
-int store_options PROTO ((unsigned char *, int, struct option_cache **,
+int cons_options PROTO ((struct packet *, struct dhcp_packet *,
+ struct tree_cache **, int, int, int));
+int store_options PROTO ((unsigned char *, int, struct tree_cache **,
unsigned char *, int, int, int, int));
char *pretty_print_option PROTO ((unsigned int,
unsigned char *, int, int, int));
void do_packet PROTO ((struct interface_info *,
struct dhcp_packet *, int,
unsigned int, struct iaddr, struct hardware *));
-struct data_string dhcp_option_lookup PROTO ((struct packet *, int));
-struct data_string agent_suboption_lookup PROTO ((struct packet *, int));
-struct data_string server_option_lookup PROTO ((struct packet *, int));
-void dhcp_option_set PROTO ((struct option_state *, struct option_cache *,
- enum statement_op));
-void server_option_set PROTO ((struct option_state *, struct option_cache *,
- enum statement_op));
/* errwarn.c */
extern int warnings_occurred;
@@ -626,16 +482,10 @@ extern u_int16_t remote_port;
extern int log_priority;
extern int log_perror;
-#ifdef USE_FALLBACK
-extern struct interface_info fallback_interface;
-#endif
-
extern char *path_dhcpd_conf;
extern char *path_dhcpd_db;
extern char *path_dhcpd_pid;
-extern int dhcp_max_agent_option_packet_length;
-
int main PROTO ((int, char **, char **));
void cleanup PROTO ((void));
void lease_pinged PROTO ((struct iaddr, u_int8_t *, int));
@@ -656,67 +506,41 @@ int readconf PROTO ((void));
void read_leases PROTO ((void));
int parse_statement PROTO ((FILE *,
struct group *, int, struct host_decl *, int));
-struct option_cache *parse_allow_deny PROTO ((FILE *, int));
+void parse_allow_deny PROTO ((FILE *, struct group *, int));
+void skip_to_semi PROTO ((FILE *));
int parse_boolean PROTO ((FILE *));
+int parse_semi PROTO ((FILE *));
int parse_lbrace PROTO ((FILE *));
void parse_host_declaration PROTO ((FILE *, struct group *));
+char *parse_host_name PROTO ((FILE *));
void parse_class_declaration PROTO ((FILE *, struct group *, int));
+void parse_lease_time PROTO ((FILE *, TIME *));
void parse_shared_net_declaration PROTO ((FILE *, struct group *));
void parse_subnet_declaration PROTO ((FILE *, struct shared_network *));
void parse_group_declaration PROTO ((FILE *, struct group *));
-struct option_cache *parse_fixed_addr_param PROTO ((FILE *));
+void parse_hardware_param PROTO ((FILE *, struct hardware *));
+char *parse_string PROTO ((FILE *));
+struct tree *parse_ip_addr_or_hostname PROTO ((FILE *, int));
+struct tree_cache *parse_fixed_addr_param PROTO ((FILE *));
+void parse_option_param PROTO ((FILE *, struct group *));
TIME parse_timestamp PROTO ((FILE *));
struct lease *parse_lease_declaration PROTO ((FILE *));
void parse_address_range PROTO ((FILE *, struct subnet *));
-
-/* parse.c */
-void skip_to_semi PROTO ((FILE *));
-int parse_semi PROTO ((FILE *));
-char *parse_string PROTO ((FILE *));
-char *parse_host_name PROTO ((FILE *));
-struct expression *parse_ip_addr_or_hostname PROTO ((FILE *, int));
-void parse_hardware_param PROTO ((FILE *, struct hardware *));
-void parse_lease_time PROTO ((FILE *, TIME *));
+TIME parse_date PROTO ((FILE *));
unsigned char *parse_numeric_aggregate PROTO ((FILE *,
unsigned char *, int *,
int, int, int));
void convert_num PROTO ((unsigned char *, char *, int, int));
-TIME parse_date PROTO ((FILE *));
-struct option *parse_option_name PROTO ((FILE *));
-unsigned char *parse_cshl PROTO ((FILE *, int *));
-struct executable_statement *parse_executable_statement PROTO ((FILE *,
- int *));
-struct executable_statement *parse_executable_statements PROTO ((FILE *,
- int *));
-struct executable_statement *parse_if_statement PROTO ((FILE *, int *));
-struct expression *parse_boolean_expression PROTO ((FILE *, int *));
-struct expression *parse_data_expression PROTO ((FILE *, int *));
-struct expression *parse_numeric_expression PROTO ((FILE *, int *));
-struct executable_statement *parse_option_statement PROTO ((FILE *, int,
- struct option *,
- enum statement_op)
- );
-struct expression *parse_option_token PROTO ((FILE *, char *,
- struct expression *, int, int));
/* tree.c */
pair cons PROTO ((caddr_t, pair));
-struct expression *make_host_lookup PROTO ((char *));
+struct tree_cache *tree_cache PROTO ((struct tree *));
+struct tree *tree_host_lookup PROTO ((char *));
struct dns_host_entry *enter_dns_host PROTO ((char *));
-struct expression *make_const_data PROTO ((unsigned char *, int, int, int));
-struct expression *make_concat PROTO ((struct expression *,
- struct expression *));
-struct expression *make_substring PROTO ((struct expression *,
- struct expression *,
- struct expression *));
-struct expression *make_limit PROTO ((struct expression *, int));
-struct option_cache *option_cache PROTO ((struct expression *,
- struct option *));
-int evaluate_boolean_expression PROTO ((struct packet *, struct expression *));
-struct data_string evaluate_data_expression PROTO ((struct packet *,
- struct expression *));
-unsigned long evaluate_numeric_expression PROTO ((struct packet *,
- struct expression *));
+struct tree *tree_const PROTO ((unsigned char *, int));
+struct tree *tree_concat PROTO ((struct tree *, struct tree *));
+struct tree *tree_limit PROTO ((struct tree *, int));
+int tree_evaluate PROTO ((struct tree_cache *));
/* dhcp.c */
extern int outstanding_pings;
@@ -752,12 +576,12 @@ extern struct subnet *find_grouped_subnet PROTO ((struct shared_network *,
struct iaddr));
extern struct subnet *find_subnet PROTO ((struct iaddr));
void enter_shared_network PROTO ((struct shared_network *));
+int subnet_inner_than PROTO ((struct subnet *, struct subnet *, int));
void enter_subnet PROTO ((struct subnet *));
void enter_lease PROTO ((struct lease *));
int supersede_lease PROTO ((struct lease *, struct lease *, int));
void release_lease PROTO ((struct lease *));
void abandon_lease PROTO ((struct lease *, char *));
-void dissociate_lease PROTO ((struct lease *));
struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
struct lease *find_lease_by_hw_addr PROTO ((unsigned char *, int));
struct lease *find_lease_by_ip_addr PROTO ((struct iaddr));
@@ -765,6 +589,8 @@ void uid_hash_add PROTO ((struct lease *));
void uid_hash_delete PROTO ((struct lease *));
void hw_hash_add PROTO ((struct lease *));
void hw_hash_delete PROTO ((struct lease *));
+struct class *add_class PROTO ((int, char *));
+struct class *find_class PROTO ((int, unsigned char *, int));
struct group *clone_group PROTO ((struct group *, char *));
void write_leases PROTO ((void));
void dump_subnets PROTO ((void));
@@ -774,8 +600,8 @@ VOIDPTR dmalloc PROTO ((int, char *));
void dfree PROTO ((VOIDPTR, char *));
struct packet *new_packet PROTO ((char *));
struct dhcp_packet *new_dhcp_packet PROTO ((char *));
-struct expression *new_expression PROTO ((char *));
-struct option_cache *new_option_cache PROTO ((char *));
+struct tree *new_tree PROTO ((char *));
+struct tree_cache *new_tree_cache PROTO ((char *));
struct hash_table *new_hash_table PROTO ((int, char *));
struct hash_bucket *new_hash_bucket PROTO ((char *));
struct lease *new_lease PROTO ((char *));
@@ -799,10 +625,10 @@ void free_subnet PROTO ((struct subnet *, char *));
void free_lease PROTO ((struct lease *, char *));
void free_hash_bucket PROTO ((struct hash_bucket *, char *));
void free_hash_table PROTO ((struct hash_table *, char *));
-void free_expression PROTO ((struct expression *, char *));
+void free_tree_cache PROTO ((struct tree_cache *, char *));
void free_packet PROTO ((struct packet *, char *));
void free_dhcp_packet PROTO ((struct dhcp_packet *, char *));
-void free_option_cache PROTO ((struct option_cache *, char *));
+void free_tree PROTO ((struct tree *, char *));
/* print.c */
char *print_hw_addr PROTO ((int, int, unsigned char *));
@@ -824,7 +650,6 @@ ssize_t send_fallback PROTO ((struct interface_info *,
struct packet *, struct dhcp_packet *, size_t,
struct in_addr,
struct sockaddr_in *, struct hardware *));
-void fallback_discard PROTO ((struct protocol *));
#endif
#ifdef USE_SOCKET_SEND
@@ -835,6 +660,9 @@ ssize_t send_packet PROTO ((struct interface_info *,
struct in_addr,
struct sockaddr_in *, struct hardware *));
#endif
+#if defined (USE_SOCKET_FALLBACK)
+void fallback_discard PROTO ((struct protocol *));
+#endif
#ifdef USE_SOCKET_RECEIVE
void if_reinitialize_receive PROTO ((struct interface_info *));
void if_register_receive PROTO ((struct interface_info *));
@@ -843,7 +671,8 @@ ssize_t receive_packet PROTO ((struct interface_info *,
struct sockaddr_in *, struct hardware *));
#endif
#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
-void if_enable PROTO ((struct interface_info *));
+int can_unicast_without_arp PROTO ((void));
+void maybe_setup_fallback PROTO ((void));
#endif
/* bpf.c */
@@ -866,7 +695,32 @@ ssize_t receive_packet PROTO ((struct interface_info *,
struct sockaddr_in *, struct hardware *));
#endif
#if defined (USE_BPF_SEND)
-void if_enable PROTO ((struct interface_info *));
+int can_unicast_without_arp PROTO ((void));
+void maybe_setup_fallback PROTO ((void));
+#endif
+
+/* lpf.c */
+#if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
+int if_register_lpf PROTO ( (struct interface_info *));
+#endif
+#ifdef USE_LPF_SEND
+void if_reinitialize_send PROTO ((struct interface_info *));
+void if_register_send PROTO ((struct interface_info *));
+ssize_t send_packet PROTO ((struct interface_info *,
+ struct packet *, struct dhcp_packet *, size_t,
+ struct in_addr,
+ struct sockaddr_in *, struct hardware *));
+#endif
+#ifdef USE_LPF_RECEIVE
+void if_reinitialize_receive PROTO ((struct interface_info *));
+void if_register_receive PROTO ((struct interface_info *));
+ssize_t receive_packet PROTO ((struct interface_info *,
+ unsigned char *, size_t,
+ struct sockaddr_in *, struct hardware *));
+#endif
+#if defined (USE_LPF_SEND)
+int can_unicast_without_arp PROTO ((void));
+void maybe_setup_fallback PROTO ((void));
#endif
/* nit.c */
@@ -890,12 +744,8 @@ ssize_t receive_packet PROTO ((struct interface_info *,
struct sockaddr_in *, struct hardware *));
#endif
#if defined (USE_NIT_SEND)
-void if_enable PROTO ((struct interface_info *));
-#endif
-
-/* dlpi.c */
-#if defined (USE_DLPI_SEND) || defined (USE_DLPI_RECEIVE)
-int if_register_dlpi PROTO ( (struct interface_info *));
+int can_unicast_without_arp PROTO ((void));
+void maybe_setup_fallback PROTO ((void));
#endif
#ifdef USE_DLPI_SEND
@@ -913,7 +763,10 @@ ssize_t receive_packet PROTO ((struct interface_info *,
unsigned char *, size_t,
struct sockaddr_in *, struct hardware *));
#endif
-
+#if defined (USE_DLPI_SEND)
+int can_unicast_without_arp PROTO ((void));
+void maybe_setup_fallback PROTO ((void));
+#endif
/* raw.c */
#ifdef USE_RAW_SEND
@@ -923,10 +776,13 @@ ssize_t send_packet PROTO ((struct interface_info *,
struct packet *, struct dhcp_packet *, size_t,
struct in_addr,
struct sockaddr_in *, struct hardware *));
+int can_unicast_without_arp PROTO ((void));
+void maybe_setup_fallback PROTO ((void));
#endif
/* dispatch.c */
-extern struct interface_info *interfaces, *dummy_interfaces;
+extern struct interface_info *interfaces,
+ *dummy_interfaces, *fallback_interface;
extern struct protocol *protocols;
extern int quiet_interface_discovery;
extern void (*bootp_packet_handler) PROTO ((struct interface_info *,
@@ -935,38 +791,32 @@ extern void (*bootp_packet_handler) PROTO ((struct interface_info *,
struct iaddr, struct hardware *));
extern struct timeout *timeouts;
void discover_interfaces PROTO ((int));
+struct interface_info *setup_fallback PROTO ((void));
void reinitialize_interfaces PROTO ((void));
void dispatch PROTO ((void));
int locate_network PROTO ((struct packet *));
+void got_one PROTO ((struct protocol *));
void add_timeout PROTO ((TIME, void (*) PROTO ((void *)), void *));
-#if 0
-void add_fast_timeout PROTO ((UTIME, void (*) PROTO ((void *)), void *));
-#endif
void cancel_timeout PROTO ((void (*) PROTO ((void *)), void *));
-struct protocol *add_protocol PROTO ((char *, int,
- void (*) PROTO ((struct protocol *)),
- void *));
+void add_protocol PROTO ((char *, int,
+ void (*) PROTO ((struct protocol *)), void *));
void remove_protocol PROTO ((struct protocol *));
/* hash.c */
struct hash_table *new_hash PROTO ((void));
-void add_hash PROTO ((struct hash_table *,
- unsigned char *, int, unsigned char *));
+void add_hash PROTO ((struct hash_table *, unsigned char *,
+ int, unsigned char *));
void delete_hash_entry PROTO ((struct hash_table *, unsigned char *, int));
unsigned char *hash_lookup PROTO ((struct hash_table *, unsigned char *, int));
/* tables.c */
-extern struct universe dhcp_universe;
extern struct option dhcp_options [256];
-extern struct universe agent_universe;
-extern struct option agent_options [256];
-extern struct universe server_universe;
-extern struct option server_options [256];
extern unsigned char dhcp_option_default_priority_list [];
extern int sizeof_dhcp_option_default_priority_list;
extern char *hardware_types [256];
extern struct hash_table universe_hash;
+extern struct universe dhcp_universe;
void initialize_universes PROTO ((void));
/* convert.c */
@@ -976,8 +826,8 @@ u_int16_t getUShort PROTO ((unsigned char *));
int16_t getShort PROTO ((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 putUShort PROTO ((unsigned char *, unsigned int));
+void putShort PROTO ((unsigned char *, int));
/* inet.c */
struct iaddr subnet_number PROTO ((struct iaddr, struct iaddr));
@@ -1048,7 +898,7 @@ u_int32_t wrapsum PROTO ((u_int32_t));
void assemble_hw_header PROTO ((struct interface_info *, unsigned char *,
int *, struct hardware *));
void assemble_udp_ip_header PROTO ((struct interface_info *, unsigned char *,
- int *, u_int32_t, u_int32_t, u_int32_t,
+ int *, u_int32_t, u_int32_t, unsigned int,
unsigned char *, int));
ssize_t decode_hw_header PROTO ((struct interface_info *, unsigned char *,
int, struct hardware *));
@@ -1126,12 +976,7 @@ void icmp_echoreply PROTO ((struct protocol *));
/* dns.c */
void dns_startup PROTO ((void));
-struct dns_query *find_dns_query PROTO ((struct dns_question *, int));
-void destroy_dns_query PROTO ((struct dns_query *));
-struct dns_query *ns_inaddr_lookup PROTO ((struct iaddr, struct dns_wakeup *));
-struct dns_query *ns_query PROTO ((struct dns_question *,
- unsigned char *, int, struct dns_wakeup *));
-void dns_timeout PROTO ((void *));
+int ns_inaddr_lookup PROTO ((u_int16_t, struct iaddr));
void dns_packet PROTO ((struct protocol *));
/* resolv.c */
@@ -1140,43 +985,14 @@ struct name_server *name_servers;
struct domain_search_list *domains;
void read_resolv_conf PROTO ((TIME));
-struct name_server *first_name_server PROTO ((void));
+struct sockaddr_in *pick_name_server PROTO ((void));
/* inet_addr.c */
#ifdef NEED_INET_ATON
-int inet_aton PROTO ((char *, struct in_addr *));
+int inet_aton PROTO ((const char *, struct in_addr *));
#endif
/* sysconf.c */
void sysconf_startup PROTO ((void (*) (struct sysconf_header *, void *)));
void sysconf_restart PROTO ((void *));
void sysconf_message PROTO ((struct protocol *proto));
-
-/* interact.c */
-void interact_startup PROTO ((void));
-void new_interact_connection PROTO ((struct protocol *));
-void interact_client_input PROTO ((struct protocol *));
-int interact_client_write PROTO ((struct interact_client *, char *, int));
-
-/* dhcpdi.c */
-extern struct interact_actions top_level_actions;
-
-/* class.c */
-struct class unknown_class;
-struct class known_class;
-struct collection default_collection;
-struct collection *collections;
-struct executable_statement *default_classification_rules;
-
-void classification_setup PROTO ((void));
-void classify_client PROTO ((struct packet *));
-int check_collection PROTO ((struct packet *, struct collection *));
-void classify PROTO ((struct packet *, struct class *));
-struct class *find_class PROTO ((char *));
-
-/* execute.c */
-int execute_statements PROTO ((struct packet *, struct option_state *,
- struct executable_statement *));
-void execute_statements_in_scope PROTO ((struct packet *,
- struct option_state *,
- struct group *, struct group *));
diff --git a/includes/dhctoken.h b/includes/dhctoken.h
index d26f7bd4..f7014b46 100644
--- a/includes/dhctoken.h
+++ b/includes/dhctoken.h
@@ -3,7 +3,7 @@
Tokens for config file lexer and parser. */
/*
- * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -47,9 +47,6 @@
#define SLASH '/'
#define LBRACE '{'
#define RBRACE '}'
-#define LPAREN '('
-#define RPAREN ')'
-#define EQUAL '='
#define FIRST_TOKEN HOST
#define HOST 256
@@ -127,25 +124,7 @@
#define HOSTNAME 328
#define CLIENT_HOSTNAME 329
#define REJECT 330
-#define USE_LEASE_ADDR_FOR_DEFAULT_ROUTE 331
-#define MIN_LEASE_TIME 332
-#define MIN_SECS 333
-#define AND 334
-#define OR 335
-#define NOT 336
-#define SUBSTRING 337
-#define SUFFIX 338
-#define CHECK 339
-#define EXTRACT_INT 340
-#define IF 341
-#define ADD 342
-#define BREAK 343
-#define ELSE 344
-#define ELSIF 345
-#define SUBCLASS 346
-#define MATCH 347
-#define SPAWN 348
-#define WITH 349
+#define FDDI 331
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
(x) != STRING && \
diff --git a/includes/hash.h b/includes/hash.h
index d86babad..1bebb314 100644
--- a/includes/hash.h
+++ b/includes/hash.h
@@ -3,7 +3,7 @@
Definitions for hashing... */
/*
- * Copyright (c) 1995, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -54,8 +54,3 @@ struct hash_table {
struct hash_bucket *buckets [DEFAULT_HASH_SIZE];
};
-struct named_hash {
- struct named_hash *next;
- char *name;
- struct hash_table *hash;
-};
diff --git a/includes/osdep.h b/includes/osdep.h
index 4ea4cd86..ca40e8a7 100644
--- a/includes/osdep.h
+++ b/includes/osdep.h
@@ -51,6 +51,9 @@
!defined (USE_BPF) && \
!defined (USE_BPF_SEND) && \
!defined (USE_BPF_RECEIVE) && \
+ !defined (USE_LPF) && \
+ !defined (USE_LPF_SEND) && \
+ !defined (USE_LPF_RECEIVE) && \
!defined (USE_NIT) && \
!defined (USE_NIT_SEND) && \
!defined (USE_NIT_RECEIVE) && \
@@ -141,6 +144,11 @@
# define USE_BPF_RECEIVE
#endif
+#ifdef USE_LPF
+# define USE_LPF_SEND
+# define USE_LPF_RECEIVE
+#endif
+
#ifdef USE_NIT
# define USE_NIT_SEND
# define USE_NIT_RECEIVE
@@ -165,7 +173,7 @@
fallback. */
#if defined (USE_BPF_SEND) || defined (USE_NIT_SEND) || \
- defined (USE_DLPI_SEND) || defined (USE_UPF_SEND)
+ defined (USE_DLPI_SEND) || defined (USE_UPF_SEND) || defined (USE_LPF_SEND)
# define USE_SOCKET_FALLBACK
# define USE_FALLBACK
#endif
@@ -178,7 +186,7 @@
#if defined (USE_RAW_SEND) || defined (USE_BPF_SEND) || \
defined (USE_NIT_SEND) || defined (USE_UPF_SEND) || \
- defined (USE_DLPI_SEND)
+ defined (USE_DLPI_SEND) || defined (USE_LPF_SEND)
# define PACKET_ASSEMBLY
#endif
@@ -190,7 +198,7 @@
#if defined (USE_RAW_RECEIVE) || defined (USE_BPF_SEND) || \
defined (USE_NIT_RECEIVE) || defined (USE_UPF_RECEIVE) || \
- defined (USE_DLPI_RECEIVE)
+ defined (USE_DLPI_RECEIVE) || defined (USE_LPF_RECEIVE)
# define PACKET_DECODING
#endif
diff --git a/includes/statement.h b/includes/statement.h
deleted file mode 100644
index e79274ed..00000000
--- a/includes/statement.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* statement.h
-
- Definitions for executable statements... */
-
-/*
- * Copyright (c) 1998 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises. To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''. To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-struct executable_statement {
- struct executable_statement *next;
- enum statement_op {
- if_statement,
- add_statement,
- eval_statement,
- break_statement,
- default_option_statement,
- supersede_option_statement,
- append_option_statement,
- prepend_option_statement,
- } op;
- union {
- struct {
- struct executable_statement *true, *false;
- struct expression *expr;
- } ie;
- struct expression *eval;
- struct class *add;
- struct option_cache *option;
- struct option_cache *supersede;
- struct option_cache *prepend;
- struct option_cache *append;
- } data;
-};
-
diff --git a/includes/tree.h b/includes/tree.h
index e4a62841..c2df41f5 100644
--- a/includes/tree.h
+++ b/includes/tree.h
@@ -3,8 +3,7 @@
Definitions for address trees... */
/*
- * Copyright (c) 1995, 1998 The Internet Software Consortium.
- * All rights reserved.
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -51,95 +50,51 @@ typedef struct _pair {
#define TREE_HOST_LOOKUP 2
#define TREE_CONST 3
#define TREE_LIMIT 4
-#define TREE_DATA_EXPR 5
-/* A string of data bytes, possibly accompanied by a larger buffer. */
-struct data_string {
- unsigned char *data, *buffer;
- int len;
- int terminated;
-};
-
-/* Expression tree structure. */
-
-struct expression {
- enum {
- expr_check,
- expr_equal,
- expr_substring,
- expr_suffix,
- expr_concat,
- expr_host_lookup,
- expr_and,
- expr_or,
- expr_not,
- expr_option,
- expr_hardware,
- expr_packet,
- expr_const_data,
- expr_extract_int8,
- expr_extract_int16,
- expr_extract_int32,
- expr_const_int,
- } op;
+/* Tree structure for deferred evaluation of changing values. */
+struct tree {
+ int op;
union {
- struct {
- struct expression *expr;
- struct expression *offset;
- struct expression *len;
- } substring;
- struct expression *equal [2];
- struct expression *and [2];
- struct expression *or [2];
- struct expression *not;
- struct collection *check;
- struct {
- struct expression *expr;
- struct expression *len;
- } suffix;
- struct option *option;
- struct {
- struct expression *offset;
- struct expression *len;
- } packet;
- struct data_string const_data;
- struct {
- struct expression *expr;
- struct expression *width;
- } extract_int;
- unsigned long const_int;
- struct expression *concat [2];
- struct dns_host_entry *host_lookup;
+ struct concat {
+ struct tree *left;
+ struct tree *right;
+ } concat;
+ struct host_lookup {
+ struct dns_host_entry *host;
+ } host_lookup;
+ struct const_val {
+ unsigned char *data;
+ int len;
+ } const_val;
+ struct limit {
+ struct tree *tree;
+ int limit;
+ } limit;
} data;
- int flags;
-# define EXPR_EPHEMERAL 1
-};
+};
/* DNS host entry structure... */
struct dns_host_entry {
char *hostname;
- char *buffer;
- int buf_len;
+ unsigned char *data;
int data_len;
+ int buf_len;
TIME timeout;
};
-struct option_cache {
- struct expression *expression;
- struct option *option;
+struct tree_cache {
+ unsigned char *value;
+ int len;
+ int buf_size;
+ TIME timeout;
+ struct tree *tree;
+ int flags;
+#define TC_AWAITING_RESOLUTION 1
+#define TC_TEMPORARY 2
};
-struct data_string; /* forward */
-struct packet; /* forward */
-struct option_state; /* forward */
-enum statement_op; /* forward */
-
struct universe {
char *name;
- struct data_string (*lookup_func) PROTO ((struct packet *, int));
- void (*set_func) PROTO ((struct option_state *,
- struct option_cache *,
- enum statement_op));
struct hash_table *hash;
struct option *options [256];
};
diff --git a/relay/Makefile.dist b/relay/Makefile.dist
index 95787dc2..02a6eb84 100644
--- a/relay/Makefile.dist
+++ b/relay/Makefile.dist
@@ -1,6 +1,6 @@
# Makefile.dist
#
-# Copyright (c) 1996, 1997, 1998 The Internet Software Consortium.
+# Copyright (c) 1996, 1997 The Internet Software Consortium.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -44,29 +44,22 @@ CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS)
all: $(PROG) $(CATMANPAGES)
install: $(PROG) $(CATMANPAGES)
- @for dir in $(BINDIR) $(ADMMANDIR); do \
- case $$dir in \
- /*) base=/ ;; \
- *) base="" ;; \
- esac; \
- slash=""; \
- for elt in `echo $$dir |sed -e 's/\// /g'`; do \
- if [ ! -d $$base/$$elt ]; then \
- echo Making $$base/$$elt; \
- mkdir $$base/$$elt; \
- chmod 755 $$base/$$elt; \
- fi; \
- base=$$base$$slash$$elt; \
- slash=/; \
- done; \
- done
$(INSTALL) dhcrelay $(BINDIR); $(CHMOD) 755 $(BINDIR)/dhcrelay
+ if [ ! -d $(ADMMANDIR) ]; then \
+ mkdir $(ADMMANDIR); \
+ chmod 755 $(ADMMANDIR); \
+ fi
+ if [ ! -d $(FFMANDIR) ]; then \
+ mkdir $(FFMANDIR); \
+ chmod 755 $(FFMANDIR); \
+ fi
+ if [ ! -d $(VARDB) ]; then \
+ mkdir $(VARDB); \
+ chmod 755 $(VARDB); \
+ fi
$(MANINSTALL) $(MANFROM) dhcrelay.cat8 $(MANTO) \
$(ADMMANDIR)/dhcrelay$(ADMMANEXT)
-depend:
- makedepend $(INCLUDES) $(PREDEFINES) $(SRCS)
-
clean:
-rm -f $(OBJS) dhclient.o
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index 80f382b4..98369797 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -41,8 +41,8 @@
*/
#ifndef lint
-static char copyright[] =
-"$Id: dhcrelay.c,v 1.14 1998/06/25 18:37:45 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
+static char ocopyright [] =
+"$Id: dhcrelay.c,v 1.9.2.8 1998/12/23 14:18:52 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -64,12 +64,6 @@ char *tlname;
char *path_dhcrelay_pid = _PATH_DHCRELAY_PID;
-#ifdef USE_FALLBACK
-struct interface_info fallback_interface;
-#endif
-
-int dhcp_max_agent_option_packet_length = 0;
-
u_int16_t local_port;
u_int16_t remote_port;
int log_priority;
@@ -79,6 +73,13 @@ struct server_list {
struct sockaddr_in to;
} *servers;
+static char copyright [] =
+"Copyright 1997, 1998 The Internet Software Consortium.";
+static char arr [] = "All rights reserved.";
+static char message [] = "Internet Software Consortium DHCP Relay Agent V2.0b1pl8";
+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";
+
int main (argc, argv, envp)
int argc;
char **argv, **envp;
@@ -155,6 +156,14 @@ int main (argc, argv, envp)
}
}
+ if (!quiet) {
+ note (message);
+ note (copyright);
+ note (arr);
+ note (contrib);
+ note (url);
+ }
+
/* Default to the DHCP/BOOTP port. */
if (!local_port) {
ent = getservbyname ("dhcps", "udp");
@@ -231,7 +240,7 @@ int main (argc, argv, envp)
return 0;
}
-void relay (ip, packbuf, length, from_port, from, hfrom)
+void relay (ip, packet, length, from_port, from, hfrom)
struct interface_info *ip;
struct dhcp_packet *packet;
int length;
@@ -251,13 +260,11 @@ void relay (ip, packbuf, length, from_port, from, hfrom)
/* If it's a bootreply, forward it to the client. */
if (packet -> op == BOOTREPLY) {
-#ifndef USE_FALLBACK
- if (!(packet -> flags & htons (BOOTP_BROADCAST))) {
+ if (!(packet -> flags & htons (BOOTP_BROADCAST)) &&
+ can_unicast_without_arp ()) {
to.sin_addr = packet -> yiaddr;
to.sin_port = remote_port;
- } else
-#endif
- {
+ } else {
to.sin_addr.s_addr = htonl (INADDR_BROADCAST);
to.sin_port = remote_port;
}
@@ -316,19 +323,11 @@ void relay (ip, packbuf, length, from_port, from, hfrom)
/* Otherwise, it's a BOOTREQUEST, so forward it to all the
servers. */
for (sp = servers; sp; sp = sp -> next) {
- if (
-#ifdef USE_FALLBACK
- send_fallback (&fallback_interface,
- (struct packet *)0,
- packet, length, ip -> primary_address,
- &sp -> to, (struct hardware *)0)
-#else
- send_packet (interfaces,
+ if (send_packet ((fallback_interface
+ ? fallback_interface : interfaces),
(struct packet *)0,
packet, length, ip -> primary_address,
- &sp -> to, (struct hardware *)0)
-#endif
- < 0) {
+ &sp -> to, (struct hardware *)0) < 0) {
debug ("send_packet: %m");
} else {
debug ("forwarded BOOTREQUEST for %s to %s",
diff --git a/server/Makefile.dist b/server/Makefile.dist
index 36bf6af0..9dbea5dc 100644
--- a/server/Makefile.dist
+++ b/server/Makefile.dist
@@ -1,6 +1,6 @@
# Makefile.dist
#
-# Copyright (c) 1996, 1997, 1998 The Internet Software Consortium.
+# Copyright (c) 1996, 1997 The Internet Software Consortium.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
#
CATMANPAGES = dhcpd.cat8 dhcpd.conf.cat5 dhcpd.leases.cat5
-SRCS = dhcpd.c dhcp.c bootp.c confpars.c db.c dhcpdi.c class.c
-OBJS = dhcpd.o dhcp.o bootp.o confpars.o db.o dhcpdi.o class.o
+SRCS = dhcpd.c dhcp.c bootp.c confpars.c db.c
+OBJS = dhcpd.o dhcp.o bootp.o confpars.o db.o
PROG = dhcpd
MAN = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
@@ -44,23 +44,19 @@ CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS)
all: $(PROG) $(CATMANPAGES)
install: $(PROG) $(CATMANPAGES)
- @for dir in $(BINDIR) $(ADMMANDIR) $(FFMANDIR) $(VARDB); do \
- case $$dir in \
- /*) base=/ ;; \
- *) base="" ;; \
- esac; \
- slash=""; \
- for elt in `echo $$dir |sed -e 's/\// /g'`; do \
- if [ ! -d $$base/$$elt ]; then \
- echo Making $$base/$$elt; \
- mkdir $$base/$$elt; \
- chmod 755 $$base/$$elt; \
- fi; \
- base=$$base$$slash$$elt; \
- slash=/; \
- done; \
- done
$(INSTALL) dhcpd $(BINDIR); $(CHMOD) 755 $(BINDIR)/dhcpd
+ if [ ! -d $(ADMMANDIR) ]; then \
+ mkdir $(ADMMANDIR); \
+ chmod 755 $(ADMMANDIR); \
+ fi
+ if [ ! -d $(FFMANDIR) ]; then \
+ mkdir $(FFMANDIR); \
+ chmod 755 $(FFMANDIR); \
+ fi
+ if [ ! -d $(VARDB) ]; then \
+ mkdir $(VARDB); \
+ chmod 755 $(VARDB); \
+ fi
$(MANINSTALL) $(MANFROM) dhcpd.cat8 $(MANTO) \
$(ADMMANDIR)/dhcpd$(ADMMANEXT)
$(MANINSTALL) $(MANFROM) dhcpd.conf.cat5 $(MANTO) \
@@ -68,12 +64,9 @@ install: $(PROG) $(CATMANPAGES)
$(MANINSTALL) $(MANFROM) dhcpd.leases.cat5 $(MANTO) \
$(FFMANDIR)/dhcpd.leases$(FFMANEXT)
-depend:
- makedepend $(INCLUDES) $(PREDEFINES) $(SRCS)
-
clean:
-rm -f $(OBJS)
-
+
realclean: clean
-rm -f $(PROG) $(CATMANPAGES) *~ #*
diff --git a/server/bootp.c b/server/bootp.c
index 4c6a247d..3bbb88ab 100644
--- a/server/bootp.c
+++ b/server/bootp.c
@@ -3,7 +3,7 @@
BOOTP Protocol support. */
/*
- * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: bootp.c,v 1.31 1998/06/25 03:41:03 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: bootp.c,v 1.28.2.2 1998/12/21 04:21:30 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -58,12 +58,11 @@ void bootp (packet)
struct sockaddr_in to;
struct in_addr from;
struct hardware hto;
- struct option_state options;
+ struct tree_cache *options [256];
struct subnet *subnet;
struct lease *lease;
struct iaddr ip_address;
int i;
- struct data_string d1;
if (packet -> raw -> op != BOOTREQUEST)
return;
@@ -109,6 +108,70 @@ void bootp (packet)
}
}
+ if (host && (!host -> group -> allow_booting)) {
+ note ("Ignoring excluded BOOTP client %s",
+ host -> name
+ ? host -> name
+ : print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr));
+ return;
+ }
+
+ if (host && (!host -> group -> allow_bootp)) {
+ note ("Ignoring BOOTP request from client %s",
+ host -> name
+ ? host -> name
+ : print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr));
+ return;
+ }
+
+ /* If we've been told not to boot unknown clients,
+ and we didn't find any host record for this client,
+ ignore it. */
+ if (!host && !(packet -> shared_network ->
+ group -> boot_unknown_clients)) {
+ note ("Ignoring unknown BOOTP client %s via %s",
+ print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr),
+ packet -> raw -> giaddr.s_addr
+ ? inet_ntoa (packet -> raw -> giaddr)
+ : packet -> interface -> name);
+ return;
+ }
+
+ /* If we've been told not to boot with bootp on this
+ network, ignore it. */
+ if (!host &&
+ !(packet -> shared_network -> group -> allow_bootp)) {
+ note ("Ignoring BOOTP request from client %s via %s",
+ print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr),
+ packet -> raw -> giaddr.s_addr
+ ? inet_ntoa (packet -> raw -> giaddr)
+ : packet -> interface -> name);
+ return;
+ }
+
+ /* If the packet is from a host we don't know and there
+ are no dynamic bootp addresses on the network it came
+ in on, drop it on the floor. */
+ if (!(packet -> shared_network -> group -> dynamic_bootp)) {
+ lose:
+ note ("No applicable record for BOOTP host %s via %s",
+ print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr),
+ packet -> raw -> giaddr.s_addr
+ ? inet_ntoa (packet -> raw -> giaddr)
+ : packet -> interface -> name);
+ return;
+ }
+
/* If a lease has already been assigned to this client
and it's still okay to use dynamic bootp on
that lease, reassign it. */
@@ -145,55 +208,23 @@ void bootp (packet)
return;
}
}
- note ("No dynamic leases for BOOTP client %s",
- print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr));
+ goto lose;
}
- /* Run the executable statements to compute the client and server
- options. */
-
- memset (&options, 0, sizeof options);
-
- /* Execute the subnet statements. */
- execute_statements_in_scope (packet, &options,
- lease -> subnet -> group,
- (struct group *)0);
-
- /* Execute the host statements. */
- execute_statements_in_scope (packet, &options, hp -> group,
- lease -> subnet -> group);
-
- /* Drop the request if it's not allowed for this client. */
- if (options.server_options [SV_ALLOW_BOOTP]) {
- d1 = evaluate_data_expression
- (packet, (options.server_options
- [SV_ALLOW_BOOTP] -> expression));
- if (d1.len && !d1.data [0]) {
- note ("Ignoring BOOTP client %s",
- print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr));
- return;
- }
- }
-
- if (options.server_options [SV_ALLOW_BOOTING]) {
- d1 = evaluate_data_expression
- (packet, (options.server_options
- [SV_ALLOW_BOOTING] -> expression));
- if (d1.len && !d1.data [0]) {
- note ("Declining to boot client %s",
- lease -> host -> name
- ? lease -> host -> name
- : print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr));
- return;
- }
+ /* Make sure we're allowed to boot this client. */
+ if (hp && (!hp -> group -> allow_booting)) {
+ note ("Ignoring excluded BOOTP client %s",
+ hp -> name);
+ return;
}
-
+
+ /* Make sure we're allowed to boot this client with bootp. */
+ if (hp && (!hp -> group -> allow_bootp)) {
+ note ("Ignoring BOOTP request from client %s",
+ hp -> name);
+ return;
+ }
+
/* Set up the outgoing packet... */
memset (&outgoing, 0, sizeof outgoing);
memset (&raw, 0, sizeof raw);
@@ -206,13 +237,24 @@ void bootp (packet)
packet -> raw -> options, DHCP_OPTION_LEN);
outgoing.packet_length = BOOTP_MIN_LEN;
} else {
+ /* Come up with a list of options that we want to send
+ to this client. Start with the per-subnet options,
+ and then override those with client-specific
+ options. */
+
+ memcpy (options, subnet -> group -> options, sizeof options);
+
+ for (i = 0; i < 256; i++) {
+ if (hp -> group -> options [i])
+ options [i] = hp -> group -> options [i];
+ }
+
/* Pack the options into the buffer. Unlike DHCP, we
can't pack options into the filename and server
name buffers. */
outgoing.packet_length =
- cons_options (packet,
- outgoing.raw, 0, &options, 0, 0, 1);
+ cons_options (packet, outgoing.raw, options, 0, 0, 1);
if (outgoing.packet_length < BOOTP_MIN_LEN)
outgoing.packet_length = BOOTP_MIN_LEN;
}
@@ -230,41 +272,27 @@ void bootp (packet)
memcpy (&raw.yiaddr, ip_address.iabuf, sizeof raw.yiaddr);
/* Figure out the address of the next server. */
- raw.siaddr = lease -> shared_network -> interface -> primary_address;
- i = SV_NEXT_SERVER;
- if (options.server_options [i]) {
- d1 = evaluate_data_expression
- (packet, options.server_options [i] -> expression);
- /* If there was more than one answer, take the first. */
- if (d1.len >= 4 && d1.data)
- memcpy (&raw.siaddr, d1.data, 4);
- }
+ if (hp && hp -> group -> next_server.len)
+ memcpy (&raw.siaddr, hp -> group -> next_server.iabuf, 4);
+ else if (subnet -> group -> next_server.len)
+ memcpy (&raw.siaddr, subnet -> group -> next_server.iabuf, 4);
+ else if (subnet -> interface_address.len)
+ memcpy (&raw.siaddr, subnet -> interface_address.iabuf, 4);
+ else
+ raw.siaddr = packet -> interface -> primary_address;
raw.giaddr = packet -> raw -> giaddr;
-
- /* Figure out the filename. */
- i = SV_FILENAME;
- if (options.server_options [i]) {
- d1 = evaluate_data_expression
- (packet, options.server_options [i] -> expression);
- memcpy (raw.file, d1.data,
- d1.len > sizeof raw.file ? sizeof raw.file : d1.len);
- if (sizeof raw.file > d1.len)
- memset (&raw.file [d1.len],
- 0, (sizeof raw.file) - d1.len);
- }
-
- /* Choose a server name as above. */
- i = SV_SERVER_NAME;
- if (options.server_options [i]) {
- d1 = evaluate_data_expression
- (packet, options.server_options [i] -> expression);
- memcpy (raw.sname, d1.data,
- d1.len > sizeof raw.sname ? sizeof raw.sname : d1.len);
- if (sizeof raw.sname > d1.len)
- memset (&raw.sname [d1.len],
- 0, (sizeof raw.sname) - d1.len);
+ if (hp -> group -> server_name) {
+ strncpy (raw.sname, hp -> group -> server_name,
+ (sizeof raw.sname) - 1);
+ raw.sname [(sizeof raw.sname) - 1] = 0;
}
+ if (hp -> group -> filename) {
+ strncpy (raw.file, hp -> group -> filename,
+ (sizeof raw.file) - 1);
+ raw.file [(sizeof raw.file) - 1] = 0;
+ } else
+ memcpy (raw.file, packet -> raw -> file, sizeof raw.file);
/* Set up the hardware destination address... */
hto.htype = packet -> raw -> htype;
@@ -295,15 +323,15 @@ void bootp (packet)
to.sin_addr = raw.giaddr;
to.sin_port = local_port;
-#ifdef USE_FALLBACK
- result = send_fallback (&fallback_interface,
- (struct packet *)0,
- &raw, outgoing.packet_length,
- from, &to, &hto);
- if (result < 0)
- warn ("send_fallback: %m");
- return;
-#endif
+ if (fallback_interface) {
+ result = send_packet (fallback_interface,
+ (struct packet *)0,
+ &raw, outgoing.packet_length,
+ from, &to, &hto);
+ if (result < 0)
+ warn ("send_packet: %m");
+ return;
+ }
/* Otherwise, broadcast it on the local network. */
} else {
to.sin_addr.s_addr = INADDR_BROADCAST;
diff --git a/server/class.c b/server/class.c
deleted file mode 100644
index f98588c6..00000000
--- a/server/class.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/* class.c
-
- Handling for client classes. */
-
-/*
- * Copyright (c) 1998 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises. To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''. To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: class.c,v 1.3 1998/06/25 03:42:18 mellon Exp $ Copyright (c) 1998 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-/*
- * Internally, there are three basic kinds of classes: classes that are
- * never matched, and must be assigned through classification rules (e.g.,
- * known-clients and unknown-clients, above), classes that are assigned
- * by doing a hash lookup, and classes that must be matched on an individual
- * basis. These classes are all declared the same way:
- *
- * class [<class-name>] {
- * match if <match-expr>;
- * ...
- * }
- *
- * It is possible to declare a class that spawns other classes - if a client
- * matches the class, a new class is created that matches the client's
- * parameters more specifically. Classes that are created in this way are
- * attached to the class that spawned them with a hash table, and if a client
- * matches the hash, the more general test is not done. Care should be taken
- * in constructing such classes: a poorly-chosen spawn test can cause such a
- * class to grow without bound.
- *
- * class [<class-name>] {
- * match if <match-expr>;
- * spawn <spawn-expr>;
- * }
- *
- * Testing a whole litany of classes can take quite a bit of time for each
- * incoming packet. In order to make this process more efficient, it may
- * be desirable to group classes into collections, and then write a more
- * complicated set of classification rules so as to perform fewer tests.
- * Classes can be grouped into collections by writing a collection statement
- * in the class declaration:
- *
- * collection <collection-name>;
- *
- * By default, all classes are members of the "default" collection.
- *
- * Beware: if you declare a class to be part of a collection other than
- * "default" but do not update the classification rules, that class will
- * never be considered during the client classification process.
- */
-
-/*
- * Expressions used to make matches:
- *
- * expression :== LPAREN expression RPAREN |
- * expression OR expression |
- * expression AND expression |
- * NOT expression |
- * test_expr
- *
- * test_expr :== extract_expr EQUALS extract_expr |
- * CHECK_COLLECTION STRING
- *
- * extract_expr :== SUBSTRING extract_expr NUMBER NUMBER |
- * SUFFIX extract_expr NUMBER |
- * OPTION IDENTIFIER DOT IDENTIFIER |
- * OPTION IDENTIFIER |
- * CHADDR
- * HTYPE
- * HARDWARE
- * data_expr
- *
- * data_expr :== STRING |
- * hex_data_expr
- *
- * hex_data_expr :== HEX_NUMBER |
- * hex_data_expr COLON HEX_NUMBER
- *
- * For example:
- *
- * chaddr = 08:00:2b:4c:2a:29 AND htype = 1;
- *
- * substring chaddr 0 3 = 08:00:2b;
- *
- * substring dhcp-client-identifier 1 3 = "RAS";
- *
- * substring relay.circuit-id = 04:2c:59:31;
- */
-
-/*
- * Clients are classified based on classification rules, which can be
- * specified on a per-group basis. By default, the following classification
- * rules apply:
- *
- * classification-rules {
- * check-collection "default";
- * }
- *
- */
-
-struct class unknown_class = {
- (struct class *)0,
- "unknown",
- (struct hash_table *)0,
- (struct expression *)0,
- (struct expression *)0,
- (struct group *)0,
-};
-
-struct class known_class = {
- (struct class *)0,
- "unknown",
- (struct hash_table *)0,
- (struct expression *)0,
- (struct expression *)0,
- (struct group *)0,
-};
-
-struct collection default_collection = {
- (struct collection *)0,
- "default",
- (struct class *)0,
-};
-
-struct collection *collections = &default_collection;
-struct executable_statement *default_classification_rules;
-
-/* Build the default classification rule tree. */
-
-void classification_setup ()
-{
- struct executable_statement *rules;
- struct expression *me;
-
- /* check-collection "default" */
- me = (struct expression *)dmalloc (sizeof (struct expression),
- "default check expression");
- if (!me)
- error ("Can't allocate default check expression");
- memset (me, 0, sizeof *me);
- me -> op = expr_check;
- me -> data.check = &default_collection;
-
- /* eval ... */
- rules = (struct executable_statement *)
- dmalloc (sizeof (struct executable_statement),
- "add default collection check rule");
- if (!rules)
- error ("Can't allocate check of default collection");
- memset (rules, 0, sizeof *rules);
- rules -> op = eval_statement;
- rules -> data.eval = me;
-
- default_classification_rules = rules;
-}
-
-void classify_client (packet)
- struct packet *packet;
-{
- execute_statements (packet, (struct option_state *)0,
- default_classification_rules);
-}
-
-int check_collection (packet, collection)
- struct packet *packet;
- struct collection *collection;
-{
- struct class *class, *nc;
- struct data_string data;
- int matched = 0;
-
- for (class = collection -> classes; class; class = class -> nic) {
- if (class -> hash) {
- data = evaluate_data_expression (packet,
- class -> spawn);
- nc = (struct class *)hash_lookup (class -> hash,
- data.data, data.len);
- if (nc) {
- classify (packet, class);
- matched = 1;
- continue;
- }
- }
- if (class -> expr &&
- evaluate_boolean_expression (packet, class -> expr)) {
- if (class -> spawn) {
- data = evaluate_data_expression
- (packet, class -> spawn);
- nc = (struct class *)
- dmalloc (sizeof (struct class),
- "class spawn");
- memset (nc, 0, sizeof *nc);
- nc -> group = class -> group;
- if (!class -> hash)
- class -> hash = new_hash ();
- add_hash (class -> hash,
- data.data, data.len,
- (unsigned char *)nc);
- classify (packet, nc);
- } else
- classify (packet, class);
- matched = 1;
- }
- }
- return matched;
-}
-
-void classify (packet, class)
- struct packet *packet;
- struct class *class;
-{
- if (packet -> class_count < PACKET_MAX_CLASSES)
- packet -> classes [packet -> class_count++] = class;
- else
- warn ("too many groups for %s",
- print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr));
-}
-
-struct class *find_class (name)
- char *name;
-{
- struct collection *lp;
- struct class *cp;
-
- for (lp = collections; lp; lp = lp -> next) {
- for (cp = lp -> classes; cp; cp = cp -> nic)
- if (cp -> name && !strcmp (name, cp -> name))
- return cp;
- }
- return (struct class *)0;
-}
diff --git a/server/confpars.c b/server/confpars.c
index 147674c8..a938fbcb 100644
--- a/server/confpars.c
+++ b/server/confpars.c
@@ -3,7 +3,7 @@
Parser for dhcpd config file... */
/*
- * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: confpars.c,v 1.51 1998/06/25 03:51:59 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: confpars.c,v 1.45.2.4 1998/11/24 23:02:54 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -66,6 +66,14 @@ int readconf ()
/* Set up the initial dhcp option universe. */
initialize_universes ();
+ /* Set up the global defaults... */
+ root_group.default_lease_time = 43200; /* 12 hours. */
+ root_group.max_lease_time = 86400; /* 24 hours. */
+ root_group.bootp_lease_cutoff = MAX_TIME;
+ root_group.boot_unknown_clients = 1;
+ root_group.allow_bootp = 1;
+ root_group.allow_booting = 1;
+
if ((cfile = fopen (path_dhcpd_conf, "r")) == NULL)
error ("Can't open %s: %m", path_dhcpd_conf);
do {
@@ -73,9 +81,9 @@ int readconf ()
if (token == EOF)
break;
declaration = parse_statement (cfile, &root_group,
- ROOT_GROUP,
- (struct host_decl *)0,
- declaration);
+ ROOT_GROUP,
+ (struct host_decl *)0,
+ declaration);
} while (1);
token = next_token (&val, cfile); /* Clear the peek buffer */
@@ -147,7 +155,6 @@ void read_leases ()
| fixed-address-parameter
| ALLOW allow-deny-keyword
| DENY allow-deny-keyword
- | USE_LEASE_ADDR_FOR_DEFAULT_ROUTE boolean
declaration :== host-declaration
| group-declaration
@@ -168,18 +175,13 @@ int parse_statement (cfile, group, type, host_decl, declaration)
char *val;
struct shared_network *share;
char *t, *n;
- struct expression *expr;
- struct data_string data;
+ struct tree *tree;
+ struct tree_cache *cache;
struct hardware hardware;
- struct executable_statement *et, *ep;
- struct option *option;
- struct option_cache *cache;
- int lose;
- switch (peek_token (&val, cfile)) {
+ switch (next_token (&val, cfile)) {
case HOST:
- next_token (&val, cfile);
- if (type != HOST_DECL && type != CLASS_DECL)
+ if (type != HOST_DECL)
parse_host_declaration (cfile, group);
else {
parse_warn ("host declarations not allowed here.");
@@ -188,8 +190,7 @@ int parse_statement (cfile, group, type, host_decl, declaration)
return 1;
case GROUP:
- next_token (&val, cfile);
- if (type != HOST_DECL && type != CLASS_DECL)
+ if (type != HOST_DECL)
parse_group_declaration (cfile, group);
else {
parse_warn ("host declarations not allowed here.");
@@ -198,16 +199,13 @@ int parse_statement (cfile, group, type, host_decl, declaration)
return 1;
case TIMESTAMP:
- next_token (&val, cfile);
parsed_time = parse_timestamp (cfile);
break;
case SHARED_NETWORK:
- next_token (&val, cfile);
if (type == SHARED_NET_DECL ||
type == HOST_DECL ||
- type == SUBNET_DECL ||
- type == CLASS_DECL) {
+ type == SUBNET_DECL) {
parse_warn ("shared-network parameters not %s.",
"allowed here");
skip_to_semi (cfile);
@@ -218,9 +216,7 @@ int parse_statement (cfile, group, type, host_decl, declaration)
return 1;
case SUBNET:
- next_token (&val, cfile);
- if (type == HOST_DECL || type == SUBNET_DECL ||
- type == CLASS_DECL) {
+ if (type == HOST_DECL || type == SUBNET_DECL) {
parse_warn ("subnet declarations not allowed here.");
skip_to_semi (cfile);
return 1;
@@ -258,47 +254,88 @@ int parse_statement (cfile, group, type, host_decl, declaration)
return 1;
case VENDOR_CLASS:
- next_token (&val, cfile);
- if (type == CLASS_DECL) {
- parse_warn ("class declarations not allowed here.");
- skip_to_semi (cfile);
- break;
- }
parse_class_declaration (cfile, group, 0);
return 1;
case USER_CLASS:
- next_token (&val, cfile);
- if (type == CLASS_DECL) {
- parse_warn ("class declarations not allowed here.");
- skip_to_semi (cfile);
- break;
- }
parse_class_declaration (cfile, group, 1);
return 1;
- case CLASS:
- next_token (&val, cfile);
- if (type == CLASS_DECL) {
- parse_warn ("class declarations not allowed here.");
- skip_to_semi (cfile);
- break;
- }
- parse_class_declaration (cfile, group, 2);
- return 1;
+ case DEFAULT_LEASE_TIME:
+ parse_lease_time (cfile, &group -> default_lease_time);
+ break;
- case SUBCLASS:
- next_token (&val, cfile);
- if (type == CLASS_DECL) {
- parse_warn ("class declarations not allowed here.");
- skip_to_semi (cfile);
+ case MAX_LEASE_TIME:
+ parse_lease_time (cfile, &group -> max_lease_time);
+ break;
+
+ case DYNAMIC_BOOTP_LEASE_CUTOFF:
+ group -> bootp_lease_cutoff = parse_date (cfile);
+ break;
+
+ case DYNAMIC_BOOTP_LEASE_LENGTH:
+ parse_lease_time (cfile, &group -> bootp_lease_length);
+ break;
+
+ case BOOT_UNKNOWN_CLIENTS:
+ if (type == HOST_DECL)
+ parse_warn ("boot-unknown-clients not allowed here.");
+ group -> boot_unknown_clients = parse_boolean (cfile);
+ break;
+
+ case ONE_LEASE_PER_CLIENT:
+ if (type == HOST_DECL)
+ parse_warn ("one-lease-per-client not allowed here.");
+ group -> one_lease_per_client = parse_boolean (cfile);
+ break;
+
+ case GET_LEASE_HOSTNAMES:
+ if (type == HOST_DECL)
+ parse_warn ("get-lease-hostnames not allowed here.");
+ group -> get_lease_hostnames = parse_boolean (cfile);
+ break;
+
+ case USE_HOST_DECL_NAMES:
+ if (type == HOST_DECL)
+ parse_warn ("use-host-decl-names not allowed here.");
+ group -> use_host_decl_names = parse_boolean (cfile);
+ break;
+
+ case NEXT_SERVER:
+ tree = parse_ip_addr_or_hostname (cfile, 0);
+ if (!tree)
break;
- }
- parse_class_declaration (cfile, group, 3);
- return 1;
+ cache = tree_cache (tree);
+ if (!tree_evaluate (cache))
+ error ("next-server is not known");
+ group -> next_server.len = 4;
+ memcpy (group -> next_server.iabuf,
+ cache -> value, group -> next_server.len);
+ parse_semi (cfile);
+ break;
+
+ case OPTION:
+ parse_option_param (cfile, group);
+ break;
+
+ case SERVER_IDENTIFIER:
+ tree = parse_ip_addr_or_hostname (cfile, 0);
+ if (!tree)
+ return declaration;
+ group -> options [DHO_DHCP_SERVER_IDENTIFIER] =
+ tree_cache (tree);
+ token = next_token (&val, cfile);
+ break;
+
+ case FILENAME:
+ group -> filename = parse_string (cfile);
+ break;
+
+ case SERVER_NAME:
+ group -> server_name = parse_string (cfile);
+ break;
case HARDWARE:
- next_token (&val, cfile);
parse_hardware_param (cfile, &hardware);
if (host_decl)
host_decl -> interface = hardware;
@@ -308,7 +345,6 @@ int parse_statement (cfile, group, type, host_decl, declaration)
break;
case FIXED_ADDR:
- next_token (&val, cfile);
cache = parse_fixed_addr_param (cfile);
if (host_decl)
host_decl -> fixed_addr = cache;
@@ -318,7 +354,6 @@ int parse_statement (cfile, group, type, host_decl, declaration)
break;
case RANGE:
- next_token (&val, cfile);
if (type != SUBNET_DECL || !group -> subnet) {
parse_warn ("range declaration not allowed here.");
skip_to_semi (cfile);
@@ -328,62 +363,20 @@ int parse_statement (cfile, group, type, host_decl, declaration)
return declaration;
case ALLOW:
+ parse_allow_deny (cfile, group, 1);
+ break;
+
case DENY:
- token = next_token (&val, cfile);
- cache = parse_allow_deny (cfile,
- token == ALLOW ? 1 : 0);
- et = (struct executable_statement *)dmalloc (sizeof *et,
- "allow/deny");
- if (!et)
- error ("no memory for %s statement",
- token == ALLOW ? "allow" : "deny");
- memset (et, 0, sizeof *et);
- et -> op = supersede_option_statement;
- et -> data.option = cache;
- goto insert_statement;
+ parse_allow_deny (cfile, group, 0);
+ break;
default:
- et = (struct executable_statement *)0;
- if (is_identifier (token)) {
- option = ((struct option *)
- hash_lookup (server_universe.hash,
- (unsigned char *)val, 0));
- if (option) {
- et = parse_option_statement
- (cfile, 1, option,
- supersede_option_statement);
- if (!et)
- return declaration;
- }
- }
-
- if (!et) {
- lose = 0;
- et = parse_executable_statement (cfile, &lose);
- if (!et) {
- if (declaration && !lose)
- parse_warn ("expecting a %s.",
- "declaration");
- else
- parse_warn ("expecting a parameter%s.",
- " or declaration");
- skip_to_semi (cfile);
- return declaration;
- }
- }
- if (!et) {
- parse_warn ("expecting a %sdeclaration",
- declaration ? "" : "parameter or ");
- return declaration;
- }
- insert_statement:
- if (group -> statements) {
- for (ep = group -> statements; ep -> next;
- ep = ep -> next)
- ;
- ep -> next = et;
-
- }
+ if (declaration)
+ parse_warn ("expecting a declaration.");
+ else
+ parse_warn ("expecting a parameter or declaration.");
+ skip_to_semi (cfile);
+ return declaration;
}
if (declaration) {
@@ -399,44 +392,38 @@ int parse_statement (cfile, group, type, host_decl, declaration)
| DYNAMIC_BOOTP
| UNKNOWN_CLIENTS */
-struct option_cache *parse_allow_deny (cfile, flag)
+void parse_allow_deny (cfile, group, flag)
FILE *cfile;
+ struct group *group;
int flag;
{
int token;
char *val;
- char rf = flag;
- struct option_cache *oc;
token = next_token (&val, cfile);
switch (token) {
case BOOTP:
- oc = option_cache (make_const_data (&rf, 1, 0, 1),
- &server_options [SV_ALLOW_BOOTP]);
+ group -> allow_bootp = flag;
break;
case BOOTING:
- oc = option_cache (make_const_data (&rf, 1, 0, 1),
- &server_options [SV_ALLOW_BOOTING]);
+ group -> allow_booting = flag;
break;
case DYNAMIC_BOOTP:
- oc = option_cache (make_const_data (&rf, 1, 0, 1),
- &server_options [SV_DYNAMIC_BOOTP]);
+ group -> dynamic_bootp = flag;
break;
case UNKNOWN_CLIENTS:
- oc = option_cache (make_const_data (&rf, 1, 0, 1),
- &server_options [SV_BOOT_UNKNOWN_CLIENTS]);
+ group -> boot_unknown_clients = flag;
break;
default:
parse_warn ("expecting allow/deny key");
skip_to_semi (cfile);
- return (struct option_cache *)0;
+ return;
}
parse_semi (cfile);
- return oc;
}
/* boolean :== ON SEMI | OFF SEMI | TRUE SEMI | FALSE SEMI */
@@ -492,17 +479,11 @@ void parse_host_declaration (cfile, group)
char *val;
int token;
struct host_decl *host;
- char *name;
+ char *name = parse_host_name (cfile);
int declaration = 0;
- token = peek_token (&val, cfile);
- if (token != LBRACE) {
- name = parse_host_name (cfile);
- if (!name)
- return;
- } else {
- name = (char *)0;
- }
+ if (!name)
+ return;
host = (struct host_decl *)dmalloc (sizeof (struct host_decl),
"parse_host_declaration");
@@ -531,6 +512,24 @@ void parse_host_declaration (cfile, group)
declaration);
} while (1);
+ if (!host -> group -> options [DHO_HOST_NAME] &&
+ host -> group -> use_host_decl_names) {
+ host -> group -> options [DHO_HOST_NAME] =
+ new_tree_cache ("parse_host_declaration");
+ if (!host -> group -> options [DHO_HOST_NAME])
+ error ("can't allocate a tree cache for hostname.");
+ host -> group -> options [DHO_HOST_NAME] -> len =
+ strlen (name);
+ host -> group -> options [DHO_HOST_NAME] -> value =
+ (unsigned char *)name;
+ host -> group -> options [DHO_HOST_NAME] -> buf_size =
+ host -> group -> options [DHO_HOST_NAME] -> len;
+ host -> group -> options [DHO_HOST_NAME] -> timeout =
+ 0xFFFFFFFF;
+ host -> group -> options [DHO_HOST_NAME] -> tree =
+ (struct tree *)0;
+ }
+
enter_host (host);
}
@@ -544,13 +543,8 @@ void parse_class_declaration (cfile, group, type)
{
char *val;
int token;
- struct class *class, *pc;
+ struct class *class;
int declaration = 0;
- int lose;
- struct data_string data;
- char *name;
- struct executable_statement *stmt = (struct executable_statement *)0;
- struct expression *expr;
token = next_token (&val, cfile);
if (token != STRING) {
@@ -559,111 +553,10 @@ void parse_class_declaration (cfile, group, type)
return;
}
- /* See if there's already a class with the specified name. */
- pc = (struct class *)find_class (val);
-
- /* If this isn't a subclass, we're updating an existing class. */
- if (pc && type != 0 && type != 1 && type != 3) {
- class = pc;
- pc = (struct class *)0;
- }
-
- /* If this _is_ a subclass, there _must_ be a class with the
- same name. */
- if (!pc && (type == 0 || type == 1 || type == 3)) {
- parse_warn ("no class named %s", val);
- skip_to_semi (cfile);
- return;
- }
-
- /* The old vendor-class and user-class declarations had an implicit
- match. We don't do the implicit match anymore. Instead, for
- backward compatibility, we have an implicit-vendor-class and an
- implicit-user-class. vendor-class and user-class declarations
- are turned into subclasses of the implicit classes, and the
- spawn expression of the implicit classes extracts the contents of
- the vendor class or user class. */
- if (type == 0 || type == 1) {
- data.len = strlen (val);
- data.data = dmalloc (data.len + 1, "parse_class_declaration");
- data.buffer = (char *)0;
- data.terminated = 1;
-
- name = type ? "implicit-vendor-class" : "implicit-user-class";
- } else if (type == 2) {
- if (!(name = dmalloc (strlen (val) + 1,
- "parse_class_declaration")))
- error ("No memory for class name %s.", val);
- strcpy (name, val);
- } else {
- name = (char *)0;
- }
-
- /* If this is a straight subclass, parse the hash string. */
- if (type == 3) {
- token = peek_token (&val, cfile);
- if (token == STRING) {
- token = next_token (&val, cfile);
- data.len = strlen (val);
- data.data = dmalloc (data.len + 1,
- "parse_class_declaration");
- data.buffer = (char *)0;
- data.terminated = 1;
- } else if (token == NUMBER_OR_NAME || token == NUMBER) {
- data.data = parse_cshl (cfile, &data.len);
- if (!data.data)
- return;
- data.terminated = 0;
- data.buffer = 0;
- }
- }
-
- /* See if there's already a class in the hash table matching the
- hash data. */
- if (type == 0 || type == 1 || type == 3)
- class = ((struct class *)
- hash_lookup (pc -> hash, data.data, data.len));
-
- /* If we didn't find an existing class, allocate a new one. */
- if (!class) {
- /* Allocate the class structure... */
- class = (struct class *)dmalloc (sizeof (struct class),
- "parse_class_declaration");
- if (!class)
- error ("No memory for class %s.", val);
- memset (class, 0, sizeof *class);
- if (pc) {
- class -> group =
- clone_group (pc -> group,
- "parse_class_declaration");
- add_hash (pc -> hash,
- data.data, data.len, (unsigned char *)class);
- } else {
- class -> group =
- clone_group (group, "parse_class_declaration");
- }
-
- /* If this is an implicit vendor or user class, add a
- statement that causes the vendor or user class ID to
- be sent back in the reply. */
- if (type == 0 || type == 1) {
- stmt = ((struct executable_statement *)
- dmalloc (sizeof (struct executable_statement),
- "implicit user/vendor class"));
- if (!stmt)
- error ("no memory for class statement.");
- memset (stmt, 0, sizeof *stmt);
- stmt -> op = supersede_option_statement;
- stmt -> data.option =
- (option_cache
- (make_const_data (data.data, data.len, 0, 1),
- dhcp_universe.options
- [type
- ? DHO_DHCP_CLASS_IDENTIFIER
- : DHO_DHCP_USER_CLASS_ID]));
- class -> statements = stmt;
- }
- }
+ class = add_class (type, val);
+ if (!class)
+ error ("No memory for class %s.", val);
+ class -> group = clone_group (group, "parse_class_declaration");
if (!parse_lbrace (cfile))
return;
@@ -677,50 +570,6 @@ void parse_class_declaration (cfile, group, type)
token = next_token (&val, cfile);
parse_warn ("unexpected end of file");
break;
- } else if (token == MATCH) {
- if (pc) {
- parse_warn ("invalid match in subclass.");
- skip_to_semi (cfile);
- break;
- }
- if (class -> expr) {
- parse_warn ("can't override match.");
- skip_to_semi (cfile);
- break;
- }
- token = next_token (&val, cfile);
- token = next_token (&val, cfile);
- if (token != IF) {
- parse_warn ("expecting if after match");
- skip_to_semi (cfile);
- break;
- }
- class -> expr =
- parse_boolean_expression (cfile, &lose);
- if (lose)
- break;
- } else if (token == SPAWN) {
- if (pc) {
- parse_warn ("invalid spawn in subclass.");
- skip_to_semi (cfile);
- break;
- }
- if (class -> spawn) {
- parse_warn ("can't override spawn.");
- skip_to_semi (cfile);
- break;
- }
- token = next_token (&val, cfile);
- token = next_token (&val, cfile);
- if (token != WITH) {
- parse_warn ("expecting with after spawn");
- skip_to_semi (cfile);
- break;
- }
- class -> spawn =
- parse_data_expression (cfile, &lose);
- if (lose)
- break;
} else {
declaration = parse_statement (cfile, class -> group,
CLASS_DECL,
@@ -809,7 +658,7 @@ void parse_subnet_declaration (cfile, share)
{
char *val;
int token;
- struct subnet *subnet, *t;
+ struct subnet *subnet, *t, *u;
struct iaddr iaddr;
unsigned char addr [4];
int len = sizeof addr;
@@ -865,13 +714,30 @@ void parse_subnet_declaration (cfile, share)
declaration);
} while (1);
+ /* If this subnet supports dynamic bootp, flag it so in the
+ shared_network containing it. */
+ if (subnet -> group -> dynamic_bootp)
+ share -> group -> dynamic_bootp = 1;
+ if (subnet -> group -> one_lease_per_client)
+ share -> group -> one_lease_per_client = 1;
+
/* Add the subnet to the list of subnets in this shared net. */
if (!share -> subnets)
share -> subnets = subnet;
else {
+ u = (struct subnet *)0;
for (t = share -> subnets;
- t -> next_sibling; t = t -> next_sibling)
- ;
+ t -> next_sibling; t = t -> next_sibling) {
+ if (subnet_inner_than (subnet, t, 0)) {
+ if (u)
+ u -> next_sibling = subnet;
+ else
+ share -> subnets = subnet;
+ subnet -> next_sibling = t;
+ return;
+ }
+ u = t;
+ }
t -> next_sibling = subnet;
}
}
@@ -908,32 +774,303 @@ void parse_group_declaration (cfile, group)
} while (1);
}
+/* ip-addr-or-hostname :== ip-address | hostname
+ ip-address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
+
+ Parse an ip address or a hostname. If uniform is zero, put in
+ a TREE_LIMIT node to catch hostnames that evaluate to more than
+ one IP address. */
+
+struct tree *parse_ip_addr_or_hostname (cfile, uniform)
+ FILE *cfile;
+ int uniform;
+{
+ char *val;
+ int token;
+ unsigned char addr [4];
+ int len = sizeof addr;
+ char *name;
+ struct tree *rv;
+
+ token = peek_token (&val, cfile);
+ if (is_identifier (token)) {
+ name = parse_host_name (cfile);
+ if (!name)
+ return (struct tree *)0;
+ rv = tree_host_lookup (name);
+ if (!uniform)
+ rv = tree_limit (rv, 4);
+ } else if (token == NUMBER) {
+ if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
+ return (struct tree *)0;
+ rv = tree_const (addr, len);
+ } else {
+ if (token != RBRACE && token != LBRACE)
+ token = next_token (&val, cfile);
+ parse_warn ("%s (%d): expecting IP address or hostname",
+ val, token);
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ return (struct tree *)0;
+ }
+
+ return rv;
+}
+
+
/* fixed-addr-parameter :== ip-addrs-or-hostnames SEMI
ip-addrs-or-hostnames :== ip-addr-or-hostname
| ip-addrs-or-hostnames ip-addr-or-hostname */
-struct option_cache *parse_fixed_addr_param (cfile)
+struct tree_cache *parse_fixed_addr_param (cfile)
FILE *cfile;
{
char *val;
int token;
- struct expression *expr = (struct expression *)0;
- struct expression *tmp;
+ struct tree *tree = (struct tree *)0;
+ struct tree *tmp;
do {
tmp = parse_ip_addr_or_hostname (cfile, 0);
- if (expr)
- expr = make_concat (expr, tmp);
+ if (tree)
+ tree = tree_concat (tree, tmp);
else
- expr = tmp;
+ tree = tmp;
token = peek_token (&val, cfile);
if (token == COMMA)
token = next_token (&val, cfile);
} while (token == COMMA);
if (!parse_semi (cfile))
- return (struct option_cache *)0;
- return option_cache (expr, (struct option *)0);
+ return (struct tree_cache *)0;
+ return tree_cache (tree);
+}
+
+/* option_parameter :== identifier DOT identifier <syntax> SEMI
+ | identifier <syntax> SEMI
+
+ Option syntax is handled specially through format strings, so it
+ would be painful to come up with BNF for it. However, it always
+ starts as above and ends in a SEMI. */
+
+void parse_option_param (cfile, group)
+ FILE *cfile;
+ struct group *group;
+{
+ char *val;
+ int token;
+ unsigned char buf [4];
+ char *vendor;
+ char *fmt;
+ struct universe *universe;
+ struct option *option;
+ struct tree *tree = (struct tree *)0;
+ struct tree *t;
+
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting identifier after option keyword.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ return;
+ }
+ vendor = malloc (strlen (val) + 1);
+ if (!vendor)
+ error ("no memory for vendor token.");
+ strcpy (vendor, val);
+ token = peek_token (&val, cfile);
+ if (token == DOT) {
+ /* Go ahead and take the DOT token... */
+ token = next_token (&val, cfile);
+
+ /* The next token should be an identifier... */
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting identifier after '.'");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ return;
+ }
+
+ /* Look up the option name hash table for the specified
+ vendor. */
+ universe = ((struct universe *)
+ hash_lookup (&universe_hash,
+ (unsigned char *)vendor, 0));
+ /* If it's not there, we can't parse the rest of the
+ declaration. */
+ if (!universe) {
+ parse_warn ("no vendor named %s.", vendor);
+ skip_to_semi (cfile);
+ return;
+ }
+ } else {
+ /* Use the default hash table, which contains all the
+ standard dhcp option names. */
+ val = vendor;
+ universe = &dhcp_universe;
+ }
+
+ /* Look up the actual option info... */
+ option = (struct option *)hash_lookup (universe -> hash,
+ (unsigned char *)val, 0);
+
+ /* If we didn't get an option structure, it's an undefined option. */
+ if (!option) {
+ if (val == vendor)
+ parse_warn ("no option named %s", val);
+ else
+ parse_warn ("no option named %s for vendor %s",
+ val, vendor);
+ skip_to_semi (cfile);
+ return;
+ }
+
+ /* Free the initial identifier token. */
+ free (vendor);
+
+ /* Parse the option data... */
+ do {
+ /* Set a flag if this is an array of a simple type (i.e.,
+ not an array of pairs of IP addresses, or something
+ like that. */
+ int uniform = option -> format [1] == 'A';
+
+ for (fmt = option -> format; *fmt; fmt++) {
+ if (*fmt == 'A')
+ break;
+ switch (*fmt) {
+ case 'X':
+ token = peek_token (&val, cfile);
+ if (token == NUMBER_OR_NAME ||
+ token == NUMBER) {
+ do {
+ token = next_token
+ (&val, cfile);
+ if (token != NUMBER
+ && token != NUMBER_OR_NAME)
+ goto need_number;
+ convert_num (buf, val, 16, 8);
+ tree = tree_concat
+ (tree,
+ tree_const (buf, 1));
+ token = peek_token
+ (&val, cfile);
+ if (token == COLON)
+ token = next_token
+ (&val, cfile);
+ } while (token == COLON);
+ } else if (token == STRING) {
+ token = next_token (&val, cfile);
+ tree = tree_concat
+ (tree,
+ tree_const ((unsigned char *)
+ val,
+ strlen (val)));
+ } else {
+ parse_warn ("expecting string %s.",
+ "or hexadecimal data");
+ skip_to_semi (cfile);
+ return;
+ }
+ break;
+
+ case 't': /* Text string... */
+ token = next_token (&val, cfile);
+ if (token != STRING
+ && !is_identifier (token)) {
+ parse_warn ("expecting string.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ return;
+ }
+ tree = tree_concat
+ (tree,
+ tree_const ((unsigned char *)val,
+ strlen (val)));
+ break;
+
+ case 'I': /* IP address or hostname. */
+ t = parse_ip_addr_or_hostname (cfile, uniform);
+ if (!t)
+ return;
+ tree = tree_concat (tree, t);
+ break;
+
+ case 'L': /* Unsigned 32-bit integer... */
+ case 'l': /* Signed 32-bit integer... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ need_number:
+ parse_warn ("expecting number.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ return;
+ }
+ convert_num (buf, val, 0, 32);
+ tree = tree_concat (tree, tree_const (buf, 4));
+ break;
+ case 's': /* Signed 16-bit integer. */
+ case 'S': /* Unsigned 16-bit integer. */
+ token = next_token (&val, cfile);
+ if (token != NUMBER)
+ goto need_number;
+ convert_num (buf, val, 0, 16);
+ tree = tree_concat (tree, tree_const (buf, 2));
+ break;
+ case 'b': /* Signed 8-bit integer. */
+ case 'B': /* Unsigned 8-bit integer. */
+ token = next_token (&val, cfile);
+ if (token != NUMBER)
+ goto need_number;
+ convert_num (buf, val, 0, 8);
+ tree = tree_concat (tree, tree_const (buf, 1));
+ break;
+ case 'f': /* Boolean flag. */
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting identifier.");
+ bad_flag:
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ return;
+ }
+ if (!strcasecmp (val, "true")
+ || !strcasecmp (val, "on"))
+ buf [0] = 1;
+ else if (!strcasecmp (val, "false")
+ || !strcasecmp (val, "off"))
+ buf [0] = 0;
+ else {
+ parse_warn ("expecting boolean.");
+ goto bad_flag;
+ }
+ tree = tree_concat (tree, tree_const (buf, 1));
+ break;
+ default:
+ warn ("Bad format %c in parse_option_param.",
+ *fmt);
+ skip_to_semi (cfile);
+ return;
+ }
+ }
+ if (*fmt == 'A') {
+ token = peek_token (&val, cfile);
+ if (token == COMMA) {
+ token = next_token (&val, cfile);
+ continue;
+ }
+ break;
+ }
+ } while (*fmt == 'A');
+
+ token = next_token (&val, cfile);
+ if (token != SEMI) {
+ parse_warn ("semicolon expected.");
+ skip_to_semi (cfile);
+ return;
+ }
+ group -> options [option -> code] = tree_cache (tree);
}
/* timestamp :== date
@@ -999,7 +1136,7 @@ struct lease *parse_lease_declaration (cfile)
parse_warn ("unexpected end of file");
break;
}
- strncpy (tbuf, val, sizeof tbuf);
+ strncpy (val, tbuf, sizeof tbuf);
tbuf [(sizeof tbuf) - 1] = 0;
/* Parse any of the times associated with the lease. */
@@ -1157,7 +1294,7 @@ void parse_address_range (cfile, subnet)
if ((token = peek_token (&val, cfile)) == DYNAMIC_BOOTP) {
token = next_token (&val, cfile);
- dynamic = 1;
+ subnet -> group -> dynamic_bootp = dynamic = 1;
}
/* Get the bottom address in the range... */
@@ -1189,3 +1326,4 @@ void parse_address_range (cfile, subnet)
new_address_range (low, high, subnet, dynamic);
}
+
diff --git a/server/db.c b/server/db.c
index a3469f7a..f5a8b6c9 100644
--- a/server/db.c
+++ b/server/db.c
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: db.c,v 1.19 1998/08/05 19:32:20 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: db.c,v 1.17.2.1 1998/08/05 19:33:16 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -71,9 +71,6 @@ int write_lease (lease)
++errors;
}
- /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
- somebody invents a time machine, I think we can safely disregard
- it. */
t = gmtime (&lease -> starts);
sprintf (tbuf, "%d %d/%02d/%02d %02d:%02d:%02d;",
t -> tm_wday, t -> tm_year + 1900,
diff --git a/server/dhcp.c b/server/dhcp.c
index c4ba3612..d1d4e465 100644
--- a/server/dhcp.c
+++ b/server/dhcp.c
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: dhcp.c,v 1.65 1998/06/25 21:24:23 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhcp.c,v 1.57.2.12 1998/12/20 17:53:02 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -86,12 +86,9 @@ void dhcp (packet)
void dhcpdiscover (packet)
struct packet *packet;
{
- struct lease *lease;
+ struct lease *lease = find_lease (packet, packet -> shared_network, 0);
struct host_decl *hp;
- /* Classify the client. */
- classify_client (packet);
-
note ("DHCPDISCOVER from %s via %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
@@ -100,8 +97,6 @@ void dhcpdiscover (packet)
? inet_ntoa (packet -> raw -> giaddr)
: packet -> interface -> name);
- lease = find_lease (packet, packet -> shared_network, 0);
-
/* Sourceless packets don't make sense here. */
if (!packet -> shared_network) {
note ("Packet from unknown subnet: %s",
@@ -125,9 +120,25 @@ void dhcpdiscover (packet)
warning message, so that if it continues to lose,
the administrator will eventually investigate. */
if (lease -> flags & ABANDONED_LEASE) {
- warn ("Reclaiming abandoned IP address %s.\n",
- piaddr (lease -> ip_addr));
- lease -> flags &= ~ABANDONED_LEASE;
+ struct lease *lp;
+
+ /* See if we can find an unabandoned lease first. */
+ for (lp = lease; lp; lp = lp -> prev) {
+ if (lp -> ends > cur_time)
+ break;
+ if (!lp -> flags & ABANDONED_LEASE) {
+ lease = lp;
+ break;
+ }
+ }
+
+ /* If we can't find an unabandoned lease, reclaim the
+ abandoned lease. */
+ if (lease -> flags & ABANDONED_LEASE) {
+ warn ("Reclaiming abandoned IP address %s.",
+ piaddr (lease -> ip_addr));
+ lease -> flags &= ~ABANDONED_LEASE;
+ }
}
/* Try to find a host_decl that matches the client
@@ -156,7 +167,24 @@ void dhcpdiscover (packet)
}
}
- ack_lease (packet, lease, DHCPOFFER, cur_time + 120);
+ /* If this subnet won't boot unknown clients, ignore the
+ request. */
+ if (!lease -> host &&
+ !lease -> subnet -> group -> boot_unknown_clients) {
+ note ("Ignoring unknown client %s",
+ print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr));
+ } else if (lease -> host &&
+ !lease -> host -> group -> allow_booting) {
+ note ("Declining to boot client %s",
+ lease -> host -> name
+ ? lease -> host -> name
+ : print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr));
+ } else
+ ack_lease (packet, lease, DHCPOFFER, cur_time + 120);
}
void dhcprequest (packet)
@@ -399,29 +427,32 @@ void nak_lease (packet, cip)
unsigned char nak = DHCPNAK;
struct packet outgoing;
struct hardware hto;
- int i;
- struct option_state options;
+ struct tree_cache *options [256];
+ struct tree_cache dhcpnak_tree;
+ struct tree_cache dhcpmsg_tree;
- memset (&options, 0, sizeof options);
+ memset (options, 0, sizeof options);
memset (&outgoing, 0, sizeof outgoing);
memset (&raw, 0, sizeof raw);
outgoing.raw = &raw;
/* Set DHCP_MESSAGE_TYPE to DHCPNAK */
- i = DHO_DHCP_MESSAGE_TYPE;
- options.dhcp_options [i] =
- option_cache (make_const_data (&nak, sizeof nak, 0, 0),
- dhcp_universe.options [i]);
+ options [DHO_DHCP_MESSAGE_TYPE] = &dhcpnak_tree;
+ options [DHO_DHCP_MESSAGE_TYPE] -> value = &nak;
+ options [DHO_DHCP_MESSAGE_TYPE] -> len = sizeof nak;
+ options [DHO_DHCP_MESSAGE_TYPE] -> buf_size = sizeof nak;
+ options [DHO_DHCP_MESSAGE_TYPE] -> timeout = 0xFFFFFFFF;
+ options [DHO_DHCP_MESSAGE_TYPE] -> tree = (struct tree *)0;
/* Set DHCP_MESSAGE to whatever the message is */
- i = DHO_DHCP_MESSAGE;
- options.server_options [i] =
- option_cache (make_const_data (dhcp_message,
- strlen (dhcp_message),
- 1, 0),
- dhcp_universe.options [i]);
-
+ options [DHO_DHCP_MESSAGE] = &dhcpmsg_tree;
+ options [DHO_DHCP_MESSAGE] -> value = (unsigned char *)dhcp_message;
+ options [DHO_DHCP_MESSAGE] -> len =
+ options [DHO_DHCP_MESSAGE] -> buf_size = strlen (dhcp_message);
+ options [DHO_DHCP_MESSAGE] -> timeout = 0xFFFFFFFF;
+ options [DHO_DHCP_MESSAGE] -> tree = (struct tree *)0;
+
/* Do not use the client's requested parameter list. */
packet -> options [DHO_DHCP_PARAMETER_REQUEST_LIST].len = 0;
packet -> options [DHO_DHCP_PARAMETER_REQUEST_LIST].data =
@@ -429,7 +460,7 @@ void nak_lease (packet, cip)
/* Set up the option buffer... */
outgoing.packet_length =
- cons_options (packet, outgoing.raw, 0, &options, 0, 0, 0);
+ cons_options (packet, outgoing.raw, options, 0, 0, 0);
/* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
raw.siaddr = packet -> interface -> primary_address;
@@ -486,14 +517,15 @@ void nak_lease (packet, cip)
to.sin_addr = raw.giaddr;
to.sin_port = local_port;
-#ifdef USE_FALLBACK
- result = send_fallback (&fallback_interface,
- packet, &raw, outgoing.packet_length,
- from, &to, &hto);
- if (result < 0)
- warn ("send_fallback: %m");
- return;
-#endif
+ if (fallback_interface) {
+ result = send_packet (fallback_interface,
+ packet, &raw,
+ outgoing.packet_length,
+ from, &to, &hto);
+ if (result < 0)
+ warn ("send_fallback: %m");
+ return;
+ }
} else {
to.sin_addr.s_addr = htonl (INADDR_BROADCAST);
to.sin_port = remote_port;
@@ -517,11 +549,9 @@ void ack_lease (packet, lease, offer, when)
struct lease_state *state;
TIME lease_time;
TIME offered_lease_time;
- struct data_string d1;
- TIME comp_lease_time;
+ struct class *vendor_class, *user_class;
int i;
- int val;
/* If we're already acking this lease, don't do it again. */
if (lease -> state) {
@@ -529,7 +559,44 @@ void ack_lease (packet, lease, offer, when)
return;
}
- /* XXX Process class restrictions. */
+ if (packet -> options [DHO_DHCP_CLASS_IDENTIFIER].len) {
+ vendor_class =
+ find_class (0,
+ packet ->
+ options [DHO_DHCP_CLASS_IDENTIFIER].data,
+ packet ->
+ options [DHO_DHCP_CLASS_IDENTIFIER].len);
+ } else {
+ vendor_class = (struct class *)0;
+ }
+
+ if (packet -> options [DHO_DHCP_USER_CLASS_ID].len) {
+ user_class =
+ find_class (1,
+ packet ->
+ options [DHO_DHCP_USER_CLASS_ID].data,
+ packet ->
+ options [DHO_DHCP_USER_CLASS_ID].len);
+ } else {
+ user_class = (struct class *)0;
+ }
+
+ /*
+ * If there is not a specific host entry, and either the
+ * vendor class or user class (if they exist) deny booting,
+ * then bug out.
+ */
+ if (!lease -> host) {
+ if (vendor_class && !vendor_class -> group -> allow_booting) {
+ debug ("Booting denied by vendor class");
+ return;
+ }
+
+ if (user_class && !user_class -> group -> allow_booting) {
+ debug ("Booting denied by user class");
+ return;
+ }
+ }
/* Allocate a lease state structure... */
state = new_lease_state ("ack_lease");
@@ -562,104 +629,38 @@ void ack_lease (packet, lease, offer, when)
lease -> client_hostname = 0;
}
- /* Process all of the executable statements associated with
- this lease. */
- memset (&state -> options, 0, sizeof state -> options);
-
- /* Steal the agent options from the packet. */
- if (packet -> agent_options) {
- state -> options.agent_options = packet -> agent_options;
- packet -> agent_options = (struct agent_options *)0;
- }
-
- /* Execute the subnet statements. */
- execute_statements_in_scope (packet, &state -> options,
- lease -> subnet -> group,
- (struct group *)0);
-
- /* Vendor and user classes are only supported for DHCP clients. */
- if (state -> offer) {
- /* XXX process class stuff here. */
- }
-
- /* If we have a host_decl structure, run the options associated
- with its group. */
- if (lease -> host)
- execute_statements_in_scope (packet, &state -> options,
- lease -> host -> group,
- lease -> subnet -> group);
-
- /* Make sure this packet satisfies the configured minimum
- number of seconds. */
- if (state -> options.server_options [SV_MIN_SECS]) {
- d1 = evaluate_data_expression
- (packet,
- (state -> options.server_options
- [SV_MIN_SECS] -> expression));
- if (d1.len && packet -> raw -> secs < d1.data [0])
- return;
- }
-
- /* Drop the request if it's not allowed for this client. */
- if (!lease -> host &&
- state -> options.server_options [SV_BOOT_UNKNOWN_CLIENTS]) {
- d1 = evaluate_data_expression
- (packet, (state -> options.server_options
- [SV_BOOT_UNKNOWN_CLIENTS] -> expression));
- if (d1.len && !d1.data [0]) {
- note ("Ignoring unknown client %s",
- print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr));
- return;
- }
- }
-
- /* Drop the request if it's not allowed for this client. */
- if (!offer &&
- state -> options.server_options [SV_ALLOW_BOOTP]) {
- d1 = evaluate_data_expression
- (packet, (state -> options.server_options
- [SV_ALLOW_BOOTP] -> expression));
- if (d1.len && !d1.data [0]) {
- note ("Ignoring BOOTP client %s",
- print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr));
- return;
- }
- }
-
- if (state -> options.server_options [SV_ALLOW_BOOTING]) {
- d1 = evaluate_data_expression
- (packet, (state -> options.server_options
- [SV_ALLOW_BOOTING] -> expression));
- if (d1.len && !d1.data [0]) {
- note ("Declining to boot client %s",
- lease -> host -> name
- ? lease -> host -> name
- : print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr));
- return;
- }
- }
-
- /* Figure out the filename. */
- if (state -> options.server_options [SV_FILENAME])
- state -> filename =
- (evaluate_data_expression
- (packet,
- (state -> options.
- server_options [SV_FILENAME] -> expression)));
+ /* Choose a filename; first from the host_decl, if any, then from
+ the user class, then from the vendor class. */
+ if (lease -> host && lease -> host -> group -> filename)
+ strncpy (state -> filename, lease -> host -> group -> filename,
+ sizeof state -> filename);
+ else if (user_class && user_class -> group -> filename)
+ strncpy (state -> filename, user_class -> group -> filename,
+ sizeof state -> filename);
+ else if (vendor_class && vendor_class -> group -> filename)
+ strncpy (state -> filename, vendor_class -> group -> filename,
+ sizeof state -> filename);
+ else if (packet -> raw -> file [0])
+ strncpy (state -> filename, packet -> raw -> file,
+ sizeof state -> filename);
+ else if (lease -> subnet -> group -> filename)
+ strncpy (state -> filename,
+ lease -> subnet -> group -> filename,
+ sizeof state -> filename);
+ else
+ strcpy (state -> filename, "");
/* Choose a server name as above. */
- if (state -> options.server_options [SV_SERVER_NAME])
+ if (lease -> host && lease -> host -> group -> server_name)
+ state -> server_name = lease -> host -> group -> server_name;
+ else if (user_class && user_class -> group -> server_name)
+ state -> server_name = user_class -> group -> server_name;
+ else if (vendor_class && vendor_class -> group -> server_name)
+ state -> server_name = vendor_class -> group -> server_name;
+ else if (lease -> subnet -> group -> server_name)
state -> server_name =
- (evaluate_data_expression
- (packet,
- (state -> options.
- server_options [SV_SERVER_NAME] -> expression)));
+ lease -> subnet -> group -> server_name;
+ else state -> server_name = (char *)0;
/* At this point, we have a lease that we can offer the client.
Now we construct a lease structure that contains what we want,
@@ -677,88 +678,59 @@ void ack_lease (packet, lease, offer, when)
/* Figure out how long a lease to assign. If this is a
dynamic BOOTP lease, its duration must be infinite. */
if (offer) {
- if (packet -> options [DHO_DHCP_LEASE_TIME].len ==
- sizeof (u_int32_t)) {
+ if (packet -> options [DHO_DHCP_LEASE_TIME].len == 4) {
lease_time = getULong
- (packet -> options [DHO_DHCP_LEASE_TIME].data);
- comp_lease_time = DEFAULT_MAX_LEASE_TIME;
- i = SV_MAX_LEASE_TIME;
- if (state ->
- options.server_options [i]) {
- d1 = evaluate_data_expression
- (packet,
- state -> options.
- server_options [i] -> expression);
- if (d1.len == sizeof (u_int32_t))
- comp_lease_time = getULong (d1.data);
- }
-
- /* Enforce the maximum lease length. */
- if (lease_time > comp_lease_time)
- lease_time = comp_lease_time;
+ (packet -> options [DHO_DHCP_LEASE_TIME].data);
- } else {
- i = SV_DEFAULT_LEASE_TIME;
- lease_time = DEFAULT_DEFAULT_LEASE_TIME;
- if (state ->
- options.server_options [i]) {
- d1 = evaluate_data_expression
- (packet,
- state -> options.
- server_options [i] -> expression);
- if (d1.len == sizeof (u_int32_t))
- lease_time = getULong (d1.data);
+ /* Don't let the client ask for a longer lease than
+ is supported for this subnet or host. */
+ if (lease -> host &&
+ lease -> host -> group -> max_lease_time) {
+ if (lease_time >
+ lease -> host -> group -> max_lease_time)
+ lease_time = (lease -> host ->
+ group -> max_lease_time);
+ } else {
+ if (lease_time >
+ lease -> subnet -> group -> max_lease_time)
+ lease_time = (lease -> subnet ->
+ group -> max_lease_time);
}
+ } else {
+ if (lease -> host
+ && lease -> host -> group -> default_lease_time)
+ lease_time = (lease -> host ->
+ group -> default_lease_time);
+ else
+ lease_time = (lease -> subnet ->
+ group -> default_lease_time);
}
- i = SV_MIN_LEASE_TIME;
- comp_lease_time = DEFAULT_MIN_LEASE_TIME;
- if (state -> options.server_options [i]) {
- d1 = evaluate_data_expression
- (packet,
- state -> options.
- server_options [i] -> expression);
- if (d1.len == sizeof (u_int32_t))
- comp_lease_time = getULong (d1.data);
- }
-
- if (lease_time < comp_lease_time)
- lease_time = comp_lease_time;
-
state -> offered_expiry = cur_time + lease_time;
if (when)
lt.ends = when;
else
lt.ends = state -> offered_expiry;
} else {
- lease_time = MAX_TIME - cur_time;
-
- i = SV_BOOTP_LEASE_LENGTH;
- if (state -> options.server_options [i]) {
- d1 = evaluate_data_expression
- (packet,
- state -> options.
- server_options [i] -> expression);
- if (d1.len == sizeof (u_int32_t))
- lease_time = getULong (d1.data);
- }
-
- i = SV_BOOTP_LEASE_CUTOFF;
- if (state -> options.server_options [i]) {
- d1 = evaluate_data_expression
- (packet,
- state -> options.
- server_options [i] -> expression);
- if (d1.len == sizeof (u_int32_t))
- lease_time = getULong (d1.data) - cur_time;
- }
-
- lt.ends = state -> offered_expiry = cur_time + lease_time;
+ if (lease -> host &&
+ lease -> host -> group -> bootp_lease_length)
+ lt.ends = (cur_time +
+ lease -> host ->
+ group -> bootp_lease_length);
+ else if (lease -> subnet -> group -> bootp_lease_length)
+ lt.ends = (cur_time +
+ lease -> subnet ->
+ group -> bootp_lease_length);
+ else if (lease -> host &&
+ lease -> host -> group -> bootp_lease_cutoff)
+ lt.ends = lease -> host -> group -> bootp_lease_cutoff;
+ else
+ lt.ends = (lease -> subnet ->
+ group -> bootp_lease_cutoff);
+ state -> offered_expiry = lt.ends;
lt.flags = BOOTP_LEASE;
}
- lt.timestamp = cur_time;
-
/* Record the uid, if given... */
i = DHO_DHCP_CLIENT_IDENTIFIER;
if (packet -> options [i].len) {
@@ -828,66 +800,143 @@ void ack_lease (packet, lease, offer, when)
state -> hops = packet -> raw -> hops;
state -> offer = offer;
- /* Get the Maximum Message Size option from the packet, if one
- was sent. */
- if (packet -> options [DHO_DHCP_MAX_MESSAGE_SIZE].data) {
- state -> max_message_size =
- getUShort (packet ->
- options [DHO_DHCP_MAX_MESSAGE_SIZE].data);
+ /* Figure out what options to send to the client: */
+
+ /* Start out with the subnet options... */
+ memcpy (state -> options,
+ lease -> subnet -> group -> options,
+ sizeof state -> options);
+
+ /* Vendor and user classes are only supported for DHCP clients. */
+ if (state -> offer) {
+ /* If we have a vendor class, install those options,
+ superseding any subnet options. */
+ if (vendor_class) {
+ for (i = 0; i < 256; i++)
+ if (vendor_class -> group -> options [i])
+ state -> options [i] =
+ (vendor_class -> group ->
+ options [i]);
+ }
+
+ /* If we have a user class, install those options,
+ superseding any subnet and vendor class options. */
+ if (user_class) {
+ for (i = 0; i < 256; i++)
+ if (user_class -> group -> options [i])
+ state -> options [i] =
+ (user_class -> group ->
+ options [i]);
+ }
+
+ }
+
+ /* If we have a host_decl structure, install the associated
+ options, superseding anything that's in the way. */
+ if (lease -> host) {
+ for (i = 0; i < 256; i++)
+ if (lease -> host -> group -> options [i])
+ state -> options [i] = (lease -> host ->
+ group -> options [i]);
+ }
+
+ /* If we didn't get a hostname from an option somewhere, see if
+ we can get one from the lease. */
+ i = DHO_HOST_NAME;
+ if (!state -> options [i] && lease -> hostname) {
+ state -> options [i] = new_tree_cache ("hostname");
+ state -> options [i] -> flags = TC_TEMPORARY;
+ state -> options [i] -> value =
+ (unsigned char *)lease -> hostname;
+ state -> options [i] -> len = strlen (lease -> hostname);
+ state -> options [i] -> buf_size = state -> options [i] -> len;
+ state -> options [i] -> timeout = 0xFFFFFFFF;
+ state -> options [i] -> tree = (struct tree *)0;
}
/* Now, if appropriate, put in DHCP-specific options that
override those. */
if (state -> offer) {
i = DHO_DHCP_MESSAGE_TYPE;
- state -> options.dhcp_options [i] =
- option_cache (make_const_data (&state -> offer,
- sizeof state -> offer,
- 0, 0),
- dhcp_universe.options [i]);
+ state -> options [i] = new_tree_cache ("message-type");
+ state -> options [i] -> flags = TC_TEMPORARY;
+ state -> options [i] -> value = &state -> offer;
+ state -> options [i] -> len = sizeof state -> offer;
+ state -> options [i] -> buf_size = sizeof state -> offer;
+ state -> options [i] -> timeout = 0xFFFFFFFF;
+ state -> options [i] -> tree = (struct tree *)0;
i = DHO_DHCP_SERVER_IDENTIFIER;
- if (!state -> options.dhcp_options [i]) {
- state -> options.dhcp_options [i] =
- (option_cache
- (make_const_data
- ((unsigned char *)
- &state -> ip -> primary_address,
- sizeof state -> ip -> primary_address,
- 0, 0),
- dhcp_universe.options [i]));
+ if (!state -> options [i]) {
+ use_primary:
+ state -> options [i] = new_tree_cache ("server-id");
+ state -> options [i] -> value =
+ (unsigned char *)&state ->
+ ip -> primary_address;
+ state -> options [i] -> len =
+ sizeof state -> ip -> primary_address;
+ state -> options [i] -> buf_size
+ = state -> options [i] -> len;
+ state -> options [i] -> timeout = 0xFFFFFFFF;
+ state -> options [i] -> tree = (struct tree *)0;
+ state -> from.len =
+ sizeof state -> ip -> primary_address;
+ memcpy (state -> from.iabuf,
+ &state -> ip -> primary_address,
+ state -> from.len);
+ } else {
+ /* Find the value of the server identifier... */
+ if (!tree_evaluate (state -> options [i]))
+ goto use_primary;
+ if (!state -> options [i] -> value ||
+ (state -> options [i] -> len >
+ sizeof state -> from.iabuf))
+ goto use_primary;
+
+ state -> from.len = state -> options [i] -> len;
+ memcpy (state -> from.iabuf,
+ state -> options [i] -> value,
+ state -> from.len);
}
- offered_lease_time =
- state -> offered_expiry - cur_time;
+ /* Sanity check the lease time. */
+ if ((state -> offered_expiry - cur_time) < 15)
+ offered_lease_time = (lease -> subnet ->
+ group -> default_lease_time);
+ else if (state -> offered_expiry - cur_time >
+ lease -> subnet -> group -> max_lease_time)
+ offered_lease_time = (lease -> subnet ->
+ group -> max_lease_time);
+ else
+ offered_lease_time =
+ state -> offered_expiry - cur_time;
putULong ((unsigned char *)&state -> expiry,
offered_lease_time);
i = DHO_DHCP_LEASE_TIME;
- if (state -> options.dhcp_options [i])
- warn ("dhcp-lease-time option for %s overridden.",
- inet_ntoa (state -> ciaddr));
- state -> options.dhcp_options [i] =
- option_cache (make_const_data ((unsigned char *)
- &state -> expiry,
- sizeof state -> expiry,
- 0, 0),
- dhcp_universe.options [i]);
+ state -> options [i] = new_tree_cache ("lease-expiry");
+ state -> options [i] -> flags = TC_TEMPORARY;
+ state -> options [i] -> value =
+ (unsigned char *)&state -> expiry;
+ state -> options [i] -> len = sizeof state -> expiry;
+ state -> options [i] -> buf_size = sizeof state -> expiry;
+ state -> options [i] -> timeout = 0xFFFFFFFF;
+ state -> options [i] -> tree = (struct tree *)0;
/* Renewal time is lease time * 0.5. */
offered_lease_time /= 2;
putULong ((unsigned char *)&state -> renewal,
offered_lease_time);
i = DHO_DHCP_RENEWAL_TIME;
- if (state -> options.dhcp_options [i])
- warn ("dhcp-renewal-time option for %s overridden.",
- inet_ntoa (state -> ciaddr));
- state -> options.dhcp_options [i] =
- option_cache (make_const_data ((unsigned char *)
- &state -> renewal,
- sizeof state -> renewal,
- 0, 0),
- dhcp_universe.options [i]);
+ state -> options [i] = new_tree_cache ("renewal-time");
+ state -> options [i] -> flags = TC_TEMPORARY;
+ state -> options [i] -> value =
+ (unsigned char *)&state -> renewal;
+ state -> options [i] -> len = sizeof state -> renewal;
+ state -> options [i] -> buf_size = sizeof state -> renewal;
+ state -> options [i] -> timeout = 0xFFFFFFFF;
+ state -> options [i] -> tree = (struct tree *)0;
+
/* Rebinding time is lease time * 0.875. */
offered_lease_time += (offered_lease_time / 2
@@ -895,95 +944,62 @@ void ack_lease (packet, lease, offer, when)
putULong ((unsigned char *)&state -> rebind,
offered_lease_time);
i = DHO_DHCP_REBINDING_TIME;
- if (state -> options.dhcp_options [i])
- warn ("dhcp-rebinding-time option for %s overridden.",
- inet_ntoa (state -> ciaddr));
- state -> options.dhcp_options [i] =
- option_cache (make_const_data ((unsigned char *)
- &state -> rebind,
- sizeof state -> rebind,
- 0, 0),
- dhcp_universe.options [i]);
- }
-
- /* Use the subnet mask from the subnet declaration if no other
- mask has been provided. */
- i = DHO_SUBNET_MASK;
- if (!state -> options.dhcp_options [i]) {
- state -> options.dhcp_options [i] =
- (option_cache
- (make_const_data (lease -> subnet -> netmask.iabuf,
- lease -> subnet -> netmask.len,
- 0, 0),
- dhcp_universe.options [i]));
- }
-
- /* Use the hostname from the host declaration if there is one
- and no hostname has otherwise been provided, and if the
- use-host-decl-name flag is set. */
- i = DHO_HOST_NAME;
- if (!state -> options.dhcp_options [i] &&
- lease -> host && lease -> host -> name) {
- d1 = evaluate_data_expression
- (packet, (state -> options.server_options
- [SV_USE_HOST_DECL_NAMES] -> expression));
- if (d1.len && d1.data [0]) {
- state -> options.dhcp_options [i] =
- (option_cache
- (make_const_data (lease -> host -> name,
- strlen (lease ->
- host -> name),
- 1, 0),
- dhcp_universe.options [i]));
+ state -> options [i] = new_tree_cache ("rebind-time");
+ state -> options [i] -> flags = TC_TEMPORARY;
+ state -> options [i] -> value =
+ (unsigned char *)&state -> rebind;
+ state -> options [i] -> len = sizeof state -> rebind;
+ state -> options [i] -> buf_size = sizeof state -> rebind;
+ state -> options [i] -> timeout = 0xFFFFFFFF;
+ state -> options [i] -> tree = (struct tree *)0;
+
+ /* If we used the vendor class the client specified, we
+ have to return it. */
+ if (vendor_class) {
+ i = DHO_DHCP_CLASS_IDENTIFIER;
+ state -> options [i] =
+ new_tree_cache ("class-identifier");
+ state -> options [i] -> flags = TC_TEMPORARY;
+ state -> options [i] -> value =
+ (unsigned char *)vendor_class -> name;
+ state -> options [i] -> len =
+ strlen (vendor_class -> name);
+ state -> options [i] -> buf_size =
+ state -> options [i] -> len;
+ state -> options [i] -> timeout = 0xFFFFFFFF;
+ state -> options [i] -> tree = (struct tree *)0;
}
- }
- /* If we don't have a hostname yet, and we've been asked to do
- a reverse lookup to find the hostname, do it. */
- if (!state -> options.dhcp_options [i]
- && state -> options.server_options [SV_GET_LEASE_HOSTNAMES]) {
- d1 = evaluate_data_expression
- (packet, (state -> options.server_options
- [SV_GET_LEASE_HOSTNAMES] -> expression));
- if (d1.len && d1.data [0]) {
- struct in_addr ia;
- struct hostent *h;
-
- memcpy (&ia, lease -> ip_addr.iabuf, 4);
-
- h = gethostbyaddr ((char *)&ia, sizeof ia, AF_INET);
- if (!h)
- warn ("No hostname for %s", inet_ntoa (ia));
- else {
- state -> options.dhcp_options [i] =
- option_cache
- (make_const_data
- (h -> h_name,
- strlen (h -> h_name) + 1,
- 1, 1),
- dhcp_universe.options [i]);
- }
+ /* If we used the user class the client specified, we
+ have to return it. */
+ if (user_class) {
+ i = DHO_DHCP_USER_CLASS_ID;
+ state -> options [i] = new_tree_cache ("user-class");
+ state -> options [i] -> flags = TC_TEMPORARY;
+ state -> options [i] -> value =
+ (unsigned char *)user_class -> name;
+ state -> options [i] -> len =
+ strlen (user_class -> name);
+ state -> options [i] -> buf_size =
+ state -> options [i] -> len;
+ state -> options [i] -> timeout = 0xFFFFFFFF;
+ state -> options [i] -> tree = (struct tree *)0;
}
}
- /* If so directed, use the leased IP address as the router address.
- This supposedly makes Win95 machines ARP for all IP addresses,
- so if the local router does proxy arp, you win. */
-
- i = SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
- if (state -> options.server_options [i]) {
- d1 = evaluate_data_expression
- (packet,
- state -> options.server_options [i] -> expression);
- if (d1.len && d1.data) {
- i = DHO_ROUTERS;
-
- state -> options.dhcp_options [i] =
- option_cache (make_const_data
- (lease -> ip_addr.iabuf,
- lease -> ip_addr.len, 0, 0),
- dhcp_universe.options [i]);
- }
+ /* Use the subnet mask from the subnet declaration if no other
+ mask has been provided. */
+ i = DHO_SUBNET_MASK;
+ if (!state -> options [i]) {
+ state -> options [i] = new_tree_cache ("subnet-mask");
+ state -> options [i] -> flags = TC_TEMPORARY;
+ state -> options [i] -> value =
+ lease -> subnet -> netmask.iabuf;
+ state -> options [i] -> len = lease -> subnet -> netmask.len;
+ state -> options [i] -> buf_size =
+ lease -> subnet -> netmask.len;
+ state -> options [i] -> timeout = 0xFFFFFFFF;
+ state -> options [i] -> tree = (struct tree *)0;
}
#ifdef DEBUG_PACKET
@@ -995,11 +1011,14 @@ void ack_lease (packet, lease, offer, when)
/* If this is a DHCPOFFER, ping the lease address before actually
sending the offer. */
- if (offer == DHCPOFFER && !(lease -> flags & STATIC_LEASE)) {
+ if (offer == DHCPOFFER && !(lease -> flags & STATIC_LEASE) &&
+ cur_time - lease -> timestamp > 60) {
+ lease -> timestamp = cur_time;
icmp_echorequest (&lease -> ip_addr);
add_timeout (cur_time + 1, lease_ping_timeout, lease);
++outstanding_pings;
} else {
+ lease -> timestamp = cur_time;
dhcp_reply (lease);
}
}
@@ -1017,9 +1036,6 @@ void dhcp_reply (lease)
int i;
struct lease_state *state = lease -> state;
int nulltp, bootpp;
- struct agent_options *a, *na;
- struct option_tag *ot, *not;
- struct data_string d1;
if (!state)
error ("dhcp_reply was supplied lease with no state!");
@@ -1029,28 +1045,16 @@ void dhcp_reply (lease)
/* Copy in the filename if given; otherwise, flag the filename
buffer as available for options. */
- if (state -> filename.len && state -> filename.data) {
- memcpy (raw.file,
- state -> filename.data,
- state -> filename.len > sizeof raw.file
- ? sizeof raw.file : state -> filename.len);
- if (sizeof raw.file > state -> filename.len)
- memset (&raw.file [state -> filename.len], 0,
- (sizeof raw.file) - state -> filename.len);
- } else
+ if (state -> filename [0])
+ strncpy (raw.file, state -> filename, sizeof raw.file);
+ else
bufs |= 1;
/* Copy in the server name if given; otherwise, flag the
server_name buffer as available for options. */
- if (state -> server_name.len && state -> server_name.data) {
- memcpy (raw.sname,
- state -> server_name.data,
- state -> server_name.len > sizeof raw.sname
- ? sizeof raw.sname : state -> server_name.len);
- if (sizeof raw.sname > state -> server_name.len)
- memset (&raw.sname [state -> server_name.len], 0,
- (sizeof raw.sname) - state -> server_name.len);
- } else
+ if (state -> server_name)
+ strncpy (raw.sname, state -> server_name, sizeof raw.sname);
+ else
bufs |= 2; /* XXX */
memcpy (raw.chaddr, lease -> hardware_addr.haddr, sizeof raw.chaddr);
@@ -1072,45 +1076,31 @@ void dhcp_reply (lease)
/* Insert such options as will fit into the buffer. */
packet_length = cons_options ((struct packet *)0, &raw,
- state -> max_message_size,
- &state -> options,
- bufs, nulltp, bootpp);
+ state -> options, bufs, nulltp, bootpp);
/* Having done the cons_options(), we can release the tree_cache
entries. */
for (i = 0; i < 256; i++) {
- if (state -> options.dhcp_options [i])
- free_option_cache (state -> options.dhcp_options [i],
- "dhcp_reply");
- if (state -> options.server_options [i])
- free_option_cache (state -> options.dhcp_options [i],
- "dhcp_reply");
-
- }
-
- /* We can also release the agent options, if any... */
- for (a = state -> options.agent_options; a; a = na) {
- na = a -> next;
- for (ot = a -> first; ot; ot = not) {
- not = ot -> next;
- free (ot);
- }
+ if (state -> options [i] &&
+ state -> options [i] -> flags & TC_TEMPORARY)
+ free_tree_cache (state -> options [i], "dhcp_reply");
}
memcpy (&raw.ciaddr, &state -> ciaddr, sizeof raw.ciaddr);
memcpy (&raw.yiaddr, lease -> ip_addr.iabuf, 4);
/* Figure out the address of the next server. */
- raw.siaddr = state -> ip -> primary_address;
- if (state -> options.server_options [SV_NEXT_SERVER]) {
- d1 = evaluate_data_expression
- ((struct packet *)0,
- (state -> options.
- server_options [SV_NEXT_SERVER] -> expression));
- /* If there was more than one answer, take the first. */
- if (d1.len >= 4 && d1.data)
- memcpy (&raw.siaddr, d1.data, 4);
- }
+ if (lease -> host && lease -> host -> group -> next_server.len)
+ memcpy (&raw.siaddr,
+ lease -> host -> group -> next_server.iabuf, 4);
+ else if (lease -> subnet -> group -> next_server.len)
+ memcpy (&raw.siaddr,
+ lease -> subnet -> group -> next_server.iabuf, 4);
+ else if (lease -> subnet -> interface_address.len)
+ memcpy (&raw.siaddr,
+ lease -> subnet -> interface_address.iabuf, 4);
+ else
+ raw.siaddr = state -> ip -> primary_address;
raw.giaddr = state -> giaddr;
@@ -1144,8 +1134,6 @@ void dhcp_reply (lease)
#endif
memset (to.sin_zero, 0, sizeof to.sin_zero);
- from = state -> ip -> primary_address;
-
#ifdef DEBUG_PACKET
dump_raw ((unsigned char *)&raw, packet_length);
#endif
@@ -1160,49 +1148,50 @@ void dhcp_reply (lease)
to.sin_addr = raw.giaddr;
to.sin_port = local_port;
-#ifdef USE_FALLBACK
- result = send_fallback (&fallback_interface,
- (struct packet *)0,
- &raw, packet_length,
- raw.siaddr, &to, &hto);
- if (result < 0)
- warn ("send_fallback: %m");
+ if (fallback_interface) {
+ result = send_packet (fallback_interface,
+ (struct packet *)0,
+ &raw, packet_length,
+ raw.siaddr, &to, &hto);
+ if (result < 0)
+ warn ("send_fallback: %m");
- free_lease_state (state, "dhcp_reply fallback 1");
- lease -> state = (struct lease_state *)0;
- return;
-#endif
+ free_lease_state (state, "dhcp_reply fallback 1");
+ lease -> state = (struct lease_state *)0;
+ return;
+ }
- /* If it comes from a client who already knows its address and
+ /* If it comes from a client that already knows its address and
is not requesting a broadcast response, sent it directly to
that client. */
} else if (raw.ciaddr.s_addr && state -> offer == DHCPACK &&
- !(raw.flags & htons (BOOTP_BROADCAST))) {
+ !(raw.flags & htons (BOOTP_BROADCAST)) &&
+ can_unicast_without_arp ()) {
to.sin_addr = state -> ciaddr;
to.sin_port = remote_port; /* XXX */
-#ifdef USE_FALLBACK
- result = send_fallback (&fallback_interface,
- (struct packet *)0,
- &raw, packet_length,
- raw.siaddr, &to, &hto);
- if (result < 0)
- warn ("send_fallback: %m");
- free_lease_state (state, "dhcp_reply fallback 1");
- lease -> state = (struct lease_state *)0;
- return;
-#endif
-
- /* Otherwise, broadcast it on the local network. */
+ if (fallback_interface) {
+ result = send_packet (fallback_interface,
+ (struct packet *)0,
+ &raw, packet_length,
+ raw.siaddr, &to, &hto);
+ if (result < 0)
+ warn ("send_fallback: %m");
+ free_lease_state (state, "dhcp_reply fallback 1");
+ lease -> state = (struct lease_state *)0;
+ return;
+ }
} else {
+ /* Otherwise, broadcast it on the local network. */
to.sin_addr.s_addr = htonl (INADDR_BROADCAST);
to.sin_port = remote_port; /* XXX */
}
+ memcpy (&from, state -> from.iabuf, sizeof from);
result = send_packet (state -> ip,
(struct packet *)0, &raw, packet_length,
- raw.siaddr, &to, &hto);
+ from, &to, &hto);
if (result < 0)
warn ("sendpkt: %m");
@@ -1326,7 +1315,9 @@ struct lease *find_lease (packet, share, ours)
int i = DHO_DHCP_CLIENT_IDENTIFIER;
/* If for some reason the client has more than one lease
on the subnet that matches its uid, pick the one that
- it asked for. */
+ it asked for. It might be nice in some cases to
+ release the extraneous leases, but better to leave
+ that to a human. */
if (packet -> options [i].data &&
ip_lease -> uid_len == packet -> options [i].len &&
!memcmp (packet -> options [i].data,
@@ -1337,16 +1328,6 @@ struct lease *find_lease (packet, share, ours)
packet -> raw -> hlen,
packet -> raw -> chaddr),
ip_lease -> shared_network -> name);
-
- /* If the client is REQUESTing the lease, it shouldn't
- still be using the old one, so we can free it for
- allocation. This is only true if the duplicate
- lease is on the same network, of course. */
-
- if (packet -> packet_type == DHCPREQUEST &&
- share == uid_lease -> shared_network)
- dissociate_lease (uid_lease);
-
uid_lease = ip_lease;
}
ip_lease = (struct lease *)0;
@@ -1430,7 +1411,7 @@ struct lease *find_lease (packet, share, ours)
if (uid_lease) {
if (lease) {
if (packet -> packet_type == DHCPREQUEST)
- dissociate_lease (uid_lease);
+ release_lease (uid_lease);
} else {
lease = uid_lease;
lease -> host = (struct host_decl *)0;
@@ -1441,7 +1422,7 @@ struct lease *find_lease (packet, share, ours)
if (hw_lease) {
if (lease) {
if (packet -> packet_type == DHCPREQUEST)
- dissociate_lease (hw_lease);
+ release_lease (hw_lease);
} else {
lease = hw_lease;
lease -> host = (struct host_decl *)0;
@@ -1464,8 +1445,8 @@ struct lease *find_lease (packet, share, ours)
/* If we find an abandoned lease, take it, but print a
warning message, so that if it continues to lose,
the administrator will eventually investigate. */
- if (lease -> flags & ABANDONED_LEASE) {
- warn ("Reclaiming REQUESTed abandoned IP address %s.\n",
+ if (lease && lease -> flags & ABANDONED_LEASE) {
+ warn ("Reclaiming REQUESTed abandoned IP address %s.",
piaddr (lease -> ip_addr));
lease -> flags &= ~ABANDONED_LEASE;
}
@@ -1490,8 +1471,17 @@ struct lease *mockup_lease (packet, share, hp)
mock.next = mock.prev = (struct lease *)0;
mock.shared_network = mock.subnet -> shared_network;
mock.host = hp;
- mock.uid = hp -> client_identifier.data;
- mock.uid_len = hp -> client_identifier.len;
+
+ if (hp -> group -> options [DHO_DHCP_CLIENT_IDENTIFIER]) {
+ mock.uid = hp -> group ->
+ options [DHO_DHCP_CLIENT_IDENTIFIER] -> value;
+ mock.uid_len = hp -> group ->
+ options [DHO_DHCP_CLIENT_IDENTIFIER] -> len;
+ } else {
+ mock.uid = (unsigned char *)0;
+ mock.uid_len = 0;
+ }
+
mock.hardware_addr = hp -> interface;
mock.starts = mock.timestamp = mock.ends = MIN_TIME;
mock.flags = STATIC_LEASE;
diff --git a/server/dhcpd.c b/server/dhcpd.c
index afbbe884..b2359f5a 100644
--- a/server/dhcpd.c
+++ b/server/dhcpd.c
@@ -42,13 +42,15 @@
#ifndef lint
static char ocopyright[] =
-"$Id: dhcpd.c,v 1.52 1998/07/10 04:52:25 mellon Exp $ Copyright 1995, 1996, 1997, 1998 The Internet Software Consortium.";
+"$Id: dhcpd.c,v 1.45.2.7 1998/12/23 14:18:47 mellon Exp $ Copyright 1995, 1996, 1997, 1998 The Internet Software Consortium.";
#endif
static char copyright[] =
-"Copyright 1995, 1996 The Internet Software Consortium.";
+"Copyright 1995, 1996, 1997, 1998 The Internet Software Consortium.";
static char arr [] = "All rights reserved.";
-static char message [] = "Internet Software Consortium DHCPD $Name: $";
+static char message [] = "Internet Software Consortium DHCP Server V2.0b1pl8 ";
+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";
#include "dhcpd.h"
@@ -60,10 +62,6 @@ struct group root_group;
struct iaddr server_identifier;
int server_identifier_matched;
-#ifdef USE_FALLBACK
-struct interface_info fallback_interface;
-#endif
-
u_int16_t local_port;
u_int16_t remote_port;
@@ -78,8 +76,6 @@ char *path_dhcpd_conf = _PATH_DHCPD_CONF;
char *path_dhcpd_db = _PATH_DHCPD_DB;
char *path_dhcpd_pid = _PATH_DHCPD_PID;
-int dhcp_max_agent_option_packet_length = DHCP_MTU_MAX;
-
int main (argc, argv, envp)
int argc;
char **argv, **envp;
@@ -175,6 +171,8 @@ int main (argc, argv, envp)
note (message);
note (copyright);
note (arr);
+ note (contrib);
+ note (url);
}
/* Default to the DHCP/BOOTP port. */
@@ -195,17 +193,6 @@ int main (argc, argv, envp)
/* Get the current time... */
GET_TIME (&cur_time);
- /* Initialize DNS support... */
-#if 0
- dns_startup ();
-#endif
-
- /* Start the interactive client listener. */
- interact_startup ();
-
- /* Set up the client classification system. */
- classification_setup ();
-
/* Read the dhcpd.conf file... */
if (!readconf ())
error ("Configuration file errors encountered -- exiting");
@@ -338,11 +325,6 @@ void lease_pinged (from, packet, length)
return;
}
- if (lp -> ends > cur_time) {
- warn ("ICMP Echo reply arrived while lease %s was valid.\n",
- piaddr (from));
- }
-
/* At this point it looks like we pinged a lease and got a
response, which shouldn't have happened. */
free_lease_state (lp -> state, "lease_pinged");
diff --git a/server/dhcpd.conf b/server/dhcpd.conf
index 596f750c..a50dee07 100644
--- a/server/dhcpd.conf
+++ b/server/dhcpd.conf
@@ -14,10 +14,19 @@ server-identifier toccata.fugue.com;
option domain-name "fugue.com";
option domain-name-servers toccata.fugue.com;
-option subnet-mask 255.255.255.224;
-default-lease-time 600;
-max-lease-time 7200;
+# Shared network declaration is used to group subnets which share the same
+# physical network together. The name is specified so that the shared
+# network can be referred to in log messages - it serves no other function.
+shared-network FUGUE {
+
+# option definitions common to this shared network.
+ option subnet-mask 255.255.255.224;
+ default-lease-time 600;
+ max-lease-time 7200;
+
+# One of the two IP subnets that share this physical network
+#
# Address ranges can be specified for each subnet attached to
# a shared network. Since these subnets share the same physical
# network, addresses are pooled together, and assignments are made
@@ -31,18 +40,28 @@ max-lease-time 7200;
# options that aren't specified in the subnet are taken from the shared
# network (if any) and then from the global option list.
-subnet 204.254.239.0 netmask 255.255.255.224 {
- range 204.254.239.10 204.254.239.20;
- option broadcast-address 204.254.239.31;
- option routers prelude.fugue.com;
-}
+ subnet 204.254.239.0 netmask 255.255.255.224 {
+ range 204.254.239.10 204.254.239.20;
+ option broadcast-address 204.254.239.31;
+ option routers prelude.fugue.com;
+ }
-subnet 204.254.239.32 netmask 255.255.255.224 {
- range dynamic-bootp 204.254.239.10 204.254.239.20;
- option broadcast-address 204.254.239.31;
- option routers snarg.fugue.com;
+# The other subnet that shares this physical network
+ subnet 204.254.239.32 netmask 255.255.255.224 {
+ range dynamic-bootp 204.254.239.10 204.254.239.20;
+ option broadcast-address 204.254.239.31;
+ option routers snarg.fugue.com;
+ }
}
+# IP subnets that are alone on their physical wire should be declared by
+# themselves. ISC dhcpd may still refer to them as shared networks in
+# log messages, but this is simply an artifact of the underlying data
+# structures.
+#
+# Note that options can be specified in the subnet declaration which
+# supersede the global options specified earlier.
+
subnet 192.5.5.0 netmask 255.255.255.224 {
range 192.5.5.26 192.5.5.30;
option name-servers bb.home.vix.com, gw.home.vix.com;
diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5
index 45242234..f6bfc92e 100644
--- a/server/dhcpd.conf.5
+++ b/server/dhcpd.conf.5
@@ -1,6 +1,6 @@
.\" dhcpd.conf.5
.\"
-.\" Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
+.\" Copyright (c) 1995, 1996 The Internet Software Consortium.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -493,39 +493,6 @@ should be the maximum length in seconds that will be assigned to a
lease if the client requesting the lease asks for a specific
expiration time.
.PP
-.B The
-.I min-lease-time
-.B statement
-.PP
- \fBmin-lease-time\fR \fItime\fR\fB;\fR
-.PP
-.I Time
-should be the minimum length in seconds that will be assigned to a
-lease if the client requesting the lease asks for a specific
-expiration time.
-.PP
-.B The
-.I min-secs
-.B statement
-.PP
- \fBmin-secs\fR \fIseconds\fR\fB;\fR
-.PP
-.I Seconds
-should be the minimum number of seconds since a client began trying to
-acquire a new lease before the DHCP server will respond to its request.
-The number of seconds is based on what the client reports, and the maximum
-value that the client can report is 255 seconds. Generally, setting this
-to one will result in the DHCP server not responding to the client's first
-request, but always responding to its second request.
-.PP
-This can be used
-to set up a secondary DHCP server which never offers an address to a client
-until the primary server has been given a chance to do so. If the primary
-server is down, the client will bind to the secondary server, but otherwise
-clients should always bind to the primary. Note that this does not, by
-itself, permit a primary server and a secondary server to share a pool of
-dynamically-allocatable addresses.
-.PP
.B The
.I hardware
.B statement
@@ -696,19 +663,6 @@ An \fIoption host-name\fR statement within a host declaration will
override the use of the name in the host declaration.
.PP
.B The
-.I use-lease-addr-for-default-route
-.B statement
-.PP
- \fBuse-lease-addr-for-default-route\fR \fIflag\fR\fB;\fR
-.PP
-If the \fIuse-lease-addr-for-default-route\fR parameter is true in a
-given scope, then instead of sending the value specified in the
-routers option (or sending no value at all), the IP address of the
-lease being assigned is sent to the client. This supposedly causes
-Win95 machines to ARP for all IP addresses, which can be helpful if
-your router is configured for proxy ARP.
-.PP
-.B The
.I server-identifier
.B statement
.PP
diff --git a/server/dhcpd.leases.cat5 b/server/dhcpd.leases.cat5
index 9aab943a..f509e622 100644
--- a/server/dhcpd.leases.cat5
+++ b/server/dhcpd.leases.cat5
@@ -10,39 +10,161 @@ NNAAMMEE
DDEESSCCRRIIPPTTIIOONN
The Internet Software Consortium DHCP Server keeps a per­
sistent database of leases that it has assigned. This
- database is a free-form ASCII file containing one valid
- declaration per lease. If more than one declaration
- appears for a given lease, the last one in the file is
- used. The file is written as a log, so this is not an
- unusual occurrance.
+ database is a free-form ASCII file containing a series of
+ lease declarations. Every time a lease is acquired,
+ renewed or released, its new value is recorded at the end
+ of the lease file. So if more than one declaration
+ appears for a given lease, the last one in the file is the
+ current one.
When dhcpd is first installed, there is no lease database.
- However, dhcpd requires that a lease database be present
+ However, dhcpd requires that a lease database be present
before it will start. To make the initial lease database,
just create an empty file called /var/db/dhcpd.leases.
- In order to prevent the lease database from growing with­
- out bound, the file is rewritten from time to time.
+ In order to prevent the lease database from growing with­
+ out bound, the file is rewritten from time to time.
First, a temporary lease database is created and all known
leases are dumped to it. Then, the old lease database is
- renamed /var/db/dhcpd.leases~. Finally, the newly writ­
+ renamed /var/db/dhcpd.leases~. Finally, the newly writ­
ten lease database is moved into place.
There is a window of vulnerability where if the dhcpd pro­
- cess is killed or the system crashes after the old lease
- database has been renamed but before the new one has been
- moved into place, there will be no /var/db/dhcpd.leases.
+ cess is killed or the system crashes after the old lease
+ database has been renamed but before the new one has been
+ moved into place, there will be no /var/db/dhcpd.leases.
In this case, dhcpd will refuse to start, and will require
- manual intervention. DDOO NNOOTT simply create a new lease
+ manual intervention. DDOO NNOOTT simply create a new lease
file when this happens - if you do, you will lose all your
- old bindings, and chaos will ensue. Instead, rename
- /var/db/dhcpd.leases~ to /var/db/dhcpd.leases, restoring
- the old, valid lease file, and then start dhcpd. This
+ old bindings, and chaos will ensue. Instead, rename
+ /var/db/dhcpd.leases~ to /var/db/dhcpd.leases, restoring
+ the old, valid lease file, and then start dhcpd. This
guarantees that a valid lease file will be restored.
FFOORRMMAATT
- The format of the lease declarations is not currently doc­
- umented.
+ Lease descriptions are stored in a format that is parsed
+ by the same recursive descent parser used to read the
+ ddhhccppdd..ccoonnff((55)) and ddhhcclliieenntt..ccoonnff((55)) files. Currently, the
+ only declaration that is used in the dhcpd.leases file is
+ the lleeaassee declaration.
+
+ lleeaassee _i_p_-_a_d_d_r_e_s_s {{ _s_t_a_t_e_m_e_n_t_s_._._. }}
+
+ Each lease declaration include the single IP address that
+ has been leased to the client. The statements within the
+ braces define the duration of the lease and to whom it is
+ assigned.
+
+ The start and end time of a lease are recorded using the
+ ``starts'' and ``ends'' statements:
+
+
+
+
+ 1
+
+
+
+
+
+dhcpd.leases(5) dhcpd.leases(5)
+
+
+ ssttaarrttss _d_a_t_e;;
+ eennddss _d_a_t_e;;
+
+ Dates are specified as follows:
+
+ _w_e_e_k_d_a_y _y_e_a_r//_m_o_n_t_h//_d_a_y _h_o_u_r::_m_i_n_u_t_e::_s_e_c_o_n_d
+
+ The weekday is present to make it easy for a human to tell
+ when a lease expires - it's specified as a number from
+ zero to six, with zero being Sunday. The day of week is
+ ignored on input. The year is specified with the century,
+ so it should generally be four digits except for really
+ long leases. The month is specified as a number starting
+ with 1 for January. The day of the month is likewise
+ specified starting with 1. The hour is a number between 0
+ and 23, the minute a number between 0 and 59, and the sec­
+ ond also a number between 0 and 59.
+
+ Lease times are specified in Greenwich Mean Time (GMT),
+ not in the local time zone. Since Greenwich is actually
+ on Daylight Savings Time part of the year, there is proba­
+ bly nowhere in the world where the times recorded on a
+ lease are always the same as wall clock times. On a unix
+ machine, one can often figure out the current time in GMT
+ by typing ddaattee --uu.
+
+ The MAC address of the network interface that was used to
+ acquire the lease is recorded with the hhaarrddwwaarree statement:
+
+ hhaarrddwwaarree _h_a_r_d_w_a_r_e_-_t_y_p_e _m_a_c_-_a_d_d_r_e_s_s;;
+
+ The MAC address is specified as a series of hexadecimal
+ octets, seperated by colons.
+
+ If the client used a client identifier to acquire its
+ address, the client identifier is recorded using the uuiidd
+ statement:
+
+ uuiidd _c_l_i_e_n_t_-_i_d_e_n_t_i_f_i_e_r;;
+
+ The client identifier is recorded as a series of hexadeci­
+ mal octets, regardless of whether the client specifies an
+ ASCII string or uses the newer hardware type/MAC address
+ format.
+
+ If the client sends a hostname using the _C_l_i_e_n_t _H_o_s_t_n_a_m_e
+ option, as specified in some versions of the DHCP-DNS
+ Interaction draft, that hostname is recorded using the
+ cclliieenntt--hhoossttnnaammee statement.
+
+ cclliieenntt--hhoossttnnaammee ""_h_o_s_t_n_a_m_e"";;
+
+ If the client sends its hostname using the _H_o_s_t_n_a_m_e
+ option, as Windows 95 does, it is recorded using the
+
+
+
+ 2
+
+
+
+
+
+dhcpd.leases(5) dhcpd.leases(5)
+
+
+ hhoossttnnaammee statement.
+
+ hhoossttnnaammee ""_h_o_s_t_n_a_m_e"";;
+
+ The DHCP server may determine that a lease has been mis­
+ used in some way, either because a client that has been
+ assigned a lease NAKs it, or because the server's own
+ attempt to see if an address is in use prior to reusing it
+ reveals that the address is in fact already in use. In
+ that case, the aabbaannddoonneedd statement will be used to indi­
+ cate that the lease should not be reassigned.
+
+ aabbaannddoonneedd;;
+
+ Abandoned leases are reclaimed automatically. When a
+ client asks for a new address, and the server finds that
+ there are no new addresses, it checks to see if there are
+ any abandoned leases, and allocates the least recently
+ abandoned lease. The standard mechanisms for checking
+ for lease address conflicts are still followed, so if the
+ abandoned lease's IP address is still in use, it will be
+ reabandoned.
+
+ If a client rreeqquueessttss an abandoned address, the server
+ assumes that the reason the address was abandoned was that
+ the lease file was corrupted, and that the client is the
+ machine that responded when the lease was probed, causing
+ it to be abandoned. In that case, the address is immedi­
+ ately assigned to the client.
FFIILLEESS
//vvaarr//ddbb//ddhhccppdd..lleeaasseess
@@ -61,6 +183,16 @@ AAUUTTHHOORR
- 1
+
+
+
+
+
+
+
+
+
+
+ 3
diff --git a/server/dhcpdi.c b/server/dhcpdi.c
deleted file mode 100644
index 82815b2c..00000000
--- a/server/dhcpdi.c
+++ /dev/null
@@ -1,1075 +0,0 @@
-/* dhcpdi.c
-
- Text interaction routines for dhcp server. */
-
-/*
- * Copyright (c) 1998 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software was written for the Internet Software Consortium by
- * Ted Lemon <mellon@fugue.com> in cooperation with Vixie Enterprises.
- * To learn more about the Internet Software Consortium, see
- * ``http://www.vix.com/isc''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: dhcpdi.c,v 1.1 1998/04/09 05:19:26 mellon Exp $ Copyright (c) 1998 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-static void top_level_ls PROTO ((struct interact_client *));
-static void top_level_print PROTO ((struct interact_client *, char *));
-static void top_level_set PROTO ((struct interact_client *, char *));
-static void top_level_rm PROTO ((struct interact_client *, char *));
-static void top_level_cd PROTO ((struct interact_client *, char *));
-static void top_level_cdup PROTO ((struct interact_client *));
-static void *top_level_next PROTO ((struct interact_client *, void *));
-
-static void interface_class_ls PROTO ((struct interact_client *));
-static void interface_class_print PROTO ((struct interact_client *, char *));
-static void interface_class_set PROTO ((struct interact_client *, char *));
-static void interface_class_rm PROTO ((struct interact_client *, char *));
-static void interface_class_cd PROTO ((struct interact_client *, char *));
-static void interface_class_cdup PROTO ((struct interact_client *));
-static void *interface_class_next PROTO ((struct interact_client *, void *));
-
-static void interface_ls PROTO ((struct interact_client *));
-static void interface_print PROTO ((struct interact_client *, char *));
-static void interface_set PROTO ((struct interact_client *, char *));
-static void interface_rm PROTO ((struct interact_client *, char *));
-static void interface_cd PROTO ((struct interact_client *, char *));
-static void interface_cdup PROTO ((struct interact_client *));
-static void *interface_next PROTO ((struct interact_client *, void *));
-
-static void shared_network_ls PROTO ((struct interact_client *));
-static void shared_network_class_ls PROTO ((struct interact_client *));
-static void shared_network_class_print PROTO ((struct interact_client *,
- char *));
-static void shared_network_class_set PROTO ((struct interact_client *,
- char *));
-static void shared_network_class_rm PROTO ((struct interact_client *,
- char *));
-static void shared_network_class_cd PROTO ((struct interact_client *,
- char *));
-static void shared_network_class_cdup PROTO ((struct interact_client *));
-static void *shared_network_class_next PROTO ((struct interact_client *,
- void *));
-
-static void shared_network_print PROTO ((struct interact_client *, char *));
-static void shared_network_set PROTO ((struct interact_client *, char *));
-static void shared_network_rm PROTO ((struct interact_client *, char *));
-static void shared_network_cd PROTO ((struct interact_client *, char *));
-static void shared_network_cdup PROTO ((struct interact_client *));
-static void *shared_network_next PROTO ((struct interact_client *, void *));
-
-static void subnet_class_ls PROTO ((struct interact_client *));
-static void subnet_class_print PROTO ((struct interact_client *, char *));
-static void subnet_class_set PROTO ((struct interact_client *, char *));
-static void subnet_class_rm PROTO ((struct interact_client *, char *));
-static void subnet_class_cd PROTO ((struct interact_client *, char *));
-static void subnet_class_cdup PROTO ((struct interact_client *));
-static void *subnet_class_next PROTO ((struct interact_client *, void *));
-static void *subnet_class_next_share PROTO ((struct interact_client *,
- void *));
-
-static void subnet_ls PROTO ((struct interact_client *));
-static void subnet_print PROTO ((struct interact_client *, char *));
-static void subnet_set PROTO ((struct interact_client *, char *));
-static void subnet_rm PROTO ((struct interact_client *, char *));
-static void subnet_cd PROTO ((struct interact_client *, char *));
-static void subnet_cdup PROTO ((struct interact_client *));
-static void *subnet_next PROTO ((struct interact_client *, void *));
-
-static void host_class_ls PROTO ((struct interact_client *));
-static void host_class_print PROTO ((struct interact_client *, char *));
-static void host_class_set PROTO ((struct interact_client *, char *));
-static void host_class_rm PROTO ((struct interact_client *, char *));
-static void host_class_cd PROTO ((struct interact_client *, char *));
-static void host_class_cdup PROTO ((struct interact_client *));
-static void *host_class_next PROTO ((struct interact_client *, void *));
-
-static void host_ls PROTO ((struct interact_client *));
-static void host_print PROTO ((struct interact_client *, char *));
-static void host_set PROTO ((struct interact_client *, char *));
-static void host_rm PROTO ((struct interact_client *, char *));
-static void host_cd PROTO ((struct interact_client *, char *));
-static void host_cdup PROTO ((struct interact_client *));
-static void *host_next PROTO ((struct interact_client *, void *));
-
-static void lease_ls PROTO ((struct interact_client *));
-static void lease_print PROTO ((struct interact_client *, char *));
-static void lease_set PROTO ((struct interact_client *, char *));
-static void lease_rm PROTO ((struct interact_client *, char *));
-static void lease_cd PROTO ((struct interact_client *, char *));
-static void lease_cdup PROTO ((struct interact_client *));
-static void lease_cdup_host PROTO ((struct interact_client *));
-static void *lease_next PROTO ((struct interact_client *, void *));
-
-static void *lease_next_active PROTO ((struct interact_client *, void *));
-static void *lease_next_free PROTO ((struct interact_client *, void *));
-static void *lease_next_abandoned PROTO ((struct interact_client *, void *));
-
-static void class_class_ls PROTO ((struct interact_client *));
-static void class_class_print PROTO ((struct interact_client *, char *));
-static void class_class_set PROTO ((struct interact_client *, char *));
-static void class_class_rm PROTO ((struct interact_client *, char *));
-static void class_class_cd PROTO ((struct interact_client *, char *));
-static void class_class_cdup PROTO ((struct interact_client *));
-static void *class_class_next PROTO ((struct interact_client *, void *));
-
-static void class_ls PROTO ((struct interact_client *));
-static void class_print PROTO ((struct interact_client *, char *));
-static void class_set PROTO ((struct interact_client *, char *));
-static void class_rm PROTO ((struct interact_client *, char *));
-static void class_cd PROTO ((struct interact_client *, char *));
-static void class_cdup PROTO ((struct interact_client *));
-static void *class_next PROTO ((struct interact_client *, void *));
-
-static void group_ls PROTO ((struct interact_client *));
-static void group_print PROTO ((struct interact_client *, char *));
-static void group_set PROTO ((struct interact_client *, char *));
-static void group_rm PROTO ((struct interact_client *, char *));
-static void group_cd PROTO ((struct interact_client *, char *));
-static void group_cdup PROTO ((struct interact_client *));
-static void group_cdup_share PROTO ((struct interact_client *));
-static void *group_next PROTO ((struct interact_client *, void *));
-
-struct interact_actions top_level_actions = {
- top_level_ls,
- top_level_print,
- top_level_set,
- top_level_rm,
- top_level_cd,
- top_level_cdup,
- top_level_next };
-
-static struct interact_actions interface_class_actions = {
- interface_class_ls,
- interface_class_print,
- interface_class_set,
- interface_class_rm,
- interface_class_cd,
- interface_class_cdup,
- interface_class_next };
-
-static struct interact_actions interface_actions = {
- interface_ls,
- interface_print,
- interface_set,
- interface_rm,
- interface_cd,
- interface_cdup,
- interface_next };
-
-static struct interact_actions shared_network_class_actions = {
- shared_network_class_ls,
- shared_network_class_print,
- shared_network_class_set,
- shared_network_class_rm,
- shared_network_class_cd,
- shared_network_class_cdup,
- shared_network_class_next };
-
-static struct interact_actions shared_network_actions = {
- shared_network_ls,
- shared_network_print,
- shared_network_set,
- shared_network_rm,
- shared_network_cd,
- shared_network_cdup,
- shared_network_next };
-
-static struct interact_actions subnet_class_actions = {
- subnet_class_ls,
- subnet_class_print,
- subnet_class_set,
- subnet_class_rm,
- subnet_class_cd,
- subnet_class_cdup,
- subnet_class_next };
-
-static struct interact_actions subnet_actions = {
- subnet_ls,
- subnet_print,
- subnet_set,
- subnet_rm,
- subnet_cd,
- subnet_cdup,
- subnet_next };
-
-static struct interact_actions host_class_actions = {
- host_class_ls,
- host_class_print,
- host_class_set,
- host_class_rm,
- host_class_cd,
- host_class_cdup,
- host_class_next };
-
-static struct interact_actions host_actions = {
- host_ls,
- host_print,
- host_set,
- host_rm,
- host_cd,
- host_cdup,
- host_next };
-
-static struct interact_actions lease_actions = {
- lease_ls,
- lease_print,
- lease_set,
- lease_rm,
- lease_cd,
- lease_cdup,
- lease_next };
-
-static struct interact_actions class_class_actions = {
- class_class_ls,
- class_class_print,
- class_class_set,
- class_class_rm,
- class_class_cd,
- class_class_cdup,
- class_class_next };
-
-static struct interact_actions class_actions = {
- class_ls,
- class_print,
- class_set,
- class_rm,
- class_cd,
- class_cdup,
- class_next };
-
-static struct interact_actions group_actions = {
- group_ls,
- group_print,
- group_set,
- group_rm,
- group_cd,
- group_cdup,
- group_next };
-
-
-static void top_level_ls (client)
- struct interact_client *client;
-{
- interact_client_write (client, "interfaces", 0);
- interact_client_write (client, "shared networks", 0);
- interact_client_write (client, "subnets", 0);
- interact_client_write (client, "classes", 0);
- interact_client_write (client, "hosts", 1);
-}
-
-static void top_level_print (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "can't print that.", 1);
-}
-
-static void top_level_set (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "can't set that.", 1);
-}
-
-static void top_level_rm (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "can't remove that.", 1);
-}
-
-static void top_level_cd (client, string)
- struct interact_client *client;
- char *string;
-{
- if (!strcmp (string, "interfaces")) {
- client -> cur_node_actions = interface_actions;
- client -> cur_node_actions.cdup = top_level_cdup;
- } else if (!strcmp (string, "shared networks")) {
- client -> cur_node_actions = shared_network_actions;
- client -> cur_node_actions.cdup = top_level_cdup;
- } else if (!strcmp (string, "subnets")) {
- client -> cur_node_actions = subnet_actions;
- client -> cur_node_actions.cdup = top_level_cdup;
- } else if (!strcmp (string, "classes")) {
- client -> cur_node_actions = class_actions;
- client -> cur_node_actions.cdup = top_level_cdup;
- } else if (!strcmp (string, "hosts")) {
- client -> cur_node_actions = host_actions;
- client -> cur_node_actions.cdup = top_level_cdup;
- } else {
- interact_client_write (client, "can't cd to that.", 1);
- return;
- }
- interact_client_write (client, "done.", 1);
-}
-
-static void top_level_cdup (client)
- struct interact_client *client;
-{
- client -> cur_node_actions = top_level_actions;
- client -> cur_node = (void *)0;
-}
-
-static void *top_level_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- return (void *)0;
-}
-
-static void interface_class_ls (client)
- struct interact_client *client;
-{
- struct interface_info *ip = client -> cur_node;
-
- for (ip = interfaces; ip; ip = ip -> next) {
- interact_client_write (client, ip -> name, ip -> next ? 0 : 1);
- }
-}
-
-static void interface_class_print (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "nothing to print.", 1);
-}
-
-static void interface_class_set (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "can't set that.", 1);
-}
-
-static void interface_class_rm (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "can't remove that.", 1);
-}
-
-static void interface_class_cd (client, string)
- struct interact_client *client;
- char *string;
-{
- int i;
- struct interface_info *ip;
-
- i = strlen (string);
- for (ip = interfaces; ip; ip = ip -> next)
- if (!strcmp (ip -> name, string))
- break;
- if (!ip) {
- interact_client_write (client, "no such interface.", 1);
- return;
- }
- client -> cur_node = ip;
- client -> cur_node_actions = interface_class_actions;
- interact_client_write (client, "done.", 1);
-}
-
-static void interface_class_cdup (client)
- struct interact_client *client;
-{
- struct interface_info *ip = client -> cur_node;
-
- client -> cur_node = ip -> shared_network;
- client -> cur_node_actions = shared_network_actions;
- client -> cur_node_actions.cdup = top_level_cdup;
-}
-
-static void *interface_class_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- return (void *)0;
-}
-
-static void interface_ls (client)
- struct interact_client *client;
-{
- struct interface_info *ip = client -> cur_node;
-
- if (ip -> shared_network)
- interact_client_write (client, "shared network", 0);
- if (ip -> primary_address.s_addr)
- interact_client_write (client, "ip address", 0);
- if (ip -> client)
- interact_client_write (client, "client state", 0);
- interact_client_write (client, "hardware type", 0);
- interact_client_write (client, "hardware address", 1);
-}
-
-static void interface_print (client, string)
- struct interact_client *client;
- char *string;
-{
- struct interface_info *ip = client -> cur_node;
-
- if (!strcmp (string, "ip address"))
- interact_client_write (client,
- inet_ntoa (ip -> primary_address), 1);
- else if (!strcmp (string, "hardware type"))
- interact_client_write (client,
- hardware_types [ip -> hw_address.htype],
- 1);
- else if (!strcmp (string, "hardware address"))
- interact_client_write (client,
- print_hw_addr (ip -> hw_address.htype,
- ip -> hw_address.hlen,
- ip -> hw_address.haddr),
- 1);
- else if (!strcmp (string, "shared network"))
- interact_client_write (client,
- ip -> shared_network -> name, 1);
- else
- interact_client_write (client, "can't print that.", 1);
-}
-
-static void interface_set (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "can't set that.", 1);
-}
-
-static void interface_rm (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "can't remove that.", 1);
-}
-
-static void interface_cd (client, string)
- struct interact_client *client;
- char *string;
-{
- struct interface_info *ip = client -> cur_node;
- int i;
-
- if (!strcmp (string, "shared network")) {
- client -> cur_node_actions = shared_network_actions;
- client -> cur_node_actions.cdup =
- shared_network_cdup;
- client -> cur_node = ip -> shared_network;
- interact_client_write (client, "done.", 1);
- } else
- interact_client_write (client, "can't cd to that.", 1);
-}
-
-static void interface_cdup (client)
- struct interact_client *client;
-{
- struct interface_info *ip = client -> cur_node;
-
- client -> cur_node = (void *)0;
- client -> cur_node_actions = interface_class_actions;
- client -> cur_node_actions.cdup = top_level_cdup;
-}
-
-static void *interface_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- return (void *)0;
-}
-
-static void shared_network_class_ls (client)
- struct interact_client *client;
-{
- interact_client_write (client, "name", 0);
- interact_client_write (client, "subnets", 0);
- interact_client_write (client, "group", 0);
- interact_client_write (client, "leases", 0);
- interact_client_write (client, "active leases", 0);
- interact_client_write (client, "free leases", 0);
- interact_client_write (client, "abandoned leases", 1);
-}
-
-static void shared_network_class_print (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "nothing to print.", 1);
-}
-
-static void shared_network_class_set (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "can't set that.", 1);
-}
-
-static void shared_network_class_rm (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "can't remove that.", 1);
-}
-
-static void shared_network_class_cd (client, string)
- struct interact_client *client;
- char *string;
-{
- struct shared_network *share = client -> cur_node;
-
- if (!strcmp (string, "subnets")) {
- client -> cur_node = share -> subnets;
- client -> cur_node_actions = subnet_class_actions;
- client -> cur_node_actions.next = subnet_class_next_share;
- client -> cur_node_actions.cdup = subnet_class_cdup;
- } else if (!strcmp (string, "group")) {
- client -> cur_node = share -> group;
- client -> cur_node_actions = group_actions;
- client -> cur_node_actions.cdup = group_cdup_share;
- } else if (!strcmp (string, "leases")) {
- client -> cur_node = share -> leases;
- client -> cur_node_actions = lease_actions;
- } else if (!strcmp (string, "active leases")) {
- client -> cur_node = share -> leases;
- client -> cur_node_actions = lease_actions;
- client -> cur_node_actions.next = lease_next_active;
- } else if (!strcmp (string, "free leases")) {
- client -> cur_node = share -> leases;
- client -> cur_node_actions = lease_actions;
- client -> cur_node_actions.next = lease_next_free;
- } else if (!strcmp (string, "abandoned leases")) {
- client -> cur_node = share -> leases;
- client -> cur_node_actions = lease_actions;
- client -> cur_node_actions.next = lease_next_abandoned;
- } else {
- interact_client_write (client, "can't cd to that.", 1);
- return;
- }
- interact_client_write (client, "done.", 1);
-}
-
-static void shared_network_class_cdup (client)
- struct interact_client *client;
-{
- struct shared_network *share = client -> cur_node;
-
- if (share -> interface)
- client -> cur_node = share -> interface;
- else
- top_level_cdup (client);
-}
-
-static void *shared_network_class_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- return (void *)0;
-}
-
-static void shared_network_ls (client)
- struct interact_client *client;
-{
-}
-
-static void shared_network_print (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "name", 0);
- interact_client_write (client, "subnets", 0);
- interact_client_write (client, "group", 0);
- interact_client_write (client, "leases", 0);
- interact_client_write (client, "active leases", 0);
- interact_client_write (client, "free leases", 0);
- interact_client_write (client, "abandoned leases", 1);
-}
-
-static void shared_network_set (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "can't set that.", 1);
-}
-
-static void shared_network_rm (client, string)
- struct interact_client *client;
- char *string;
-{
- interact_client_write (client, "can't remove that.", 1);
-}
-
-static void shared_network_cd (client, string)
- struct interact_client *client;
- char *string;
-{
- struct shared_network *share = client -> cur_node;
-
- if (!strcmp (string, "subnets")) {
- client -> cur_node = share -> subnets;
- client -> cur_node_actions = subnet_actions;
- client -> cur_node_actions.next = subnet_class_next_share;
- } else if (!strcmp (string, "group")) {
- client -> cur_node = share -> group;
- client -> cur_node_actions = group_actions;
- client -> cur_node_actions.cdup = group_cdup_share;
- } else if (!strcmp (string, "leases")) {
- client -> cur_node = share -> leases;
- client -> cur_node_actions = lease_actions;
- } else if (!strcmp (string, "active leases")) {
- client -> cur_node = share -> leases;
- client -> cur_node_actions = lease_actions;
- client -> cur_node_actions.next = lease_next_active;
- } else if (!strcmp (string, "free leases")) {
- client -> cur_node = share -> leases;
- client -> cur_node_actions = lease_actions;
- client -> cur_node_actions.next = lease_next_free;
- } else if (!strcmp (string, "abandoned leases")) {
- client -> cur_node = share -> leases;
- client -> cur_node_actions = lease_actions;
- client -> cur_node_actions.next = lease_next_abandoned;
- } else {
- interact_client_write (client, "can't cd to that.", 1);
- return;
- }
- interact_client_write (client, "done.", 1);
-}
-
-static void shared_network_cdup (client)
- struct interact_client *client;
-{
- struct shared_network *share = client -> cur_node;
-
- if (share -> interface)
- client -> cur_node = share -> interface;
- else
- top_level_cdup (client);
-}
-
-static void *shared_network_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- return (void *)0;
-}
-
-static void subnet_class_ls (client)
- struct interact_client *client;
-{
-}
-
-static void subnet_class_print (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void subnet_class_set (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void subnet_class_rm (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void subnet_class_cd (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void subnet_class_cdup (client)
- struct interact_client *client;
-{
-}
-
-static void *subnet_class_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- struct subnet *subnet = ptr;
- return subnet -> next_subnet;
-}
-
-static void *subnet_class_next_share (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- struct subnet *subnet = ptr;
- return subnet -> next_sibling;
-}
-
-static void subnet_ls (client)
- struct interact_client *client;
-{
-}
-
-static void subnet_print (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void subnet_set (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void subnet_rm (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void subnet_cd (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void subnet_cdup (client)
- struct interact_client *client;
-{
-}
-
-static void *subnet_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- return (void *)0;
-}
-
-static void host_class_ls (client)
- struct interact_client *client;
-{
-}
-
-static void host_class_print (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void host_class_set (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void host_class_rm (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void host_class_cd (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void host_class_cdup (client)
- struct interact_client *client;
-{
-}
-
-static void *host_class_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- return (void *)0;
-}
-
-static void host_ls (client)
- struct interact_client *client;
-{
-}
-
-static void host_print (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void host_set (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void host_rm (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void host_cd (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void host_cdup (client)
- struct interact_client *client;
-{
-}
-
-static void *host_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- return (void *)0;
-}
-
-static void lease_ls (client)
- struct interact_client *client;
-{
-}
-
-static void lease_print (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void lease_set (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void lease_rm (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void lease_cd (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void lease_cdup (client)
- struct interact_client *client;
-{
- struct lease *lease = client -> cur_node;
- client -> cur_node = lease -> shared_network;
- client -> cur_node_actions = shared_network_actions;
-}
-
-static void lease_cdup_host (client)
- struct interact_client *client;
-{
- struct lease *lease = client -> cur_node;
- if (lease -> host) {
- client -> cur_node = lease -> host;
- client -> cur_node_actions = host_actions;
- } else
- lease_cdup (client);
-}
-
-static void *lease_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- struct lease *lease = ptr;
- return lease -> next;
-}
-
-static void *lease_next_active (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- struct lease *lease = ptr;
- for (; lease; lease = lease -> next)
- if (lease -> ends > cur_time)
- return lease;
- return (void *)0;
-}
-
-static void *lease_next_free (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- struct lease *lease = ptr;
- for (; lease; lease = lease -> next)
- if (lease -> ends < cur_time)
- return lease;
- return (void *)0;
-}
-
-static void *lease_next_abandoned (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- struct lease *lease = ptr;
- for (; lease; lease = lease -> next)
- if (lease -> flags & ABANDONED_LEASE)
- return lease;
- return (void *)0;
-}
-
-static void class_class_ls (client)
- struct interact_client *client;
-{
-}
-
-static void class_class_print (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void class_class_set (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void class_class_rm (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void class_class_cd (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void class_class_cdup (client)
- struct interact_client *client;
-{
-}
-
-static void *class_class_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- return (void *)0;
-}
-
-static void class_ls (client)
- struct interact_client *client;
-{
-}
-
-static void class_print (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void class_set (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void class_rm (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void class_cd (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void class_cdup (client)
- struct interact_client *client;
-{
-}
-
-static void *class_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- return (void *)0;
-}
-
-static void group_ls (client)
- struct interact_client *client;
-{
-}
-
-static void group_print (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void group_set (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void group_rm (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void group_cd (client, string)
- struct interact_client *client;
- char *string;
-{
-}
-
-static void group_cdup (client)
- struct interact_client *client;
-{
-}
-
-static void group_cdup_share (client)
- struct interact_client *client;
-{
-}
-
-static void *group_next (client, ptr)
- struct interact_client *client;
- void *ptr;
-{
- return (void *)0;
-}
diff --git a/site.conf b/site.conf
deleted file mode 100644
index 92529939..00000000
--- a/site.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-# Put local site configuration stuff here to override the default
-# settings in Makefile.conf
-