summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Lemon <source@isc.org>2001-06-27 00:31:20 +0000
committerTed Lemon <source@isc.org>2001-06-27 00:31:20 +0000
commitd758ad8cac9c00c70cfe4dd459bf7e87c268c579 (patch)
tree85d7e10e40b0e1061a40f45ef0e9f44073346482
parent07b958004f4e39f9b222115b1b050044a2434ea1 (diff)
downloadisc-dhcp-d758ad8cac9c00c70cfe4dd459bf7e87c268c579.tar.gz
Merge changes between 3.0rc7 and 3.0rc8pl2.
-rw-r--r--Makefile.conf90
-rw-r--r--RELNOTES114
-rw-r--r--client/clparse.c93
-rw-r--r--client/dhclient.831
-rw-r--r--client/dhclient.c218
-rw-r--r--client/dhclient.conf.520
-rwxr-xr-xclient/scripts/bsdos13
-rwxr-xr-xclient/scripts/freebsd13
-rwxr-xr-xclient/scripts/linux13
-rwxr-xr-xclient/scripts/netbsd13
-rw-r--r--client/scripts/nextstep13
-rw-r--r--client/scripts/openbsd13
-rwxr-xr-xclient/scripts/solaris13
-rw-r--r--common/alloc.c207
-rw-r--r--common/comapi.c257
-rw-r--r--common/conflex.c6
-rw-r--r--common/dhcp-options.511
-rw-r--r--common/discover.c27
-rw-r--r--common/dispatch.c27
-rw-r--r--common/dns.c469
-rw-r--r--common/ethernet.c6
-rw-r--r--common/execute.c127
-rw-r--r--common/icmp.c49
-rw-r--r--common/inet.c61
-rw-r--r--common/memory.c14
-rw-r--r--common/options.c48
-rw-r--r--common/packet.c18
-rw-r--r--common/parse.c111
-rw-r--r--common/print.c54
-rw-r--r--common/tables.c993
-rw-r--r--common/tree.c206
-rwxr-xr-xconfigure70
-rw-r--r--dhcpctl/Makefile.dist22
-rw-r--r--dhcpctl/cltest.c2
-rw-r--r--dhcpctl/dhcpctl.315
-rw-r--r--dhcpctl/dhcpctl.c47
-rw-r--r--dhcpctl/dhcpctl.h1
-rw-r--r--dhcpctl/omshell.c106
-rw-r--r--dhcpctl/remote.c2
-rw-r--r--dst/dst_internal.h2
-rw-r--r--includes/cdefs.h2
-rw-r--r--includes/cf/qnx.h70
-rw-r--r--includes/cf/rhapsody.h4
-rw-r--r--includes/cf/sunos4.h2
-rw-r--r--includes/dhcpd.h133
-rw-r--r--includes/dhctoken.h4
-rw-r--r--includes/failover.h2
-rw-r--r--includes/minires/minires.h2
-rw-r--r--includes/minires/res_update.h4
-rw-r--r--includes/netinet/if_ether.h22
-rw-r--r--includes/omapip/alloc.h22
-rw-r--r--includes/omapip/hash.h4
-rw-r--r--includes/omapip/omapip.h23
-rw-r--r--includes/omapip/omapip_p.h11
-rw-r--r--includes/omapip/trace.h1
-rw-r--r--includes/osdep.h2
-rw-r--r--includes/statement.h2
-rw-r--r--includes/version.h2
-rw-r--r--minires/ns_sign.c4
-rw-r--r--minires/ns_verify.c4
-rw-r--r--minires/res_findzonecut.c4
-rw-r--r--minires/res_init.c8
-rw-r--r--minires/res_sendsigned.c4
-rw-r--r--minires/res_update.c15
-rw-r--r--omapip/Makefile.dist11
-rw-r--r--omapip/alloc.c236
-rw-r--r--omapip/array.c19
-rw-r--r--omapip/auth.c11
-rw-r--r--omapip/buffer.c16
-rw-r--r--omapip/connection.c22
-rw-r--r--omapip/dispatch.c23
-rw-r--r--omapip/generic.c96
-rw-r--r--omapip/hash.c83
-rw-r--r--omapip/message.c18
-rw-r--r--omapip/omapi.3302
-rw-r--r--omapip/protocol.c11
-rw-r--r--omapip/result.c4
-rw-r--r--omapip/support.c13
-rw-r--r--omapip/test.c2
-rw-r--r--omapip/toisc.c2
-rw-r--r--omapip/trace.c36
-rw-r--r--relay/dhcrelay.823
-rw-r--r--server/bootp.c11
-rw-r--r--server/class.c30
-rw-r--r--server/confpars.c115
-rw-r--r--server/db.c108
-rw-r--r--server/ddns.c444
-rw-r--r--server/dhcp.c407
-rw-r--r--server/dhcpd.816
-rw-r--r--server/dhcpd.c230
-rw-r--r--server/dhcpd.conf.544
-rw-r--r--server/failover.c231
-rw-r--r--server/mdb.c451
-rw-r--r--server/omapi.c492
-rw-r--r--server/salloc.c113
-rw-r--r--server/stables.c936
-rw-r--r--tests/failover/dhcp-1.cf46
-rw-r--r--tests/failover/dhcp-2.cf33
-rwxr-xr-xtests/failover/new-failover6
99 files changed, 5909 insertions, 2698 deletions
diff --git a/Makefile.conf b/Makefile.conf
index 1d4a7945..a8c64ac6 100644
--- a/Makefile.conf
+++ b/Makefile.conf
@@ -19,6 +19,7 @@
## Defaults...
SCRIPT = none
+USERBINDIR = /usr/bin
BINDIR = /usr/sbin
CLIENTBINDIR=/sbin
ADMMANDIR = /usr/share/man/cat8
@@ -27,6 +28,8 @@ FFMANDIR = /usr/share/man/cat5
FFMANEXT = .0
LIBMANDIR = /usr/share/man/cat3
LIBMANEXT = .0
+USRMANDIR = /usr/share/man/cat1
+USRMANEXT = .0
MANCAT = cat
INSTALL = install -c -m 444
MANINSTALL = install -c
@@ -38,7 +41,7 @@ VARDB = /var/db
LIBDIR=/usr/local/lib
INCDIR=/usr/local/include
LIBS =
-COPTS = $(BINDDEF)
+COPTS = $(BINDDEF) $(CC_OPTIONS)
DEBUG = -g
RANLIB = ranlib
MKDEP = mkdep
@@ -86,14 +89,16 @@ MINORVERSION=MinorVersion
##--nextstep--
#CF = cf/nextstep.h
#CC=cc
-#COPTS = -Wall $(BINDDEF)
+#COPTS = -Wall $(BINDDEF) $(CC_OPTIONS)
#BINDIR=/usr/etc
#ADMMANDIR = /usr/local/man/cat8
#FFMANDIR = /usr/local/man/cat5
#LIBMANDIR = /usr/local/man/cat3
+#USRMANDIR = /usr/local/man/cat1
#ADMMANEXT = .8
#FFMANEXT = .5
#LIBMANEXT = .3
+#USRMANEXT = .3
#VARRUN = /etc
#VARDB = /etc
##--nextstep--
@@ -119,7 +124,8 @@ MINORVERSION=MinorVersion
#CC=gcc
#COPTS = $(BINDDEF) -Wall -Wno-unused -Wno-implicit -Wno-comment \
# -Wno-uninitialized -Wno-char-subscripts -Wno-switch -Werror \
-# -DSOLARIS_MAJOR=$(MAJORVERSION) -DSOLARIS_MINOR=$(MINORVERSION)
+# -DSOLARIS_MAJOR=$(MAJORVERSION) -DSOLARIS_MINOR=$(MINORVERSION) \
+# $(CC_OPTIONS)
#CF = cf/sunos5-5.h
#ADMMANDIR = /usr/share/man/man1m
#ADMMANEXT = .1m
@@ -127,6 +133,8 @@ MINORVERSION=MinorVersion
#FFMANEXT = .4
#LIBMANDIR = /usr/share/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/share/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /etc
#VARDB = /etc
@@ -140,7 +148,8 @@ MINORVERSION=MinorVersion
#LIBS = -lresolv -lsocket -lnsl -lgen
#CC=cc
#COPTS = -D__svr4__ $(BINDDEF) -erroff=E_END_OF_LOOP_CODE_NOT_REACHED \
-# -DSOLARIS_MAJOR=$(MAJORVERSION) -DSOLARIS_MINOR=$(MINORVERSION)
+# -DSOLARIS_MAJOR=$(MAJORVERSION) -DSOLARIS_MINOR=$(MINORVERSION) \
+# $(CC_OPTIONS)
#CF = cf/sunos5-5.h
#ADMMANDIR = /usr/share/man/man1m
#ADMMANEXT = .1m
@@ -148,6 +157,8 @@ MINORVERSION=MinorVersion
#FFMANEXT = .4
#LIBMANDIR = /usr/share/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/share/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /etc
#VARDB = /etc
@@ -156,7 +167,7 @@ MINORVERSION=MinorVersion
## DEC Alpha/OSF1
##--alphaosf--
-#COPTS = -std
+#COPTS = -std $(CC_OPTIONS)
#INSTALL=/usr/ucb/installbsd -c
#MANINSTALL=/usr/ucb/installbsd -c
#CF = cf/alphaosf.h
@@ -195,10 +206,18 @@ MINORVERSION=MinorVersion
##--rhapsody--
#CF = cf/rhapsody.h
#COPTS = -Wall -Wno-unused -Wno-implicit -Wno-comment \
-# -Wno-uninitialized -Wno-switch -Werror -pipe $(BINDDEF)
+# -Wno-uninitialized -Wno-switch -Werror -pipe $(BINDDEF) $(CC_OPTIONS)
##SCRIPT=rhapsody
##--rhapsody--
+## Darwin/MacOSX
+##--darwin--
+#CF = cf/rhapsody.h
+#COPTS = -Ddarwin -Wall -Wno-unused -Wno-implicit -Wno-comment \
+# -Wno-uninitialized -Wno-switch -Werror -pipe $(BINDDEF) $(CC_OPTIONS)
+##SCRIPT=rhapsody
+##--darwin--
+
## NetBSD
##--netbsd--
#CF = cf/netbsd.h
@@ -207,7 +226,7 @@ MINORVERSION=MinorVersion
# -Wimplicit-function-declaration -Wpointer-arith -Wcast-qual \
# -Wcast-align -Wwrite-strings -Wconversion -Wmissing-prototypes \
# -Wmissing-declarations -Wnested-externs \
-# -pipe $(BINDDEF)
+# -pipe $(BINDDEF) $(CC_OPTIONS)
#SCRIPT=netbsd
##MKDEP=makedepend
##--netbsd--
@@ -224,7 +243,7 @@ MINORVERSION=MinorVersion
# -Wimplicit-function-declaration -Wpointer-arith -Wcast-qual \
# -Wwrite-strings -Wmissing-prototypes \
# -Wmissing-declarations -Wnested-externs \
-# -pipe $(BINDDEF)
+# -pipe $(BINDDEF) $(CC_OPTIONS)
#SCRIPT=netbsd
##--netbsd-nocast--
@@ -241,11 +260,14 @@ MINORVERSION=MinorVersion
#FFMANEXT = .5
#LIBMANDIR = /usr/man/cat3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/cat1
+#USRMANEXT = .1
##--ultrix--
## Linux 1.x
##--linux-1--
-#COPTS = -DLINUX_MAJOR=$(MAJORVERSION) -DLINUX_MINOR=$(MINORVERSION) $(BINDDEF)
+#COPTS = -DLINUX_MAJOR=$(MAJORVERSION) -DLINUX_MINOR=$(MINORVERSION) \
+# $(BINDDEF) $(CC_OPTIONS)
#CF = cf/linux.h
#ADMMANDIR = /usr/man/man8
#ADMMANEXT = .8
@@ -253,6 +275,8 @@ MINORVERSION=MinorVersion
#FFMANEXT = .5
#LIBMANDIR = /usr/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /var/run
#VARDB = /var/state/dhcp
@@ -261,7 +285,8 @@ MINORVERSION=MinorVersion
## Linux 2.0
##--linux-2.0--
-#COPTS = -DLINUX_MAJOR=$(MAJORVERSION) -DLINUX_MINOR=$(MINORVERSION) $(BINDDEF)
+#COPTS = -DLINUX_MAJOR=$(MAJORVERSION) -DLINUX_MINOR=$(MINORVERSION) \
+# $(BINDDEF) $(CC_OPTIONS)
#CF = cf/linux.h
#ADMMANDIR = /usr/man/man8
#ADMMANEXT = .8
@@ -269,6 +294,8 @@ MINORVERSION=MinorVersion
#FFMANEXT = .5
#LIBMANDIR = /usr/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /var/run
#VARDB = /var/state/dhcp
@@ -277,7 +304,8 @@ MINORVERSION=MinorVersion
## Linux 2.1
##--linux-2.1--
-#COPTS = -DLINUX_MAJOR=$(MAJORVERSION) -DLINUX_MINOR=$(MINORVERSION) $(BINDDEF)
+#COPTS = -DLINUX_MAJOR=$(MAJORVERSION) -DLINUX_MINOR=$(MINORVERSION) \
+# $(BINDDEF) $(CC_OPTIONS)
#CF = cf/linux.h
#ADMMANDIR = /usr/man/man8
#ADMMANEXT = .8
@@ -285,6 +313,8 @@ MINORVERSION=MinorVersion
#FFMANEXT = .5
#LIBMANDIR = /usr/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /var/run
#VARDB = /var/state/dhcp
@@ -293,7 +323,8 @@ MINORVERSION=MinorVersion
## Linux 2.2
##--linux-2.2--
-#COPTS = -DLINUX_MAJOR=$(MAJORVERSION) -DLINUX_MINOR=$(MINORVERSION) $(BINDDEF)
+#COPTS = -DLINUX_MAJOR=$(MAJORVERSION) -DLINUX_MINOR=$(MINORVERSION) \
+# $(BINDDEF) $(CC_OPTIONS)
#CF = cf/linux.h
#ADMMANDIR = /usr/man/man8
#ADMMANEXT = .8
@@ -301,6 +332,8 @@ MINORVERSION=MinorVersion
#FFMANEXT = .5
#LIBMANDIR = /usr/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /var/run
#VARDB = /var/state/dhcp
@@ -340,6 +373,7 @@ MINORVERSION=MinorVersion
#CC=gcc
#PREDEFINES=-DSCO
#LIBS = -lsocket
+#USERBINDIR = /usr/local/dhcp/bin
#BINDIR = /usr/local/dhcp/bin
#CLIENTBINDIR = /usr/local/dhcp/bin
#ADMMANDIR = /usr/local/dhcp/man/cat.ADMN
@@ -365,9 +399,11 @@ MINORVERSION=MinorVersion
#FFMANEXT = .5
#LIBMANDIR = /usr/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /etc
-#COPTS=-w3 -Dlint $(BINDDEF)
+#COPTS=-w3 -Dlint $(BINDDEF) $(CC_OPTIONS)
#LFLAGS=$(DEBUG) "-Wl,op symfile" -l socket
#MANINSTALL = /bin/true
#INSTALL = cp
@@ -375,6 +411,26 @@ MINORVERSION=MinorVersion
#CLIENTBINDIR = /etc
##--qnx--
+
+## QNX RTP (v6, NTO)
+##--qnxnto--
+#CF = cf/qnx.h
+#ADMMANDIR = /opt/man/man8
+#ADMMANEXT = .8
+#FFMANDIR = /opt/man/man5
+#FFMANEXT = .5
+#LIBMANDIR = /opt/man/man3
+#LIBMANEXT = .3
+#MANCAT = man
+#COPTS=-w3 -Dlint $(BINDDEF)
+#LFLAGS=-l socket
+#MANINSTALL = /bin/cp
+#INSTALL = /bin/cp
+#BINDIR = /opt/sbin
+#USERBINDIR= /opt/bin
+#CLIENTBINDIR = /opt/sbin
+##--qnxnto--
+
## CygWin32
##--cygwin32--
#CF = cf/cygwin32.h
@@ -384,6 +440,8 @@ MINORVERSION=MinorVersion
#FFMANEXT = .5
#LIBMANDIR = /usr/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/man1
+#USRMANEXT = .1
#VARRUN = /etc
#MANINSTALL = /bin/true
#INSTALL = cp
@@ -402,7 +460,7 @@ MINORVERSION=MinorVersion
##--irix--
#LFLAGS=$(DEBUG) -Wl,-woff,84 -Wl,-woff,85 -Wl,-woff,134
#CC=gcc
-#COPTS = -I/usr/local/include $(BINDDEF)
+#COPTS = -I/usr/local/include $(BINDDEF) $(CC_OPTIONS)
#CF = cf/irix.h
#BINDIR = /usr/local/etc
#ADMMANDIR = /usr/local/man/man8
@@ -411,6 +469,8 @@ MINORVERSION=MinorVersion
#FFMANEXT = .5
#LIBMANDIR = /usr/local/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/local/man/man1
+#USRMANEXT = .1
#MANCAT = man
#INSTALL = install
#MANINSTALL = install
@@ -422,7 +482,7 @@ MINORVERSION=MinorVersion
## HP-UX
##--hpux-cc--
-#COPTS = $(BINDDEF)
+#COPTS = $(BINDDEF) $(CC_OPTIONS)
#LFLAGS = -Wl,+vnocompatwarnings
#INSTALL = install -i
#MANINSTALL = install -i
diff --git a/RELNOTES b/RELNOTES
index 81bdee66..ffaacf02 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -56,6 +56,120 @@ Murrell at BC Tel Advanced Communications. I'd like to express my
thanks to all of these good people here, both for working on the code
and for prodding me into improving it.
+ Changes since 3.0 Release Candidate 8 Patchlevel 1
+
+- Fix a parsing bug that broke dns updates (both interim and ad-hoc).
+ This was introduced in rc8pl1 as an unintended result of the memory
+ leakage fixes that were in pl1.
+
+- Fix a long-standing bug where the server would record that an update
+ had been done for a client with no name, even though no update had
+ been done, and then when the client's lease expired the deletion of
+ that nonexistant record would time out because the name was the null
+ string.
+
+- Clean up the omshell, dhcpctl and omapi man pages a bit.
+
+
+ Changes since 3.0 Release Candidate 8
+
+- Fix a bug that could cause the DHCP server to spin if
+ one-lease-per-client was enabled.
+
+- Fix a bug that was causing core dumps on BSD/os in the presence of
+ malformed packets.
+
+- In partner-down state, don't restrict lease lengths to MCLT.
+
+- On the failover secondary, record the MCLT received from the primary
+ so that if we come up without a connection to the primary we don't
+ wind up giving out zero-length leases.
+
+- Fix some compilation problems on BSD/os.
+
+- Fix a bunch of memory leaks.
+
+- Fix a couple of bugs in the option printer.
+
+- Fix an obscure error reporting bug in the dns update code, and also
+ make the message clearer when a key algorithm isn't supported.
+
+- Fix a bug in the tracing code that prevented trace runs that used
+ tcp connections from being played back.
+
+- Add some additional debugging capability for catching memory leaks
+ on exit.
+
+- Make the client release the lease correctly on shutdown.
+
+- Add some configurability to the build system.
+
+- Install omshell manual page in man1, not man8.
+
+- Craig Gwydir sent in a patch that fixes a long-standing bug in the
+ DHCP client that could cause core dumps, but that for some reason
+ hadn't been noticed until now.
+
+ Changes since 3.0 Release Candidate 7
+
+- Fix a bug in failover where we weren't sending updates after a
+ transition from communications-interrupted to normal.
+
+- Handle expired/released/reset -> free transition according to the
+ protocol specification (this works - the other way not only wasn't
+ conformant, but also didn't work).
+
+- Add a control object in both client and server that allows either
+ daemon to be shut down cleanly.
+
+- When writing a lease, if we run out of disk space, shut down the
+ output file and insist on writing a new one before proceeding.
+
+- In the server, if the OMAPI listener port is occupied, keep trying
+ to get it, rather than simply giving up and exiting.
+
+- Support fetching variables from leases and also updating and adding
+ variables to leases via OMAPI.
+
+- If two failover peers have wildly different clocks, refuse to start
+ doing failover.
+
+- Fix a bug in the DNS update code that could cause core dumps when
+ running on alpha processors.
+
+- Fixed a bug in ddns updates for static lease entries, thanks to a
+ patch from Andrey M Linkevitch.
+
+- Add support for Darwin/MacOS X
+
+- Install omshell (including new documentation).
+
+- Support DNS updates in the client (this is a very obscure feature
+ that most DHCP client users probably will not be able to use).
+
+- Somewhat cleaner status logging in the client.
+
+- Make OMAPI key naming syntax compatible with the way keys are
+ actually named (key names are domain names).
+
+- Fix a bug in the lease file writer.
+
+- Install DHCP ISC headers in a different place than BIND 9 ISC
+ headers, to avoid causing trouble in BIND 9 builds.
+
+- Don't send updates for attributes on an object when the attributes
+ haven't changed. Support deleting attributes on remote objects.
+
+- Fix a number of bugs in omshell, and add the unset and refresh
+ statements.
+
+- Handle disconnects in OMAPI a little bit more intelligently (so that
+ the caller gets ECONNRESET instead of EINVAL).
+
+- Fix a bunch of bugs in the handling of clients that have existing
+ leases when the try to renew their leases while failover is
+ operating.
+
Changes since 3.0 Release Candidate 3
- Do lease billing on startup in a way that I *think* will finally do
diff --git a/client/clparse.c b/client/clparse.c
index eb82b461..eaf4f579 100644
--- a/client/clparse.c
+++ b/client/clparse.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: clparse.c,v 1.62 2001/05/04 00:51:35 mellon Exp $ Copyright (c) 1996-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: clparse.c,v 1.63 2001/06/27 00:29:27 mellon Exp $ Copyright (c) 1996-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -70,11 +70,6 @@ u_int32_t default_requested_options [] = {
isc_result_t read_client_conf ()
{
- int file;
- struct parse *cfile;
- const char *val;
- int token;
- int declaration = 0;
struct client_config *config;
struct client_state *state;
struct interface_info *ip;
@@ -106,26 +101,12 @@ isc_result_t read_client_conf ()
if (!top_level_config.on_transmission)
log_fatal ("no memory for top-level on_transmission group");
- if ((file = open (path_dhclient_conf, O_RDONLY)) >= 0) {
- cfile = (struct parse *)0;
- new_parse (&cfile, file, (char *)0, 0, path_dhclient_conf, 0);
-
- do {
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == END_OF_FILE)
- break;
- parse_client_statement (cfile,
- (struct interface_info *)0,
- &top_level_config);
- } while (1);
- token = next_token (&val, (unsigned *)0, cfile);
- status = (cfile -> warnings_occurred
- ? ISC_R_BADPARSE
- : ISC_R_SUCCESS);
- close (file);
- end_parse (&cfile);
+ status = read_client_conf_file (path_dhclient_conf,
+ (struct interface_info *)0,
+ &top_level_config);
+ if (status != ISC_R_SUCCESS) {
+ ;
#ifdef LATER
- } else {
/* Set up the standard name service updater routine. */
parse = (struct parse *)0;
status = new_parse (&parse, -1, default_client_config,
@@ -175,6 +156,37 @@ isc_result_t read_client_conf ()
return status;
}
+int read_client_conf_file (const char *name, struct interface_info *ip,
+ struct client_config *client)
+{
+ int file;
+ struct parse *cfile;
+ const char *val;
+ int token;
+ isc_result_t status;
+
+ if ((file = open (name, O_RDONLY)) < 0)
+ return uerr2isc (errno);
+
+ cfile = (struct parse *)0;
+ new_parse (&cfile, file, (char *)0, 0, path_dhclient_conf, 0);
+
+ do {
+ token = peek_token (&val, (unsigned *)0, cfile);
+ if (token == END_OF_FILE)
+ break;
+ parse_client_statement (cfile, ip, client);
+ } while (1);
+ token = next_token (&val, (unsigned *)0, cfile);
+ status = (cfile -> warnings_occurred
+ ? ISC_R_BADPARSE
+ : ISC_R_SUCCESS);
+ close (file);
+ end_parse (&cfile);
+ return status;
+}
+
+
/* lease-file :== client-lease-statements END_OF_FILE
client-lease-statements :== <nil>
| client-lease-statements LEASE client-lease-statement */
@@ -246,8 +258,23 @@ void parse_client_statement (cfile, ip, config)
enum policy policy;
int known;
int tmp, i;
+ isc_result_t status;
switch (peek_token (&val, (unsigned *)0, cfile)) {
+ case INCLUDE:
+ next_token (&val, (unsigned *)0, cfile);
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != STRING) {
+ parse_warn (cfile, "filename string expected.");
+ skip_to_semi (cfile);
+ } else {
+ status = read_client_conf_file (val, ip, config);
+ if (status != ISC_R_SUCCESS)
+ parse_warn (cfile, "%s: bad parse.", val);
+ parse_semi (cfile);
+ }
+ return;
+
case KEY:
next_token (&val, (unsigned *)0, cfile);
if (ip) {
@@ -531,9 +558,10 @@ void parse_client_statement (cfile, ip, config)
}
} else {
struct executable_statement **eptr, *sptr;
- if (stmt -> op == send_option_statement ||
- (stmt -> op == on_statement &&
- (stmt -> data.on.evtypes & ON_TRANSMISSION))) {
+ if (stmt &&
+ (stmt -> op == send_option_statement ||
+ (stmt -> op == on_statement &&
+ (stmt -> data.on.evtypes & ON_TRANSMISSION)))) {
eptr = &config -> on_transmission -> statements;
if (stmt -> op == on_statement) {
sptr = (struct executable_statement *)0;
@@ -551,9 +579,12 @@ void parse_client_statement (cfile, ip, config)
} else
eptr = &config -> on_receipt -> statements;
- for (; *eptr; eptr = &(*eptr) -> next)
- ;
- executable_statement_reference (eptr, stmt, MDL);
+ if (stmt) {
+ for (; *eptr; eptr = &(*eptr) -> next)
+ ;
+ executable_statement_reference (eptr,
+ stmt, MDL);
+ }
return;
}
break;
diff --git a/client/dhclient.8 b/client/dhclient.8
index 7fef673b..52da6796 100644
--- a/client/dhclient.8
+++ b/client/dhclient.8
@@ -246,6 +246,37 @@ supplying the
flag.
.SH CONFIGURATION
The syntax of the dhclient.conf(8) file is discussed seperately.
+.SH OMAPI
+The DHCP client provides some ability to control it while it is
+running, without stopping it. This capability is provided using OMAPI,
+an API for manipulating remote objects. OMAPI clients connect to the
+client using TCP/IP, authenticate, and can then examine the client's
+current status and make changes to it.
+.PP
+Rather than implementing the underlying OMAPI protocol directly, user
+programs should use the dhcpctl API or OMAPI itself. Dhcpctl is a
+wrapper that handles some of the housekeeping chores that OMAPI does
+not do automatically. Dhcpctl and OMAPI are documented in \fBdhcpctl(3)\fR
+and \fBomapi(3)\fR. Most things you'd want to do with the client can
+be done directly using the \fBomshell(1)\fR command, rather than
+having to write a special program.
+.SH THE CONTROL OBJECT
+The control object allows you to shut the client down, releasing all
+leases that it holds and deleting any DNS records it may have added.
+It also allows you to pause the client - this unconfigures any
+interfaces the client is using. You can then restart it, which
+causes it to reconfigure those interfaces. You would normally pause
+the client prior to going into hibernation or sleep on a laptop
+computer. You would then resume it after the power comes back.
+This allows PC cards to be shut down while the computer is hibernating
+or sleeping, and then reinitialized to their previous state once the
+computer comes out of hibernation or sleep.
+.PP
+The control object has one attribute - the state attribute. To shut
+the client down, set its state attribute to 2. It will automatically
+do a DHCPRELEASE. To pause it, set its state attribute to 3. To
+resume it, set its state attribute to 4.
+.PP
.SH FILES
.B CLIENTBINDIR/dhclient-script,
.B ETCDIR/dhclient.conf, DBDIR/dhclient.leases, RUNDIR/dhclient.pid,
diff --git a/client/dhclient.c b/client/dhclient.c
index 364505e1..e3667c74 100644
--- a/client/dhclient.c
+++ b/client/dhclient.c
@@ -41,7 +41,7 @@
#ifndef lint
static char ocopyright[] =
-"$Id: dhclient.c,v 1.129 2001/04/16 22:07:33 mellon Exp $ Copyright (c) 1995-2001 Internet Software Consortium. All rights reserved.\n";
+"$Id: dhclient.c,v 1.130 2001/06/27 00:29:29 mellon Exp $ Copyright (c) 1995-2001 Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -445,7 +445,8 @@ int main (argc, argv, envp)
/* Set up the bootp packet handler... */
bootp_packet_handler = do_packet;
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
dmalloc_cutoff_generation = dmalloc_generation;
dmalloc_longterm = dmalloc_outstanding;
dmalloc_outstanding = 0;
@@ -551,7 +552,8 @@ void state_reboot (cpp)
/* If we don't remember an active lease, go straight to INIT. */
if (!client -> active ||
- client -> active -> is_bootp) {
+ client -> active -> is_bootp ||
+ client -> active -> expiry <= cur_time) {
state_init (client);
return;
}
@@ -880,6 +882,7 @@ void bind_lease (client)
client -> state = S_BOUND;
reinitialize_interfaces ();
go_daemon ();
+ client_dns_update (client, 1);
}
/* state_bound is called when we've successfully bound to a particular
@@ -925,6 +928,32 @@ void state_bound (cpp)
send_request (client);
}
+/* state_stop is called when we've been told to shut down. We unconfigure
+ the interfaces, and then stop operating until told otherwise. */
+
+void state_stop (cpp)
+ void *cpp;
+{
+ struct client_state *client = cpp;
+ int i;
+
+ /* Cancel all timeouts. */
+ cancel_timeout (state_selecting, client);
+ cancel_timeout (send_discover, client);
+ cancel_timeout (send_request, client);
+ cancel_timeout (state_bound, client);
+
+ /* If we have an address, unconfigure it. */
+ if (client -> active) {
+ script_init (client, "STOP", client -> active -> medium);
+ script_write_params (client, "old_", client -> active);
+ if (client -> alias)
+ script_write_params (client, "alias_",
+ client -> alias);
+ script_go (client);
+ }
+}
+
int commit_leases ()
{
return 0;
@@ -1021,6 +1050,7 @@ void dhcpoffer (packet)
const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
struct iaddrlist *ap;
struct option_cache *oc;
+ char obuf [1024];
#ifdef DEBUG_PACKET
dump_packet (packet);
@@ -1045,17 +1075,20 @@ void dhcpoffer (packet)
return;
}
- log_info ("%s from %s", name, piaddr (packet -> client_addr));
+ sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr));
/* If this lease doesn't supply the minimum required parameters,
blow it off. */
if (client -> config -> required_options) {
- for (i = 0; client -> config -> required_options [i]; i++) {
- if (!lookup_option
- (&dhcp_universe, packet -> options,
- client -> config -> required_options [i])) {
- log_info ("%s isn't satisfactory.", name);
+ for (i = 0; client -> config -> required_options [i]; i++) {
+ if (!lookup_option
+ (&dhcp_universe, packet -> options,
+ client -> config -> required_options [i])) {
+ log_info ("%s: no %s option.",
+ obuf, (dhcp_universe.options
+ [client -> config -> required_options [i]]
+ -> name));
return;
}
}
@@ -1066,14 +1099,14 @@ void dhcpoffer (packet)
if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
!memcmp (lease -> address.iabuf,
&packet -> raw -> yiaddr, lease -> address.len)) {
- log_debug ("%s already seen.", name);
+ log_debug ("%s: already seen.", obuf);
return;
}
}
lease = packet_to_lease (packet, client);
if (!lease) {
- log_info ("packet_to_lease failed.");
+ log_info ("%s: packet_to_lease failed.", obuf);
return;
}
@@ -1114,11 +1147,12 @@ void dhcpoffer (packet)
state_selecting(). Otherwise, time out into
state_selecting at the select interval. */
if (stop_selecting <= 0)
- state_selecting (ip);
+ state_selecting (client);
else {
add_timeout (stop_selecting, state_selecting, client, 0, 0);
cancel_timeout (send_discover, client);
}
+ log_info ("%s", obuf);
}
/* Allocate a client_lease structure and initialize it from the parameters
@@ -1741,6 +1775,10 @@ void make_client_options (client, lease, type, sid, rip, prl, op)
struct option_cache *oc;
struct buffer *bp = (struct buffer *)0;
+ /* If there are any leftover options, get rid of them. */
+ if (*op)
+ option_state_dereference (op, MDL);
+
/* Allocate space for options. */
option_state_allocate (op, MDL);
@@ -1870,7 +1908,6 @@ void make_request (client, lease)
int i, j;
unsigned char *tmp, *digest;
unsigned char *old_digest_loc;
- struct option_state *options = (struct option_state *)0;
struct option_cache *oc;
memset (&client -> packet, 0, sizeof (client -> packet));
@@ -1887,13 +1924,13 @@ void make_request (client, lease)
? &lease -> address
: (struct iaddr *)0),
client -> config -> requested_options,
- &options);
+ &client -> sent_options);
/* Set up the option buffer... */
client -> packet_length =
cons_options ((struct packet *)0, &client -> packet,
(struct lease *)0, client, 0,
- (struct option_state *)0, options,
+ (struct option_state *)0, client -> sent_options,
&global_scope, 0, 0, 0, (struct data_string *)0,
client -> config -> vendor_space_name);
if (client -> packet_length < BOOTP_MIN_LEN)
@@ -2750,6 +2787,7 @@ void do_release(client)
if (client -> alias)
script_write_params (client, "alias_",
client -> alias);
+ script_write_params (client, "old_", client -> active);
script_go (client);
}
@@ -2886,3 +2924,153 @@ unsigned cons_agent_information_options (cfg_options, outpacket,
{
return length;
}
+
+static void shutdown_exit (void *foo)
+{
+ exit (0);
+}
+
+isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
+ control_object_state_t newstate)
+{
+ struct interface_info *ip;
+ struct client_state *client;
+
+ /* Do the right thing for each interface. */
+ for (ip = interfaces; ip; ip = ip -> next) {
+ for (client = ip -> client; client; client = client -> next) {
+ switch (newstate) {
+ case server_startup:
+ return ISC_R_SUCCESS;
+
+ case server_running:
+ return ISC_R_SUCCESS;
+
+ case server_shutdown:
+ if (client -> active &&
+ client -> active -> expiry > cur_time) {
+ client_dns_update (client, 0);
+ do_release (client);
+ }
+ break;
+
+ case server_hibernate:
+ state_stop (client);
+ break;
+
+ case server_awaken:
+ state_reboot (client);
+ break;
+ }
+ }
+ }
+ if (newstate == server_shutdown)
+ add_timeout (cur_time + 1, shutdown_exit, 0, 0, 0);
+ return ISC_R_SUCCESS;
+}
+
+/* See if we should do a DNS update, and if so, do it. */
+
+void client_dns_update (struct client_state *client, int addp)
+{
+ struct data_string ddns_fqdn, ddns_fwd_name,
+ ddns_dhcid, client_identifier;
+ struct option_cache *oc;
+ int ignorep;
+ int result;
+ isc_result_t rcode;
+
+ /* If we didn't send an FQDN option, we certainly aren't going to
+ be doing an update. */
+ if (!client -> sent_options)
+ return;
+
+ /* If we don't have a lease, we can't do an update. */
+ if (!client -> active)
+ return;
+
+ /* If we set the no client update flag, don't do the update. */
+ if ((oc = lookup_option (&fqdn_universe, client -> sent_options,
+ FQDN_NO_CLIENT_UPDATE)) &&
+ evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
+ (struct lease *)0, client,
+ client -> sent_options,
+ (struct option_state *)0,
+ &global_scope, oc, MDL))
+ return;
+
+ /* If we set the "server, please update" flag, or didn't set it
+ to false, don't do the update. */
+ if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
+ FQDN_SERVER_UPDATE)) ||
+ evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
+ (struct lease *)0, client,
+ client -> sent_options,
+ (struct option_state *)0,
+ &global_scope, oc, MDL))
+ return;
+
+ /* If no FQDN option was supplied, don't do the update. */
+ memset (&ddns_fwd_name, 0, sizeof ddns_fwd_name);
+ if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
+ FQDN_FQDN)) ||
+ !evaluate_option_cache (&ddns_fwd_name, (struct packet *)0,
+ (struct lease *)0, client,
+ client -> sent_options,
+ (struct option_state *)0,
+ &global_scope, oc, MDL))
+ return;
+
+ /* Make a dhcid string out of either the client identifier,
+ if we are sending one, or the interface's MAC address,
+ otherwise. */
+ memset (&ddns_dhcid, 0, sizeof ddns_dhcid);
+
+ memset (&client_identifier, 0, sizeof client_identifier);
+ if ((oc = lookup_option (&dhcp_universe, client -> sent_options,
+ DHO_DHCP_CLIENT_IDENTIFIER)) &&
+ evaluate_option_cache (&client_identifier, (struct packet *)0,
+ (struct lease *)0, client,
+ client -> sent_options,
+ (struct option_state *)0,
+ &global_scope, oc, MDL)) {
+ result = get_dhcid (&ddns_dhcid,
+ DHO_DHCP_CLIENT_IDENTIFIER,
+ client_identifier.data,
+ client_identifier.len);
+ data_string_forget (&client_identifier, MDL);
+ } else
+ result = get_dhcid (&ddns_dhcid, 0,
+ client -> interface -> hw_address.hbuf,
+ client -> interface -> hw_address.hlen);
+ if (!result) {
+ data_string_forget (&ddns_fwd_name, MDL);
+ return;
+ }
+
+ /* Start the resolver, if necessary. */
+ if (!resolver_inited) {
+ minires_ninit (&resolver_state);
+ resolver_inited = 1;
+ resolver_state.retrans = 1;
+ resolver_state.retry = 1;
+ }
+
+ /*
+ * Perform updates.
+ */
+ if (ddns_fwd_name.len && ddns_dhcid.len) {
+ if (addp)
+ rcode = ddns_update_a (&ddns_fwd_name,
+ client -> active -> address,
+ &ddns_dhcid, DEFAULT_DDNS_TTL,
+ 1);
+ else
+ rcode = ddns_remove_a (&ddns_fwd_name,
+ client -> active -> address,
+ &ddns_dhcid);
+ }
+
+ data_string_forget (&ddns_fwd_name, MDL);
+ data_string_forget (&ddns_dhcid, MDL);
+}
diff --git a/client/dhclient.conf.5 b/client/dhclient.conf.5
index 6af31826..90e1843d 100644
--- a/client/dhclient.conf.5
+++ b/client/dhclient.conf.5
@@ -227,6 +227,26 @@ than the default requested lease time, which is two hours. The other
obvious use for this statement is to send information to the server
that will allow it to differentiate between this client and other
clients or kinds of clients.
+.SH DYNAMIC DNS
+The client now has some very limited support for doing DNS updates
+when a lease is acquired. This is prototypical, and probably doesn't
+do what you want. It also only works if you happen to have control
+over your DNS server, which isn't very likely.
+.PP
+To make it work, you have to declare a key and zone as in the DHCP
+server (see \fBdhcpd.conf\fR(5) for details). You also need to
+configure the fqdn option on the client, as follows:
+.PP
+.nf
+ send fqdn.fqdn "grosse.fugue.com.";
+ send fqdn.encoded on;
+ send fqdn.server-update off;
+.fi
+.PP
+The \fIfqdn.fqdn\fR option \fBMUST\fR be a fully-qualified domain
+name. You \fBMUST\fR define a zone statement for the zone to be
+updated. The \fIfqdn.encoded\fR option may need to be set to
+\fIon\fR or \fIoff\fR, depending on the DHCP server you are using.
.SH OPTION MODIFIERS
In some cases, a client may receive option data from the server which
is not really appropriate for that client, or may not receive
diff --git a/client/scripts/bsdos b/client/scripts/bsdos
index 13be7008..d076d92d 100755
--- a/client/scripts/bsdos
+++ b/client/scripts/bsdos
@@ -1,10 +1,12 @@
#!/bin/sh
make_resolv_conf() {
- echo search $new_domain_name >/etc/resolv.conf
- for nameserver in $new_domain_name_servers; do
- echo nameserver $nameserver >>/etc/resolv.conf
- done
+ if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
+ echo search $new_domain_name >/etc/resolv.conf
+ for nameserver in $new_domain_name_servers; do
+ echo nameserver $nameserver >>/etc/resolv.conf
+ done
+ fi
}
# Must be used on exit. Invokes the local dhcp client exit hooks, if any.
@@ -127,7 +129,8 @@ if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
exit_with_hooks 0
fi
-if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
+if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
+ || [ x$reason = xSTOP ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
diff --git a/client/scripts/freebsd b/client/scripts/freebsd
index 4f2d971f..652d0d06 100755
--- a/client/scripts/freebsd
+++ b/client/scripts/freebsd
@@ -7,10 +7,12 @@ else
fi
make_resolv_conf() {
- echo search $new_domain_name >/etc/resolv.conf
- for nameserver in $new_domain_name_servers; do
- echo nameserver $nameserver >>/etc/resolv.conf
- done
+ if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
+ echo search $new_domain_name >/etc/resolv.conf
+ for nameserver in $new_domain_name_servers; do
+ echo nameserver $nameserver >>/etc/resolv.conf
+ done
+ fi
}
# Must be used on exit. Invokes the local dhcp client exit hooks, if any.
@@ -140,7 +142,8 @@ if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
exit_with_hooks 0
fi
-if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
+if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
+ || [ x$reason = xSTOP ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
diff --git a/client/scripts/linux b/client/scripts/linux
index 9f02f23f..71d00ab3 100755
--- a/client/scripts/linux
+++ b/client/scripts/linux
@@ -23,10 +23,12 @@
# of the $1 in its args.
function make_resolv_conf() {
- echo search $new_domain_name >/etc/resolv.conf
- for nameserver in $new_domain_name_servers; do
- echo nameserver $nameserver >>/etc/resolv.conf
- done
+ if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
+ echo search $new_domain_name >/etc/resolv.conf
+ for nameserver in $new_domain_name_servers; do
+ echo nameserver $nameserver >>/etc/resolv.conf
+ done
+ fi
}
# Must be used on exit. Invokes the local dhcp client exit hooks, if any.
@@ -147,7 +149,8 @@ if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
exit_with_hooks 0
fi
-if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
+if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
+ || [ x$reason = xSTOP ]; then
if [ x$alias_ip_address != x ]; then
# Turn off alias interface.
ifconfig $interface:0- inet 0
diff --git a/client/scripts/netbsd b/client/scripts/netbsd
index f61d0e78..d226cdff 100755
--- a/client/scripts/netbsd
+++ b/client/scripts/netbsd
@@ -1,10 +1,12 @@
#!/bin/sh
make_resolv_conf() {
- echo search $new_domain_name >/etc/resolv.conf
- for nameserver in $new_domain_name_servers; do
- echo nameserver $nameserver >>/etc/resolv.conf
- done
+ if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
+ echo search $new_domain_name >/etc/resolv.conf
+ for nameserver in $new_domain_name_servers; do
+ echo nameserver $nameserver >>/etc/resolv.conf
+ done
+ fi
}
# Must be used on exit. Invokes the local dhcp client exit hooks, if any.
@@ -127,7 +129,8 @@ if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
exit_with_hooks 0
fi
-if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
+if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
+ || [ x$reason = xSTOP ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
diff --git a/client/scripts/nextstep b/client/scripts/nextstep
index 1c8c2a26..7600fb14 100644
--- a/client/scripts/nextstep
+++ b/client/scripts/nextstep
@@ -31,13 +31,16 @@ if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
route add default $router 1 >/dev/null 2>&1
done
fi
- echo search $new_domain_name >/etc/resolv.conf
- for nameserver in $new_domain_name_servers; do
- echo nameserver $nameserver >>/etc/resolv.conf
- done
+ if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
+ echo search $new_domain_name >/etc/resolv.conf
+ for nameserver in $new_domain_name_servers; do
+ echo nameserver $nameserver >>/etc/resolv.conf
+ done
+ fi
exit 0
fi
-if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
+if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
+ || [ x$reason = xSTOP ]; then
if [ x$old_ip_address != x ]; then
route delete $old_ip_address 127.1 >/dev/null 2>&1
for $router in $old_routers ; do
diff --git a/client/scripts/openbsd b/client/scripts/openbsd
index 13be7008..d076d92d 100644
--- a/client/scripts/openbsd
+++ b/client/scripts/openbsd
@@ -1,10 +1,12 @@
#!/bin/sh
make_resolv_conf() {
- echo search $new_domain_name >/etc/resolv.conf
- for nameserver in $new_domain_name_servers; do
- echo nameserver $nameserver >>/etc/resolv.conf
- done
+ if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
+ echo search $new_domain_name >/etc/resolv.conf
+ for nameserver in $new_domain_name_servers; do
+ echo nameserver $nameserver >>/etc/resolv.conf
+ done
+ fi
}
# Must be used on exit. Invokes the local dhcp client exit hooks, if any.
@@ -127,7 +129,8 @@ if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
exit_with_hooks 0
fi
-if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
+if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
+ || [ x$reason = xSTOP ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
diff --git a/client/scripts/solaris b/client/scripts/solaris
index 21e83fa0..e6187c71 100755
--- a/client/scripts/solaris
+++ b/client/scripts/solaris
@@ -1,10 +1,12 @@
#!/bin/sh
make_resolv_conf() {
- echo search $new_domain_name >/etc/resolv.conf
- for nameserver in $new_domain_name_servers; do
- echo nameserver $nameserver >>/etc/resolv.conf
- done
+ if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
+ echo search $new_domain_name >/etc/resolv.conf
+ for nameserver in $new_domain_name_servers; do
+ echo nameserver $nameserver >>/etc/resolv.conf
+ done
+ fi
}
# Must be used on exit. Invokes the local dhcp client exit hooks, if any.
@@ -120,7 +122,8 @@ if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
exit_with_hooks 0
fi
-if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
+if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
+ || [ x$reason = xSTOP ]; then
if [ x$alias_ip_address != x ]; then
$ifconfig ${interface}:1 0 down > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
diff --git a/common/alloc.c b/common/alloc.c
index c5f3cfc8..3bf8393c 100644
--- a/common/alloc.c
+++ b/common/alloc.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: alloc.c,v 1.53 2001/01/25 08:18:37 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: alloc.c,v 1.54 2001/06/27 00:29:39 mellon Exp $ Copyright (c) 1996-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -52,17 +52,13 @@ static char copyright[] =
struct dhcp_packet *dhcp_free_list;
struct packet *packet_free_list;
-OMAPI_OBJECT_ALLOC (subnet, struct subnet, dhcp_type_subnet)
-OMAPI_OBJECT_ALLOC (shared_network, struct shared_network,
- dhcp_type_shared_network)
-OMAPI_OBJECT_ALLOC (group_object, struct group_object, dhcp_type_group)
-
int option_chain_head_allocate (ptr, file, line)
struct option_chain_head **ptr;
const char *file;
int line;
{
int size;
+ struct option_chain_head *h;
if (!ptr) {
log_error ("%s(%d): null pointer", file, line);
@@ -81,11 +77,10 @@ int option_chain_head_allocate (ptr, file, line)
#endif
}
- *ptr = dmalloc (sizeof **ptr, file, line);
- if (*ptr) {
- memset (*ptr, 0, sizeof **ptr);
- (*ptr) -> refcnt = 1;
- return 1;
+ h = dmalloc (sizeof *h, file, line);
+ if (h) {
+ memset (h, 0, sizeof *h);
+ return option_chain_head_reference (ptr, h, file, line);
}
return 0;
}
@@ -114,8 +109,7 @@ int option_chain_head_reference (ptr, bp, file, line)
}
*ptr = bp;
bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt);
- dmalloc_reuse (bp, file, line, 1);
+ rc_register (file, line, ptr, bp, bp -> refcnt, 0);
return 1;
}
@@ -141,14 +135,14 @@ int option_chain_head_dereference (ptr, file, line)
*ptr = (struct option_chain_head *)0;
--option_chain_head -> refcnt;
rc_register (file, line, ptr,
- option_chain_head, option_chain_head -> refcnt);
+ option_chain_head, option_chain_head -> refcnt, 1);
if (option_chain_head -> refcnt > 0)
return 1;
if (option_chain_head -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (option_chain_head);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -177,6 +171,7 @@ int group_allocate (ptr, file, line)
int line;
{
int size;
+ struct group *g;
if (!ptr) {
log_error ("%s(%d): null pointer", file, line);
@@ -195,11 +190,10 @@ int group_allocate (ptr, file, line)
#endif
}
- *ptr = dmalloc (sizeof **ptr, file, line);
- if (*ptr) {
- memset (*ptr, 0, sizeof **ptr);
- (*ptr) -> refcnt = 1;
- return 1;
+ g = dmalloc (sizeof *g, file, line);
+ if (g) {
+ memset (g, 0, sizeof *g);
+ return group_reference (ptr, g, file, line);
}
return 0;
}
@@ -228,8 +222,7 @@ int group_reference (ptr, bp, file, line)
}
*ptr = bp;
bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt);
- dmalloc_reuse (bp, file, line, 1);
+ rc_register (file, line, ptr, bp, bp -> refcnt, 0);
return 1;
}
@@ -253,14 +246,14 @@ int group_dereference (ptr, file, line)
group = *ptr;
*ptr = (struct group *)0;
--group -> refcnt;
- rc_register (file, line, ptr, group, group -> refcnt);
+ rc_register (file, line, ptr, group, group -> refcnt, 1);
if (group -> refcnt > 0)
return 1;
if (group -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (group);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -270,13 +263,17 @@ int group_dereference (ptr, file, line)
}
if (group -> object)
- group_object_dereference (&group -> object, MDL);
+ group_object_dereference (&group -> object, file, line);
if (group -> subnet)
- subnet_dereference (&group -> subnet, MDL);
+ subnet_dereference (&group -> subnet, file, line);
if (group -> shared_network)
- shared_network_dereference (&group -> shared_network, MDL);
+ shared_network_dereference (&group -> shared_network,
+ file, line);
if (group -> statements)
- executable_statement_dereference (&group -> statements, MDL);
+ executable_statement_dereference (&group -> statements,
+ file, line);
+ if (group -> next)
+ group_dereference (&group -> next, file, line);
dfree (group, file, line);
return 1;
}
@@ -439,6 +436,20 @@ void free_pair (foo, file, line)
dmalloc_reuse (free_pairs, (char *)0, 0, 0);
}
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+void relinquish_free_pairs ()
+{
+ pair pf, pc;
+
+ for (pf = free_pairs; pf; pf = pc) {
+ pc = pf -> cdr;
+ dfree (pf, MDL);
+ }
+ free_pairs = (pair)0;
+}
+#endif
+
struct expression *free_expressions;
int expression_allocate (cptr, file, line)
@@ -451,6 +462,7 @@ int expression_allocate (cptr, file, line)
if (free_expressions) {
rval = free_expressions;
free_expressions = rval -> data.not;
+ dmalloc_reuse (rval, file, line, 1);
} else {
rval = dmalloc (sizeof (struct expression), file, line);
if (!rval)
@@ -484,8 +496,7 @@ int expression_reference (ptr, src, file, line)
}
*ptr = src;
src -> refcnt++;
- rc_register (file, line, ptr, src, src -> refcnt);
- dmalloc_reuse (src, file, line, 1);
+ rc_register (file, line, ptr, src, src -> refcnt, 0);
return 1;
}
@@ -499,6 +510,20 @@ void free_expression (expr, file, line)
dmalloc_reuse (free_expressions, (char *)0, 0, 0);
}
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+void relinquish_free_expressions ()
+{
+ struct expression *e, *n;
+
+ for (e = free_expressions; e; e = n) {
+ n = e -> data.not;
+ dfree (e, MDL);
+ }
+ free_expressions = (struct expression *)0;
+}
+#endif
+
struct binding_value *free_binding_values;
int binding_value_allocate (cptr, file, line)
@@ -511,6 +536,7 @@ int binding_value_allocate (cptr, file, line)
if (free_binding_values) {
rval = free_binding_values;
free_binding_values = rval -> value.bv;
+ dmalloc_reuse (rval, file, line, 1);
} else {
rval = dmalloc (sizeof (struct binding_value), file, line);
if (!rval)
@@ -544,8 +570,7 @@ int binding_value_reference (ptr, src, file, line)
}
*ptr = src;
src -> refcnt++;
- rc_register (file, line, ptr, src, src -> refcnt);
- dmalloc_reuse (src, file, line, 1);
+ rc_register (file, line, ptr, src, src -> refcnt, 0);
return 1;
}
@@ -559,6 +584,20 @@ void free_binding_value (bv, file, line)
dmalloc_reuse (free_binding_values, (char *)0, 0, 0);
}
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+void relinquish_free_binding_values ()
+{
+ struct binding_value *b, *n;
+
+ for (b = free_binding_values; b; b = n) {
+ n = b -> value.bv;
+ dfree (b, MDL);
+ }
+ free_binding_values = (struct binding_value *)0;
+}
+#endif
+
int fundef_allocate (cptr, file, line)
struct fundef **cptr;
const char *file;
@@ -597,13 +636,26 @@ int fundef_reference (ptr, src, file, line)
}
*ptr = src;
src -> refcnt++;
- rc_register (file, line, ptr, src, src -> refcnt);
- dmalloc_reuse (src, file, line, 1);
+ rc_register (file, line, ptr, src, src -> refcnt, 0);
return 1;
}
struct option_cache *free_option_caches;
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+void relinquish_free_option_caches ()
+{
+ struct option_cache *o, *n;
+
+ for (o = free_option_caches; o; o = n) {
+ n = (struct option_cache *)(o -> expression);
+ dfree (o, MDL);
+ }
+ free_option_caches = (struct option_cache *)0;
+}
+#endif
+
int option_cache_allocate (cptr, file, line)
struct option_cache **cptr;
const char *file;
@@ -649,8 +701,7 @@ int option_cache_reference (ptr, src, file, line)
}
*ptr = src;
src -> refcnt++;
- rc_register (file, line, ptr, src, src -> refcnt);
- dmalloc_reuse (src, file, line, 1);
+ rc_register (file, line, ptr, src, src -> refcnt, 0);
return 1;
}
@@ -694,8 +745,7 @@ int buffer_reference (ptr, bp, file, line)
}
*ptr = bp;
bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt);
- dmalloc_reuse (bp, file, line, 1);
+ rc_register (file, line, ptr, bp, bp -> refcnt, 0);
return 1;
}
@@ -725,13 +775,13 @@ int buffer_dereference (ptr, file, line)
}
(*ptr) -> refcnt--;
- rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt);
+ rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1);
if (!(*ptr) -> refcnt) {
dfree ((*ptr), file, line);
} else if ((*ptr) -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (*ptr);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -784,8 +834,7 @@ int dns_host_entry_reference (ptr, bp, file, line)
}
*ptr = bp;
bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt);
- dmalloc_reuse (bp, file, line, 1);
+ rc_register (file, line, ptr, bp, bp -> refcnt, 0);
return 1;
}
@@ -806,13 +855,13 @@ int dns_host_entry_dereference (ptr, file, line)
}
(*ptr) -> refcnt--;
- rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt);
+ rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1);
if (!(*ptr) -> refcnt)
dfree ((*ptr), file, line);
if ((*ptr) -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (*ptr);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -854,7 +903,7 @@ int option_state_allocate (ptr, file, line)
memset (*ptr, 0, size);
(*ptr) -> universe_count = universe_count;
(*ptr) -> refcnt = 1;
- rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt);
+ rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 0);
return 1;
}
return 0;
@@ -884,8 +933,7 @@ int option_state_reference (ptr, bp, file, line)
}
*ptr = bp;
bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt);
- dmalloc_reuse (bp, file, line, 1);
+ rc_register (file, line, ptr, bp, bp -> refcnt, 0);
return 1;
}
@@ -909,14 +957,14 @@ int option_state_dereference (ptr, file, line)
options = *ptr;
*ptr = (struct option_state *)0;
--options -> refcnt;
- rc_register (file, line, ptr, options, options -> refcnt);
+ rc_register (file, line, ptr, options, options -> refcnt, 1);
if (options -> refcnt > 0)
return 1;
if (options -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (options);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -973,19 +1021,32 @@ int executable_statement_reference (ptr, bp, file, line)
}
*ptr = bp;
bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt);
- dmalloc_reuse (bp, file, line, 1);
+ rc_register (file, line, ptr, bp, bp -> refcnt, 0);
return 1;
}
static struct packet *free_packets;
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+void relinquish_free_packets ()
+{
+ struct packet *p, *n;
+ for (p = free_packets; p; p = n) {
+ n = (struct packet *)(p -> raw);
+ dfree (p, MDL);
+ }
+ free_packets = (struct packet *)0;
+}
+#endif
+
int packet_allocate (ptr, file, line)
struct packet **ptr;
const char *file;
int line;
{
int size;
+ struct packet *p;
if (!ptr) {
log_error ("%s(%d): null pointer", file, line);
@@ -1005,15 +1066,15 @@ int packet_allocate (ptr, file, line)
}
if (free_packets) {
- *ptr = free_packets;
- free_packets = (struct packet *)((*ptr) -> raw);
+ p = free_packets;
+ free_packets = (struct packet *)(p -> raw);
+ dmalloc_reuse (p, file, line, 1);
} else {
- *ptr = dmalloc (sizeof **ptr, file, line);
+ p = dmalloc (sizeof *p, file, line);
}
- if (*ptr) {
- memset (*ptr, 0, sizeof **ptr);
- (*ptr) -> refcnt = 1;
- return 1;
+ if (p) {
+ memset (p, 0, sizeof *p);
+ return packet_reference (ptr, p, file, line);
}
return 0;
}
@@ -1042,8 +1103,7 @@ int packet_reference (ptr, bp, file, line)
}
*ptr = bp;
bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt);
- dmalloc_reuse (bp, file, line, 1);
+ rc_register (file, line, ptr, bp, bp -> refcnt, 0);
return 1;
}
@@ -1067,14 +1127,14 @@ int packet_dereference (ptr, file, line)
packet = *ptr;
*ptr = (struct packet *)0;
--packet -> refcnt;
- rc_register (file, line, ptr, packet, packet -> refcnt);
+ rc_register (file, line, ptr, packet, packet -> refcnt, 1);
if (packet -> refcnt > 0)
return 1;
if (packet -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (packet);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -1087,6 +1147,13 @@ int packet_dereference (ptr, file, line)
option_state_dereference (&packet -> options, file, line);
if (packet -> interface)
interface_dereference (&packet -> interface, MDL);
+ if (packet -> shared_network)
+ shared_network_dereference (&packet -> shared_network, MDL);
+ for (i = 0; i < packet -> class_count && i < PACKET_MAX_CLASSES; i++) {
+ if (packet -> classes [i])
+ omapi_object_dereference ((omapi_object_t **)
+ &packet -> classes [i], MDL);
+ }
packet -> raw = (struct dhcp_packet *)free_packets;
free_packets = packet;
dmalloc_reuse (free_packets, (char *)0, 0, 0);
@@ -1099,6 +1166,7 @@ int dns_zone_allocate (ptr, file, line)
int line;
{
int size;
+ struct dns_zone *d;
if (!ptr) {
log_error ("%s(%d): null pointer", file, line);
@@ -1117,11 +1185,10 @@ int dns_zone_allocate (ptr, file, line)
#endif
}
- *ptr = dmalloc (sizeof **ptr, file, line);
- if (*ptr) {
- memset (*ptr, 0, sizeof **ptr);
- (*ptr) -> refcnt = 1;
- return 1;
+ d = dmalloc (sizeof *d, file, line);
+ if (d) {
+ memset (d, 0, sizeof *d);
+ return dns_zone_reference (ptr, d, file, line);
}
return 0;
}
@@ -1150,8 +1217,7 @@ int dns_zone_reference (ptr, bp, file, line)
}
*ptr = bp;
bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt);
- dmalloc_reuse (bp, file, line, 1);
+ rc_register (file, line, ptr, bp, bp -> refcnt, 0);
return 1;
}
@@ -1212,8 +1278,7 @@ int binding_scope_reference (ptr, bp, file, line)
}
*ptr = bp;
bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt);
- dmalloc_reuse (bp, file, line, 1);
+ rc_register (file, line, ptr, bp, bp -> refcnt, 0);
return 1;
}
diff --git a/common/comapi.c b/common/comapi.c
index 30fea7b2..68c0e1fe 100644
--- a/common/comapi.c
+++ b/common/comapi.c
@@ -3,7 +3,7 @@
OMAPI object interfaces for the DHCP server. */
/*
- * Copyright (c) 1999-2000 Internet Software Consortium.
+ * Copyright (c) 1999-2001 Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -50,21 +50,50 @@
#ifndef lint
static char copyright[] =
-"$Id: comapi.c,v 1.9 2001/05/02 06:27:52 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: comapi.c,v 1.10 2001/06/27 00:29:41 mellon Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <omapip/omapip_p.h>
+OMAPI_OBJECT_ALLOC (subnet, struct subnet, dhcp_type_subnet)
+OMAPI_OBJECT_ALLOC (shared_network, struct shared_network,
+ dhcp_type_shared_network)
+OMAPI_OBJECT_ALLOC (group_object, struct group_object, dhcp_type_group)
+OMAPI_OBJECT_ALLOC (dhcp_control, dhcp_control_object_t, dhcp_type_control)
+
omapi_object_type_t *dhcp_type_interface;
omapi_object_type_t *dhcp_type_group;
omapi_object_type_t *dhcp_type_shared_network;
omapi_object_type_t *dhcp_type_subnet;
+omapi_object_type_t *dhcp_type_control;
+dhcp_control_object_t *dhcp_control_object;
void dhcp_common_objects_setup ()
{
isc_result_t status;
+ status = omapi_object_type_register (&dhcp_type_control,
+ "control",
+ dhcp_control_set_value,
+ dhcp_control_get_value,
+ dhcp_control_destroy,
+ dhcp_control_signal_handler,
+ dhcp_control_stuff_values,
+ dhcp_control_lookup,
+ dhcp_control_create,
+ dhcp_control_remove, 0, 0, 0,
+ sizeof (dhcp_control_object_t),
+ 0);
+ if (status != ISC_R_SUCCESS)
+ log_fatal ("Can't register control object type: %s",
+ isc_result_totext (status));
+ status = dhcp_control_allocate (&dhcp_control_object, MDL);
+ if (status != ISC_R_SUCCESS)
+ log_fatal ("Can't make initial control object: %s",
+ isc_result_totext (status));
+ dhcp_control_object -> state = server_startup;
+
status = omapi_object_type_register (&dhcp_type_group,
"group",
dhcp_group_set_value,
@@ -267,7 +296,8 @@ isc_result_t dhcp_group_signal_handler (omapi_object_t *h,
if (!group -> name) {
char hnbuf [64];
sprintf (hnbuf, "ng%08lx%08lx",
- (unsigned long)cur_time, (unsigned long)group);
+ (unsigned long)cur_time,
+ (unsigned long)group);
group -> name = dmalloc (strlen (hnbuf) + 1, MDL);
if (!group -> name)
return ISC_R_NOMEMORY;
@@ -329,6 +359,9 @@ isc_result_t dhcp_group_lookup (omapi_object_t **lp,
isc_result_t status;
struct group_object *group;
+ if (!ref)
+ return ISC_R_NOKEYS;
+
/* First see if we were sent a handle. */
status = omapi_get_value_str (ref, id, "handle", &tv);
if (status == ISC_R_SUCCESS) {
@@ -420,6 +453,182 @@ isc_result_t dhcp_group_remove (omapi_object_t *lp,
return ISC_R_SUCCESS;
}
+isc_result_t dhcp_control_set_value (omapi_object_t *h,
+ omapi_object_t *id,
+ omapi_data_string_t *name,
+ omapi_typed_data_t *value)
+{
+ dhcp_control_object_t *control;
+ isc_result_t status;
+ int foo;
+ unsigned long newstate;
+
+ if (h -> type != dhcp_type_control)
+ return ISC_R_INVALIDARG;
+ control = (dhcp_control_object_t *)h;
+
+ if (!omapi_ds_strcmp (name, "state")) {
+ status = omapi_get_int_value (&newstate, value);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ status = dhcp_set_control_state (control -> state, newstate);
+ if (status == ISC_R_SUCCESS)
+ control -> state = value -> u.integer;
+ return status;
+ }
+
+ /* Try to find some inner object that can take the value. */
+ if (h -> inner && h -> inner -> type -> set_value) {
+ status = ((*(h -> inner -> type -> set_value))
+ (h -> inner, id, name, value));
+ if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
+ return status;
+ }
+
+ return ISC_R_NOTFOUND;
+}
+
+
+isc_result_t dhcp_control_get_value (omapi_object_t *h, omapi_object_t *id,
+ omapi_data_string_t *name,
+ omapi_value_t **value)
+{
+ dhcp_control_object_t *control;
+ isc_result_t status;
+ struct data_string ip_addrs;
+
+ if (h -> type != dhcp_type_control)
+ return ISC_R_INVALIDARG;
+ control = (dhcp_control_object_t *)h;
+
+ if (!omapi_ds_strcmp (name, "state"))
+ return omapi_make_int_value (value,
+ name, (int)control -> state, MDL);
+
+ /* Try to find some inner object that can take the value. */
+ if (h -> inner && h -> inner -> type -> get_value) {
+ status = ((*(h -> inner -> type -> get_value))
+ (h -> inner, id, name, value));
+ if (status == ISC_R_SUCCESS)
+ return status;
+ }
+ return ISC_R_NOTFOUND;
+}
+
+isc_result_t dhcp_control_destroy (omapi_object_t *h,
+ const char *file, int line)
+{
+ dhcp_control_object_t *control, *t;
+ isc_result_t status;
+
+ if (h -> type != dhcp_type_control)
+ return ISC_R_INVALIDARG;
+
+ /* Can't destroy the control object. */
+ return ISC_R_NOPERM;
+}
+
+isc_result_t dhcp_control_signal_handler (omapi_object_t *h,
+ const char *name, va_list ap)
+{
+ dhcp_control_object_t *control, *t;
+ isc_result_t status;
+ int updatep = 0;
+
+ if (h -> type != dhcp_type_control)
+ return ISC_R_INVALIDARG;
+ control = (dhcp_control_object_t *)h;
+
+ /* Try to find some inner object that can take the value. */
+ if (h -> inner && h -> inner -> type -> get_value) {
+ status = ((*(h -> inner -> type -> signal_handler))
+ (h -> inner, name, ap));
+ if (status == ISC_R_SUCCESS)
+ return status;
+ }
+ return ISC_R_NOTFOUND;
+}
+
+isc_result_t dhcp_control_stuff_values (omapi_object_t *c,
+ omapi_object_t *id,
+ omapi_object_t *h)
+{
+ dhcp_control_object_t *control;
+ isc_result_t status;
+
+ if (h -> type != dhcp_type_control)
+ return ISC_R_INVALIDARG;
+ control = (dhcp_control_object_t *)h;
+
+ /* Write out all the values. */
+ status = omapi_connection_put_name (c, "state");
+ if (status != ISC_R_SUCCESS)
+ return status;
+ status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
+ if (status != ISC_R_SUCCESS)
+ return status;
+ status = omapi_connection_put_uint32 (c, control -> state);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ /* Write out the inner object, if any. */
+ if (h -> inner && h -> inner -> type -> stuff_values) {
+ status = ((*(h -> inner -> type -> stuff_values))
+ (c, id, h -> inner));
+ if (status == ISC_R_SUCCESS)
+ return status;
+ }
+
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t dhcp_control_lookup (omapi_object_t **lp,
+ omapi_object_t *id, omapi_object_t *ref)
+{
+ omapi_value_t *tv = (omapi_value_t *)0;
+ isc_result_t status;
+ dhcp_control_object_t *control;
+
+ /* First see if we were sent a handle. */
+ if (ref) {
+ status = omapi_get_value_str (ref, id, "handle", &tv);
+ if (status == ISC_R_SUCCESS) {
+ status = omapi_handle_td_lookup (lp, tv -> value);
+
+ omapi_value_dereference (&tv, MDL);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ /* Don't return the object if the type is wrong. */
+ if ((*lp) -> type != dhcp_type_control) {
+ omapi_object_dereference (lp, MDL);
+ return ISC_R_INVALIDARG;
+ }
+ }
+ }
+
+ /* Otherwise, stop playing coy - there's only one control object,
+ so we can just return it. */
+ dhcp_control_reference ((dhcp_control_object_t **)lp,
+ dhcp_control_object, MDL);
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t dhcp_control_create (omapi_object_t **lp,
+ omapi_object_t *id)
+{
+ /* Can't create a control object - there can be only one. */
+ return ISC_R_NOPERM;
+}
+
+isc_result_t dhcp_control_remove (omapi_object_t *lp,
+ omapi_object_t *id)
+{
+ /* Form is emptiness; emptiness form. The control object
+ cannot go out of existance. */
+ return ISC_R_NOPERM;
+}
+
isc_result_t dhcp_subnet_set_value (omapi_object_t *h,
omapi_object_t *id,
omapi_data_string_t *name,
@@ -479,7 +688,20 @@ isc_result_t dhcp_subnet_destroy (omapi_object_t *h, const char *file, int line)
return ISC_R_INVALIDARG;
subnet = (struct subnet *)h;
- /* Can't destroy subnets yet. */
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ if (subnet -> next_subnet)
+ subnet_dereference (&subnet -> next_subnet, file, line);
+ if (subnet -> next_sibling)
+ subnet_dereference (&subnet -> next_sibling, file, line);
+ if (subnet -> shared_network)
+ shared_network_dereference (&subnet -> shared_network,
+ file, line);
+ if (subnet -> interface)
+ interface_dereference (&subnet -> interface, file, line);
+ if (subnet -> group)
+ group_dereference (&subnet -> group, file, line);
+#endif
return ISC_R_SUCCESS;
}
@@ -623,7 +845,32 @@ isc_result_t dhcp_shared_network_destroy (omapi_object_t *h,
return ISC_R_INVALIDARG;
shared_network = (struct shared_network *)h;
- /* Can't destroy shared_networks yet. */
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ if (shared_network -> next)
+ shared_network_dereference (&shared_network -> next,
+ file, line);
+ if (shared_network -> name) {
+ dfree (shared_network -> name, file, line);
+ shared_network -> name = 0;
+ }
+ if (shared_network -> subnets)
+ subnet_dereference (&shared_network -> subnets, file, line);
+ if (shared_network -> interface)
+ interface_dereference (&shared_network -> interface,
+ file, line);
+ if (shared_network -> pools)
+ omapi_object_dereference ((omapi_object_t **)
+ &shared_network -> pools, file, line);
+ if (shared_network -> group)
+ group_dereference (&shared_network -> group, file, line);
+#if defined (FAILOVER_PROTOCOL)
+ if (shared_network -> failover_peer)
+ omapi_object_dereference ((omapi_object_t **)
+ &shared_network -> failover_peer,
+ file, line);
+#endif
+#endif /* DEBUG_MEMORY_LEAKAGE */
return ISC_R_SUCCESS;
}
diff --git a/common/conflex.c b/common/conflex.c
index 5f2d895c..76db7be6 100644
--- a/common/conflex.c
+++ b/common/conflex.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: conflex.c,v 1.93 2001/05/17 19:03:43 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: conflex.c,v 1.94 2001/06/27 00:29:42 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -606,6 +606,8 @@ static enum dhcp_token intern (atom, dfv)
return DNS_DELETE;
if (!strcasecmp (atom + 1, "omain"))
return DOMAIN;
+ if (!strcasecmp (atom + 1, "omain-name"))
+ return DOMAIN_NAME;
if (!strcasecmp (atom + 1, "ebug"))
return TOKEN_DEBUG;
if (!strcasecmp (atom + 1, "eny"))
@@ -928,6 +930,8 @@ static enum dhcp_token intern (atom, dfv)
return TOKEN_RESERVED;
if (!strcasecmp (atom + 1, "emove"))
return REMOVE;
+ if (!strcasecmp (atom + 1, "efresh"))
+ return REFRESH;
break;
case 's':
if (!strcasecmp (atom + 1, "tate"))
diff --git a/common/dhcp-options.5 b/common/dhcp-options.5
index 2a8c00cf..a2dfeab8 100644
--- a/common/dhcp-options.5
+++ b/common/dhcp-options.5
@@ -83,14 +83,21 @@ Unsigned 8-bit integers are also sometimes referred to as octets.
The
.B text
data type specifies an NVT ASCII string, which must be
-enclosed in double quotes - for example, to specify a domain-name
+enclosed in double quotes - for example, to specify a root-path
option, the syntax would be
.nf
.sp 1
-option domain-name "isc.org";
+option root-path "10.0.1.4:/var/tmp/rootfs";
.fi
.PP
The
+.B domain-name
+data type specifies a domain name, which must not
+enclosed in double quotes. This data type is not used for any
+existing DHCP options. The domain name is stored just as if it were
+a text option.
+.PP
+The
.B flag
data type specifies a boolean value. Booleans can be either true or
false (or on or off, if that makes more sense to you).
diff --git a/common/discover.c b/common/discover.c
index 4dc8b25f..c11abb9c 100644
--- a/common/discover.c
+++ b/common/discover.c
@@ -43,14 +43,14 @@
#ifndef lint
static char copyright[] =
-"$Id: discover.c,v 1.43 2001/05/17 19:03:44 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: discover.c,v 1.44 2001/06/27 00:29:44 mellon Exp $ Copyright (c) 1995-2001 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;
-extern int interfaces_invalidated;
+int interfaces_invalidated;
int quiet_interface_discovery;
u_int16_t local_port;
u_int16_t remote_port;
@@ -406,6 +406,7 @@ void discover_interfaces (state)
log_fatal ("Can't allocate interface %s: %s",
name, isc_result_totext (status));
tmp -> flags = ir;
+ strncpy (tmp -> name, name, IFNAMSIZ);
interface_reference (&tmp -> next, interfaces, MDL);
interface_dereference (&interfaces, MDL);
interface_reference (&interfaces, tmp, MDL);
@@ -839,8 +840,23 @@ isc_result_t dhcp_interface_destroy (omapi_object_t *h,
return ISC_R_INVALIDARG;
interface = (struct interface_info *)h;
- if (interface -> ifp)
+ if (interface -> ifp) {
dfree (interface -> ifp, file, line);
+ interface -> ifp = 0;
+ }
+ if (interface -> next)
+ interface_dereference (&interface -> next, file, line);
+ if (interface -> rbuf) {
+ dfree (interface -> rbuf, file, line);
+ interface -> rbuf = (unsigned char *)0;
+ }
+ if (interface -> client)
+ interface -> client = (struct client_state *)0;
+
+ if (interface -> shared_network)
+ omapi_object_dereference ((omapi_object_t **)
+ &interface -> shared_network, MDL);
+
return ISC_R_SUCCESS;
}
@@ -924,6 +940,9 @@ isc_result_t dhcp_interface_lookup (omapi_object_t **ip,
isc_result_t status;
struct interface_info *interface;
+ if (!ref)
+ return ISC_R_NOKEYS;
+
/* First see if we were sent a handle. */
status = omapi_get_value_str (ref, id, "handle", &tv);
if (status == ISC_R_SUCCESS) {
@@ -1095,7 +1114,7 @@ void interface_stash (struct interface_info *tptr)
}
interface_vector = vec;
}
- interface_vector [tptr -> index] = tptr;
+ interface_reference (&interface_vector [tptr -> index], tptr, MDL);
if (tptr -> index >= interface_count)
interface_count = tptr -> index + 1;
#if defined (TRACING)
diff --git a/common/dispatch.c b/common/dispatch.c
index fee34f7c..4b5923cc 100644
--- a/common/dispatch.c
+++ b/common/dispatch.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: dispatch.c,v 1.63 2001/02/12 19:41:30 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dispatch.c,v 1.64 2001/06/27 00:29:45 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -51,8 +51,6 @@ static char copyright[] =
struct timeout *timeouts;
static struct timeout *free_timeouts;
-int interfaces_invalidated;
-
void set_time (u_int32_t t)
{
/* Do any outstanding timeouts. */
@@ -205,3 +203,26 @@ void cancel_timeout (where, what)
free_timeouts = q;
}
}
+
+#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+void cancel_all_timeouts ()
+{
+ struct timeout *t, *n;
+ for (t = timeouts; t; t = n) {
+ n = t -> next;
+ if (t -> unref && t -> what)
+ (*t -> unref) (&t -> what, MDL);
+ t -> next = free_timeouts;
+ free_timeouts = t;
+ }
+}
+
+void relinquish_timeouts ()
+{
+ struct timeout *t, *n;
+ for (t = free_timeouts; t; t = n) {
+ n = t -> next;
+ dfree (t, MDL);
+ }
+}
+#endif
diff --git a/common/dns.c b/common/dns.c
index abd329de..49f52b33 100644
--- a/common/dns.c
+++ b/common/dns.c
@@ -3,7 +3,7 @@
Domain Name Service subroutines. */
/*
- * Copyright (c) 2000 Internet Software Consortium.
+ * Copyright (c) 2001 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: dns.c,v 1.35 2001/02/22 07:37:13 mellon Exp $ Copyright (c) 2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dns.c,v 1.36 2001/06/27 00:29:46 mellon Exp $ Copyright (c) 2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -151,7 +151,9 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname,
strlen (zone -> key -> name) > NS_MAXDNAME) ||
(!zone -> key -> algorithm ||
strlen (zone -> key -> algorithm) > NS_MAXDNAME) ||
- (!zone -> key)) {
+ (!zone -> key) ||
+ (!zone -> key -> key) ||
+ (zone -> key -> key -> len == 0)) {
return ISC_R_INVALIDKEY;
}
tkey = dmalloc (sizeof *tkey, MDL);
@@ -202,7 +204,8 @@ isc_result_t enter_dns_zone (struct dns_zone *zone)
} else {
dns_zone_hash =
new_hash ((hash_reference)dns_zone_reference,
- (hash_dereference)dns_zone_dereference, 1);
+ (hash_dereference)dns_zone_dereference, 1,
+ MDL);
if (!dns_zone_hash)
return ISC_R_NOMEMORY;
}
@@ -213,7 +216,7 @@ isc_result_t enter_dns_zone (struct dns_zone *zone)
isc_result_t dns_zone_lookup (struct dns_zone **zone, const char *name)
{
struct dns_zone *tz = (struct dns_zone *)0;
- unsigned len;
+ int len;
char *tname = (char *)0;
isc_result_t status;
@@ -222,7 +225,7 @@ isc_result_t dns_zone_lookup (struct dns_zone **zone, const char *name)
len = strlen (name);
if (name [len - 1] != '.') {
- tname = dmalloc (len + 2, MDL);
+ tname = dmalloc ((unsigned)len + 2, MDL);
if (!tname)
return ISC_R_NOMEMORY;;
strcpy (tname, name);
@@ -260,14 +263,14 @@ int dns_zone_dereference (ptr, file, line)
dns_zone = *ptr;
*ptr = (struct dns_zone *)0;
--dns_zone -> refcnt;
- rc_register (file, line, ptr, dns_zone, dns_zone -> refcnt);
+ rc_register (file, line, ptr, dns_zone, dns_zone -> refcnt, 1);
if (dns_zone -> refcnt > 0)
return 1;
if (dns_zone -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (dns_zone);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -312,7 +315,7 @@ isc_result_t find_cached_zone (const char *dname, ns_class class,
return ISC_R_INVALIDARG;
/* For each subzone, try to find a cached zone. */
- for (np = dname - 1; np; np = strchr (np, '.')) {
+ for (np = dname; np; np = strchr (np, '.')) {
np++;
status = dns_zone_lookup (&zone, np);
if (status == ISC_R_SUCCESS)
@@ -466,12 +469,21 @@ void cache_found_zone (ns_class class,
enter_dns_zone (zone);
}
-int get_dhcid (struct data_string *id, struct lease *lease)
+/* Have to use TXT records for now. */
+#define T_DHCID T_TXT
+
+int get_dhcid (struct data_string *id,
+ int type, const u_int8_t *data, unsigned len)
{
unsigned char buf[MD5_DIGEST_LENGTH];
MD5_CTX md5;
int i;
+ /* Types can only be 0..(2^16)-1. */
+ if (type < 0 || type > 65535)
+ return 0;
+
+ /* Hexadecimal MD5 digest plus two byte type and NUL. */
if (!buffer_allocate (&id -> buffer,
(MD5_DIGEST_LENGTH * 2) + 3, MDL))
return 0;
@@ -494,27 +506,13 @@ int get_dhcid (struct data_string *id, struct lease *lease)
* M. Stapp, Y. Rekhter
*/
- MD5_Init (&md5);
-
- if (lease -> uid) {
- id -> buffer -> data [0] =
- "0123456789abcdef" [DHO_DHCP_CLIENT_IDENTIFIER >> 4];
- id -> buffer -> data [1] =
- "0123456789abcdef" [DHO_DHCP_CLIENT_IDENTIFIER % 15];
- /* Use the DHCP Client Identifier option. */
- MD5_Update (&md5, lease -> uid, lease -> uid_len);
- } else if (lease -> hardware_addr.hlen) {
- id -> buffer -> data [0] = '0';
- id -> buffer -> data [1] = '0';
- /* Use the link-layer address. */
- MD5_Update (&md5,
- lease -> hardware_addr.hbuf,
- lease -> hardware_addr.hlen);
- } else {
- /* Uh-oh. Something isn't right here. */
- return 1;
- }
+ /* Put the type in the first two bytes. */
+ id -> buffer -> data [0] = "0123456789abcdef" [type >> 4];
+ id -> buffer -> data [1] = "0123456789abcdef" [type % 15];
+ /* Mash together an MD5 hash of the identifier. */
+ MD5_Init (&md5);
+ MD5_Update (&md5, data, len);
MD5_Final (buf, &md5);
/* Convert into ASCII. */
@@ -528,8 +526,417 @@ int get_dhcid (struct data_string *id, struct lease *lease)
id -> buffer -> data [id -> len] = 0;
id -> terminated = 1;
- return 0;
+ return 1;
}
+
+/* Now for the DDNS update code that is shared between client and
+ server... */
+
+isc_result_t ddns_update_a (struct data_string *ddns_fwd_name,
+ struct iaddr ddns_addr,
+ struct data_string *ddns_dhcid,
+ unsigned long ttl, int rrsetp)
+{
+ ns_updque updqueue;
+ ns_updrec *updrec;
+ isc_result_t result;
+ char ddns_address [16];
+
+ if (ddns_addr.len != 4)
+ return ISC_R_INVALIDARG;
+#ifndef NO_SNPRINTF
+ snprintf (ddns_address, 16, "%d.%d.%d.%d",
+ ddns_addr.iabuf[0], ddns_addr.iabuf[1],
+ ddns_addr.iabuf[2], ddns_addr.iabuf[3]);
+#else
+ sprintf (ddns_address, "%d.%d.%d.%d",
+ ddns_addr.iabuf[0], ddns_addr.iabuf[1],
+ ddns_addr.iabuf[2], ddns_addr.iabuf[3]);
+#endif
+
+ /*
+ * When a DHCP client or server intends to update an A RR, it first
+ * prepares a DNS UPDATE query which includes as a prerequisite the
+ * assertion that the name does not exist. The update section of the
+ * query attempts to add the new name and its IP address mapping (an A
+ * RR), and the DHCID RR with its unique client-identity.
+ * -- "Interaction between DHCP and DNS"
+ */
+
+ ISC_LIST_INIT (updqueue);
+
+ /*
+ * A RR does not exist.
+ */
+ updrec = minires_mkupdrec (S_PREREQ,
+ (const char *)ddns_fwd_name -> data,
+ C_IN, T_A, 0);
+ if (!updrec) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+
+ updrec -> r_data = (unsigned char *)0;
+ updrec -> r_size = 0;
+ updrec -> r_opcode = rrsetp ? NXRRSET : NXDOMAIN;
+
+ ISC_LIST_APPEND (updqueue, updrec, r_link);
+
+
+ /*
+ * Add A RR.
+ */
+ updrec = minires_mkupdrec (S_UPDATE,
+ (const char *)ddns_fwd_name -> data,
+ C_IN, T_A, ttl);
+ if (!updrec) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+
+ updrec -> r_data = (unsigned char *)ddns_address;
+ updrec -> r_size = strlen (ddns_address);
+ updrec -> r_opcode = ADD;
+
+ ISC_LIST_APPEND (updqueue, updrec, r_link);
+
+
+ /*
+ * Add DHCID RR.
+ */
+ updrec = minires_mkupdrec (S_UPDATE,
+ (const char *)ddns_fwd_name -> data,
+ C_IN, T_DHCID, ttl);
+ if (!updrec) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+
+ updrec -> r_data = ddns_dhcid -> data;
+ updrec -> r_size = ddns_dhcid -> len;
+ updrec -> r_opcode = ADD;
+
+ ISC_LIST_APPEND (updqueue, updrec, r_link);
+
+
+ /*
+ * Attempt to perform the update.
+ */
+ result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
+
+ print_dns_status ((int)result, &updqueue);
+
+ while (!ISC_LIST_EMPTY (updqueue)) {
+ updrec = ISC_LIST_HEAD (updqueue);
+ ISC_LIST_UNLINK (updqueue, updrec, r_link);
+ minires_freeupdrec (updrec);
+ }
+
+
+ /*
+ * If this update operation succeeds, the updater can conclude that it
+ * has added a new name whose only RRs are the A and DHCID RR records.
+ * The A RR update is now complete (and a client updater is finished,
+ * while a server might proceed to perform a PTR RR update).
+ * -- "Interaction between DHCP and DNS"
+ */
+
+ if (result == ISC_R_SUCCESS)
+ return result;
+
+
+ /*
+ * If the first update operation fails with YXDOMAIN, the updater can
+ * conclude that the intended name is in use. The updater then
+ * attempts to confirm that the DNS name is not being used by some
+ * other host. The updater prepares a second UPDATE query in which the
+ * prerequisite is that the desired name has attached to it a DHCID RR
+ * whose contents match the client identity. The update section of
+ * this query deletes the existing A records on the name, and adds the
+ * A record that matches the DHCP binding and the DHCID RR with the
+ * client identity.
+ * -- "Interaction between DHCP and DNS"
+ */
+
+ if (result != (rrsetp ? ISC_R_YXRRSET : ISC_R_YXDOMAIN))
+ return result;
+
+
+ /*
+ * DHCID RR exists, and matches client identity.
+ */
+ updrec = minires_mkupdrec (S_PREREQ,
+ (const char *)ddns_fwd_name -> data,
+ C_IN, T_DHCID, 0);
+ if (!updrec) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+
+ updrec -> r_data = ddns_dhcid -> data;
+ updrec -> r_size = ddns_dhcid -> len;
+ updrec -> r_opcode = YXRRSET;
+
+ ISC_LIST_APPEND (updqueue, updrec, r_link);
+
+
+ /*
+ * Delete A RRset.
+ */
+ updrec = minires_mkupdrec (S_UPDATE,
+ (const char *)ddns_fwd_name -> data,
+ C_IN, T_A, 0);
+ if (!updrec) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+
+ updrec -> r_data = (unsigned char *)0;
+ updrec -> r_size = 0;
+ updrec -> r_opcode = DELETE;
+
+ ISC_LIST_APPEND (updqueue, updrec, r_link);
+
+
+ /*
+ * Add A RR.
+ */
+ updrec = minires_mkupdrec (S_UPDATE,
+ (const char *)ddns_fwd_name -> data,
+ C_IN, T_A, ttl);
+ if (!updrec) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+
+ updrec -> r_data = (unsigned char *)ddns_address;
+ updrec -> r_size = strlen (ddns_address);
+ updrec -> r_opcode = ADD;
+
+ ISC_LIST_APPEND (updqueue, updrec, r_link);
+
+
+ /*
+ * Attempt to perform the update.
+ */
+ result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
+
+ print_dns_status ((int)result, &updqueue);
+
+ /*
+ * If this query succeeds, the updater can conclude that the current
+ * client was the last client associated with the domain name, and that
+ * the name now contains the updated A RR. The A RR update is now
+ * complete (and a client updater is finished, while a server would
+ * then proceed to perform a PTR RR update).
+ * -- "Interaction between DHCP and DNS"
+ */
+
+ /*
+ * If the second query fails with NXRRSET, the updater must conclude
+ * that the client's desired name is in use by another host. At this
+ * juncture, the updater can decide (based on some administrative
+ * configuration outside of the scope of this document) whether to let
+ * the existing owner of the name keep that name, and to (possibly)
+ * perform some name disambiguation operation on behalf of the current
+ * client, or to replace the RRs on the name with RRs that represent
+ * the current client. If the configured policy allows replacement of
+ * existing records, the updater submits a query that deletes the
+ * existing A RR and the existing DHCID RR, adding A and DHCID RRs that
+ * represent the IP address and client-identity of the new client.
+ * -- "Interaction between DHCP and DNS"
+ */
+
+ error:
+ while (!ISC_LIST_EMPTY (updqueue)) {
+ updrec = ISC_LIST_HEAD (updqueue);
+ ISC_LIST_UNLINK (updqueue, updrec, r_link);
+ minires_freeupdrec (updrec);
+ }
+
+ return result;
+}
+
+isc_result_t ddns_remove_a (struct data_string *ddns_fwd_name,
+ struct iaddr ddns_addr,
+ struct data_string *ddns_dhcid)
+{
+ ns_updque updqueue;
+ ns_updrec *updrec;
+ isc_result_t result = SERVFAIL;
+ char ddns_address [16];
+
+ if (ddns_addr.len != 4)
+ return ISC_R_INVALIDARG;
+
+#ifndef NO_SNPRINTF
+ snprintf (ddns_address, 16, "%d.%d.%d.%d",
+ ddns_addr.iabuf[0], ddns_addr.iabuf[1],
+ ddns_addr.iabuf[2], ddns_addr.iabuf[3]);
+#else
+ sprintf (ddns_address, "%d.%d.%d.%d",
+ ddns_addr.iabuf[0], ddns_addr.iabuf[1],
+ ddns_addr.iabuf[2], ddns_addr.iabuf[3]);
+#endif
+
+
+ /*
+ * The entity chosen to handle the A record for this client (either the
+ * client or the server) SHOULD delete the A record that was added when
+ * the lease was made to the client.
+ *
+ * In order to perform this delete, the updater prepares an UPDATE
+ * query which contains two prerequisites. The first prerequisite
+ * asserts that the DHCID RR exists whose data is the client identity
+ * described in Section 4.3. The second prerequisite asserts that the
+ * data in the A RR contains the IP address of the lease that has
+ * expired or been released.
+ * -- "Interaction between DHCP and DNS"
+ */
+
+ ISC_LIST_INIT (updqueue);
+
+ /*
+ * DHCID RR exists, and matches client identity.
+ */
+ updrec = minires_mkupdrec (S_PREREQ,
+ (const char *)ddns_fwd_name -> data,
+ C_IN, T_DHCID,0);
+ if (!updrec) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+
+ updrec -> r_data = ddns_dhcid -> data;
+ updrec -> r_size = ddns_dhcid -> len;
+ updrec -> r_opcode = YXRRSET;
+
+ ISC_LIST_APPEND (updqueue, updrec, r_link);
+
+
+ /*
+ * A RR matches the expiring lease.
+ */
+ updrec = minires_mkupdrec (S_PREREQ,
+ (const char *)ddns_fwd_name -> data,
+ C_IN, T_A, 0);
+ if (!updrec) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+
+ updrec -> r_data = (unsigned char *)ddns_address;
+ updrec -> r_size = strlen (ddns_address);
+ updrec -> r_opcode = YXRRSET;
+
+ ISC_LIST_APPEND (updqueue, updrec, r_link);
+
+
+ /*
+ * Delete appropriate A RR.
+ */
+ updrec = minires_mkupdrec (S_UPDATE,
+ (const char *)ddns_fwd_name -> data,
+ C_IN, T_A, 0);
+ if (!updrec) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+
+ updrec -> r_data = (unsigned char *)ddns_address;
+ updrec -> r_size = strlen (ddns_address);
+ updrec -> r_opcode = DELETE;
+
+ ISC_LIST_APPEND (updqueue, updrec, r_link);
+
+ /*
+ * Attempt to perform the update.
+ */
+ result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
+ print_dns_status ((int)result, &updqueue);
+
+ /*
+ * If the query fails, the updater MUST NOT delete the DNS name. It
+ * may be that the host whose lease on the server has expired has moved
+ * to another network and obtained a lease from a different server,
+ * which has caused the client's A RR to be replaced. It may also be
+ * that some other client has been configured with a name that matches
+ * the name of the DHCP client, and the policy was that the last client
+ * to specify the name would get the name. In this case, the DHCID RR
+ * will no longer match the updater's notion of the client-identity of
+ * the host pointed to by the DNS name.
+ * -- "Interaction between DHCP and DNS"
+ */
+
+ if (result != ISC_R_SUCCESS)
+ goto error;
+
+ while (!ISC_LIST_EMPTY (updqueue)) {
+ updrec = ISC_LIST_HEAD (updqueue);
+ ISC_LIST_UNLINK (updqueue, updrec, r_link);
+ minires_freeupdrec (updrec);
+ }
+
+ /* If the deletion of the A succeeded, and there are no A records
+ left for this domain, then we can blow away the DHCID record
+ as well. We can't blow away the DHCID record above because
+ it's possible that more than one A has been added to this
+ domain name. */
+ ISC_LIST_INIT (updqueue);
+
+ /*
+ * A RR does not exist.
+ */
+ updrec = minires_mkupdrec (S_PREREQ,
+ (const char *)ddns_fwd_name -> data,
+ C_IN, T_A, 0);
+ if (!updrec) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+
+ updrec -> r_data = (unsigned char *)0;
+ updrec -> r_size = 0;
+ updrec -> r_opcode = NXRRSET;
+
+ ISC_LIST_APPEND (updqueue, updrec, r_link);
+
+ /*
+ * Delete appropriate DHCID RR.
+ */
+ updrec = minires_mkupdrec (S_UPDATE,
+ (const char *)ddns_fwd_name -> data,
+ C_IN, T_DHCID, 0);
+ if (!updrec) {
+ result = ISC_R_NOMEMORY;
+ goto error;
+ }
+
+ updrec -> r_data = ddns_dhcid -> data;
+ updrec -> r_size = ddns_dhcid -> len;
+ updrec -> r_opcode = DELETE;
+
+ ISC_LIST_APPEND (updqueue, updrec, r_link);
+
+ /*
+ * Attempt to perform the update.
+ */
+ result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
+ print_dns_status ((int)result, &updqueue);
+
+ /* Fall through. */
+ error:
+
+ while (!ISC_LIST_EMPTY (updqueue)) {
+ updrec = ISC_LIST_HEAD (updqueue);
+ ISC_LIST_UNLINK (updqueue, updrec, r_link);
+ minires_freeupdrec (updrec);
+ }
+
+ return result;
+}
+
+
#endif /* NSUPDATE */
HASH_FUNCTIONS (dns_zone, const char *, struct dns_zone)
diff --git a/common/ethernet.c b/common/ethernet.c
index 772392e9..0c51df35 100644
--- a/common/ethernet.c
+++ b/common/ethernet.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: ethernet.c,v 1.6 2000/03/24 00:22:20 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: ethernet.c,v 1.7 2001/06/27 00:29:47 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -61,7 +61,7 @@ void assemble_ethernet_header (interface, buf, bufix, to)
unsigned *bufix;
struct hardware *to;
{
- struct ether_header eh;
+ struct isc_ether_header eh;
if (to && to -> hlen == 7) /* XXX */
memcpy (eh.ether_dhost, &to -> hbuf [1],
@@ -90,7 +90,7 @@ ssize_t decode_ethernet_header (interface, buf, bufix, from)
unsigned bufix;
struct hardware *from;
{
- struct ether_header eh;
+ struct isc_ether_header eh;
memcpy (&eh, buf + bufix, ETHER_HEADER_SIZE);
diff --git a/common/execute.c b/common/execute.c
index e7b8ca7c..aeaac1b9 100644
--- a/common/execute.c
+++ b/common/execute.c
@@ -3,7 +3,7 @@
Support for executable statements. */
/*
- * Copyright (c) 1998-2000 Internet Software Consortium.
+ * Copyright (c) 1998-2001 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: execute.c,v 1.44 2001/01/16 22:56:56 mellon Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: execute.c,v 1.45 2001/06/27 00:29:48 mellon Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -182,7 +182,7 @@ int execute_statements (result, packet, lease, client_state,
if (!execute_statements
(result, packet, lease, client_state,
in_options, out_options, scope,
- rc ? r -> data.ie.true : r -> data.ie.false))
+ rc ? r -> data.ie.tc : r -> data.ie.fc))
return 0;
break;
@@ -190,7 +190,7 @@ int execute_statements (result, packet, lease, client_state,
status = evaluate_expression
((struct binding_value **)0,
packet, lease, client_state, in_options,
- out_options, scope, r -> data.eval);
+ out_options, scope, r -> data.eval, MDL);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("exec: evaluate: %s",
(status ? "succeeded" : "failed"));
@@ -201,7 +201,7 @@ int execute_statements (result, packet, lease, client_state,
status = evaluate_expression
(result, packet,
lease, client_state, in_options,
- out_options, scope, r -> data.retval);
+ out_options, scope, r -> data.retval, MDL);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("exec: return: %s",
(status ? "succeeded" : "failed"));
@@ -307,7 +307,8 @@ int execute_statements (result, packet, lease, client_state,
(&binding -> value, packet,
lease, client_state,
in_options, out_options,
- scope, r -> data.set.expr));
+ scope, r -> data.set.expr,
+ MDL));
} else {
if (!(binding_value_allocate
(&binding -> value, MDL))) {
@@ -384,7 +385,7 @@ int execute_statements (result, packet, lease, client_state,
(&binding -> value, packet, lease,
client_state,
in_options, out_options,
- scope, e -> data.set.expr));
+ scope, e -> data.set.expr, MDL));
binding -> next = ns -> bindings;
ns -> bindings = binding;
}
@@ -417,7 +418,8 @@ int execute_statements (result, packet, lease, client_state,
status = (evaluate_data_expression
(&ds, packet,
lease, client_state, in_options,
- out_options, scope, r -> data.log.expr));
+ out_options, scope, r -> data.log.expr,
+ MDL));
#if defined (DEBUG_EXPRESSIONS)
log_debug ("exec: log");
@@ -543,7 +545,7 @@ int executable_statement_dereference (ptr, file, line)
}
(*ptr) -> refcnt--;
- rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt);
+ rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1);
if ((*ptr) -> refcnt > 0) {
*ptr = (struct executable_statement *)0;
return 1;
@@ -552,7 +554,7 @@ int executable_statement_dereference (ptr, file, line)
if ((*ptr) -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (*ptr);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -596,12 +598,12 @@ int executable_statement_dereference (ptr, file, line)
if ((*ptr) -> data.ie.expr)
expression_dereference (&(*ptr) -> data.ie.expr,
file, line);
- if ((*ptr) -> data.ie.true)
+ if ((*ptr) -> data.ie.tc)
executable_statement_dereference
- (&(*ptr) -> data.ie.true, file, line);
- if ((*ptr) -> data.ie.false)
+ (&(*ptr) -> data.ie.tc, file, line);
+ if ((*ptr) -> data.ie.fc)
executable_statement_dereference
- (&(*ptr) -> data.ie.false, file, line);
+ (&(*ptr) -> data.ie.fc, file, line);
break;
case eval_statement:
@@ -737,23 +739,23 @@ void write_statements (file, statements, indent)
indent + 3, indent + 3, 1);
else_if:
token_print_indent (file, col, indent, " ", "", "{");
- write_statements (file, x -> data.ie.true, indent + 2);
- if (x -> data.ie.false &&
- x -> data.ie.false -> op == if_statement &&
- !x -> data.ie.false -> next) {
+ write_statements (file, x -> data.ie.tc, indent + 2);
+ if (x -> data.ie.fc &&
+ x -> data.ie.fc -> op == if_statement &&
+ !x -> data.ie.fc -> next) {
indent_spaces (file, indent);
fprintf (file, "} elsif ");
- x = x -> data.ie.false;
+ x = x -> data.ie.fc;
col = write_expression (file,
x -> data.ie.expr,
indent + 6,
indent + 6, 1);
goto else_if;
}
- if (x -> data.ie.false) {
+ if (x -> data.ie.fc) {
indent_spaces (file, indent);
fprintf (file, "} else {");
- write_statements (file, x -> data.ie.false,
+ write_statements (file, x -> data.ie.fc,
indent + 2);
}
indent_spaces (file, indent);
@@ -921,14 +923,15 @@ int find_matching_case (struct executable_statement **ep,
status = (evaluate_data_expression (&ds, packet, lease,
client_state, in_options,
- out_options, scope, expr));
+ out_options, scope, expr,
+ MDL));
if (status) {
for (s = stmt; s; s = s -> next) {
if (s -> op == case_statement) {
sub = (evaluate_data_expression
(&cd, packet, lease, client_state,
in_options, out_options,
- scope, s -> data.c_case));
+ scope, s -> data.c_case, MDL));
if (sub && cd.len == ds.len &&
!memcmp (cd.data, ds.data, cd.len))
{
@@ -978,3 +981,81 @@ int find_matching_case (struct executable_statement **ep,
}
return 0;
}
+
+int executable_statement_foreach (struct executable_statement *stmt,
+ int (*callback) (struct
+ executable_statement *,
+ void *, int),
+ void *vp, int condp)
+{
+ struct executable_statement *foo;
+ int ok = 0;
+ int result;
+
+ for (foo = stmt; foo; foo = foo -> next) {
+ if ((*callback) (foo, vp, condp) != 0)
+ ok = 1;
+ switch (foo -> op) {
+ case null_statement:
+ break;
+ case if_statement:
+ if (executable_statement_foreach (stmt -> data.ie.tc,
+ callback, vp, 1))
+ ok = 1;
+ if (executable_statement_foreach (stmt -> data.ie.fc,
+ callback, vp, 1))
+ ok = 1;
+ break;
+ case add_statement:
+ break;
+ case eval_statement:
+ break;
+ case break_statement:
+ break;
+ case default_option_statement:
+ break;
+ case supersede_option_statement:
+ break;
+ case append_option_statement:
+ break;
+ case prepend_option_statement:
+ break;
+ case send_option_statement:
+ break;
+ case statements_statement:
+ if ((executable_statement_foreach
+ (stmt -> data.statements, callback, vp, condp)))
+ ok = 1;
+ break;
+ case on_statement:
+ if ((executable_statement_foreach
+ (stmt -> data.on.statements, callback, vp, 1)))
+ ok = 1;
+ break;
+ case switch_statement:
+ if ((executable_statement_foreach
+ (stmt -> data.s_switch.statements, callback, vp, 1)))
+ ok = 1;
+ break;
+ case case_statement:
+ break;
+ case default_statement:
+ break;
+ case set_statement:
+ break;
+ case unset_statement:
+ break;
+ case let_statement:
+ if ((executable_statement_foreach
+ (stmt -> data.let.statements, callback, vp, 0)))
+ ok = 1;
+ break;
+ case define_statement:
+ break;
+ case log_statement:
+ case return_statement:
+ break;
+ }
+ }
+ return ok;
+}
diff --git a/common/icmp.c b/common/icmp.c
index aa8463c4..ed208d5d 100644
--- a/common/icmp.c
+++ b/common/icmp.c
@@ -44,23 +44,19 @@
#ifndef lint
static char copyright[] =
-"$Id: icmp.c,v 1.30 2001/04/23 21:41:36 mellon Exp $ Copyright (c) 1996-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: icmp.c,v 1.31 2001/06/27 00:29:49 mellon Exp $ Copyright (c) 1996-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include "netinet/ip.h"
#include "netinet/ip_icmp.h"
-struct icmp_state {
- OMAPI_OBJECT_PREAMBLE;
- int socket;
- void (*icmp_handler) PROTO ((struct iaddr, u_int8_t *, int));
-};
-
-static struct icmp_state *icmp_state;
+struct icmp_state *icmp_state;
static omapi_object_type_t *dhcp_type_icmp;
static int no_icmp;
+OMAPI_OBJECT_ALLOC (icmp_state, struct icmp_state, dhcp_type_icmp)
+
#if defined (TRACING)
trace_type_t *trace_icmp_input;
trace_type_t *trace_icmp_output;
@@ -93,13 +89,8 @@ void icmp_startup (routep, handler)
log_fatal ("Can't register icmp object type: %s",
isc_result_totext (result));
- new = (struct icmp_state *)dmalloc (sizeof *new, MDL);
- if (!new)
- log_fatal ("Unable to allocate state for icmp protocol");
- memset (new, 0, sizeof *new);
- new -> refcnt = 1;
- new -> type = dhcp_type_icmp;
- new -> icmp_handler = handler;
+ icmp_state_allocate (&icmp_state, MDL);
+ icmp_state -> icmp_handler = handler;
#if defined (TRACING)
trace_icmp_input = trace_type_register ("icmp-input", (void *)0,
@@ -119,34 +110,33 @@ void icmp_startup (routep, handler)
protocol = proto -> p_proto;
/* Get a raw socket for the ICMP protocol. */
- new -> socket = socket (AF_INET, SOCK_RAW, protocol);
- if (new -> socket < 0) {
+ icmp_state -> socket = socket (AF_INET, SOCK_RAW, protocol);
+ if (icmp_state -> socket < 0) {
no_icmp = 1;
log_error ("unable to create icmp socket: %m");
return;
}
#if defined (HAVE_SETFD)
- if (fcntl (new -> socket, F_SETFD, 1) < 0)
+ if (fcntl (icmp_state -> socket, F_SETFD, 1) < 0)
log_error ("Can't set close-on-exec on icmp: %m");
#endif
/* Make sure it does routing... */
state = 0;
- if (setsockopt (new -> socket, SOL_SOCKET, SO_DONTROUTE,
+ if (setsockopt (icmp_state -> socket, SOL_SOCKET, SO_DONTROUTE,
(char *)&state, sizeof state) < 0)
log_fatal ("Can't disable SO_DONTROUTE on ICMP: %m");
- result = omapi_register_io_object ((omapi_object_t *)new,
- icmp_readsocket, 0,
- icmp_echoreply, 0, 0);
+ result = (omapi_register_io_object
+ ((omapi_object_t *)icmp_state,
+ icmp_readsocket, 0, icmp_echoreply, 0, 0));
if (result != ISC_R_SUCCESS)
log_fatal ("Can't register icmp handle: %s",
isc_result_totext (result));
#if defined (TRACING)
}
#endif
- icmp_state = new;
}
int icmp_readsocket (h)
@@ -316,17 +306,18 @@ void trace_icmp_input_stop (trace_type_t *ttype) { }
void trace_icmp_output_input (trace_type_t *ttype, unsigned length, char *buf)
{
struct icmp *icmp;
- struct iaddr *ia;
+ struct iaddr ia;
- if (length != (sizeof (*icmp) + (sizeof *ia))) {
+ if (length != (sizeof (*icmp) + (sizeof ia))) {
log_error ("trace_icmp_output_input: data size mismatch %d:%d",
- length, (int)((sizeof (*icmp)) + (sizeof *ia)));
+ length, (int)((sizeof (*icmp)) + (sizeof ia)));
return;
}
- ia = (struct iaddr *)buf;
- icmp = (struct icmp *)(ia + 1);
+ ia.len = 4;
+ memcpy (ia.iabuf, buf, 4);
+ icmp = (struct icmp *)(buf + 1);
- log_error ("trace_icmp_output_input: unsent ping to %s", piaddr (*ia));
+ log_error ("trace_icmp_output_input: unsent ping to %s", piaddr (ia));
}
void trace_icmp_output_stop (trace_type_t *ttype) { }
diff --git a/common/inet.c b/common/inet.c
index c021a905..f03e1893 100644
--- a/common/inet.c
+++ b/common/inet.c
@@ -4,7 +4,7 @@
way... */
/*
- * Copyright (c) 1995-1999 Internet Software Consortium.
+ * Copyright (c) 1995-2001 Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,7 @@
#ifndef lint
static char copyright[] =
-"$Id: inet.c,v 1.8 2000/03/17 03:59:01 mellon Exp $ Copyright (c) 1995-1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: inet.c,v 1.9 2001/06/27 00:29:51 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -183,3 +183,60 @@ char *piaddr (addr)
}
return pbuf;
}
+
+char *piaddr1 (addr)
+ struct iaddr addr;
+{
+ static char pbuf [4 * 16];
+ char *s = pbuf;
+ int i;
+
+ if (addr.len == 0) {
+ strcpy (s, "<null address>");
+ }
+ for (i = 0; i < addr.len; i++) {
+ sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]);
+ s += strlen (s);
+ }
+ return pbuf;
+}
+
+char *piaddrmask (struct iaddr addr, struct iaddr mask,
+ const char *file, int line)
+{
+ char *s, *t;
+ int i, mw;
+ unsigned len;
+
+ for (i = 0; i < 32; i++) {
+ if (!mask.iabuf [3 - i / 8])
+ i += 7;
+ else if (mask.iabuf [3 - i / 8] & (1 << (i % 8)))
+ break;
+ }
+ mw = 32 - i;
+ len = mw > 9 ? 2 : 1;
+ len += 4; /* three dots and a slash. */
+ for (i = 0; i < (mw / 8) + 1; i++) {
+ if (addr.iabuf [i] > 99)
+ len += 3;
+ else if (addr.iabuf [i] > 9)
+ len += 2;
+ else
+ len++;
+ }
+ s = dmalloc (len + 1, file, line);
+ if (!s)
+ return s;
+ t = s;
+ sprintf (t, "%d", addr.iabuf [0]);
+ t += strlen (t);
+ for (i = 1; i < (mw / 8) + 1; i++) {
+ sprintf (t, ".%d", addr.iabuf [i]);
+ t += strlen (t);
+ }
+ *t++ = '/';
+ sprintf (t, "%d", mw);
+ return s;
+}
+
diff --git a/common/memory.c b/common/memory.c
index ad78a9cd..1e709da5 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: memory.c,v 1.66 2000/05/16 23:02:23 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: memory.c,v 1.67 2001/06/27 00:29:52 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -131,7 +131,7 @@ isc_result_t supersede_group (struct group_object *group, int writep)
group_name_hash = new_hash ((hash_reference)
group_object_reference,
(hash_dereference)
- group_object_dereference, 0);
+ group_object_dereference, 0, MDL);
t = (struct group_object *)0;
}
@@ -165,13 +165,9 @@ int clone_group (struct group **gp, struct group *group,
return 0;
if (group == *gp)
*gp = (struct group *)0;
- group_reference (gp, g, MDL);
+ group_reference (gp, g, file, line);
g -> authoritative = group -> authoritative;
- if (group -> shared_network) {
- shared_network_reference (&g -> shared_network,
- group -> shared_network, MDL);
- }
- group_reference (&g -> next, group, MDL);
- group_dereference (&g, MDL);
+ group_reference (&g -> next, group, file, line);
+ group_dereference (&g, file, line);
return 1;
}
diff --git a/common/options.c b/common/options.c
index 56f3674b..25c62422 100644
--- a/common/options.c
+++ b/common/options.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: options.c,v 1.85 2001/03/01 21:44:31 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: options.c,v 1.86 2001/06/27 00:29:54 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#define DHCP_OPTION_DATA
@@ -933,6 +933,8 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
{
static char optbuf [32768]; /* XXX */
int hunksize = 0;
+ int opthunk = 0;
+ int hunkinc = 0;
int numhunk = -1;
int numelem = 0;
char fmtbuf [32];
@@ -942,6 +944,7 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
const unsigned char *dp = data;
struct in_addr foo;
char comma;
+ unsigned long tval;
if (emit_commas)
comma = ',';
@@ -996,6 +999,7 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
}
fmtbuf [l + 1] = 0;
break;
+ case 'd':
case 't':
fmtbuf [l] = 't';
fmtbuf [l + 1] = 0;
@@ -1006,26 +1010,35 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
while (option -> format [i] &&
option -> format [i] != '.')
i++;
- enumbuf [l] = find_enumeration (&option -> format [k],
- i - k);
+ enumbuf [l] =
+ find_enumeration (&option -> format [k] + 1,
+ i - k - 1);
hunksize += 1;
+ hunkinc = 1;
break;
case 'I':
case 'l':
case 'L':
+ case 'T':
hunksize += 4;
+ hunkinc = 4;
break;
case 's':
case 'S':
hunksize += 2;
+ hunkinc = 2;
break;
case 'b':
case 'B':
case 'f':
hunksize++;
+ hunkinc = 1;
break;
case 'e':
break;
+ case 'o':
+ opthunk += hunkinc;
+ break;
default:
log_error ("%s: garbage in format string: %s",
option -> name,
@@ -1035,7 +1048,7 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
}
/* Check for too few bytes... */
- if (hunksize > len) {
+ if (hunksize - opthunk > len) {
log_error ("%s: expecting at least %d bytes; got %d",
option -> name,
hunksize, len);
@@ -1115,6 +1128,13 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
sprintf (op, "%ld", (long)getLong (dp));
dp += 4;
break;
+ case 'T':
+ tval = getULong (dp);
+ if (tval == -1)
+ sprintf (op, "%s", "infinite");
+ else
+ sprintf (op, "%ld", tval);
+ break;
case 'L':
sprintf (op, "%ld",
(unsigned long)getULong (dp));
@@ -1146,19 +1166,22 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
fmtbuf [j]);
}
op += strlen (op);
+ if (dp == data + len)
+ break;
if (j + 1 < numelem && comma != ':')
*op++ = ' ';
}
if (i + 1 < numhunk) {
*op++ = comma;
}
-
+ if (dp == data + len)
+ break;
}
return optbuf;
}
int get_option (result, universe, packet, lease, client_state,
- in_options, cfg_options, options, scope, code)
+ in_options, cfg_options, options, scope, code, file, line)
struct data_string *result;
struct universe *universe;
struct packet *packet;
@@ -1169,6 +1192,8 @@ int get_option (result, universe, packet, lease, client_state,
struct option_state *options;
struct binding_scope **scope;
unsigned code;
+ const char *file;
+ int line;
{
struct option_cache *oc;
@@ -1178,7 +1203,8 @@ int get_option (result, universe, packet, lease, client_state,
if (!oc)
return 0;
if (!evaluate_option_cache (result, packet, lease, client_state,
- in_options, cfg_options, scope, oc, MDL))
+ in_options, cfg_options, scope, oc,
+ file, line))
return 0;
return 1;
}
@@ -1490,7 +1516,7 @@ int option_cache_dereference (ptr, file, line)
}
(*ptr) -> refcnt--;
- rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt);
+ rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1);
if (!(*ptr) -> refcnt) {
if ((*ptr) -> data.buffer)
data_string_forget (&(*ptr) -> data, file, line);
@@ -1508,7 +1534,7 @@ int option_cache_dereference (ptr, file, line)
if ((*ptr) -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (*ptr);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -2174,11 +2200,11 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
dmalloc_outstanding - previous_outstanding,
dmalloc_outstanding, dmalloc_longterm);
#endif
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE)
dmalloc_dump_outstanding ();
#endif
#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
- dump_rc_history ();
+ dump_rc_history (0);
#endif
}
diff --git a/common/packet.c b/common/packet.c
index cafe26e3..50e0bf43 100644
--- a/common/packet.c
+++ b/common/packet.c
@@ -3,7 +3,7 @@
Packet assembly code, originally contributed by Archie Cobbs. */
/*
- * Copyright (c) 1996-1999 Internet Software Consortium.
+ * Copyright (c) 1996-2001 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.40 2001/02/26 22:21:10 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: packet.c,v 1.41 2001/06/27 00:29:55 mellon Exp $ Copyright (c) 1996-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -239,6 +239,7 @@ ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, buflen)
static int udp_packets_length_overflow;
unsigned len;
unsigned ulen;
+ int ignore = 0;
ip = (struct ip *)(buf + bufix);
udp = (struct udphdr *)(buf + bufix + ip_len);
@@ -274,9 +275,13 @@ ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, buflen)
}
/* Check the IP packet length. */
- if (ntohs (ip -> ip_len) != buflen)
- log_debug ("ip length %d disagrees with bytes received %d.",
- ntohs (ip -> ip_len), buflen);
+ if (ntohs (ip -> ip_len) != buflen) {
+ if ((ntohs (ip -> ip_len + 2) & ~1) == buflen)
+ ignore = 1;
+ else
+ log_debug ("ip length %d disagrees with bytes received %d.",
+ ntohs (ip -> ip_len), buflen);
+ }
/* Copy out the IP source address... */
memcpy (&from -> sin_addr, &ip -> ip_src, 4);
@@ -302,7 +307,8 @@ ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, buflen)
}
return -1;
}
- if (len + data < buf + bufix + buflen)
+ if (len + data < buf + bufix + buflen &&
+ len + data != buf + bufix + buflen && !ignore)
log_debug ("accepting packet with data after udp payload.");
if (len + data > buf + bufix + buflen) {
log_debug ("dropping packet with bogus uh_ulen %ld",
diff --git a/common/parse.c b/common/parse.c
index 9c8e5dbe..b840541b 100644
--- a/common/parse.c
+++ b/common/parse.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: parse.c,v 1.104 2001/05/02 16:59:30 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: parse.c,v 1.105 2001/06/27 00:29:56 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -295,7 +295,7 @@ int parse_ip_addr_or_hostname (expr, cfile, uniform)
} else if (token == NUMBER) {
if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
return 0;
- return make_const_data (expr, addr, len, 0, 1);
+ return make_const_data (expr, addr, len, 0, 1, MDL);
} else {
if (token != RBRACE && token != LBRACE)
token = next_token (&val, (unsigned *)0, cfile);
@@ -975,7 +975,7 @@ void parse_option_space_decl (cfile)
universes = ua;
}
universes [nu -> index] = nu;
- nu -> hash = new_hash (0, 0, 1);
+ nu -> hash = new_hash (0, 0, 1, MDL);
if (!nu -> hash)
log_fatal ("Can't allocate %s option hash table.", nu -> name);
universe_hash_add (universe_hash, nu -> name, 0, nu, MDL);
@@ -1152,6 +1152,9 @@ int parse_option_code_definition (cfile, option)
case IP_ADDRESS:
type = 'I';
break;
+ case DOMAIN_NAME:
+ type = 'd';
+ goto no_arrays;
case TEXT:
type = 't';
no_arrays:
@@ -1292,7 +1295,7 @@ int parse_base64 (data, cfile)
from64 [] = {64, 64, 64, 64, 64, 64, 64, 64, /* \"#$%&' */
64, 64, 64, 62, 64, 64, 64, 63, /* ()*+,-./ */
52, 53, 54, 55, 56, 57, 58, 59, /* 01234567 */
- 60, 61, 64, 64, 64, 64, 64, 64, /* 90:;<=>? */
+ 60, 61, 64, 64, 64, 64, 64, 64, /* 89:;<=>? */
64, 0, 1, 2, 3, 4, 5, 6, /* @ABCDEFG */
7, 8, 9, 10, 11, 12, 13, 14, /* HIJKLMNO */
15, 16, 17, 18, 19, 20, 21, 22, /* PQRSTUVW */
@@ -1522,6 +1525,7 @@ int parse_executable_statement (result, cfile, lose, case_context)
int i;
struct dns_zone *zone;
isc_result_t status;
+ char *s;
token = peek_token (&val, (unsigned *)0, cfile);
switch (token) {
@@ -1954,9 +1958,14 @@ int parse_executable_statement (result, cfile, lose, case_context)
}
i = strlen (zone -> name);
if (zone -> name [i - 1] != '.') {
- parse_warn (cfile,
- "zone name must not be relative %s: %s",
- "(must end in '.')", zone -> name);
+ s = dmalloc ((unsigned)i + 2, MDL);
+ if (!s)
+ goto badzone;
+ strcpy (s, zone -> name);
+ s [i] = '.';
+ s [i + 1] = 0;
+ dfree (zone -> name, MDL);
+ zone -> name = s;
}
if (!parse_zone (zone, cfile))
goto badzone;
@@ -1969,6 +1978,7 @@ int parse_executable_statement (result, cfile, lose, case_context)
dns_zone_dereference (&zone, MDL);
return 0;
}
+ dns_zone_dereference (&zone, MDL);
return 1;
/* Also not really a statement, but same idea as above. */
@@ -2287,6 +2297,7 @@ int parse_key (struct parse *cfile)
key -> name, isc_result_totext (status));
goto bad;
}
+ omapi_auth_key_dereference (&key, MDL);
return 1;
rbad:
@@ -2548,7 +2559,7 @@ int parse_if_statement (result, cfile, lose)
executable_statement_dereference (result, MDL);
return 0;
}
- if (!parse_executable_statements (&(*result) -> data.ie.true,
+ if (!parse_executable_statements (&(*result) -> data.ie.tc,
cfile, lose, context_any)) {
if (*lose) {
/* Try to even things up. */
@@ -2574,7 +2585,7 @@ int parse_if_statement (result, cfile, lose)
token = peek_token (&val, (unsigned *)0, cfile);
if (token == IF) {
token = next_token (&val, (unsigned *)0, cfile);
- if (!parse_if_statement (&(*result) -> data.ie.false,
+ if (!parse_if_statement (&(*result) -> data.ie.fc,
cfile, lose)) {
if (!*lose)
parse_warn (cfile,
@@ -2592,7 +2603,7 @@ int parse_if_statement (result, cfile, lose)
} else {
token = next_token (&val, (unsigned *)0, cfile);
if (!(parse_executable_statements
- (&(*result) -> data.ie.false,
+ (&(*result) -> data.ie.fc,
cfile, lose, context_any))) {
executable_statement_dereference (result, MDL);
return 0;
@@ -2608,7 +2619,7 @@ int parse_if_statement (result, cfile, lose)
}
} else if (token == ELSIF) {
token = next_token (&val, (unsigned *)0, cfile);
- if (!parse_if_statement (&(*result) -> data.ie.false,
+ if (!parse_if_statement (&(*result) -> data.ie.fc,
cfile, lose)) {
if (!*lose)
parse_warn (cfile,
@@ -2618,7 +2629,7 @@ int parse_if_statement (result, cfile, lose)
return 0;
}
} else
- (*result) -> data.ie.false = (struct executable_statement *)0;
+ (*result) -> data.ie.fc = (struct executable_statement *)0;
return 1;
}
@@ -3008,6 +3019,7 @@ int parse_non_binary (expr, cfile, lose, context)
*expr, MDL);
expression_dereference (expr, MDL);
expression_reference (expr, nexp, MDL);
+ expression_dereference (&nexp, MDL);
goto concat_another;
}
@@ -3096,23 +3108,28 @@ int parse_non_binary (expr, cfile, lose, context)
if (token != LPAREN)
goto nolparen;
- nexp = *expr;
+ nexp = (struct expression *)0;
+ expression_reference (&nexp, *expr, MDL);
do {
- nexp -> op = expr_pick_first_value;
- if (!(parse_data_expression
- (&nexp -> data.pick_first_value.car,
- cfile, lose)))
- goto nodata;
+ nexp -> op = expr_pick_first_value;
+ if (!(parse_data_expression
+ (&nexp -> data.pick_first_value.car,
+ cfile, lose)))
+ goto nodata;
- token = next_token (&val, (unsigned *)0, cfile);
- if (token == COMMA) {
- if (!(expression_allocate
- (&nexp -> data.pick_first_value.cdr,
- MDL)))
- log_fatal ("can't allocate expr");
- nexp = nexp -> data.pick_first_value.cdr;
- }
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token == COMMA) {
+ struct expression *foo = (struct expression *)0;
+ if (!expression_allocate (&foo, MDL))
+ log_fatal ("can't allocate expr");
+ expression_reference
+ (&nexp -> data.pick_first_value.cdr, foo, MDL);
+ expression_dereference (&nexp, MDL);
+ expression_reference (&nexp, foo, MDL);
+ expression_dereference (&foo, MDL);
+ }
} while (token == COMMA);
+ expression_dereference (&nexp, MDL);
if (token != RPAREN)
goto norparen;
@@ -3533,7 +3550,7 @@ int parse_non_binary (expr, cfile, lose, context)
case STRING:
token = next_token (&val, &len, cfile);
if (!make_const_data (expr, (const unsigned char *)val,
- len, 1, 1))
+ len, 1, 1, MDL))
log_fatal ("can't make constant string expression.");
break;
@@ -4220,8 +4237,10 @@ int parse_option_statement (result, cfile, lookups, option, op)
log_fatal ("no memory for option statement.");
(*result) -> op = op;
if (expr && !option_cache (&(*result) -> data.option,
- (struct data_string *)0, expr, option))
+ (struct data_string *)0, expr, option, MDL))
log_fatal ("no memory for option cache");
+ if (expr)
+ expression_dereference (&expr, MDL);
return 1;
}
@@ -4256,7 +4275,7 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
}
token = next_token (&val, &len, cfile);
if (!make_const_data (&t, (const unsigned char *)val,
- len, 1, 1))
+ len, 1, 1, MDL))
log_fatal ("No memory for %s", val);
break;
@@ -4282,7 +4301,7 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
} else if (token == STRING) {
token = next_token (&val, &len, cfile);
if (!make_const_data (&t, (const unsigned char *)val,
- len, 1, 1))
+ len, 1, 1, MDL))
log_fatal ("No memory for \"%s\"", val);
} else {
if ((*fmt) [1] != 'o') {
@@ -4294,6 +4313,16 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
}
break;
+ case 'd': /* Domain name... */
+ val = parse_host_name (cfile);
+ if (!val) {
+ parse_warn (cfile, "not a valid domain name.");
+ skip_to_semi (cfile);
+ return 0;
+ }
+ len = strlen (val);
+ goto make_string;
+
case 't': /* Text string... */
token = peek_token (&val, (unsigned *)0, cfile);
if (token != STRING && !is_identifier (token)) {
@@ -4305,8 +4334,9 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
return 0;
}
token = next_token (&val, &len, cfile);
+ make_string:
if (!make_const_data (&t, (const unsigned char *)val,
- len, 1, 1))
+ len, 1, 1, MDL))
log_fatal ("No memory for concatenation");
break;
@@ -4332,7 +4362,7 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
parse_warn (cfile, "unknown value");
goto foo;
}
- if (!make_const_data (&t, &e -> value, 1, 0, 1))
+ if (!make_const_data (&t, &e -> value, 1, 0, 1, MDL))
return 0;
break;
@@ -4343,7 +4373,8 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
} else {
if (!parse_ip_addr (cfile, &addr))
return 0;
- if (!make_const_data (&t, addr.iabuf, addr.len, 0, 1))
+ if (!make_const_data (&t, addr.iabuf, addr.len,
+ 0, 1, MDL))
return 0;
}
break;
@@ -4354,7 +4385,7 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
goto check_number;
token = next_token (&val, (unsigned *)0, cfile);
putLong (buf, -1);
- if (!make_const_data (&t, buf, 4, 0, 1))
+ if (!make_const_data (&t, buf, 4, 0, 1, MDL))
return 0;
break;
@@ -4373,7 +4404,7 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
}
token = next_token (&val, (unsigned *)0, cfile);
convert_num (cfile, buf, val, 0, 32);
- if (!make_const_data (&t, buf, 4, 0, 1))
+ if (!make_const_data (&t, buf, 4, 0, 1, MDL))
return 0;
break;
@@ -4384,7 +4415,7 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
goto need_number;
token = next_token (&val, (unsigned *)0, cfile);
convert_num (cfile, buf, val, 0, 16);
- if (!make_const_data (&t, buf, 2, 0, 1))
+ if (!make_const_data (&t, buf, 2, 0, 1, MDL))
return 0;
break;
@@ -4395,7 +4426,7 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
goto need_number;
token = next_token (&val, (unsigned *)0, cfile);
convert_num (cfile, buf, val, 0, 8);
- if (!make_const_data (&t, buf, 1, 0, 1))
+ if (!make_const_data (&t, buf, 1, 0, 1, MDL))
return 0;
break;
@@ -4425,7 +4456,7 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
goto bad_flag;
}
token = next_token (&val, (unsigned *)0, cfile);
- if (!make_const_data (&t, buf, 1, 0, 1))
+ if (!make_const_data (&t, buf, 1, 0, 1, MDL))
return 0;
break;
@@ -4438,9 +4469,9 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
if (expr) {
if (!make_concat (rv, expr, t))
return 0;
- expression_dereference (&t, MDL);
} else
- *rv = t;
+ expression_reference (rv, t, MDL);
+ expression_dereference (&t, MDL);
return 1;
}
diff --git a/common/print.c b/common/print.c
index 20f6a24e..807a53c7 100644
--- a/common/print.c
+++ b/common/print.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: print.c,v 1.53 2001/05/04 01:05:17 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: print.c,v 1.54 2001/06/27 00:29:57 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -111,7 +111,7 @@ char *quotify_buf (const unsigned char *s, unsigned len,
if (s [i] == ' ')
*nsp++ = ' ';
else if (!isascii (s [i]) || !isprint (s [i])) {
- sprintf (nsp, "\\%3.3o", s [i]);
+ sprintf (nsp, "\\%03o", s [i]);
nsp += 4;
} else if (s [i] == '"' || s [i] == '\\') {
*nsp++ = '\\';
@@ -124,6 +124,56 @@ char *quotify_buf (const unsigned char *s, unsigned len,
return buf;
}
+char *print_base64 (const unsigned char *buf, unsigned len,
+ const char *file, int line)
+{
+ char *s, *b;
+ unsigned bl;
+ int i;
+ unsigned val, extra;
+ static char to64 [] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ bl = ((len * 4 + 2) / 3) + 1;
+ b = dmalloc (bl + 1, file, line);
+ if (!b)
+ return (char *)0;
+
+ i = 0;
+ s = b;
+ while (i != len) {
+ val = buf [i++];
+ extra = val & 3;
+ val = val >> 2;
+ *s++ = to64 [val];
+ if (i == len) {
+ *s++ = to64 [extra << 4];
+ *s++ = '=';
+ break;
+ }
+ val = (extra << 8) + buf [i++];
+ extra = val & 15;
+ val = val >> 4;
+ *s++ = to64 [val];
+ if (i == len) {
+ *s++ = to64 [extra << 2];
+ *s++ = '=';
+ break;
+ }
+ val = (extra << 8) + buf [i++];
+ extra = val & 0x3f;
+ val = val >> 6;
+ *s++ = to64 [val];
+ *s++ = to64 [extra];
+ }
+ if (!len)
+ *s++ = '=';
+ *s++ = 0;
+ if (s > b + bl + 1)
+ abort ();
+ return b;
+}
+
char *print_hw_addr (htype, hlen, data)
int htype;
int hlen;
diff --git a/common/tables.c b/common/tables.c
index 9e48eeb3..d7c7b6c8 100644
--- a/common/tables.c
+++ b/common/tables.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: tables.c,v 1.51 2001/03/14 15:39:32 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: tables.c,v 1.52 2001/06/27 00:29:58 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -93,6 +93,7 @@ HASH_FUNCTIONS (option, const char *, struct option)
the name of the set of enumeration values to parse or emit,
followed by a '.'. The width of the data is specified in the
named enumeration. Named enumerations are tracked in parse.c.
+ d - Domain name (i.e., FOO or FOO.BAR).
*/
struct universe dhcp_universe;
@@ -369,250 +370,250 @@ struct option nwip_options [256] = {
{ "autoretry-secs", "B", &nwip_universe, 9 },
{ "nwip-1-1", "f", &nwip_universe, 10 },
{ "primary-dss", "I", &nwip_universe, 11 },
- { "option-12", "X", &nwip_universe, 12 },
- { "option-13", "X", &nwip_universe, 13 },
- { "option-14", "X", &nwip_universe, 14 },
- { "option-15", "X", &nwip_universe, 15 },
- { "option-16", "X", &nwip_universe, 16 },
- { "option-17", "X", &nwip_universe, 17 },
- { "option-18", "X", &nwip_universe, 18 },
- { "option-19", "X", &nwip_universe, 19 },
- { "option-20", "X", &nwip_universe, 20 },
- { "option-21", "X", &nwip_universe, 21 },
- { "option-22", "X", &nwip_universe, 22 },
- { "option-23", "X", &nwip_universe, 23 },
- { "option-24", "X", &nwip_universe, 24 },
- { "option-25", "X", &nwip_universe, 25 },
- { "option-26", "X", &nwip_universe, 26 },
- { "option-27", "X", &nwip_universe, 27 },
- { "option-28", "X", &nwip_universe, 28 },
- { "option-29", "X", &nwip_universe, 29 },
- { "option-30", "X", &nwip_universe, 30 },
- { "option-31", "X", &nwip_universe, 31 },
- { "option-32", "X", &nwip_universe, 32 },
- { "option-33", "X", &nwip_universe, 33 },
- { "option-34", "X", &nwip_universe, 34 },
- { "option-35", "X", &nwip_universe, 35 },
- { "option-36", "X", &nwip_universe, 36 },
- { "option-37", "X", &nwip_universe, 37 },
- { "option-38", "X", &nwip_universe, 38 },
- { "option-39", "X", &nwip_universe, 39 },
- { "option-40", "X", &nwip_universe, 40 },
- { "option-41", "X", &nwip_universe, 41 },
- { "option-42", "X", &nwip_universe, 42 },
- { "option-43", "X", &nwip_universe, 43 },
- { "option-44", "X", &nwip_universe, 44 },
- { "option-45", "X", &nwip_universe, 45 },
- { "option-46", "X", &nwip_universe, 46 },
- { "option-47", "X", &nwip_universe, 47 },
- { "option-48", "X", &nwip_universe, 48 },
- { "option-49", "X", &nwip_universe, 49 },
- { "option-50", "X", &nwip_universe, 50 },
- { "option-51", "X", &nwip_universe, 51 },
- { "option-52", "X", &nwip_universe, 52 },
- { "option-53", "X", &nwip_universe, 53 },
- { "option-54", "X", &nwip_universe, 54 },
- { "option-55", "X", &nwip_universe, 55 },
- { "option-56", "X", &nwip_universe, 56 },
- { "option-57", "X", &nwip_universe, 57 },
- { "option-58", "X", &nwip_universe, 58 },
- { "option-59", "X", &nwip_universe, 59 },
- { "option-60", "X", &nwip_universe, 60 },
- { "option-61", "X", &nwip_universe, 61 },
- { "option-62", "X", &nwip_universe, 62 },
- { "option-63", "X", &nwip_universe, 63 },
- { "option-64", "X", &nwip_universe, 64 },
- { "option-65", "X", &nwip_universe, 65 },
- { "option-66", "X", &nwip_universe, 66 },
- { "option-67", "X", &nwip_universe, 67 },
- { "option-68", "X", &nwip_universe, 68 },
- { "option-69", "X", &nwip_universe, 69 },
- { "option-70", "X", &nwip_universe, 70 },
- { "option-71", "X", &nwip_universe, 71 },
- { "option-72", "X", &nwip_universe, 72 },
- { "option-73", "X", &nwip_universe, 73 },
- { "option-74", "X", &nwip_universe, 74 },
- { "option-75", "X", &nwip_universe, 75 },
- { "option-76", "X", &nwip_universe, 76 },
- { "option-77", "X", &nwip_universe, 77 },
- { "option-78", "X", &nwip_universe, 78 },
- { "option-79", "X", &nwip_universe, 79 },
- { "option-80", "X", &nwip_universe, 80 },
- { "option-81", "X", &nwip_universe, 81 },
- { "option-82", "X", &nwip_universe, 82 },
- { "option-83", "X", &nwip_universe, 83 },
- { "option-84", "X", &nwip_universe, 84 },
- { "option-85", "X", &nwip_universe, 85 },
- { "option-86", "X", &nwip_universe, 86 },
- { "option-87", "X", &nwip_universe, 87 },
- { "option-88", "X", &nwip_universe, 88 },
- { "option-89", "X", &nwip_universe, 89 },
- { "option-90", "X", &nwip_universe, 90 },
- { "option-91", "X", &nwip_universe, 91 },
- { "option-92", "X", &nwip_universe, 92 },
- { "option-93", "X", &nwip_universe, 93 },
- { "option-94", "X", &nwip_universe, 94 },
- { "option-95", "X", &nwip_universe, 95 },
- { "option-96", "X", &nwip_universe, 96 },
- { "option-97", "X", &nwip_universe, 97 },
- { "option-98", "X", &nwip_universe, 98 },
- { "option-99", "X", &nwip_universe, 99 },
- { "option-100", "X", &nwip_universe, 100 },
- { "option-101", "X", &nwip_universe, 101 },
- { "option-102", "X", &nwip_universe, 102 },
- { "option-103", "X", &nwip_universe, 103 },
- { "option-104", "X", &nwip_universe, 104 },
- { "option-105", "X", &nwip_universe, 105 },
- { "option-106", "X", &nwip_universe, 106 },
- { "option-107", "X", &nwip_universe, 107 },
- { "option-108", "X", &nwip_universe, 108 },
- { "option-109", "X", &nwip_universe, 109 },
- { "option-110", "X", &nwip_universe, 110 },
- { "option-111", "X", &nwip_universe, 111 },
- { "option-112", "X", &nwip_universe, 112 },
- { "option-113", "X", &nwip_universe, 113 },
- { "option-114", "X", &nwip_universe, 114 },
- { "option-115", "X", &nwip_universe, 115 },
- { "option-116", "X", &nwip_universe, 116 },
- { "option-117", "X", &nwip_universe, 117 },
- { "option-118", "X", &nwip_universe, 118 },
- { "option-119", "X", &nwip_universe, 119 },
- { "option-120", "X", &nwip_universe, 120 },
- { "option-121", "X", &nwip_universe, 121 },
- { "option-122", "X", &nwip_universe, 122 },
- { "option-123", "X", &nwip_universe, 123 },
- { "option-124", "X", &nwip_universe, 124 },
- { "option-125", "X", &nwip_universe, 125 },
- { "option-126", "X", &nwip_universe, 126 },
- { "option-127", "X", &nwip_universe, 127 },
- { "option-128", "X", &nwip_universe, 128 },
- { "option-129", "X", &nwip_universe, 129 },
- { "option-130", "X", &nwip_universe, 130 },
- { "option-131", "X", &nwip_universe, 131 },
- { "option-132", "X", &nwip_universe, 132 },
- { "option-133", "X", &nwip_universe, 133 },
- { "option-134", "X", &nwip_universe, 134 },
- { "option-135", "X", &nwip_universe, 135 },
- { "option-136", "X", &nwip_universe, 136 },
- { "option-137", "X", &nwip_universe, 137 },
- { "option-138", "X", &nwip_universe, 138 },
- { "option-139", "X", &nwip_universe, 139 },
- { "option-140", "X", &nwip_universe, 140 },
- { "option-141", "X", &nwip_universe, 141 },
- { "option-142", "X", &nwip_universe, 142 },
- { "option-143", "X", &nwip_universe, 143 },
- { "option-144", "X", &nwip_universe, 144 },
- { "option-145", "X", &nwip_universe, 145 },
- { "option-146", "X", &nwip_universe, 146 },
- { "option-147", "X", &nwip_universe, 147 },
- { "option-148", "X", &nwip_universe, 148 },
- { "option-149", "X", &nwip_universe, 149 },
- { "option-150", "X", &nwip_universe, 150 },
- { "option-151", "X", &nwip_universe, 151 },
- { "option-152", "X", &nwip_universe, 152 },
- { "option-153", "X", &nwip_universe, 153 },
- { "option-154", "X", &nwip_universe, 154 },
- { "option-155", "X", &nwip_universe, 155 },
- { "option-156", "X", &nwip_universe, 156 },
- { "option-157", "X", &nwip_universe, 157 },
- { "option-158", "X", &nwip_universe, 158 },
- { "option-159", "X", &nwip_universe, 159 },
- { "option-160", "X", &nwip_universe, 160 },
- { "option-161", "X", &nwip_universe, 161 },
- { "option-162", "X", &nwip_universe, 162 },
- { "option-163", "X", &nwip_universe, 163 },
- { "option-164", "X", &nwip_universe, 164 },
- { "option-165", "X", &nwip_universe, 165 },
- { "option-166", "X", &nwip_universe, 166 },
- { "option-167", "X", &nwip_universe, 167 },
- { "option-168", "X", &nwip_universe, 168 },
- { "option-169", "X", &nwip_universe, 169 },
- { "option-170", "X", &nwip_universe, 170 },
- { "option-171", "X", &nwip_universe, 171 },
- { "option-172", "X", &nwip_universe, 172 },
- { "option-173", "X", &nwip_universe, 173 },
- { "option-174", "X", &nwip_universe, 174 },
- { "option-175", "X", &nwip_universe, 175 },
- { "option-176", "X", &nwip_universe, 176 },
- { "option-177", "X", &nwip_universe, 177 },
- { "option-178", "X", &nwip_universe, 178 },
- { "option-179", "X", &nwip_universe, 179 },
- { "option-180", "X", &nwip_universe, 180 },
- { "option-181", "X", &nwip_universe, 181 },
- { "option-182", "X", &nwip_universe, 182 },
- { "option-183", "X", &nwip_universe, 183 },
- { "option-184", "X", &nwip_universe, 184 },
- { "option-185", "X", &nwip_universe, 185 },
- { "option-186", "X", &nwip_universe, 186 },
- { "option-187", "X", &nwip_universe, 187 },
- { "option-188", "X", &nwip_universe, 188 },
- { "option-189", "X", &nwip_universe, 189 },
- { "option-190", "X", &nwip_universe, 190 },
- { "option-191", "X", &nwip_universe, 191 },
- { "option-192", "X", &nwip_universe, 192 },
- { "option-193", "X", &nwip_universe, 193 },
- { "option-194", "X", &nwip_universe, 194 },
- { "option-195", "X", &nwip_universe, 195 },
- { "option-196", "X", &nwip_universe, 196 },
- { "option-197", "X", &nwip_universe, 197 },
- { "option-198", "X", &nwip_universe, 198 },
- { "option-199", "X", &nwip_universe, 199 },
- { "option-200", "X", &nwip_universe, 200 },
- { "option-201", "X", &nwip_universe, 201 },
- { "option-202", "X", &nwip_universe, 202 },
- { "option-203", "X", &nwip_universe, 203 },
- { "option-204", "X", &nwip_universe, 204 },
- { "option-205", "X", &nwip_universe, 205 },
- { "option-206", "X", &nwip_universe, 206 },
- { "option-207", "X", &nwip_universe, 207 },
- { "option-208", "X", &nwip_universe, 208 },
- { "option-209", "X", &nwip_universe, 209 },
- { "authenticate", "X", &nwip_universe, 210 },
- { "option-211", "X", &nwip_universe, 211 },
- { "option-212", "X", &nwip_universe, 212 },
- { "option-213", "X", &nwip_universe, 213 },
- { "option-214", "X", &nwip_universe, 214 },
- { "option-215", "X", &nwip_universe, 215 },
- { "option-216", "X", &nwip_universe, 216 },
- { "option-217", "X", &nwip_universe, 217 },
- { "option-218", "X", &nwip_universe, 218 },
- { "option-219", "X", &nwip_universe, 219 },
- { "option-220", "X", &nwip_universe, 220 },
- { "option-221", "X", &nwip_universe, 221 },
- { "option-222", "X", &nwip_universe, 222 },
- { "option-223", "X", &nwip_universe, 223 },
- { "option-224", "X", &nwip_universe, 224 },
- { "option-225", "X", &nwip_universe, 225 },
- { "option-226", "X", &nwip_universe, 226 },
- { "option-227", "X", &nwip_universe, 227 },
- { "option-228", "X", &nwip_universe, 228 },
- { "option-229", "X", &nwip_universe, 229 },
- { "option-230", "X", &nwip_universe, 230 },
- { "option-231", "X", &nwip_universe, 231 },
- { "option-232", "X", &nwip_universe, 232 },
- { "option-233", "X", &nwip_universe, 233 },
- { "option-234", "X", &nwip_universe, 234 },
- { "option-235", "X", &nwip_universe, 235 },
- { "option-236", "X", &nwip_universe, 236 },
- { "option-237", "X", &nwip_universe, 237 },
- { "option-238", "X", &nwip_universe, 238 },
- { "option-239", "X", &nwip_universe, 239 },
- { "option-240", "X", &nwip_universe, 240 },
- { "option-241", "X", &nwip_universe, 241 },
- { "option-242", "X", &nwip_universe, 242 },
- { "option-243", "X", &nwip_universe, 243 },
- { "option-244", "X", &nwip_universe, 244 },
- { "option-245", "X", &nwip_universe, 245 },
- { "option-246", "X", &nwip_universe, 246 },
- { "option-247", "X", &nwip_universe, 247 },
- { "option-248", "X", &nwip_universe, 248 },
- { "option-249", "X", &nwip_universe, 249 },
- { "option-250", "X", &nwip_universe, 250 },
- { "option-251", "X", &nwip_universe, 251 },
- { "option-252", "X", &nwip_universe, 252 },
- { "option-253", "X", &nwip_universe, 253 },
- { "option-254", "X", &nwip_universe, 254 },
- { "option-end", "e", &nwip_universe, 255 },
+ { "#12", "X", &nwip_universe, 12 },
+ { "#13", "X", &nwip_universe, 13 },
+ { "#14", "X", &nwip_universe, 14 },
+ { "#15", "X", &nwip_universe, 15 },
+ { "#16", "X", &nwip_universe, 16 },
+ { "#17", "X", &nwip_universe, 17 },
+ { "#18", "X", &nwip_universe, 18 },
+ { "#19", "X", &nwip_universe, 19 },
+ { "#20", "X", &nwip_universe, 20 },
+ { "#21", "X", &nwip_universe, 21 },
+ { "#22", "X", &nwip_universe, 22 },
+ { "#23", "X", &nwip_universe, 23 },
+ { "#24", "X", &nwip_universe, 24 },
+ { "#25", "X", &nwip_universe, 25 },
+ { "#26", "X", &nwip_universe, 26 },
+ { "#27", "X", &nwip_universe, 27 },
+ { "#28", "X", &nwip_universe, 28 },
+ { "#29", "X", &nwip_universe, 29 },
+ { "#30", "X", &nwip_universe, 30 },
+ { "#31", "X", &nwip_universe, 31 },
+ { "#32", "X", &nwip_universe, 32 },
+ { "#33", "X", &nwip_universe, 33 },
+ { "#34", "X", &nwip_universe, 34 },
+ { "#35", "X", &nwip_universe, 35 },
+ { "#36", "X", &nwip_universe, 36 },
+ { "#37", "X", &nwip_universe, 37 },
+ { "#38", "X", &nwip_universe, 38 },
+ { "#39", "X", &nwip_universe, 39 },
+ { "#40", "X", &nwip_universe, 40 },
+ { "#41", "X", &nwip_universe, 41 },
+ { "#42", "X", &nwip_universe, 42 },
+ { "#43", "X", &nwip_universe, 43 },
+ { "#44", "X", &nwip_universe, 44 },
+ { "#45", "X", &nwip_universe, 45 },
+ { "#46", "X", &nwip_universe, 46 },
+ { "#47", "X", &nwip_universe, 47 },
+ { "#48", "X", &nwip_universe, 48 },
+ { "#49", "X", &nwip_universe, 49 },
+ { "#50", "X", &nwip_universe, 50 },
+ { "#51", "X", &nwip_universe, 51 },
+ { "#52", "X", &nwip_universe, 52 },
+ { "#53", "X", &nwip_universe, 53 },
+ { "#54", "X", &nwip_universe, 54 },
+ { "#55", "X", &nwip_universe, 55 },
+ { "#56", "X", &nwip_universe, 56 },
+ { "#57", "X", &nwip_universe, 57 },
+ { "#58", "X", &nwip_universe, 58 },
+ { "#59", "X", &nwip_universe, 59 },
+ { "#60", "X", &nwip_universe, 60 },
+ { "#61", "X", &nwip_universe, 61 },
+ { "#62", "X", &nwip_universe, 62 },
+ { "#63", "X", &nwip_universe, 63 },
+ { "#64", "X", &nwip_universe, 64 },
+ { "#65", "X", &nwip_universe, 65 },
+ { "#66", "X", &nwip_universe, 66 },
+ { "#67", "X", &nwip_universe, 67 },
+ { "#68", "X", &nwip_universe, 68 },
+ { "#69", "X", &nwip_universe, 69 },
+ { "#70", "X", &nwip_universe, 70 },
+ { "#71", "X", &nwip_universe, 71 },
+ { "#72", "X", &nwip_universe, 72 },
+ { "#73", "X", &nwip_universe, 73 },
+ { "#74", "X", &nwip_universe, 74 },
+ { "#75", "X", &nwip_universe, 75 },
+ { "#76", "X", &nwip_universe, 76 },
+ { "#77", "X", &nwip_universe, 77 },
+ { "#78", "X", &nwip_universe, 78 },
+ { "#79", "X", &nwip_universe, 79 },
+ { "#80", "X", &nwip_universe, 80 },
+ { "#81", "X", &nwip_universe, 81 },
+ { "#82", "X", &nwip_universe, 82 },
+ { "#83", "X", &nwip_universe, 83 },
+ { "#84", "X", &nwip_universe, 84 },
+ { "#85", "X", &nwip_universe, 85 },
+ { "#86", "X", &nwip_universe, 86 },
+ { "#87", "X", &nwip_universe, 87 },
+ { "#88", "X", &nwip_universe, 88 },
+ { "#89", "X", &nwip_universe, 89 },
+ { "#90", "X", &nwip_universe, 90 },
+ { "#91", "X", &nwip_universe, 91 },
+ { "#92", "X", &nwip_universe, 92 },
+ { "#93", "X", &nwip_universe, 93 },
+ { "#94", "X", &nwip_universe, 94 },
+ { "#95", "X", &nwip_universe, 95 },
+ { "#96", "X", &nwip_universe, 96 },
+ { "#97", "X", &nwip_universe, 97 },
+ { "#98", "X", &nwip_universe, 98 },
+ { "#99", "X", &nwip_universe, 99 },
+ { "#100", "X", &nwip_universe, 100 },
+ { "#101", "X", &nwip_universe, 101 },
+ { "#102", "X", &nwip_universe, 102 },
+ { "#103", "X", &nwip_universe, 103 },
+ { "#104", "X", &nwip_universe, 104 },
+ { "#105", "X", &nwip_universe, 105 },
+ { "#106", "X", &nwip_universe, 106 },
+ { "#107", "X", &nwip_universe, 107 },
+ { "#108", "X", &nwip_universe, 108 },
+ { "#109", "X", &nwip_universe, 109 },
+ { "#110", "X", &nwip_universe, 110 },
+ { "#111", "X", &nwip_universe, 111 },
+ { "#112", "X", &nwip_universe, 112 },
+ { "#113", "X", &nwip_universe, 113 },
+ { "#114", "X", &nwip_universe, 114 },
+ { "#115", "X", &nwip_universe, 115 },
+ { "#116", "X", &nwip_universe, 116 },
+ { "#117", "X", &nwip_universe, 117 },
+ { "#118", "X", &nwip_universe, 118 },
+ { "#119", "X", &nwip_universe, 119 },
+ { "#120", "X", &nwip_universe, 120 },
+ { "#121", "X", &nwip_universe, 121 },
+ { "#122", "X", &nwip_universe, 122 },
+ { "#123", "X", &nwip_universe, 123 },
+ { "#124", "X", &nwip_universe, 124 },
+ { "#125", "X", &nwip_universe, 125 },
+ { "#126", "X", &nwip_universe, 126 },
+ { "#127", "X", &nwip_universe, 127 },
+ { "#128", "X", &nwip_universe, 128 },
+ { "#129", "X", &nwip_universe, 129 },
+ { "#130", "X", &nwip_universe, 130 },
+ { "#131", "X", &nwip_universe, 131 },
+ { "#132", "X", &nwip_universe, 132 },
+ { "#133", "X", &nwip_universe, 133 },
+ { "#134", "X", &nwip_universe, 134 },
+ { "#135", "X", &nwip_universe, 135 },
+ { "#136", "X", &nwip_universe, 136 },
+ { "#137", "X", &nwip_universe, 137 },
+ { "#138", "X", &nwip_universe, 138 },
+ { "#139", "X", &nwip_universe, 139 },
+ { "#140", "X", &nwip_universe, 140 },
+ { "#141", "X", &nwip_universe, 141 },
+ { "#142", "X", &nwip_universe, 142 },
+ { "#143", "X", &nwip_universe, 143 },
+ { "#144", "X", &nwip_universe, 144 },
+ { "#145", "X", &nwip_universe, 145 },
+ { "#146", "X", &nwip_universe, 146 },
+ { "#147", "X", &nwip_universe, 147 },
+ { "#148", "X", &nwip_universe, 148 },
+ { "#149", "X", &nwip_universe, 149 },
+ { "#150", "X", &nwip_universe, 150 },
+ { "#151", "X", &nwip_universe, 151 },
+ { "#152", "X", &nwip_universe, 152 },
+ { "#153", "X", &nwip_universe, 153 },
+ { "#154", "X", &nwip_universe, 154 },
+ { "#155", "X", &nwip_universe, 155 },
+ { "#156", "X", &nwip_universe, 156 },
+ { "#157", "X", &nwip_universe, 157 },
+ { "#158", "X", &nwip_universe, 158 },
+ { "#159", "X", &nwip_universe, 159 },
+ { "#160", "X", &nwip_universe, 160 },
+ { "#161", "X", &nwip_universe, 161 },
+ { "#162", "X", &nwip_universe, 162 },
+ { "#163", "X", &nwip_universe, 163 },
+ { "#164", "X", &nwip_universe, 164 },
+ { "#165", "X", &nwip_universe, 165 },
+ { "#166", "X", &nwip_universe, 166 },
+ { "#167", "X", &nwip_universe, 167 },
+ { "#168", "X", &nwip_universe, 168 },
+ { "#169", "X", &nwip_universe, 169 },
+ { "#170", "X", &nwip_universe, 170 },
+ { "#171", "X", &nwip_universe, 171 },
+ { "#172", "X", &nwip_universe, 172 },
+ { "#173", "X", &nwip_universe, 173 },
+ { "#174", "X", &nwip_universe, 174 },
+ { "#175", "X", &nwip_universe, 175 },
+ { "#176", "X", &nwip_universe, 176 },
+ { "#177", "X", &nwip_universe, 177 },
+ { "#178", "X", &nwip_universe, 178 },
+ { "#179", "X", &nwip_universe, 179 },
+ { "#180", "X", &nwip_universe, 180 },
+ { "#181", "X", &nwip_universe, 181 },
+ { "#182", "X", &nwip_universe, 182 },
+ { "#183", "X", &nwip_universe, 183 },
+ { "#184", "X", &nwip_universe, 184 },
+ { "#185", "X", &nwip_universe, 185 },
+ { "#186", "X", &nwip_universe, 186 },
+ { "#187", "X", &nwip_universe, 187 },
+ { "#188", "X", &nwip_universe, 188 },
+ { "#189", "X", &nwip_universe, 189 },
+ { "#190", "X", &nwip_universe, 190 },
+ { "#191", "X", &nwip_universe, 191 },
+ { "#192", "X", &nwip_universe, 192 },
+ { "#193", "X", &nwip_universe, 193 },
+ { "#194", "X", &nwip_universe, 194 },
+ { "#195", "X", &nwip_universe, 195 },
+ { "#196", "X", &nwip_universe, 196 },
+ { "#197", "X", &nwip_universe, 197 },
+ { "#198", "X", &nwip_universe, 198 },
+ { "#199", "X", &nwip_universe, 199 },
+ { "#200", "X", &nwip_universe, 200 },
+ { "#201", "X", &nwip_universe, 201 },
+ { "#202", "X", &nwip_universe, 202 },
+ { "#203", "X", &nwip_universe, 203 },
+ { "#204", "X", &nwip_universe, 204 },
+ { "#205", "X", &nwip_universe, 205 },
+ { "#206", "X", &nwip_universe, 206 },
+ { "#207", "X", &nwip_universe, 207 },
+ { "#208", "X", &nwip_universe, 208 },
+ { "#209", "X", &nwip_universe, 209 },
+ { "#210", "X", &nwip_universe, 210 },
+ { "#211", "X", &nwip_universe, 211 },
+ { "#212", "X", &nwip_universe, 212 },
+ { "#213", "X", &nwip_universe, 213 },
+ { "#214", "X", &nwip_universe, 214 },
+ { "#215", "X", &nwip_universe, 215 },
+ { "#216", "X", &nwip_universe, 216 },
+ { "#217", "X", &nwip_universe, 217 },
+ { "#218", "X", &nwip_universe, 218 },
+ { "#219", "X", &nwip_universe, 219 },
+ { "#220", "X", &nwip_universe, 220 },
+ { "#221", "X", &nwip_universe, 221 },
+ { "#222", "X", &nwip_universe, 222 },
+ { "#223", "X", &nwip_universe, 223 },
+ { "#224", "X", &nwip_universe, 224 },
+ { "#225", "X", &nwip_universe, 225 },
+ { "#226", "X", &nwip_universe, 226 },
+ { "#227", "X", &nwip_universe, 227 },
+ { "#228", "X", &nwip_universe, 228 },
+ { "#229", "X", &nwip_universe, 229 },
+ { "#230", "X", &nwip_universe, 230 },
+ { "#231", "X", &nwip_universe, 231 },
+ { "#232", "X", &nwip_universe, 232 },
+ { "#233", "X", &nwip_universe, 233 },
+ { "#234", "X", &nwip_universe, 234 },
+ { "#235", "X", &nwip_universe, 235 },
+ { "#236", "X", &nwip_universe, 236 },
+ { "#237", "X", &nwip_universe, 237 },
+ { "#238", "X", &nwip_universe, 238 },
+ { "#239", "X", &nwip_universe, 239 },
+ { "#240", "X", &nwip_universe, 240 },
+ { "#241", "X", &nwip_universe, 241 },
+ { "#242", "X", &nwip_universe, 242 },
+ { "#243", "X", &nwip_universe, 243 },
+ { "#244", "X", &nwip_universe, 244 },
+ { "#245", "X", &nwip_universe, 245 },
+ { "#246", "X", &nwip_universe, 246 },
+ { "#247", "X", &nwip_universe, 247 },
+ { "#248", "X", &nwip_universe, 248 },
+ { "#249", "X", &nwip_universe, 249 },
+ { "#250", "X", &nwip_universe, 250 },
+ { "#251", "X", &nwip_universe, 251 },
+ { "#252", "X", &nwip_universe, 252 },
+ { "#253", "X", &nwip_universe, 253 },
+ { "#254", "X", &nwip_universe, 254 },
+ { "#end", "e", &nwip_universe, 255 },
};
struct universe fqdn_universe;
@@ -626,253 +627,253 @@ struct option fqdn_options [256] = {
{ "hostname", "t", &fqdn_universe, 6 },
{ "domainname", "t", &fqdn_universe, 7 },
{ "fqdn", "t", &fqdn_universe, 8 },
- { "option-9", "X", &fqdn_universe, 9 },
- { "option-10", "X", &fqdn_universe, 10 },
- { "option-11", "X", &fqdn_universe, 11 },
- { "option-12", "X", &fqdn_universe, 12 },
- { "option-13", "X", &fqdn_universe, 13 },
- { "option-14", "X", &fqdn_universe, 14 },
- { "option-15", "X", &fqdn_universe, 15 },
- { "option-16", "X", &fqdn_universe, 16 },
- { "option-17", "X", &fqdn_universe, 17 },
- { "option-18", "X", &fqdn_universe, 18 },
- { "option-19", "X", &fqdn_universe, 19 },
- { "option-20", "X", &fqdn_universe, 20 },
- { "option-21", "X", &fqdn_universe, 21 },
- { "option-22", "X", &fqdn_universe, 22 },
- { "option-23", "X", &fqdn_universe, 23 },
- { "option-24", "X", &fqdn_universe, 24 },
- { "option-25", "X", &fqdn_universe, 25 },
- { "option-26", "X", &fqdn_universe, 26 },
- { "option-27", "X", &fqdn_universe, 27 },
- { "option-28", "X", &fqdn_universe, 28 },
- { "option-29", "X", &fqdn_universe, 29 },
- { "option-30", "X", &fqdn_universe, 30 },
- { "option-31", "X", &fqdn_universe, 31 },
- { "option-32", "X", &fqdn_universe, 32 },
- { "option-33", "X", &fqdn_universe, 33 },
- { "option-34", "X", &fqdn_universe, 34 },
- { "option-35", "X", &fqdn_universe, 35 },
- { "option-36", "X", &fqdn_universe, 36 },
- { "option-37", "X", &fqdn_universe, 37 },
- { "option-38", "X", &fqdn_universe, 38 },
- { "option-39", "X", &fqdn_universe, 39 },
- { "option-40", "X", &fqdn_universe, 40 },
- { "option-41", "X", &fqdn_universe, 41 },
- { "option-42", "X", &fqdn_universe, 42 },
- { "option-43", "X", &fqdn_universe, 43 },
- { "option-44", "X", &fqdn_universe, 44 },
- { "option-45", "X", &fqdn_universe, 45 },
- { "option-46", "X", &fqdn_universe, 46 },
- { "option-47", "X", &fqdn_universe, 47 },
- { "option-48", "X", &fqdn_universe, 48 },
- { "option-49", "X", &fqdn_universe, 49 },
- { "option-50", "X", &fqdn_universe, 50 },
- { "option-51", "X", &fqdn_universe, 51 },
- { "option-52", "X", &fqdn_universe, 52 },
- { "option-53", "X", &fqdn_universe, 53 },
- { "option-54", "X", &fqdn_universe, 54 },
- { "option-55", "X", &fqdn_universe, 55 },
- { "option-56", "X", &fqdn_universe, 56 },
- { "option-57", "X", &fqdn_universe, 57 },
- { "option-58", "X", &fqdn_universe, 58 },
- { "option-59", "X", &fqdn_universe, 59 },
- { "option-60", "X", &fqdn_universe, 60 },
- { "option-61", "X", &fqdn_universe, 61 },
- { "option-62", "X", &fqdn_universe, 62 },
- { "option-63", "X", &fqdn_universe, 63 },
- { "option-64", "X", &fqdn_universe, 64 },
- { "option-65", "X", &fqdn_universe, 65 },
- { "option-66", "X", &fqdn_universe, 66 },
- { "option-67", "X", &fqdn_universe, 67 },
- { "option-68", "X", &fqdn_universe, 68 },
- { "option-69", "X", &fqdn_universe, 69 },
- { "option-70", "X", &fqdn_universe, 70 },
- { "option-71", "X", &fqdn_universe, 71 },
- { "option-72", "X", &fqdn_universe, 72 },
- { "option-73", "X", &fqdn_universe, 73 },
- { "option-74", "X", &fqdn_universe, 74 },
- { "option-75", "X", &fqdn_universe, 75 },
- { "option-76", "X", &fqdn_universe, 76 },
- { "option-77", "X", &fqdn_universe, 77 },
- { "option-78", "X", &fqdn_universe, 78 },
- { "option-79", "X", &fqdn_universe, 79 },
- { "option-80", "X", &fqdn_universe, 80 },
- { "option-81", "X", &fqdn_universe, 81 },
- { "option-82", "X", &fqdn_universe, 82 },
- { "option-83", "X", &fqdn_universe, 83 },
- { "option-84", "X", &fqdn_universe, 84 },
- { "option-85", "X", &fqdn_universe, 85 },
- { "option-86", "X", &fqdn_universe, 86 },
- { "option-87", "X", &fqdn_universe, 87 },
- { "option-88", "X", &fqdn_universe, 88 },
- { "option-89", "X", &fqdn_universe, 89 },
- { "option-90", "X", &fqdn_universe, 90 },
- { "option-91", "X", &fqdn_universe, 91 },
- { "option-92", "X", &fqdn_universe, 92 },
- { "option-93", "X", &fqdn_universe, 93 },
- { "option-94", "X", &fqdn_universe, 94 },
- { "option-95", "X", &fqdn_universe, 95 },
- { "option-96", "X", &fqdn_universe, 96 },
- { "option-97", "X", &fqdn_universe, 97 },
- { "option-98", "X", &fqdn_universe, 98 },
- { "option-99", "X", &fqdn_universe, 99 },
- { "option-100", "X", &fqdn_universe, 100 },
- { "option-101", "X", &fqdn_universe, 101 },
- { "option-102", "X", &fqdn_universe, 102 },
- { "option-103", "X", &fqdn_universe, 103 },
- { "option-104", "X", &fqdn_universe, 104 },
- { "option-105", "X", &fqdn_universe, 105 },
- { "option-106", "X", &fqdn_universe, 106 },
- { "option-107", "X", &fqdn_universe, 107 },
- { "option-108", "X", &fqdn_universe, 108 },
- { "option-109", "X", &fqdn_universe, 109 },
- { "option-110", "X", &fqdn_universe, 110 },
- { "option-111", "X", &fqdn_universe, 111 },
- { "option-112", "X", &fqdn_universe, 112 },
- { "option-113", "X", &fqdn_universe, 113 },
- { "option-114", "X", &fqdn_universe, 114 },
- { "option-115", "X", &fqdn_universe, 115 },
- { "option-116", "X", &fqdn_universe, 116 },
- { "option-117", "X", &fqdn_universe, 117 },
- { "option-118", "X", &fqdn_universe, 118 },
- { "option-119", "X", &fqdn_universe, 119 },
- { "option-120", "X", &fqdn_universe, 120 },
- { "option-121", "X", &fqdn_universe, 121 },
- { "option-122", "X", &fqdn_universe, 122 },
- { "option-123", "X", &fqdn_universe, 123 },
- { "option-124", "X", &fqdn_universe, 124 },
- { "option-125", "X", &fqdn_universe, 125 },
- { "option-126", "X", &fqdn_universe, 126 },
- { "option-127", "X", &fqdn_universe, 127 },
- { "option-128", "X", &fqdn_universe, 128 },
- { "option-129", "X", &fqdn_universe, 129 },
- { "option-130", "X", &fqdn_universe, 130 },
- { "option-131", "X", &fqdn_universe, 131 },
- { "option-132", "X", &fqdn_universe, 132 },
- { "option-133", "X", &fqdn_universe, 133 },
- { "option-134", "X", &fqdn_universe, 134 },
- { "option-135", "X", &fqdn_universe, 135 },
- { "option-136", "X", &fqdn_universe, 136 },
- { "option-137", "X", &fqdn_universe, 137 },
- { "option-138", "X", &fqdn_universe, 138 },
- { "option-139", "X", &fqdn_universe, 139 },
- { "option-140", "X", &fqdn_universe, 140 },
- { "option-141", "X", &fqdn_universe, 141 },
- { "option-142", "X", &fqdn_universe, 142 },
- { "option-143", "X", &fqdn_universe, 143 },
- { "option-144", "X", &fqdn_universe, 144 },
- { "option-145", "X", &fqdn_universe, 145 },
- { "option-146", "X", &fqdn_universe, 146 },
- { "option-147", "X", &fqdn_universe, 147 },
- { "option-148", "X", &fqdn_universe, 148 },
- { "option-149", "X", &fqdn_universe, 149 },
- { "option-150", "X", &fqdn_universe, 150 },
- { "option-151", "X", &fqdn_universe, 151 },
- { "option-152", "X", &fqdn_universe, 152 },
- { "option-153", "X", &fqdn_universe, 153 },
- { "option-154", "X", &fqdn_universe, 154 },
- { "option-155", "X", &fqdn_universe, 155 },
- { "option-156", "X", &fqdn_universe, 156 },
- { "option-157", "X", &fqdn_universe, 157 },
- { "option-158", "X", &fqdn_universe, 158 },
- { "option-159", "X", &fqdn_universe, 159 },
- { "option-160", "X", &fqdn_universe, 160 },
- { "option-161", "X", &fqdn_universe, 161 },
- { "option-162", "X", &fqdn_universe, 162 },
- { "option-163", "X", &fqdn_universe, 163 },
- { "option-164", "X", &fqdn_universe, 164 },
- { "option-165", "X", &fqdn_universe, 165 },
- { "option-166", "X", &fqdn_universe, 166 },
- { "option-167", "X", &fqdn_universe, 167 },
- { "option-168", "X", &fqdn_universe, 168 },
- { "option-169", "X", &fqdn_universe, 169 },
- { "option-170", "X", &fqdn_universe, 170 },
- { "option-171", "X", &fqdn_universe, 171 },
- { "option-172", "X", &fqdn_universe, 172 },
- { "option-173", "X", &fqdn_universe, 173 },
- { "option-174", "X", &fqdn_universe, 174 },
- { "option-175", "X", &fqdn_universe, 175 },
- { "option-176", "X", &fqdn_universe, 176 },
- { "option-177", "X", &fqdn_universe, 177 },
- { "option-178", "X", &fqdn_universe, 178 },
- { "option-179", "X", &fqdn_universe, 179 },
- { "option-180", "X", &fqdn_universe, 180 },
- { "option-181", "X", &fqdn_universe, 181 },
- { "option-182", "X", &fqdn_universe, 182 },
- { "option-183", "X", &fqdn_universe, 183 },
- { "option-184", "X", &fqdn_universe, 184 },
- { "option-185", "X", &fqdn_universe, 185 },
- { "option-186", "X", &fqdn_universe, 186 },
- { "option-187", "X", &fqdn_universe, 187 },
- { "option-188", "X", &fqdn_universe, 188 },
- { "option-189", "X", &fqdn_universe, 189 },
- { "option-190", "X", &fqdn_universe, 190 },
- { "option-191", "X", &fqdn_universe, 191 },
- { "option-192", "X", &fqdn_universe, 192 },
- { "option-193", "X", &fqdn_universe, 193 },
- { "option-194", "X", &fqdn_universe, 194 },
- { "option-195", "X", &fqdn_universe, 195 },
- { "option-196", "X", &fqdn_universe, 196 },
- { "option-197", "X", &fqdn_universe, 197 },
- { "option-198", "X", &fqdn_universe, 198 },
- { "option-199", "X", &fqdn_universe, 199 },
- { "option-200", "X", &fqdn_universe, 200 },
- { "option-201", "X", &fqdn_universe, 201 },
- { "option-202", "X", &fqdn_universe, 202 },
- { "option-203", "X", &fqdn_universe, 203 },
- { "option-204", "X", &fqdn_universe, 204 },
- { "option-205", "X", &fqdn_universe, 205 },
- { "option-206", "X", &fqdn_universe, 206 },
- { "option-207", "X", &fqdn_universe, 207 },
- { "option-208", "X", &fqdn_universe, 208 },
- { "option-209", "X", &fqdn_universe, 209 },
- { "authenticate", "X", &fqdn_universe, 210 },
- { "option-211", "X", &fqdn_universe, 211 },
- { "option-212", "X", &fqdn_universe, 212 },
- { "option-213", "X", &fqdn_universe, 213 },
- { "option-214", "X", &fqdn_universe, 214 },
- { "option-215", "X", &fqdn_universe, 215 },
- { "option-216", "X", &fqdn_universe, 216 },
- { "option-217", "X", &fqdn_universe, 217 },
- { "option-218", "X", &fqdn_universe, 218 },
- { "option-219", "X", &fqdn_universe, 219 },
- { "option-220", "X", &fqdn_universe, 220 },
- { "option-221", "X", &fqdn_universe, 221 },
- { "option-222", "X", &fqdn_universe, 222 },
- { "option-223", "X", &fqdn_universe, 223 },
- { "option-224", "X", &fqdn_universe, 224 },
- { "option-225", "X", &fqdn_universe, 225 },
- { "option-226", "X", &fqdn_universe, 226 },
- { "option-227", "X", &fqdn_universe, 227 },
- { "option-228", "X", &fqdn_universe, 228 },
- { "option-229", "X", &fqdn_universe, 229 },
- { "option-230", "X", &fqdn_universe, 230 },
- { "option-231", "X", &fqdn_universe, 231 },
- { "option-232", "X", &fqdn_universe, 232 },
- { "option-233", "X", &fqdn_universe, 233 },
- { "option-234", "X", &fqdn_universe, 234 },
- { "option-235", "X", &fqdn_universe, 235 },
- { "option-236", "X", &fqdn_universe, 236 },
- { "option-237", "X", &fqdn_universe, 237 },
- { "option-238", "X", &fqdn_universe, 238 },
- { "option-239", "X", &fqdn_universe, 239 },
- { "option-240", "X", &fqdn_universe, 240 },
- { "option-241", "X", &fqdn_universe, 241 },
- { "option-242", "X", &fqdn_universe, 242 },
- { "option-243", "X", &fqdn_universe, 243 },
- { "option-244", "X", &fqdn_universe, 244 },
- { "option-245", "X", &fqdn_universe, 245 },
- { "option-246", "X", &fqdn_universe, 246 },
- { "option-247", "X", &fqdn_universe, 247 },
- { "option-248", "X", &fqdn_universe, 248 },
- { "option-249", "X", &fqdn_universe, 249 },
- { "option-250", "X", &fqdn_universe, 250 },
- { "option-251", "X", &fqdn_universe, 251 },
- { "option-252", "X", &fqdn_universe, 252 },
- { "option-253", "X", &fqdn_universe, 253 },
- { "option-254", "X", &fqdn_universe, 254 },
- { "option-end", "e", &fqdn_universe, 255 },
+ { "#9", "X", &fqdn_universe, 9 },
+ { "#10", "X", &fqdn_universe, 10 },
+ { "#11", "X", &fqdn_universe, 11 },
+ { "#12", "X", &fqdn_universe, 12 },
+ { "#13", "X", &fqdn_universe, 13 },
+ { "#14", "X", &fqdn_universe, 14 },
+ { "#15", "X", &fqdn_universe, 15 },
+ { "#16", "X", &fqdn_universe, 16 },
+ { "#17", "X", &fqdn_universe, 17 },
+ { "#18", "X", &fqdn_universe, 18 },
+ { "#19", "X", &fqdn_universe, 19 },
+ { "#20", "X", &fqdn_universe, 20 },
+ { "#21", "X", &fqdn_universe, 21 },
+ { "#22", "X", &fqdn_universe, 22 },
+ { "#23", "X", &fqdn_universe, 23 },
+ { "#24", "X", &fqdn_universe, 24 },
+ { "#25", "X", &fqdn_universe, 25 },
+ { "#26", "X", &fqdn_universe, 26 },
+ { "#27", "X", &fqdn_universe, 27 },
+ { "#28", "X", &fqdn_universe, 28 },
+ { "#29", "X", &fqdn_universe, 29 },
+ { "#30", "X", &fqdn_universe, 30 },
+ { "#31", "X", &fqdn_universe, 31 },
+ { "#32", "X", &fqdn_universe, 32 },
+ { "#33", "X", &fqdn_universe, 33 },
+ { "#34", "X", &fqdn_universe, 34 },
+ { "#35", "X", &fqdn_universe, 35 },
+ { "#36", "X", &fqdn_universe, 36 },
+ { "#37", "X", &fqdn_universe, 37 },
+ { "#38", "X", &fqdn_universe, 38 },
+ { "#39", "X", &fqdn_universe, 39 },
+ { "#40", "X", &fqdn_universe, 40 },
+ { "#41", "X", &fqdn_universe, 41 },
+ { "#42", "X", &fqdn_universe, 42 },
+ { "#43", "X", &fqdn_universe, 43 },
+ { "#44", "X", &fqdn_universe, 44 },
+ { "#45", "X", &fqdn_universe, 45 },
+ { "#46", "X", &fqdn_universe, 46 },
+ { "#47", "X", &fqdn_universe, 47 },
+ { "#48", "X", &fqdn_universe, 48 },
+ { "#49", "X", &fqdn_universe, 49 },
+ { "#50", "X", &fqdn_universe, 50 },
+ { "#51", "X", &fqdn_universe, 51 },
+ { "#52", "X", &fqdn_universe, 52 },
+ { "#53", "X", &fqdn_universe, 53 },
+ { "#54", "X", &fqdn_universe, 54 },
+ { "#55", "X", &fqdn_universe, 55 },
+ { "#56", "X", &fqdn_universe, 56 },
+ { "#57", "X", &fqdn_universe, 57 },
+ { "#58", "X", &fqdn_universe, 58 },
+ { "#59", "X", &fqdn_universe, 59 },
+ { "#60", "X", &fqdn_universe, 60 },
+ { "#61", "X", &fqdn_universe, 61 },
+ { "#62", "X", &fqdn_universe, 62 },
+ { "#63", "X", &fqdn_universe, 63 },
+ { "#64", "X", &fqdn_universe, 64 },
+ { "#65", "X", &fqdn_universe, 65 },
+ { "#66", "X", &fqdn_universe, 66 },
+ { "#67", "X", &fqdn_universe, 67 },
+ { "#68", "X", &fqdn_universe, 68 },
+ { "#69", "X", &fqdn_universe, 69 },
+ { "#70", "X", &fqdn_universe, 70 },
+ { "#71", "X", &fqdn_universe, 71 },
+ { "#72", "X", &fqdn_universe, 72 },
+ { "#73", "X", &fqdn_universe, 73 },
+ { "#74", "X", &fqdn_universe, 74 },
+ { "#75", "X", &fqdn_universe, 75 },
+ { "#76", "X", &fqdn_universe, 76 },
+ { "#77", "X", &fqdn_universe, 77 },
+ { "#78", "X", &fqdn_universe, 78 },
+ { "#79", "X", &fqdn_universe, 79 },
+ { "#80", "X", &fqdn_universe, 80 },
+ { "#81", "X", &fqdn_universe, 81 },
+ { "#82", "X", &fqdn_universe, 82 },
+ { "#83", "X", &fqdn_universe, 83 },
+ { "#84", "X", &fqdn_universe, 84 },
+ { "#85", "X", &fqdn_universe, 85 },
+ { "#86", "X", &fqdn_universe, 86 },
+ { "#87", "X", &fqdn_universe, 87 },
+ { "#88", "X", &fqdn_universe, 88 },
+ { "#89", "X", &fqdn_universe, 89 },
+ { "#90", "X", &fqdn_universe, 90 },
+ { "#91", "X", &fqdn_universe, 91 },
+ { "#92", "X", &fqdn_universe, 92 },
+ { "#93", "X", &fqdn_universe, 93 },
+ { "#94", "X", &fqdn_universe, 94 },
+ { "#95", "X", &fqdn_universe, 95 },
+ { "#96", "X", &fqdn_universe, 96 },
+ { "#97", "X", &fqdn_universe, 97 },
+ { "#98", "X", &fqdn_universe, 98 },
+ { "#99", "X", &fqdn_universe, 99 },
+ { "#100", "X", &fqdn_universe, 100 },
+ { "#101", "X", &fqdn_universe, 101 },
+ { "#102", "X", &fqdn_universe, 102 },
+ { "#103", "X", &fqdn_universe, 103 },
+ { "#104", "X", &fqdn_universe, 104 },
+ { "#105", "X", &fqdn_universe, 105 },
+ { "#106", "X", &fqdn_universe, 106 },
+ { "#107", "X", &fqdn_universe, 107 },
+ { "#108", "X", &fqdn_universe, 108 },
+ { "#109", "X", &fqdn_universe, 109 },
+ { "#110", "X", &fqdn_universe, 110 },
+ { "#111", "X", &fqdn_universe, 111 },
+ { "#112", "X", &fqdn_universe, 112 },
+ { "#113", "X", &fqdn_universe, 113 },
+ { "#114", "X", &fqdn_universe, 114 },
+ { "#115", "X", &fqdn_universe, 115 },
+ { "#116", "X", &fqdn_universe, 116 },
+ { "#117", "X", &fqdn_universe, 117 },
+ { "#118", "X", &fqdn_universe, 118 },
+ { "#119", "X", &fqdn_universe, 119 },
+ { "#120", "X", &fqdn_universe, 120 },
+ { "#121", "X", &fqdn_universe, 121 },
+ { "#122", "X", &fqdn_universe, 122 },
+ { "#123", "X", &fqdn_universe, 123 },
+ { "#124", "X", &fqdn_universe, 124 },
+ { "#125", "X", &fqdn_universe, 125 },
+ { "#126", "X", &fqdn_universe, 126 },
+ { "#127", "X", &fqdn_universe, 127 },
+ { "#128", "X", &fqdn_universe, 128 },
+ { "#129", "X", &fqdn_universe, 129 },
+ { "#130", "X", &fqdn_universe, 130 },
+ { "#131", "X", &fqdn_universe, 131 },
+ { "#132", "X", &fqdn_universe, 132 },
+ { "#133", "X", &fqdn_universe, 133 },
+ { "#134", "X", &fqdn_universe, 134 },
+ { "#135", "X", &fqdn_universe, 135 },
+ { "#136", "X", &fqdn_universe, 136 },
+ { "#137", "X", &fqdn_universe, 137 },
+ { "#138", "X", &fqdn_universe, 138 },
+ { "#139", "X", &fqdn_universe, 139 },
+ { "#140", "X", &fqdn_universe, 140 },
+ { "#141", "X", &fqdn_universe, 141 },
+ { "#142", "X", &fqdn_universe, 142 },
+ { "#143", "X", &fqdn_universe, 143 },
+ { "#144", "X", &fqdn_universe, 144 },
+ { "#145", "X", &fqdn_universe, 145 },
+ { "#146", "X", &fqdn_universe, 146 },
+ { "#147", "X", &fqdn_universe, 147 },
+ { "#148", "X", &fqdn_universe, 148 },
+ { "#149", "X", &fqdn_universe, 149 },
+ { "#150", "X", &fqdn_universe, 150 },
+ { "#151", "X", &fqdn_universe, 151 },
+ { "#152", "X", &fqdn_universe, 152 },
+ { "#153", "X", &fqdn_universe, 153 },
+ { "#154", "X", &fqdn_universe, 154 },
+ { "#155", "X", &fqdn_universe, 155 },
+ { "#156", "X", &fqdn_universe, 156 },
+ { "#157", "X", &fqdn_universe, 157 },
+ { "#158", "X", &fqdn_universe, 158 },
+ { "#159", "X", &fqdn_universe, 159 },
+ { "#160", "X", &fqdn_universe, 160 },
+ { "#161", "X", &fqdn_universe, 161 },
+ { "#162", "X", &fqdn_universe, 162 },
+ { "#163", "X", &fqdn_universe, 163 },
+ { "#164", "X", &fqdn_universe, 164 },
+ { "#165", "X", &fqdn_universe, 165 },
+ { "#166", "X", &fqdn_universe, 166 },
+ { "#167", "X", &fqdn_universe, 167 },
+ { "#168", "X", &fqdn_universe, 168 },
+ { "#169", "X", &fqdn_universe, 169 },
+ { "#170", "X", &fqdn_universe, 170 },
+ { "#171", "X", &fqdn_universe, 171 },
+ { "#172", "X", &fqdn_universe, 172 },
+ { "#173", "X", &fqdn_universe, 173 },
+ { "#174", "X", &fqdn_universe, 174 },
+ { "#175", "X", &fqdn_universe, 175 },
+ { "#176", "X", &fqdn_universe, 176 },
+ { "#177", "X", &fqdn_universe, 177 },
+ { "#178", "X", &fqdn_universe, 178 },
+ { "#179", "X", &fqdn_universe, 179 },
+ { "#180", "X", &fqdn_universe, 180 },
+ { "#181", "X", &fqdn_universe, 181 },
+ { "#182", "X", &fqdn_universe, 182 },
+ { "#183", "X", &fqdn_universe, 183 },
+ { "#184", "X", &fqdn_universe, 184 },
+ { "#185", "X", &fqdn_universe, 185 },
+ { "#186", "X", &fqdn_universe, 186 },
+ { "#187", "X", &fqdn_universe, 187 },
+ { "#188", "X", &fqdn_universe, 188 },
+ { "#189", "X", &fqdn_universe, 189 },
+ { "#190", "X", &fqdn_universe, 190 },
+ { "#191", "X", &fqdn_universe, 191 },
+ { "#192", "X", &fqdn_universe, 192 },
+ { "#193", "X", &fqdn_universe, 193 },
+ { "#194", "X", &fqdn_universe, 194 },
+ { "#195", "X", &fqdn_universe, 195 },
+ { "#196", "X", &fqdn_universe, 196 },
+ { "#197", "X", &fqdn_universe, 197 },
+ { "#198", "X", &fqdn_universe, 198 },
+ { "#199", "X", &fqdn_universe, 199 },
+ { "#200", "X", &fqdn_universe, 200 },
+ { "#201", "X", &fqdn_universe, 201 },
+ { "#202", "X", &fqdn_universe, 202 },
+ { "#203", "X", &fqdn_universe, 203 },
+ { "#204", "X", &fqdn_universe, 204 },
+ { "#205", "X", &fqdn_universe, 205 },
+ { "#206", "X", &fqdn_universe, 206 },
+ { "#207", "X", &fqdn_universe, 207 },
+ { "#208", "X", &fqdn_universe, 208 },
+ { "#209", "X", &fqdn_universe, 209 },
+ { "#210", "X", &fqdn_universe, 210 },
+ { "#211", "X", &fqdn_universe, 211 },
+ { "#212", "X", &fqdn_universe, 212 },
+ { "#213", "X", &fqdn_universe, 213 },
+ { "#214", "X", &fqdn_universe, 214 },
+ { "#215", "X", &fqdn_universe, 215 },
+ { "#216", "X", &fqdn_universe, 216 },
+ { "#217", "X", &fqdn_universe, 217 },
+ { "#218", "X", &fqdn_universe, 218 },
+ { "#219", "X", &fqdn_universe, 219 },
+ { "#220", "X", &fqdn_universe, 220 },
+ { "#221", "X", &fqdn_universe, 221 },
+ { "#222", "X", &fqdn_universe, 222 },
+ { "#223", "X", &fqdn_universe, 223 },
+ { "#224", "X", &fqdn_universe, 224 },
+ { "#225", "X", &fqdn_universe, 225 },
+ { "#226", "X", &fqdn_universe, 226 },
+ { "#227", "X", &fqdn_universe, 227 },
+ { "#228", "X", &fqdn_universe, 228 },
+ { "#229", "X", &fqdn_universe, 229 },
+ { "#230", "X", &fqdn_universe, 230 },
+ { "#231", "X", &fqdn_universe, 231 },
+ { "#232", "X", &fqdn_universe, 232 },
+ { "#233", "X", &fqdn_universe, 233 },
+ { "#234", "X", &fqdn_universe, 234 },
+ { "#235", "X", &fqdn_universe, 235 },
+ { "#236", "X", &fqdn_universe, 236 },
+ { "#237", "X", &fqdn_universe, 237 },
+ { "#238", "X", &fqdn_universe, 238 },
+ { "#239", "X", &fqdn_universe, 239 },
+ { "#240", "X", &fqdn_universe, 240 },
+ { "#241", "X", &fqdn_universe, 241 },
+ { "#242", "X", &fqdn_universe, 242 },
+ { "#243", "X", &fqdn_universe, 243 },
+ { "#244", "X", &fqdn_universe, 244 },
+ { "#245", "X", &fqdn_universe, 245 },
+ { "#246", "X", &fqdn_universe, 246 },
+ { "#247", "X", &fqdn_universe, 247 },
+ { "#248", "X", &fqdn_universe, 248 },
+ { "#249", "X", &fqdn_universe, 249 },
+ { "#250", "X", &fqdn_universe, 250 },
+ { "#251", "X", &fqdn_universe, 251 },
+ { "#252", "X", &fqdn_universe, 252 },
+ { "#253", "X", &fqdn_universe, 253 },
+ { "#254", "X", &fqdn_universe, 254 },
+ { "#end", "e", &fqdn_universe, 255 },
};
const char *hardware_types [] = {
@@ -1170,7 +1171,7 @@ void initialize_common_option_spaces()
dhcp_universe.store_length = putUChar;
dhcp_universe.index = universe_count++;
universes [dhcp_universe.index] = &dhcp_universe;
- dhcp_universe.hash = new_hash (0, 0, 1);
+ dhcp_universe.hash = new_hash (0, 0, 1, MDL);
if (!dhcp_universe.hash)
log_fatal ("Can't allocate dhcp option hash table.");
for (i = 0; i < 256; i++) {
@@ -1197,7 +1198,7 @@ void initialize_common_option_spaces()
fqdn_universe.enc_opt = &dhcp_options [DHO_NWIP_SUBOPTIONS];
nwip_universe.index = universe_count++;
universes [nwip_universe.index] = &nwip_universe;
- nwip_universe.hash = new_hash (0, 0, 1);
+ nwip_universe.hash = new_hash (0, 0, 1, MDL);
if (!nwip_universe.hash)
log_fatal ("Can't allocate nwip option hash table.");
for (i = 0; i < 256; i++) {
@@ -1224,7 +1225,7 @@ void initialize_common_option_spaces()
fqdn_universe.index = universe_count++;
fqdn_universe.enc_opt = &dhcp_options [DHO_FQDN];
universes [fqdn_universe.index] = &fqdn_universe;
- fqdn_universe.hash = new_hash (0, 0, 1);
+ fqdn_universe.hash = new_hash (0, 0, 1, MDL);
if (!fqdn_universe.hash)
log_fatal ("Can't allocate fqdn option hash table.");
for (i = 0; i < 256; i++) {
@@ -1235,7 +1236,7 @@ void initialize_common_option_spaces()
}
/* Set up the hash of universes. */
- universe_hash = new_hash (0, 0, 1);
+ universe_hash = new_hash (0, 0, 1, MDL);
universe_hash_add (universe_hash,
dhcp_universe.name, 0,
&dhcp_universe, MDL);
diff --git a/common/tree.c b/common/tree.c
index 1dd408dc..0c5fb64d 100644
--- a/common/tree.c
+++ b/common/tree.c
@@ -3,7 +3,7 @@
Routines for manipulating parse trees... */
/*
- * Copyright (c) 1995-2000 Internet Software Consortium.
+ * Copyright (c) 1995-2001 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: tree.c,v 1.101 2001/04/18 18:54:47 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: tree.c,v 1.102 2001/06/27 00:30:00 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -140,16 +140,13 @@ int enter_dns_host (dh, name)
return 1;
}
-int make_const_data (expr, data, len, terminated, allocate)
- struct expression **expr;
- const unsigned char *data;
- unsigned len;
- int terminated;
- int allocate;
+int make_const_data (struct expression **expr, const unsigned char *data,
+ unsigned len, int terminated, int allocate,
+ const char *file, int line)
{
struct expression *nt;
- if (!expression_allocate (expr, MDL)) {
+ if (!expression_allocate (expr, file, line)) {
log_error ("No memory for make_const_data tree node.");
return 0;
}
@@ -158,9 +155,9 @@ int make_const_data (expr, data, len, terminated, allocate)
if (len) {
if (allocate) {
if (!buffer_allocate (&nt -> data.const_data.buffer,
- len + terminated, MDL)) {
+ len + terminated, file, line)) {
log_error ("Can't allocate const_data buffer");
- expression_dereference (expr, MDL);
+ expression_dereference (expr, file, line);
return 0;
}
nt -> data.const_data.data =
@@ -183,7 +180,7 @@ int make_const_int (expr, val)
unsigned long val;
{
if (!expression_allocate (expr, MDL)) {
- log_error ("No memory for make_const_data tree node.");
+ log_error ("No memory for make_const_int tree node.");
return 0;
}
@@ -289,18 +286,16 @@ int make_limit (new, expr, limit)
return 1;
}
-int option_cache (oc, dp, expr, option)
- struct option_cache **oc;
- struct data_string *dp;
- struct expression *expr;
- struct option *option;
+int option_cache (struct option_cache **oc, struct data_string *dp,
+ struct expression *expr, struct option *option,
+ const char *file, int line)
{
- if (!option_cache_allocate (oc, MDL))
+ if (!option_cache_allocate (oc, file, line))
return 0;
if (dp)
- data_string_copy (&(*oc) -> data, dp, MDL);
+ data_string_copy (&(*oc) -> data, dp, file, line);
if (expr)
- expression_reference (&(*oc) -> expression, expr, MDL);
+ expression_reference (&(*oc) -> expression, expr, file, line);
(*oc) -> option = option;
return 1;
}
@@ -429,7 +424,7 @@ static int do_host_lookup (result, dns)
}
int evaluate_expression (result, packet, lease, client_state,
- in_options, cfg_options, scope, expr)
+ in_options, cfg_options, scope, expr, file, line)
struct binding_value **result;
struct packet *packet;
struct lease *lease;
@@ -438,6 +433,8 @@ int evaluate_expression (result, packet, lease, client_state,
struct option_state *cfg_options;
struct binding_scope **scope;
struct expression *expr;
+ const char *file;
+ int line;
{
struct binding_value *bv;
int status;
@@ -455,7 +452,7 @@ int evaluate_expression (result, packet, lease, client_state,
if (result)
binding_value_reference (result,
binding -> value,
- MDL);
+ file, line);
return 1;
} else
return 0;
@@ -516,7 +513,7 @@ int evaluate_expression (result, packet, lease, client_state,
evaluate_expression (&nb -> value, packet, lease,
client_state,
in_options, cfg_options, scope,
- arg -> data.arg.val);
+ arg -> data.arg.val, file, line);
nb -> next = ns -> bindings;
ns -> bindings = nb;
arg = arg -> data.arg.next;
@@ -566,7 +563,7 @@ int evaluate_expression (result, packet, lease, client_state,
bv -> type = binding_data;
status = (evaluate_data_expression
(&bv -> value.data, packet, lease, client_state,
- in_options, cfg_options, scope, expr));
+ in_options, cfg_options, scope, expr, MDL));
} else if (is_dns_expression (expr)) {
#if defined (NSUPDATE)
if (!binding_value_allocate (&bv, MDL))
@@ -582,7 +579,7 @@ int evaluate_expression (result, packet, lease, client_state,
return 0;
}
if (result && status)
- binding_value_reference (result, bv, MDL);
+ binding_value_reference (result, bv, file, line);
binding_value_dereference (&bv, MDL);
return status;
@@ -598,13 +595,13 @@ int binding_value_dereference (struct binding_value **v,
/* Decrement the reference count. If it's nonzero, we're
done. */
--(bv -> refcnt);
- rc_register (file, line, v, bv, bv -> refcnt);
+ rc_register (file, line, v, bv, bv -> refcnt, 1);
if (bv -> refcnt > 0)
return 1;
if (bv -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (bv);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -692,7 +689,8 @@ int evaluate_dns_expression (result, packet, lease, client_state, in_options,
r1 = evaluate_data_expression (&name, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.ns_add.rrname);
+ expr -> data.ns_add.rrname,
+ MDL);
if (r1) {
/* The result of the evaluation may or may not
be NUL-terminated, but we need it
@@ -710,7 +708,7 @@ int evaluate_dns_expression (result, packet, lease, client_state, in_options,
r2 = evaluate_data_expression
(&data, packet, lease, client_state,
in_options, cfg_options, scope,
- expr -> data.ns_add.rrdata);
+ expr -> data.ns_add.rrdata, MDL);
}
} else
r2 = 0;
@@ -933,11 +931,11 @@ int evaluate_boolean_expression (result, packet, lease, client_state,
bv = obv = (struct binding_value *)0;
sleft = evaluate_expression (&bv, packet, lease, client_state,
in_options, cfg_options, scope,
- expr -> data.equal [0]);
+ expr -> data.equal [0], MDL);
sright = evaluate_expression (&obv, packet, lease,
client_state, in_options,
cfg_options, scope,
- expr -> data.equal [1]);
+ expr -> data.equal [1], MDL);
if (sleft && sright) {
if (bv -> type != obv -> type)
*result = expr -> op == expr_not_equal;
@@ -1087,7 +1085,7 @@ int evaluate_boolean_expression (result, packet, lease, client_state,
!get_option (&left, expr -> data.exists -> universe,
packet, lease, client_state,
in_options, cfg_options, in_options,
- scope, expr -> data.exists -> code))
+ scope, expr -> data.exists -> code, MDL))
*result = 0;
else {
*result = 1;
@@ -1182,7 +1180,7 @@ int evaluate_boolean_expression (result, packet, lease, client_state,
bv = (struct binding_value *)0;
sleft = evaluate_expression (&bv, packet, lease, client_state,
in_options, cfg_options,
- scope, expr);
+ scope, expr, MDL);
if (sleft) {
if (bv -> type != binding_boolean)
log_error ("%s() returned type %d in %s.",
@@ -1267,7 +1265,7 @@ int evaluate_boolean_expression (result, packet, lease, client_state,
}
int evaluate_data_expression (result, packet, lease, client_state,
- in_options, cfg_options, scope, expr)
+ in_options, cfg_options, scope, expr, file, line)
struct data_string *result;
struct packet *packet;
struct lease *lease;
@@ -1276,6 +1274,8 @@ int evaluate_data_expression (result, packet, lease, client_state,
struct option_state *cfg_options;
struct binding_scope **scope;
struct expression *expr;
+ const char *file;
+ int line;
{
struct data_string data, other;
unsigned long offset, len, i;
@@ -1292,7 +1292,8 @@ int evaluate_data_expression (result, packet, lease, client_state,
s0 = evaluate_data_expression (&data, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.substring.expr);
+ expr -> data.substring.expr,
+ MDL);
/* Evaluate the offset and length. */
s1 = evaluate_numeric_expression
@@ -1309,7 +1310,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
return an empty string. Otherwise, do the
adjustments and return what's left. */
if (data.len > offset) {
- data_string_copy (result, &data, MDL);
+ data_string_copy (result, &data, file, line);
result -> len -= offset;
if (result -> len > len) {
result -> len = len;
@@ -1342,7 +1343,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
s0 = evaluate_data_expression (&data, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.suffix.expr);
+ expr -> data.suffix.expr, MDL);
/* Evaluate the length. */
s1 = evaluate_numeric_expression (&len, packet, lease,
client_state,
@@ -1350,7 +1351,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
scope,
expr -> data.suffix.len);
if (s0 && s1) {
- data_string_copy (result, &data, MDL);
+ data_string_copy (result, &data, file, line);
/* If we are returning the last N bytes of a
string whose length is <= N, just return
@@ -1361,6 +1362,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
result -> data += data.len - len;
result -> len = len;
}
+ data_string_forget (&data, MDL);
}
#if defined (DEBUG_EXPRESSIONS)
@@ -1376,11 +1378,12 @@ int evaluate_data_expression (result, packet, lease, client_state,
/* Extract an option. */
case expr_option:
if (in_options)
- s0 = get_option (result,
- expr -> data.option -> universe,
- packet, lease, client_state,
- in_options, cfg_options, in_options,
- scope, expr -> data.option -> code);
+ s0 = get_option (result,
+ expr -> data.option -> universe,
+ packet, lease, client_state,
+ in_options, cfg_options, in_options,
+ scope, expr -> data.option -> code,
+ file, line);
else
s0 = 0;
@@ -1395,11 +1398,12 @@ int evaluate_data_expression (result, packet, lease, client_state,
case expr_config_option:
if (cfg_options)
- s0 = get_option (result,
- expr -> data.option -> universe,
- packet, lease, client_state,
- in_options, cfg_options, cfg_options,
- scope, expr -> data.option -> code);
+ s0 = get_option (result,
+ expr -> data.option -> universe,
+ packet, lease, client_state,
+ in_options, cfg_options, cfg_options,
+ scope, expr -> data.option -> code,
+ file, line);
else
s0 = 0;
@@ -1414,6 +1418,24 @@ int evaluate_data_expression (result, packet, lease, client_state,
/* Combine the hardware type and address. */
case expr_hardware:
+ /* On the client, hardware is our hardware. */
+ if (client_state) {
+ memset (result, 0, sizeof *result);
+ result -> data =
+ client_state -> interface -> hw_address.hbuf;
+ result -> len =
+ client_state -> interface -> hw_address.hlen;
+#if defined (DEBUG_EXPRESSIONS)
+ log_debug ("data: hardware = %s",
+ print_hex_1 (result -> len,
+ result -> data, 60));
+#endif
+ return 1;
+ }
+
+ /* The server cares about the client's hardware address,
+ so only in the case where we are examining a packet can
+ we return anything. */
if (!packet || !packet -> raw) {
log_error ("data: hardware: raw packet not available");
return 0;
@@ -1424,7 +1446,8 @@ int evaluate_data_expression (result, packet, lease, client_state,
return 0;
}
result -> len = packet -> raw -> hlen + 1;
- if (buffer_allocate (&result -> buffer, result -> len, MDL)) {
+ if (buffer_allocate (&result -> buffer, result -> len,
+ file, line)) {
result -> data = &result -> buffer -> data [0];
result -> buffer -> data [0] = packet -> raw -> htype;
memcpy (&result -> buffer -> data [1],
@@ -1465,7 +1488,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
else
result -> len = len;
if (buffer_allocate (&result -> buffer,
- result -> len, MDL)) {
+ result -> len, file, line)) {
result -> data = &result -> buffer -> data [0];
memcpy (result -> buffer -> data,
(((unsigned char *)(packet -> raw))
@@ -1513,7 +1536,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
expr -> data.const_data.data, 60));
#endif
data_string_copy (result,
- &expr -> data.const_data, MDL);
+ &expr -> data.const_data, file, line);
return 1;
/* Hostname lookup... */
@@ -1534,18 +1557,18 @@ int evaluate_data_expression (result, packet, lease, client_state,
s0 = evaluate_data_expression (&data, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.concat [0]);
+ expr -> data.concat [0], MDL);
memset (&other, 0, sizeof other);
s1 = evaluate_data_expression (&other, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.concat [1]);
+ expr -> data.concat [1], MDL);
if (s0 && s1) {
- result -> len = data.len + other.len;
- if (!buffer_allocate (&result -> buffer,
- (result -> len +
- other.terminated), MDL)) {
+ result -> len = data.len + other.len;
+ if (!buffer_allocate (&result -> buffer,
+ (result -> len + other.terminated),
+ file, line)) {
log_error ("data: concat: no memory");
result -> len = 0;
data_string_forget (&data, MDL);
@@ -1556,9 +1579,11 @@ int evaluate_data_expression (result, packet, lease, client_state,
memcpy (result -> buffer -> data, data.data, data.len);
memcpy (&result -> buffer -> data [data.len],
other.data, other.len + other.terminated);
- } else if (s0)
+ }
+
+ if (s0)
data_string_forget (&data, MDL);
- else if (s1)
+ if (s1)
data_string_forget (&other, MDL);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("data: concat (%s, %s) = %s",
@@ -1578,7 +1603,8 @@ int evaluate_data_expression (result, packet, lease, client_state,
expr -> data.encode_int);
if (s0) {
result -> len = 1;
- if (!buffer_allocate (&result -> buffer, 1, MDL)) {
+ if (!buffer_allocate (&result -> buffer,
+ 1, file, line)) {
log_error ("data: encode_int8: no memory");
result -> len = 0;
s0 = 0;
@@ -1608,7 +1634,8 @@ int evaluate_data_expression (result, packet, lease, client_state,
expr -> data.encode_int);
if (s0) {
result -> len = 2;
- if (!buffer_allocate (&result -> buffer, 2, MDL)) {
+ if (!buffer_allocate (&result -> buffer, 2,
+ file, line)) {
log_error ("data: encode_int16: no memory");
result -> len = 0;
s0 = 0;
@@ -1637,7 +1664,8 @@ int evaluate_data_expression (result, packet, lease, client_state,
expr -> data.encode_int);
if (s0) {
result -> len = 4;
- if (!buffer_allocate (&result -> buffer, 4, MDL)) {
+ if (!buffer_allocate (&result -> buffer, 4,
+ file, line)) {
log_error ("data: encode_int32: no memory");
result -> len = 0;
s0 = 0;
@@ -1674,14 +1702,15 @@ int evaluate_data_expression (result, packet, lease, client_state,
s2 = evaluate_data_expression (&data, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.b2a.seperator);
+ expr -> data.b2a.seperator,
+ MDL);
/* Evaluate the data to be converted. */
memset (&other, 0, sizeof other);
s3 = evaluate_data_expression (&other, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.b2a.buffer);
+ expr -> data.b2a.buffer, MDL);
if (s0 && s1 && s2 && s3) {
unsigned buflen, i;
@@ -1739,7 +1768,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
}
if (!buffer_allocate (&result -> buffer,
- buflen + 1, MDL)) {
+ buflen + 1, file, line)) {
log_error ("data: binary-to-ascii: no memory");
status = 0;
goto b2a_out;
@@ -1795,7 +1824,8 @@ int evaluate_data_expression (result, packet, lease, client_state,
s1 = evaluate_data_expression (&data, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.reverse.buffer);
+ expr -> data.reverse.buffer,
+ MDL);
if (s0 && s1) {
char *upper;
@@ -1813,7 +1843,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
/* XXX reverse in place? I don't think we can. */
if (!buffer_allocate (&result -> buffer,
- data.len, MDL)) {
+ data.len, file, line)) {
log_error ("data: reverse: no memory");
status = 0;
goto reverse_out;
@@ -1850,7 +1880,8 @@ int evaluate_data_expression (result, packet, lease, client_state,
return 0;
}
result -> len = lease -> ip_addr.len;
- if (buffer_allocate (&result -> buffer, result -> len, MDL)) {
+ if (buffer_allocate (&result -> buffer, result -> len,
+ file, line)) {
result -> data = &result -> buffer -> data [0];
memcpy (&result -> buffer -> data [0],
lease -> ip_addr.iabuf, lease -> ip_addr.len);
@@ -1870,7 +1901,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
if ((evaluate_data_expression
(result, packet,
lease, client_state, in_options, cfg_options,
- scope, expr -> data.pick_first_value.car))) {
+ scope, expr -> data.pick_first_value.car, MDL))) {
#if defined (DEBUG_EXPRESSIONS)
log_debug ("data: pick_first_value (%s, xxx)",
print_hex_1 (result -> len,
@@ -1883,7 +1914,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
(evaluate_data_expression
(result, packet,
lease, client_state, in_options, cfg_options,
- scope, expr -> data.pick_first_value.cdr))) {
+ scope, expr -> data.pick_first_value.cdr, MDL))) {
#if defined (DEBUG_EXPRESSIONS)
log_debug ("data: pick_first_value (NULL, %s)",
print_hex_1 (result -> len,
@@ -1904,7 +1935,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
}
result -> len = strlen (lease -> host -> name);
if (buffer_allocate (&result -> buffer,
- result -> len + 1, MDL)) {
+ result -> len + 1, file, line)) {
result -> data = &result -> buffer -> data [0];
strcpy ((char *)&result -> buffer -> data [0],
lease -> host -> name);
@@ -1932,7 +1963,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
if (binding -> value -> type == binding_data) {
data_string_copy (result,
&binding -> value -> value.data,
- MDL);
+ file, line);
s0 = 1;
} else if (binding -> value -> type != binding_data) {
log_error ("binding type %d in %s.",
@@ -1956,7 +1987,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
bv = (struct binding_value *)0;
s0 = evaluate_expression (&bv, packet, lease, client_state,
in_options, cfg_options,
- scope, expr);
+ scope, expr, MDL);
if (s0) {
if (bv -> type != binding_data)
log_error ("%s() returned type %d in %s.",
@@ -1965,7 +1996,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
"evaluate_data_expression");
else
data_string_copy (result, &bv -> value.data,
- MDL);
+ file, line);
binding_value_dereference (&bv, MDL);
}
#if defined (DEBUG_EXPRESSIONS)
@@ -1986,7 +2017,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
sizeof packet -> raw -> file);
result -> len = fn - &(packet -> raw -> file [0]);
if (buffer_allocate (&result -> buffer,
- result -> len + 1, MDL)) {
+ result -> len + 1, file, line)) {
result -> data = &result -> buffer -> data [0];
memcpy (&result -> buffer -> data [0],
packet -> raw -> file,
@@ -2018,7 +2049,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
sizeof packet -> raw -> sname);
result -> len = fn - &packet -> raw -> sname [0];
if (buffer_allocate (&result -> buffer,
- result -> len + 1, MDL)) {
+ result -> len + 1, file, line)) {
result -> data = &result -> buffer -> data [0];
memcpy (&result -> buffer -> data [0],
packet -> raw -> sname,
@@ -2162,7 +2193,7 @@ int evaluate_numeric_expression (result, packet, lease, client_state,
memset (&data, 0, sizeof data);
status = evaluate_data_expression
(&data, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.extract_int);
+ cfg_options, scope, expr -> data.extract_int, MDL);
if (status)
*result = data.data [0];
#if defined (DEBUG_EXPRESSIONS)
@@ -2177,7 +2208,7 @@ int evaluate_numeric_expression (result, packet, lease, client_state,
memset (&data, 0, sizeof data);
status = (evaluate_data_expression
(&data, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.extract_int));
+ cfg_options, scope, expr -> data.extract_int, MDL));
if (status && data.len >= 2)
*result = getUShort (data.data);
#if defined (DEBUG_EXPRESSIONS)
@@ -2193,7 +2224,7 @@ int evaluate_numeric_expression (result, packet, lease, client_state,
memset (&data, 0, sizeof data);
status = (evaluate_data_expression
(&data, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.extract_int));
+ cfg_options, scope, expr -> data.extract_int, MDL));
if (status && data.len >= 4)
*result = getULong (data.data);
#if defined (DEBUG_EXPRESSIONS)
@@ -2311,7 +2342,7 @@ int evaluate_numeric_expression (result, packet, lease, client_state,
status = evaluate_expression (&bv, packet, lease,
client_state,
in_options, cfg_options,
- scope, expr);
+ scope, expr, MDL);
if (status) {
if (bv -> type != binding_numeric)
log_error ("%s() returned type %d in %s.",
@@ -2613,7 +2644,7 @@ int evaluate_option_cache (result, packet, lease, client_state,
return 0;
return evaluate_data_expression (result, packet, lease, client_state,
in_options, cfg_options, scope,
- oc -> expression);
+ oc -> expression, file, line);
}
/* Evaluate an option cache and extract a boolean from the result,
@@ -2709,13 +2740,13 @@ void expression_dereference (eptr, file, line)
/* Decrement the reference count. If it's nonzero, we're
done. */
--(expr -> refcnt);
- rc_register (file, line, eptr, expr, expr -> refcnt);
+ rc_register (file, line, eptr, expr, expr -> refcnt, 1);
if (expr -> refcnt > 0)
return;
if (expr -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (expr);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -3724,14 +3755,15 @@ int binding_scope_dereference (ptr, file, line)
binding_scope = *ptr;
*ptr = (struct binding_scope *)0;
--binding_scope -> refcnt;
- rc_register (file, line, ptr, binding_scope, binding_scope -> refcnt);
+ rc_register (file, line, ptr,
+ binding_scope, binding_scope -> refcnt, 1);
if (binding_scope -> refcnt > 0)
return 1;
if (binding_scope -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (binding_scope);
#endif
#if defined (POINTER_DEBUG)
abort ();
@@ -3774,11 +3806,11 @@ int fundef_dereference (ptr, file, line)
}
bp -> refcnt--;
- rc_register (file, line, ptr, bp, bp -> refcnt);
+ rc_register (file, line, ptr, bp, bp -> refcnt, 1);
if (bp -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (bp);
#endif
#if defined (POINTER_DEBUG)
abort ();
diff --git a/configure b/configure
index a7c74853..3f504beb 100755
--- a/configure
+++ b/configure
@@ -5,16 +5,23 @@
while [ $# != 0 ]; do
if [ x$1 = x--with-nsupdate ]; then
echo "nsupdate is always built now."
- else
- if [ x$1 = x--print-sysname ]; then
+ elif [ x$1 = x--print-sysname ]; then
print_sysname=yes
- else
- if [ x$sysname = x ]; then
- sysname=$1
- else
- echo "Unexpected argument: $1"
- fi
- fi
+ elif [ x$1 = x--work-dir ]; then
+ workname=$2
+ shift
+ elif [ x$1 = x--dirs ]; then
+ dirs=$2
+ shift
+ elif [ x$1 = x--no-links ]; then
+ nolinks=YES
+ elif [ x$1 = x--copts ]; then
+ copts=$2
+ shift
+ elif [ x$sysname = x ]; then
+ sysname=$1
+ else
+ echo "Unexpected argument: $1"
fi
shift
done
@@ -42,6 +49,8 @@ if [ "$sysname" = "" ]; then
;;
AIX)
sysname=aix;;
+ Darwin)
+ sysname=darwin;;
Rhapsody)
sysname=rhapsody;;
ULTRIX)
@@ -148,7 +157,14 @@ if [ "$sysname" = "" ]; then
sysname_print=hpux
fi;;
QNX)
- sysname=qnx;;
+ release=`uname -r`
+ major=`echo $release |sed -e 's/\([0-9][0-9]*\)\..*$/\1/'`
+ case $major in
+ 6)
+ sysname=qnxnto;;
+ *)
+ sysname=qnx;;
+ esac;;
NEXTSTEP)
sysname=nextstep;;
UnixWare)
@@ -195,10 +211,12 @@ if [ x$print_sysname = xyes ]; then
exit 0
fi
-if [ x$sysname_print != x ]; then
- workname=work.${sysname_print}
-else
- workname=work.${sysname}
+if [ x$workname = x ]; then
+ if [ x$sysname_print != x ]; then
+ workname=work.${sysname_print}
+ else
+ workname=work.${sysname}
+ fi
fi
echo "System Type: $sysname"
@@ -212,18 +230,28 @@ if [ ! -d $workname ]; then
mkdir $workname
fi
-for foo in . client server relay common omapip dhcpctl minires dst; do
- if [ ! -d ${workname}/$foo ]; then
- mkdir ${workname}/$foo
+if [ x"$dirs" = x ]; then
+ dirs=". client server relay common omapip dhcpctl minires dst"
+fi
+
+for foo in $dirs; do
+ bar=`basename $foo`
+ if [ ! -d ${workname}/$bar ]; then
+ mkdir ${workname}/$bar
fi
(sed $majversubst $minversubst \
-e "/^##--${sysname}--/,/^##--${sysname}--/s/^#//" \
- <Makefile.conf; cat site.conf; \
- echo "TOP = ../.."; cat $foo/Makefile.dist) \
- >${workname}/$foo/Makefile
+ <Makefile.conf; \
+ cat site.conf; \
+ echo "TOP = `pwd`"; \
+ echo CC_OPTIONS = $copts; \
+ cat $foo/Makefile.dist) \
+ >${workname}/$bar/Makefile
done
# Make the link tree in which to actually build.
-make links
+if [ x$nolinks = x ]; then
+ make links
+fi
exit 0
diff --git a/dhcpctl/Makefile.dist b/dhcpctl/Makefile.dist
index 79391f14..8686ecf6 100644
--- a/dhcpctl/Makefile.dist
+++ b/dhcpctl/Makefile.dist
@@ -17,11 +17,11 @@
# http://www.isc.org for more information.
#
-CATMANPAGES = dhcpctl.cat3
-SEDMANPAGES = dhcpctl.man3
+CATMANPAGES = dhcpctl.cat3 omshell.cat1
+SEDMANPAGES = dhcpctl.man3 omshell.man1
SRC = dhcpctl.c callback.c remote.c
OBJ = dhcpctl.o callback.o remote.o
-MAN = dhcpctl.3
+MAN = dhcpctl.3 omshell.1
HDRS = dhcpctl.h
INCLUDES = $(BINDINC) -I$(TOP)/includes
@@ -42,8 +42,9 @@ libdhcpctl.a: $(OBJ)
ar cruv libdhcpctl.a $(OBJ)
$(RANLIB) libdhcpctl.a
-install: all
- for dir in $(LIBDIR) $(LIBMANDIR) $(INCDIR); do \
+install: all $(CATMANPAGES)
+ for dir in $(LIBDIR) $(LIBMANDIR) $(INCDIR) $(USRMANDIR) \
+ $(USERBINDIR); do \
foo=""; \
for bar in `echo $(DESTDIR)$${dir} |tr / ' '`; do \
foo=$${foo}/$$bar; \
@@ -63,6 +64,10 @@ install: all
$(MANINSTALL) $(MANFROM) $${prefix}.$(MANCAT)$${suffix} $(MANTO) \
$(DESTDIR)$(LIBMANDIR)/$${prefix}$(LIBMANEXT); \
done
+ $(INSTALL) omshell $(DESTDIR)$(USERBINDIR)
+ $(CHMOD) 755 $(DESTDIR)$(USERBINDIR)/omshell
+ $(MANINSTALL) $(MANFROM) omshell.$(MANCAT)1 $(MANTO) \
+ $(DESTDIR)$(USRMANDIR)/omshell$(USRMANEXT)
depend:
$(MKDEP) $(INCLUDES) $(PREDEFINES) $(SRC)
@@ -91,4 +96,11 @@ dhcpctl.man3: dhcpctl.3
sed -e "s#ETCDIR#$(ETC)#g" -e "s#DBDIR#$(VARDB)#g" \
-e "s#RUNDIR#$(VARRUN)#g" < dhcpctl.3 >dhcpctl.man3
+omshell.cat1: omshell.man1
+ nroff -man omshell.man1 >omshell.cat1
+
+omshell.man1: omshell.1
+ sed -e "s#ETCDIR#$(ETC)#g" -e "s#DBDIR#$(VARDB)#g" \
+ -e "s#RUNDIR#$(VARRUN)#g" < omshell.1 >omshell.man1
+
# Dependencies (semi-automatically-generated)
diff --git a/dhcpctl/cltest.c b/dhcpctl/cltest.c
index 821ae4be..4589ecd1 100644
--- a/dhcpctl/cltest.c
+++ b/dhcpctl/cltest.c
@@ -42,7 +42,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
-#include <isc/result.h>
+#include <isc-dhcp/result.h>
#include "dhcpctl.h"
int main (int, char **);
diff --git a/dhcpctl/dhcpctl.3 b/dhcpctl/dhcpctl.3
index 3c752812..0111a0c1 100644
--- a/dhcpctl/dhcpctl.3
+++ b/dhcpctl/dhcpctl.3
@@ -2,7 +2,7 @@
.\"
.\" Project: DHCP
.\" File: dhcpctl.3
-.\" RCSId: $Id: dhcpctl.3,v 1.3 2001/04/16 17:44:11 tamino Exp $
+.\" RCSId: $Id: dhcpctl.3,v 1.4 2001/06/27 00:30:03 mellon Exp $
.\"
.\" Copyright (C) 2000 Nominum, Inc.
.\"
@@ -389,8 +389,8 @@ macro defined in
.Fn dhcpctl_data_string_dereference
deallocates a data string created by
.Fn omapi_data_string_new .
-The memory for the object won't be compelely deallocated until the last
-reference is released.
+The memory for the object won't be freed until the last reference is
+released.
.Sh EXAMPLES
.Pp
The following program will connect to the DHCP server running on the local
@@ -460,4 +460,11 @@ int main (int argc, char **argv) {
}
.Ed
.Sh SEE ALSO
-omapi-intro(1)
+.SH SEE ALSO
+omapi(3), omshell(3), dhcpd(8), dhclient(8), dhcpd.conf(5), dhclient.conf(5).
+.SH AUTHOR
+.B dhcpctl
+was written by Ted Lemon of Nominum, Inc. Information about Nominum
+and support contracts for DHCP and BIND can be found at
+.B http://www.nominum.com. This preliminary documentation was
+written by James Brister of Nominum, Inc.
diff --git a/dhcpctl/dhcpctl.c b/dhcpctl/dhcpctl.c
index 9e3fafa3..4560b84d 100644
--- a/dhcpctl/dhcpctl.c
+++ b/dhcpctl/dhcpctl.c
@@ -267,7 +267,6 @@ dhcpctl_status dhcpctl_set_value (dhcpctl_handle h, dhcpctl_data_string value,
omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
omapi_data_string_t *name = (omapi_data_string_t *)0;
int len;
- int ip;
status = omapi_data_string_new (&name, strlen (value_name), MDL);
if (status != ISC_R_SUCCESS)
@@ -302,7 +301,6 @@ dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, const char *value,
omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
omapi_data_string_t *name = (omapi_data_string_t *)0;
int len;
- int ip;
status = omapi_data_string_new (&name, strlen (value_name), MDL);
if (status != ISC_R_SUCCESS)
@@ -323,10 +321,10 @@ dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, const char *value,
/* dhcpctl_set_buffer_value
- Sets a NUL-terminated ASCII value on an object referred to by
- a dhcpctl_handle. like dhcpctl_set_value, but saves the
- trouble of creating a data_string for a NUL-terminated string.
- Does not update the server - just sets the value on the handle. */
+ Sets a value on an object referred to by a dhcpctl_handle. like
+ dhcpctl_set_value, but saves the trouble of creating a data_string
+ for string for which we have a buffer and length. Does not update
+ the server - just sets the value on the handle. */
dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle h,
const char *value, unsigned len,
@@ -335,7 +333,6 @@ dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle h,
isc_result_t status;
omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
omapi_data_string_t *name = (omapi_data_string_t *)0;
- int ip;
unsigned ll;
ll = strlen (value_name);
@@ -358,6 +355,29 @@ dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle h,
return status;
}
+/* dhcpctl_set_null_value
+
+ Sets a null value on an object referred to by a dhcpctl_handle. */
+
+dhcpctl_status dhcpctl_set_null_value (dhcpctl_handle h,
+ const char *value_name)
+{
+ isc_result_t status;
+ omapi_data_string_t *name = (omapi_data_string_t *)0;
+ unsigned ll;
+
+ ll = strlen (value_name);
+ status = omapi_data_string_new (&name, ll, MDL);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ memcpy (name -> value, value_name, ll);
+
+ status = omapi_set_value (h, (omapi_object_t *)0, name,
+ (omapi_typed_data_t *)0);
+ omapi_data_string_dereference (&name, MDL);
+ return status;
+}
+
/* dhcpctl_set_boolean_value
Sets a boolean value on an object - like dhcpctl_set_value,
@@ -370,7 +390,6 @@ dhcpctl_status dhcpctl_set_boolean_value (dhcpctl_handle h, int value,
omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
omapi_data_string_t *name = (omapi_data_string_t *)0;
int len;
- int ip;
status = omapi_data_string_new (&name, strlen (value_name), MDL);
if (status != ISC_R_SUCCESS)
@@ -401,7 +420,6 @@ dhcpctl_status dhcpctl_set_int_value (dhcpctl_handle h, int value,
omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
omapi_data_string_t *name = (omapi_data_string_t *)0;
int len;
- int ip;
status = omapi_data_string_new (&name, strlen (value_name), MDL);
if (status != ISC_R_SUCCESS)
@@ -508,6 +526,17 @@ dhcpctl_status dhcpctl_object_refresh (dhcpctl_handle connection,
status = omapi_protocol_send_message (connection -> outer,
(omapi_object_t *)0,
message, (omapi_object_t *)0);
+
+ /* We don't want to send the contents of the object down the
+ wire, but we do need to reference it so that we know what
+ to do with the update. */
+ status = omapi_set_object_value (message, (omapi_object_t *)0,
+ "object", h);
+ if (status != ISC_R_SUCCESS) {
+ omapi_object_dereference (&message, MDL);
+ return status;
+ }
+
omapi_object_dereference (&message, MDL);
return status;
}
diff --git a/dhcpctl/dhcpctl.h b/dhcpctl/dhcpctl.h
index 8cfe133a..398f0ead 100644
--- a/dhcpctl/dhcpctl.h
+++ b/dhcpctl/dhcpctl.h
@@ -87,6 +87,7 @@ dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle, const char *,
const char *);
dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle,
const char *, unsigned, const char *);
+dhcpctl_status dhcpctl_set_null_value (dhcpctl_handle, const char *);
dhcpctl_status dhcpctl_set_boolean_value (dhcpctl_handle, int, const char *);
dhcpctl_status dhcpctl_set_int_value (dhcpctl_handle, int, const char *);
dhcpctl_status dhcpctl_object_update (dhcpctl_handle, dhcpctl_handle);
diff --git a/dhcpctl/omshell.c b/dhcpctl/omshell.c
index bbcd2073..cdff29b6 100644
--- a/dhcpctl/omshell.c
+++ b/dhcpctl/omshell.c
@@ -47,7 +47,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
-#include <isc/result.h>
+#include <isc-dhcp/result.h>
#include "dhcpctl.h"
#include "dhcpd.h"
@@ -69,9 +69,7 @@ int check_collection (struct packet *p, struct lease *l, struct collection *c)
void classify (struct packet *packet, struct class *class) { }
static void usage (char *s) {
- fprintf (stderr,
- "Usage: %s [-n <username>] [-p <password>] "
- "[-a <algorithm>] [-P <port>]\n", s);
+ fprintf (stderr, "Usage: %s\n", s);
exit (1);
}
@@ -109,10 +107,10 @@ int main (int argc, char **argv, char **envp)
/* Initially, log errors to stderr as well as to syslogd. */
#ifdef SYSLOG_4_2
- openlog ("dhcpd", LOG_NDELAY);
+ openlog ("omshell", LOG_NDELAY);
log_priority = DHCPD_LOG_FACILITY;
#else
- openlog ("dhcpd", LOG_NDELAY, DHCPD_LOG_FACILITY);
+ openlog ("omshell", LOG_NDELAY, DHCPD_LOG_FACILITY);
#endif
status = dhcpctl_initialize ();
if (status != ISC_R_SUCCESS) {
@@ -145,9 +143,16 @@ int main (int argc, char **argv, char **envp)
for (i = 0; i < g -> nvalues; i++) {
omapi_value_t *v = g -> values [i];
+ if (!g -> values [i])
+ continue;
+
printf ("%.*s = ", (int)v -> name -> len,
v -> name -> value);
+ if (!v -> value) {
+ printf ("<null>\n");
+ continue;
+ }
switch (v -> value -> type) {
case omapi_datatype_int:
printf ("%d\n",
@@ -502,7 +507,8 @@ int main (int argc, char **argv, char **envp)
s = buf;
val = buf;
do {
- convert_num (cfile, s, val, 16, 8);
+ convert_num (cfile, (unsigned char *)s,
+ val, 16, 8);
++s;
token = next_token (&val,
(unsigned *)0, cfile);
@@ -525,6 +531,39 @@ int main (int argc, char **argv, char **envp)
goto set_usage;
break;
+ case UNSET:
+ token = next_token (&val, (unsigned *)0, cfile);
+
+ if ((!is_identifier (token) && token != STRING)) {
+ unset_usage:
+ printf ("usage: unset <name>\n");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ if (!oh) {
+ printf ("no open object.\n");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ if (!connected) {
+ printf ("not connected.\n");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ s1[0] = '\0';
+ strncat (s1, val, sizeof(s1)-1);
+
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != END_OF_FILE && token != EOL)
+ goto unset_usage;
+
+ dhcpctl_set_null_value (oh, s1);
+ break;
+
+
case TOKEN_CREATE:
case TOKEN_OPEN:
i = token;
@@ -580,6 +619,12 @@ int main (int argc, char **argv, char **envp)
break;
}
+ if (!oh) {
+ printf ("you haven't opened an object yet!\n");
+ skip_to_semi (cfile);
+ break;
+ }
+
status = dhcpctl_object_update(connection, oh);
if (status == ISC_R_SUCCESS)
status = dhcpctl_wait_for_completion
@@ -597,14 +642,18 @@ int main (int argc, char **argv, char **envp)
case REMOVE:
token = next_token (&val, (unsigned *)0, cfile);
if (token != END_OF_FILE && token != EOL) {
- printf ("usage: %s\n", val);
+ printf ("usage: remove\n");
skip_to_semi (cfile);
break;
}
if (!connected) {
printf ("not connected.\n");
- skip_to_semi (cfile);
+ break;
+ }
+
+ if (!oh) {
+ printf ("no object.\n");
break;
}
@@ -619,6 +668,38 @@ int main (int argc, char **argv, char **envp)
isc_result_totext (status));
break;
}
+ omapi_object_dereference (&oh, MDL);
+ break;
+
+ case REFRESH:
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != END_OF_FILE && token != EOL) {
+ printf ("usage: refresh\n");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ if (!connected) {
+ printf ("not connected.\n");
+ break;
+ }
+
+ if (!oh) {
+ printf ("no object.\n");
+ break;
+ }
+
+ status = dhcpctl_object_refresh(connection, oh);
+ if (status == ISC_R_SUCCESS)
+ status = dhcpctl_wait_for_completion
+ (oh, &waitstatus);
+ if (status == ISC_R_SUCCESS)
+ status = waitstatus;
+ if (status != ISC_R_SUCCESS) {
+ printf ("can't refresh object: %s\n",
+ isc_result_totext (status));
+ break;
+ }
break;
}
@@ -626,3 +707,10 @@ int main (int argc, char **argv, char **envp)
exit (0);
}
+
+/* Sigh */
+isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
+ control_object_state_t newstate)
+{
+ return ISC_R_SUCCESS;
+}
diff --git a/dhcpctl/remote.c b/dhcpctl/remote.c
index 6750b704..308c8758 100644
--- a/dhcpctl/remote.c
+++ b/dhcpctl/remote.c
@@ -307,6 +307,8 @@ isc_result_t dhcpctl_remote_signal_handler (omapi_object_t *o,
if (!strcmp (name, "updated")) {
p -> waitstatus = ISC_R_SUCCESS;
+ if (o -> inner -> type == omapi_type_generic)
+ omapi_generic_clear_flags (o -> inner);
return omapi_signal_in (o -> inner, "ready");
}
if (!strcmp (name, "status")) {
diff --git a/dst/dst_internal.h b/dst/dst_internal.h
index 69654a89..0890d803 100644
--- a/dst/dst_internal.h
+++ b/dst/dst_internal.h
@@ -40,7 +40,7 @@ typedef struct dst_key {
} DST_KEY;
#define HAS_DST_KEY
-#include <isc/dst.h>
+#include <isc-dhcp/dst.h>
/*
* define what crypto systems are supported for RSA,
* BSAFE is prefered over RSAREF; only one can be set at any time
diff --git a/includes/cdefs.h b/includes/cdefs.h
index e9d58cb7..4aadc0af 100644
--- a/includes/cdefs.h
+++ b/includes/cdefs.h
@@ -44,7 +44,7 @@
#define __ISC_DHCP_CDEFS_H__
/* Delete attributes if not gcc or not the right version of gcc. */
#if !defined(__GNUC__) || __GNUC__ < 2 || \
- (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+ (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || defined (darwin)
#define __attribute__(x)
#endif
diff --git a/includes/cf/qnx.h b/includes/cf/qnx.h
index f49e9229..17a54995 100644
--- a/includes/cf/qnx.h
+++ b/includes/cf/qnx.h
@@ -54,11 +54,17 @@
#include <sys/wait.h>
#include <signal.h>
+#ifdef __QNXNTO__
+#include <sys/param.h>
+#endif
+
#include <netdb.h>
extern int h_errno;
#include <net/if.h>
-#define INADDR_LOOPBACK ((u_long)0x7f000001)
+#ifndef __QNXNTO__
+# define INADDR_LOOPBACK ((u_long)0x7f000001)
+#endif
/* Varargs stuff... */
#include <stdarg.h>
@@ -88,23 +94,36 @@ extern int h_errno;
#define ADD_TIME(d, s1, s2) (*(d) = *(s1) + *(s2))
#define SET_MAX_TIME(x) (*(x) = INT_MAX)
+#ifndef __QNXNTO__
typedef unsigned char u_int8_t;
typedef unsigned short u_int16_t;
typedef unsigned long u_int32_t;
typedef signed short int16_t;
typedef signed long int32_t;
+#endif
+
+#ifdef __QNXNTO__
+typedef int socklen_t;
+#endif
#define strcasecmp( s1, s2 ) stricmp( s1, s2 )
#define strncasecmp( s1, s2, n ) strnicmp( s1, s2, n )
-#define vsnprintf( buf, size, fmt, list ) vsprintf( buf, fbuf, list )
#define random() rand()
#define HAVE_SA_LEN
#define BROKEN_TM_GMT
#define USE_SOCKETS
-#define NO_SNPRINTF
#undef AF_LINK
+#ifndef __QNXNTO__
+# define NO_SNPRINTF
+# define vsnprintf( buf, size, fmt, list ) vsprintf( buf, fbuf, list )
+#endif
+
+#ifdef __QNXNTO__
+# define GET_HOST_ID_MISSING
+#endif
+
/*
NOTE: to get the routing of the 255.255.255.255 broadcasts to work
under QNX, you need to issue the following command before starting
@@ -116,9 +135,48 @@ typedef signed long int32_t;
machine that dhcpd is running on.
*/
-#if defined (NSUPDATE)
-#error NSUPDATE is not supported on QNX at this time!!
+#ifndef __QNXNTO__
+# if defined (NSUPDATE)
+# error NSUPDATE is not supported on QNX at this time!!
+# endif
#endif
+
+
#ifdef NEED_PRAND_CONF
-UHOH... (this isn't present in the BIND distribution either)
+#ifndef HAVE_DEV_RANDOM
+/* You should find and install the /dev/random driver */
+ # define HAVE_DEV_RANDOM 1
+ #endif /* HAVE_DEV_RANDOM */
+
+const char *cmds[] = {
+ "/bin/ps -a 2>&1",
+ "/bin/sin 2>&1",
+ "/sbin/arp -an 2>&1",
+ "/bin/netstat -an 2>&1",
+ "/bin/df 2>&1",
+ "/bin/sin fds 2>&1",
+ "/bin/netstat -s 2>&1",
+ "/bin/sin memory 2>&1",
+ NULL
+};
+
+const char *dirs[] = {
+ "/tmp",
+ ".",
+ "/",
+ "/var/spool",
+ "/dev",
+ "/var/spool/mail",
+ "/home",
+ NULL
+};
+
+const char *files[] = {
+ "/proc/ipstats",
+ "/proc/dumper",
+ "/proc/self/as",
+ "/var/log/messages",
+ NULL
+};
#endif /* NEED_PRAND_CONF */
+
diff --git a/includes/cf/rhapsody.h b/includes/cf/rhapsody.h
index 4a992869..2622004f 100644
--- a/includes/cf/rhapsody.h
+++ b/includes/cf/rhapsody.h
@@ -3,7 +3,7 @@
System dependencies for NetBSD... */
/*
- * Copyright (c) 1996-1999 Internet Software Consortium.
+ * Copyright (c) 1996-2001 Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -101,6 +101,8 @@ extern int h_errno;
#define PTRSIZE_64BIT
#endif
+#define SOCKLEN_T int
+
#ifdef NEED_PRAND_CONF
const char *cmds[] = {
"/bin/ps -axlw 2>&1",
diff --git a/includes/cf/sunos4.h b/includes/cf/sunos4.h
index 507de374..7a8c9587 100644
--- a/includes/cf/sunos4.h
+++ b/includes/cf/sunos4.h
@@ -56,6 +56,8 @@
#define SOCKLEN_T int
#define fpos_t long
+#define fgetpos(f, p) ((*pos = ftell (f)) == -1 ? -1 : 0)
+#define fsetpos(f, p) (fseek (f, p, SEEK_SET))
/* No endian.h either. */
/*
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index d7c56a25..3723b342 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -76,7 +76,7 @@
#include "inet.h"
#include "dhctoken.h"
-#include <isc/result.h>
+#include <isc-dhcp/result.h>
#include <omapip/omapip_p.h>
#if !defined (OPTION_HASH_SIZE)
@@ -90,6 +90,14 @@
(((x) >> OPTION_HASH_EXP) & \
(OPTION_HASH_PTWO - 1))) % OPTION_HASH_SIZE;
+enum dhcp_shutdown_state {
+ shutdown_listeners,
+ shutdown_omapi_connections,
+ shutdown_drop_omapi_connections,
+ shutdown_dhcp,
+ shutdown_done
+};
+
/* Client FQDN option, failover FQDN option, etc. */
typedef struct {
u_int8_t codes [2];
@@ -233,6 +241,19 @@ struct hardware {
u_int8_t hbuf [17];
};
+typedef enum {
+ server_startup = 0,
+ server_running = 1,
+ server_shutdown = 2,
+ server_hibernate = 3,
+ server_awaken = 4
+} control_object_state_t;
+
+typedef struct {
+ OMAPI_OBJECT_PREAMBLE;
+ control_object_state_t state;
+} dhcp_control_object_t;
+
/* Lease states: */
typedef enum {
FTS_FREE = 1,
@@ -529,6 +550,7 @@ struct pool {
int lease_count;
int free_leases;
int backup_leases;
+ int index;
#if defined (FAILOVER_PROTOCOL)
dhcp_failover_state_t *failover_peer;
#endif
@@ -691,7 +713,6 @@ struct client_config {
struct iaddrlist *reject_list; /* Servers to reject. */
- struct option_state *send_options; /* Options to send. */
int omapi_port; /* port on which to accept OMAPI
connections, or -1 for no
listener. */
@@ -724,6 +745,8 @@ struct client_state {
struct client_config *config; /* Client configuration. */
struct string_list *env; /* Client script environment. */
int envc; /* Number of entries in environment. */
+
+ struct option_state *sent_options; /* Options we sent. */
};
/* Information about each network interface. */
@@ -842,6 +865,12 @@ struct dns_zone {
struct auth_key *key;
};
+struct icmp_state {
+ OMAPI_OBJECT_PREAMBLE;
+ int socket;
+ void (*icmp_handler) PROTO ((struct iaddr, u_int8_t *, int));
+};
+
#include "ctrace.h"
/* Bitmask of dhcp option codes. */
@@ -939,7 +968,8 @@ const char *pretty_print_option PROTO ((struct option *, const unsigned char *,
int get_option (struct data_string *, struct universe *,
struct packet *, struct lease *, struct client_state *,
struct option_state *, struct option_state *,
- struct option_state *, struct binding_scope **, unsigned);
+ struct option_state *, struct binding_scope **, unsigned,
+ const char *, int);
void set_option (struct universe *, struct option_state *,
struct option_cache *, enum statement_op);
struct option_cache *lookup_option PROTO ((struct universe *,
@@ -1082,10 +1112,15 @@ extern int dhcp_max_agent_option_packet_length;
int main PROTO ((int, char **, char **));
void postconf_initialization (int);
+void postdb_startup (void);
void cleanup PROTO ((void));
void lease_pinged PROTO ((struct iaddr, u_int8_t *, int));
void lease_ping_timeout PROTO ((void *));
int dhcpd_interface_setup_hook (struct interface_info *ip, struct iaddr *ia);
+enum dhcp_shutdown_state shutdown_state;
+isc_result_t dhcp_io_shutdown (omapi_object_t *, void *);
+isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
+ control_object_state_t newstate);
/* conflex.c */
isc_result_t new_parse PROTO ((struct parse **, int,
@@ -1211,8 +1246,9 @@ int make_const_option_cache PROTO ((struct option_cache **, struct buffer **,
const char *, int));
int make_host_lookup PROTO ((struct expression **, const char *));
int enter_dns_host PROTO ((struct dns_host_entry **, const char *));
-int make_const_data PROTO ((struct expression **,
- const unsigned char *, unsigned, int, int));
+int make_const_data (struct expression **,
+ const unsigned char *, unsigned, int, int,
+ const char *, int);
int make_const_int PROTO ((struct expression **, unsigned long));
int make_concat PROTO ((struct expression **,
struct expression *, struct expression *));
@@ -1222,11 +1258,13 @@ int make_substring PROTO ((struct expression **, struct expression *,
int make_limit PROTO ((struct expression **, struct expression *, int));
int make_let PROTO ((struct executable_statement **, const char *));
int option_cache PROTO ((struct option_cache **, struct data_string *,
- struct expression *, struct option *));
+ struct expression *, struct option *,
+ const char *, int));
int evaluate_expression (struct binding_value **, struct packet *,
struct lease *, struct client_state *,
struct option_state *, struct option_state *,
- struct binding_scope **, struct expression *);
+ struct binding_scope **, struct expression *,
+ const char *, int);
int binding_value_dereference (struct binding_value **, const char *, int);
#if defined (NSUPDATE)
int evaluate_dns_expression PROTO ((ns_updrec **, struct packet *,
@@ -1250,7 +1288,7 @@ int evaluate_data_expression PROTO ((struct data_string *,
struct option_state *,
struct option_state *,
struct binding_scope **,
- struct expression *));
+ struct expression *, const char *, int));
int evaluate_numeric_expression (unsigned long *, struct packet *,
struct lease *, struct client_state *,
struct option_state *, struct option_state *,
@@ -1345,7 +1383,12 @@ int clone_group (struct group **, struct group *, const char *, int);
int write_group PROTO ((struct group_object *));
/* salloc.c */
+void relinquish_lease_hunks (void);
struct lease *new_leases PROTO ((unsigned, const char *, int));
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+void relinquish_free_lease_states (void);
+#endif
OMAPI_OBJECT_ALLOC_DECL (lease, struct lease, dhcp_type_lease)
OMAPI_OBJECT_ALLOC_DECL (class, struct class, dhcp_type_class)
OMAPI_OBJECT_ALLOC_DECL (subclass, struct class, dhcp_type_subclass)
@@ -1357,6 +1400,17 @@ OMAPI_OBJECT_ALLOC_DECL (subnet, struct subnet, dhcp_type_subnet)
OMAPI_OBJECT_ALLOC_DECL (shared_network, struct shared_network,
dhcp_type_shared_network)
OMAPI_OBJECT_ALLOC_DECL (group_object, struct group_object, dhcp_type_group)
+OMAPI_OBJECT_ALLOC_DECL (dhcp_control,
+ dhcp_control_object_t, dhcp_type_control)
+
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+void relinquish_free_pairs (void);
+void relinquish_free_expressions (void);
+void relinquish_free_binding_values (void);
+void relinquish_free_option_caches (void);
+void relinquish_free_packets (void);
+#endif
int option_chain_head_allocate (struct option_chain_head **,
const char *, int);
@@ -1449,6 +1503,7 @@ int dns_zone_reference PROTO ((struct dns_zone **,
/* print.c */
char *quotify_string (const char *, const char *, int);
char *quotify_buf (const unsigned char *, unsigned, const char *, int);
+char *print_base64 (const unsigned char *, unsigned, const char *, int);
char *print_hw_addr PROTO ((int, int, unsigned char *));
void print_lease PROTO ((struct lease *));
void dump_raw PROTO ((const unsigned char *, unsigned));
@@ -1701,11 +1756,15 @@ isc_result_t interface_stuff_values (omapi_object_t *,
void add_timeout PROTO ((TIME, void (*) PROTO ((void *)), void *,
tvref_t, tvunref_t));
void cancel_timeout PROTO ((void (*) PROTO ((void *)), void *));
+void cancel_all_timeouts (void);
+void relinquish_timeouts (void);
+#if 0
struct protocol *add_protocol PROTO ((const char *, int,
void (*) PROTO ((struct protocol *)),
void *));
void remove_protocol PROTO ((struct protocol *));
+#endif
OMAPI_OBJECT_ALLOC_DECL (interface,
struct interface_info, dhcp_type_interface)
@@ -1755,6 +1814,8 @@ struct iaddr broadcast_addr PROTO ((struct iaddr, struct iaddr));
u_int32_t host_addr PROTO ((struct iaddr, struct iaddr));
int addr_eq PROTO ((struct iaddr, struct iaddr));
char *piaddr PROTO ((struct iaddr));
+char *piaddrmask (struct iaddr, struct iaddr, const char *, int);
+char *piaddr1 PROTO ((struct iaddr));
/* dhclient.c */
extern const char *path_dhclient_conf;
@@ -1779,6 +1840,7 @@ void state_init PROTO ((void *));
void state_selecting PROTO ((void *));
void state_requesting PROTO ((void *));
void state_bound PROTO ((void *));
+void state_stop PROTO ((void *));
void state_panic PROTO ((void *));
void bind_lease PROTO ((struct client_state *));
@@ -1823,6 +1885,7 @@ void do_release PROTO ((struct client_state *));
int dhclient_interface_shutdown_hook (struct interface_info *);
int dhclient_interface_discovery_hook (struct interface_info *);
isc_result_t dhclient_interface_startup_hook (struct interface_info *);
+void client_dns_update (struct client_state *client, int);
/* db.c */
int write_lease PROTO ((struct lease *));
@@ -1837,7 +1900,7 @@ void write_billing_classes (void);
int write_billing_class PROTO ((struct class *));
int commit_leases PROTO ((void));
void db_startup PROTO ((int));
-void new_lease_file PROTO ((void));
+int new_lease_file PROTO ((void));
int group_writer (struct group_object *);
/* packet.c */
@@ -1908,6 +1971,8 @@ void set_ip_address PROTO ((struct interface_info *, struct in_addr));
/* clparse.c */
isc_result_t read_client_conf PROTO ((void));
+int read_client_conf_file (const char *,
+ struct interface_info *, struct client_config *);
void read_client_leases PROTO ((void));
void parse_client_statement PROTO ((struct parse *, struct interface_info *,
struct client_config *));
@@ -1943,6 +2008,8 @@ int add_relay_agent_options PROTO ((struct interface_info *,
unsigned, struct in_addr));
/* icmp.c */
+OMAPI_OBJECT_ALLOC_DECL (icmp_state, struct icmp_state, dhcp_type_icmp)
+extern struct icmp_state *icmp_state;
void icmp_startup PROTO ((int, void (*) PROTO ((struct iaddr,
u_int8_t *, int))));
int icmp_readsocket PROTO ((omapi_object_t *));
@@ -1964,7 +2031,11 @@ isc_result_t find_cached_zone (const char *, ns_class, char *,
void forget_zone (struct dns_zone **);
void repudiate_zone (struct dns_zone **);
void cache_found_zone (ns_class, char *, struct in_addr *, int);
-int get_dhcid (struct data_string *, struct lease *);
+int get_dhcid (struct data_string *, int, const u_int8_t *, unsigned);
+isc_result_t ddns_update_a (struct data_string *, struct iaddr,
+ struct data_string *, unsigned long, int);
+isc_result_t ddns_remove_a (struct data_string *,
+ struct iaddr, struct data_string *);
#endif /* NSUPDATE */
HASH_FUNCTIONS_DECL (dns_zone, const char *, struct dns_zone)
@@ -2022,12 +2093,17 @@ int find_matching_case (struct executable_statement **,
struct option_state *, struct option_state *,
struct binding_scope **,
struct expression *, struct executable_statement *);
+int executable_statement_foreach (struct executable_statement *,
+ int (*) (struct executable_statement *,
+ void *, int), void *, int);
/* comapi.c */
extern omapi_object_type_t *dhcp_type_interface;
extern omapi_object_type_t *dhcp_type_group;
extern omapi_object_type_t *dhcp_type_shared_network;
extern omapi_object_type_t *dhcp_type_subnet;
+extern omapi_object_type_t *dhcp_type_control;
+extern dhcp_control_object_t *dhcp_control_object;
void dhcp_common_objects_setup (void);
@@ -2050,6 +2126,25 @@ isc_result_t dhcp_group_create (omapi_object_t **,
isc_result_t dhcp_group_remove (omapi_object_t *,
omapi_object_t *);
+isc_result_t dhcp_control_set_value (omapi_object_t *, omapi_object_t *,
+ omapi_data_string_t *,
+ omapi_typed_data_t *);
+isc_result_t dhcp_control_get_value (omapi_object_t *, omapi_object_t *,
+ omapi_data_string_t *,
+ omapi_value_t **);
+isc_result_t dhcp_control_destroy (omapi_object_t *, const char *, int);
+isc_result_t dhcp_control_signal_handler (omapi_object_t *,
+ const char *, va_list);
+isc_result_t dhcp_control_stuff_values (omapi_object_t *,
+ omapi_object_t *,
+ omapi_object_t *);
+isc_result_t dhcp_control_lookup (omapi_object_t **,
+ omapi_object_t *, omapi_object_t *);
+isc_result_t dhcp_control_create (omapi_object_t **,
+ omapi_object_t *);
+isc_result_t dhcp_control_remove (omapi_object_t *,
+ omapi_object_t *);
+
isc_result_t dhcp_subnet_set_value (omapi_object_t *, omapi_object_t *,
omapi_data_string_t *,
omapi_typed_data_t *);
@@ -2273,6 +2368,15 @@ isc_result_t dhcp_interface_remove (omapi_object_t *,
void interface_stash (struct interface_info *);
void interface_snorf (struct interface_info *, int);
+isc_result_t binding_scope_set_value (struct binding_scope *, int,
+ omapi_data_string_t *,
+ omapi_typed_data_t *);
+isc_result_t binding_scope_get_value (omapi_value_t **,
+ struct binding_scope *,
+ omapi_data_string_t *);
+isc_result_t binding_scope_stuff_values (omapi_object_t *,
+ struct binding_scope *);
+
/* mdb.c */
extern struct subnet *subnets;
@@ -2328,11 +2432,15 @@ 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 *));
-void write_leases PROTO ((void));
+int write_leases PROTO ((void));
int lease_enqueue (struct lease *);
void lease_instantiate (const unsigned char *, unsigned, struct lease *);
void expire_all_pools PROTO ((void));
void dump_subnets PROTO ((void));
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+void free_everything (void);
+#endif
HASH_FUNCTIONS_DECL (lease, const unsigned char *, struct lease)
HASH_FUNCTIONS_DECL (host, const unsigned char *, struct host_decl)
HASH_FUNCTIONS_DECL (class, const char *, struct class)
@@ -2354,8 +2462,9 @@ int deletePTR (const struct data_string *, const struct data_string *,
/* failover.c */
#if defined (FAILOVER_PROTOCOL)
+extern dhcp_failover_state_t *failover_states;
void dhcp_failover_startup PROTO ((void));
-void dhcp_failover_write_all_states (void);
+int dhcp_failover_write_all_states (void);
isc_result_t enter_failover_peer PROTO ((dhcp_failover_state_t *));
isc_result_t find_failover_peer PROTO ((dhcp_failover_state_t **,
const char *, const char *, int));
diff --git a/includes/dhctoken.h b/includes/dhctoken.h
index 38cb5eea..876d8f39 100644
--- a/includes/dhctoken.h
+++ b/includes/dhctoken.h
@@ -313,7 +313,9 @@ enum dhcp_token {
RECOVER_WAIT = 608,
SERVER = 609,
CONNECT = 610,
- REMOVE = 611
+ REMOVE = 611,
+ REFRESH = 612,
+ DOMAIN_NAME = 613
};
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
diff --git a/includes/failover.h b/includes/failover.h
index 9c7bd813..26854476 100644
--- a/includes/failover.h
+++ b/includes/failover.h
@@ -3,7 +3,7 @@
Definitions for address trees... */
/*
- * Copyright (c) 1999 Internet Software Consortium.
+ * Copyright (c) 2000-2001 Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/includes/minires/minires.h b/includes/minires/minires.h
index 8e69a775..2a6a1336 100644
--- a/includes/minires/minires.h
+++ b/includes/minires/minires.h
@@ -20,7 +20,7 @@
#include "minires/resolv.h"
#include "minires/res_update.h"
-#include "isc/result.h"
+#include "isc-dhcp/result.h"
/*
* Based on the Dynamic DNS reference implementation by Viraj Bais
diff --git a/includes/minires/res_update.h b/includes/minires/res_update.h
index d941dee6..634c11a9 100644
--- a/includes/minires/res_update.h
+++ b/includes/minires/res_update.h
@@ -16,7 +16,7 @@
*/
/*
- * $Id: res_update.h,v 1.2 2001/01/11 02:16:09 mellon Exp $
+ * $Id: res_update.h,v 1.3 2001/06/27 00:30:24 mellon Exp $
*/
#ifndef __RES_UPDATE_H
@@ -24,7 +24,7 @@
#include <sys/types.h>
#include "arpa/nameser.h"
-#include <isc/list.h>
+#include <isc-dhcp/list.h>
/*
* This RR-like structure is particular to UPDATE.
diff --git a/includes/netinet/if_ether.h b/includes/netinet/if_ether.h
index f61b18b6..e53b4c7f 100644
--- a/includes/netinet/if_ether.h
+++ b/includes/netinet/if_ether.h
@@ -48,28 +48,14 @@ struct ether_addr {
*/
#define ETHER_ADDR_LEN 6
-struct ether_header {
+struct isc_ether_header {
u_int8_t ether_dhost[ETHER_ADDR_LEN];
u_int8_t ether_shost[ETHER_ADDR_LEN];
u_int16_t ether_type;
};
-#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
-#define ETHERTYPE_IP 0x0800 /* IP protocol */
-#define ETHERTYPE_ARP 0x0806 /* address resolution protocol */
-#define ETHERTYPE_REVARP 0x8035 /* reverse addr resolution protocol */
-
-/*
- * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
- * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
- * by an ETHER type (as given above) and then the (variable-length) header.
- */
-#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
-#define ETHERTYPE_NTRAILER 16
-
-#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
-
-#define ETHERMTU 1500
-#define ETHERMIN (60-14)
+#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
+#define ETHERTYPE_IP 0x0800 /* IP protocol */
+#define ETHERTYPE_ARP 0x0806 /* address resolution protocol */
#define ETHER_HEADER_SIZE (ETHER_ADDR_LEN * 2 + sizeof (u_int16_t))
diff --git a/includes/omapip/alloc.h b/includes/omapip/alloc.h
index 911b61eb..a130a203 100644
--- a/includes/omapip/alloc.h
+++ b/includes/omapip/alloc.h
@@ -3,7 +3,7 @@
Definitions for the object management API protocol memory allocation... */
/*
- * Copyright (c) 1996-1999 Internet Software Consortium.
+ * Copyright (c) 1996-2001 Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,8 @@ isc_result_t omapi_buffer_reference (omapi_buffer_t **,
omapi_buffer_t *, const char *, int);
isc_result_t omapi_buffer_dereference (omapi_buffer_t **, const char *, int);
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
#define DMDOFFSET (sizeof (struct dmalloc_preamble))
#define DMLFSIZE 16
#define DMUFSIZE 16
@@ -78,24 +79,23 @@ struct rc_history_entry {
int refcnt;
};
-#define rc_register(x, l, r, y, z) do { \
+#define rc_register(x, l, r, y, z, d) do { \
rc_history [rc_history_index].file = (x); \
rc_history [rc_history_index].line = (l); \
rc_history [rc_history_index].reference = (r); \
rc_history [rc_history_index].addr = (y); \
rc_history [rc_history_index].refcnt = (z); \
- if (++rc_history_index == RC_HISTORY_MAX) \
- rc_history_index = 0; \
- ++rc_history_count; \
+ rc_history_next (d); \
} while (0)
-#define rc_register_mdl(r, y, z) \
- rc_register (__FILE__, __LINE__, r, y, z)
+#define rc_register_mdl(r, y, z, d) \
+ rc_register (__FILE__, __LINE__, r, y, z, d)
#else
-#define rc_register(file, line, reference, addr, refcnt)
-#define rc_register_mdl(reference, addr, refcnt)
+#define rc_register(file, line, reference, addr, refcnt, d)
+#define rc_register_mdl(reference, addr, refcnt, d)
#endif
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
extern struct dmalloc_preamble *dmalloc_list;
extern unsigned long dmalloc_outstanding;
extern unsigned long dmalloc_longterm;
diff --git a/includes/omapip/hash.h b/includes/omapip/hash.h
index 94e48bb2..3f91d403 100644
--- a/includes/omapip/hash.h
+++ b/includes/omapip/hash.h
@@ -123,11 +123,13 @@ int name##_hash_foreach (struct hash_table *table, \
}
+void relinquish_hash_bucket_hunks (void);
struct hash_table *new_hash_table (int, const char *, int);
void free_hash_table (struct hash_table *, const char *, int);
struct hash_bucket *new_hash_bucket (const char *, int);
void free_hash_bucket (struct hash_bucket *, const char *, int);
-struct hash_table *new_hash (hash_reference, hash_dereference, int);
+struct hash_table *new_hash (hash_reference, hash_dereference, int,
+ const char *, int);
void add_hash (struct hash_table *,
const unsigned char *, unsigned, hashed_object_t *,
const char *, int);
diff --git a/includes/omapip/omapip.h b/includes/omapip/omapip.h
index ae856fa4..84359986 100644
--- a/includes/omapip/omapip.h
+++ b/includes/omapip/omapip.h
@@ -43,7 +43,7 @@
#ifndef _OMAPIP_H_
#define _OMAPIP_H_
-#include <isc/result.h>
+#include <isc-dhcp/result.h>
typedef unsigned int omapi_handle_t;
@@ -215,6 +215,12 @@ isc_result_t name##_array_allocate (omapi_array_t **p, \
file, line)); \
} \
\
+isc_result_t name##_array_free (omapi_array_t **p, \
+ const char *file, int line) \
+{ \
+ return omapi_array_free (p, file, line); \
+} \
+ \
isc_result_t name##_array_extend (omapi_array_t *pptr, stype *ptr, int *index,\
const char *file, int line) \
{ \
@@ -235,6 +241,7 @@ isc_result_t name##_array_lookup (stype **ptr, omapi_array_t *pptr, \
#define OMAPI_ARRAY_TYPE_DECL(name, stype) \
isc_result_t name##_array_allocate (omapi_array_t **, const char *, int); \
+isc_result_t name##_array_free (omapi_array_t **, const char *, int); \
isc_result_t name##_array_extend (omapi_array_t *, stype *, int *, \
const char *, int); \
isc_result_t name##_array_set (omapi_array_t *, \
@@ -247,6 +254,7 @@ isc_result_t name##_array_lookup (stype **, \
int omapi_array_foreach_index; \
stype *var = (stype *)0; \
for (omapi_array_foreach_index = 0; \
+ array && \
omapi_array_foreach_index < (array) -> count; \
omapi_array_foreach_index++) { \
if ((array) -> data [omapi_array_foreach_index]) { \
@@ -395,6 +403,9 @@ isc_result_t omapi_io_stuff_values (omapi_object_t *,
omapi_object_t *);
isc_result_t omapi_waiter_signal_handler (omapi_object_t *,
const char *, va_list);
+isc_result_t omapi_io_state_foreach (isc_result_t (*func) (omapi_object_t *,
+ void *),
+ void *p);
isc_result_t omapi_generic_new (omapi_object_t **, const char *, int);
isc_result_t omapi_generic_set_value (omapi_object_t *, omapi_object_t *,
@@ -409,6 +420,7 @@ isc_result_t omapi_generic_signal_handler (omapi_object_t *,
isc_result_t omapi_generic_stuff_values (omapi_object_t *,
omapi_object_t *,
omapi_object_t *);
+isc_result_t omapi_generic_clear_flags (omapi_object_t *);
isc_result_t omapi_message_new (omapi_object_t **, const char *, int);
isc_result_t omapi_message_set_value (omapi_object_t *, omapi_object_t *,
@@ -456,6 +468,7 @@ extern omapi_object_type_t *omapi_type_auth_key;
extern omapi_object_type_t *omapi_object_types;
+void omapi_type_relinquish (void);
isc_result_t omapi_init (void);
isc_result_t omapi_object_type_register (omapi_object_type_t **,
const char *,
@@ -545,7 +558,8 @@ isc_result_t omapi_handle_td_lookup (omapi_object_t **, omapi_typed_data_t *);
void * dmalloc (unsigned, const char *, int);
void dfree (void *, const char *, int);
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
void dmalloc_reuse (void *, const char *, int, int);
void dmalloc_dump_outstanding (void);
#else
@@ -553,8 +567,10 @@ void dmalloc_dump_outstanding (void);
#endif
#define MDL __FILE__, __LINE__
#if defined (DEBUG_RC_HISTORY)
-void dump_rc_history (void);
+void dump_rc_history (void *);
+void rc_history_next (int);
#endif
+void omapi_print_dmalloc_usage_by_caller (void);
isc_result_t omapi_object_allocate (omapi_object_t **,
omapi_object_type_t *,
size_t, const char *, int);
@@ -592,6 +608,7 @@ isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **,
isc_result_t omapi_array_allocate (omapi_array_t **, omapi_array_ref_t,
omapi_array_deref_t, const char *, int);
+isc_result_t omapi_array_free (omapi_array_t **, const char *, int);
isc_result_t omapi_array_extend (omapi_array_t *, char *, int *,
const char *, int);
isc_result_t omapi_array_set (omapi_array_t *, void *, int, const char *, int);
diff --git a/includes/omapip/omapip_p.h b/includes/omapip/omapip_p.h
index d6e646aa..d64df0ec 100644
--- a/includes/omapip/omapip_p.h
+++ b/includes/omapip/omapip_p.h
@@ -69,8 +69,8 @@
#include "cdefs.h"
#include "osdep.h"
-#include <isc/dst.h>
-#include <isc/result.h>
+#include <isc-dhcp/dst.h>
+#include <isc-dhcp/result.h>
#include <omapip/convert.h>
#include <omapip/hash.h>
@@ -120,6 +120,7 @@ typedef struct __omapi_message_object {
struct __omapi_message_object *next, *prev;
omapi_object_t *object;
omapi_object_t *notify_object;
+ struct __omapi_protocol_object *protocol_object;
u_int32_t authlen;
omapi_typed_data_t *authenticator;
u_int32_t authid;
@@ -136,7 +137,7 @@ typedef struct __omapi_remote_auth {
omapi_object_t *a;
} omapi_remote_auth_t;
-typedef struct {
+typedef struct __omapi_protocol_object {
OMAPI_OBJECT_PREAMBLE;
u_int32_t header_size;
u_int32_t protocol_version;
@@ -216,6 +217,7 @@ typedef struct __omapi_io_object {
typedef struct __omapi_generic_object {
OMAPI_OBJECT_PREAMBLE;
omapi_value_t **values;
+ u_int8_t *changed;
int nvalues, va_max;
} omapi_generic_object_t;
@@ -294,4 +296,7 @@ void do_percentm (char *obuf, const char *ibuf);
isc_result_t uerr2isc (int);
isc_result_t ns_rcode_to_isc (int);
+
+extern omapi_message_object_t *omapi_registered_messages;
+
#endif /* __OMAPIP_OMAPIP_P_H__ */
diff --git a/includes/omapip/trace.h b/includes/omapip/trace.h
index 7bc0e509..69cb3edb 100644
--- a/includes/omapip/trace.h
+++ b/includes/omapip/trace.h
@@ -96,6 +96,7 @@ typedef struct {
u_int16_t port;
} trace_addr_t;
+void trace_free_all (void);
int trace_playback (void);
int trace_record (void);
isc_result_t trace_init (void (*set_time) (u_int32_t), const char *, int);
diff --git a/includes/osdep.h b/includes/osdep.h
index cca2bf8e..c4486e85 100644
--- a/includes/osdep.h
+++ b/includes/osdep.h
@@ -194,7 +194,7 @@
#if defined (USE_BPF_SEND) || defined (USE_NIT_SEND) || \
defined (USE_DLPI_SEND) || defined (USE_UPF_SEND) || \
defined (USE_LPF_SEND) || \
- (defined (USE_SOCKET_SEND) && defined (SO_BINDTODEVICE))
+ (defined (USE_SOCKET_SEND) && defined (HAVE_SO_BINDTODEVICE))
# define USE_SOCKET_FALLBACK
# define USE_FALLBACK
#endif
diff --git a/includes/statement.h b/includes/statement.h
index fb0d3945..fa865f38 100644
--- a/includes/statement.h
+++ b/includes/statement.h
@@ -69,7 +69,7 @@ struct executable_statement {
} op;
union {
struct {
- struct executable_statement *true, *false;
+ struct executable_statement *tc, *fc;
struct expression *expr;
} ie;
struct expression *eval;
diff --git a/includes/version.h b/includes/version.h
index ec4e75ed..193122bc 100644
--- a/includes/version.h
+++ b/includes/version.h
@@ -1,3 +1,3 @@
/* Current version of ISC DHCP Distribution. */
-#define DHCP_VERSION "V3.1-unreleased"
+#define DHCP_VERSION "V3.0rc8pl2"
diff --git a/minires/ns_sign.c b/minires/ns_sign.c
index f1d603d1..1137302a 100644
--- a/minires/ns_sign.c
+++ b/minires/ns_sign.c
@@ -16,7 +16,7 @@
*/
#ifndef lint
-static const char rcsid[] = "$Id: ns_sign.c,v 1.4 2001/02/15 14:10:58 mellon Exp $";
+static const char rcsid[] = "$Id: ns_sign.c,v 1.5 2001/06/27 00:30:32 mellon Exp $";
#endif
#if defined (TRACING)
@@ -44,7 +44,7 @@ time_t trace_mr_time (time_t *);
#include "minires/minires.h"
#include "arpa/nameser.h"
-#include <isc/dst.h>
+#include <isc-dhcp/dst.h>
#define BOUNDS_CHECK(ptr, count) \
do { \
diff --git a/minires/ns_verify.c b/minires/ns_verify.c
index ce11e873..4ebca7cf 100644
--- a/minires/ns_verify.c
+++ b/minires/ns_verify.c
@@ -16,7 +16,7 @@
*/
#ifndef lint
-static const char rcsid[] = "$Id: ns_verify.c,v 1.5 2001/02/22 07:28:22 mellon Exp $";
+static const char rcsid[] = "$Id: ns_verify.c,v 1.6 2001/06/27 00:30:33 mellon Exp $";
#endif
#define time(x) trace_mr_time (x)
@@ -40,7 +40,7 @@ static const char rcsid[] = "$Id: ns_verify.c,v 1.5 2001/02/22 07:28:22 mellon E
#include "minires/minires.h"
#include "arpa/nameser.h"
-#include <isc/dst.h>
+#include <isc-dhcp/dst.h>
time_t trace_mr_time (time_t *);
diff --git a/minires/res_findzonecut.c b/minires/res_findzonecut.c
index 4d6bff29..35d47d87 100644
--- a/minires/res_findzonecut.c
+++ b/minires/res_findzonecut.c
@@ -1,5 +1,5 @@
#if !defined(lint) && !defined(SABER)
-static const char rcsid[] = "$Id: res_findzonecut.c,v 1.14 2001/04/27 20:01:29 mellon Exp $";
+static const char rcsid[] = "$Id: res_findzonecut.c,v 1.15 2001/06/27 00:30:34 mellon Exp $";
#endif /* not lint */
/*
@@ -36,7 +36,7 @@ static const char rcsid[] = "$Id: res_findzonecut.c,v 1.14 2001/04/27 20:01:29 m
#include <stdlib.h>
#include <string.h>
-#include <isc/list.h>
+#include <isc-dhcp/list.h>
#include "minires/minires.h"
#include "arpa/nameser.h"
diff --git a/minires/res_init.c b/minires/res_init.c
index 512cdfed..cfdbb596 100644
--- a/minires/res_init.c
+++ b/minires/res_init.c
@@ -70,7 +70,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
-static const char rcsid[] = "$Id: res_init.c,v 1.4 2001/02/22 07:28:23 mellon Exp $";
+static const char rcsid[] = "$Id: res_init.c,v 1.5 2001/06/27 00:30:35 mellon Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -132,7 +132,7 @@ static u_int32_t net_mask (struct in_addr);
*
* Return 0 if completes successfully, -1 on error
*/
-extern int __res_vinit(res_state, int);
+extern int minires_vinit(res_state, int);
#if defined (TRACING)
u_int trace_mr_res_randomid(u_int);
@@ -141,12 +141,12 @@ u_int trace_mr_res_randomid(u_int);
int
res_ninit(res_state statp) {
- return (__res_vinit(statp, 0));
+ return (minires_vinit(statp, 0));
}
/* This function has to be reachable by res_data.c but not publically. */
int
-__res_vinit(res_state statp, int preinit) {
+minires_vinit(res_state statp, int preinit) {
register FILE *fp;
register char *cp, **pp;
register int n;
diff --git a/minires/res_sendsigned.c b/minires/res_sendsigned.c
index 3ed456d0..be213afe 100644
--- a/minires/res_sendsigned.c
+++ b/minires/res_sendsigned.c
@@ -15,7 +15,7 @@
#include "minires/minires.h"
#include "arpa/nameser.h"
-#include <isc/dst.h>
+#include <isc-dhcp/dst.h>
/* res_nsendsigned */
isc_result_t
@@ -59,7 +59,7 @@ res_nsendsigned(res_state statp,
if (dstkey == NULL) {
free(nstatp);
free(newmsg);
- return ISC_R_INVALIDARG;
+ return ISC_R_BADKEY;
}
nstatp->nscount = 1;
diff --git a/minires/res_update.c b/minires/res_update.c
index ffc384ab..4e2a8ec1 100644
--- a/minires/res_update.c
+++ b/minires/res_update.c
@@ -1,5 +1,5 @@
#if !defined(lint) && !defined(SABER)
-static const char rcsid[] = "$Id: res_update.c,v 1.11 2001/01/17 08:22:20 mellon Exp $";
+static const char rcsid[] = "$Id: res_update.c,v 1.12 2001/06/27 00:30:38 mellon Exp $";
#endif /* not lint */
/*
@@ -39,7 +39,7 @@ static const char rcsid[] = "$Id: res_update.c,v 1.11 2001/01/17 08:22:20 mellon
#include <stdlib.h>
#include <string.h>
-#include <isc/list.h>
+#include <isc-dhcp/list.h>
#include "minires/minires.h"
#include "arpa/nameser.h"
@@ -134,7 +134,7 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in) {
rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin,
zptr->z_class, ns_t_soa, 0);
if (rrecp == NULL) {
- rcode = -1; /* XXX */
+ rcode = ISC_R_UNEXPECTED;
goto done;
}
ISC_LIST_PREPEND(zptr->z_rrlist, rrecp, r_glink);
@@ -154,17 +154,18 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in) {
/* Send the update and remember the result. */
key = (ns_tsig_key *)0;
- if (!find_tsig_key (&key, zptr->z_origin, zcookie)) {
+ rcode = find_tsig_key (&key, zptr->z_origin, zcookie);
+ if (rcode == ISC_R_SUCCESS) {
rcode = res_nsendsigned(statp, packet, n, key,
answer, sizeof answer, &rval);
tkey_free (&key);
- } else {
+ } else if (rcode == ISC_R_NOTFOUND || rcode == ISC_R_KEY_UNKNOWN) {
rcode = res_nsend(statp, packet, n,
answer, sizeof answer, &rval);
}
- if (rcode != ISC_R_SUCCESS) {
+ if (rcode != ISC_R_SUCCESS)
goto undone;
- }
+
rcode = ns_rcode_to_isc (((HEADER *)answer)->rcode);
if (zcookie && rcode == ISC_R_BADSIG) {
repudiate_zone (&zcookie);
diff --git a/omapip/Makefile.dist b/omapip/Makefile.dist
index 4bd2b082..099f83e1 100644
--- a/omapip/Makefile.dist
+++ b/omapip/Makefile.dist
@@ -46,7 +46,8 @@ libomapi.a: $(OBJ)
$(RANLIB) libomapi.a
install: all
- for dir in $(LIBDIR) $(LIBMANDIR) $(INCDIR)/omapip $(INCDIR)/isc; do \
+ for dir in $(LIBDIR) $(LIBMANDIR) $(INCDIR)/omapip $(INCDIR)/isc-dhcp;\
+ do \
foo=""; \
for bar in `echo $(DESTDIR)$${dir} |tr / ' '`; do \
foo=$${foo}/$$bar; \
@@ -59,12 +60,14 @@ install: all
$(INSTALL) libomapi.a $(DESTDIR)$(LIBDIR)
$(CHMOD) 644 $(DESTDIR)$(LIBDIR)/libomapi.a
for file in alloc.h buffer.h omapip.h; do \
- $(INSTALL) $(TOP)/includes/omapip/$$file $(DESTDIR)$(INCDIR)/omapip; \
+ $(INSTALL) $(TOP)/includes/omapip/$$file \
+ $(DESTDIR)$(INCDIR)/omapip; \
$(CHMOD) 644 $(DESTDIR)$(INCDIR)/omapip/$$file; \
done
for file in boolean.h dst.h int.h lang.h list.h result.h types.h; do \
- $(INSTALL) $(TOP)/includes/isc/$$file $(DESTDIR)$(INCDIR)/isc; \
- $(CHMOD) 644 $(DESTDIR)$(INCDIR)/isc/$$file; \
+ $(INSTALL) $(TOP)/includes/isc-dhcp/$$file \
+ $(DESTDIR)$(INCDIR)/isc-dhcp; \
+ $(CHMOD) 644 $(DESTDIR)$(INCDIR)/isc-dhcp/$$file; \
done
for man in $(MAN); do \
prefix=`echo $$man |sed -e 's/\.[0-9]$$//'`; \
diff --git a/omapip/alloc.c b/omapip/alloc.c
index c7f07597..42161ca2 100644
--- a/omapip/alloc.c
+++ b/omapip/alloc.c
@@ -4,7 +4,7 @@
protocol... */
/*
- * Copyright (c) 1999-2000 Internet Software Consortium.
+ * Copyright (c) 1999-2001 Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,8 @@
#include <omapip/omapip_p.h>
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
struct dmalloc_preamble *dmalloc_list;
unsigned long dmalloc_outstanding;
unsigned long dmalloc_longterm;
@@ -70,7 +71,8 @@ VOIDPTR dmalloc (size, file, line)
unsigned char *foo = malloc (size + DMDSIZE);
int i;
VOIDPTR *bar;
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
struct dmalloc_preamble *dp;
#endif
if (!foo)
@@ -78,7 +80,8 @@ VOIDPTR dmalloc (size, file, line)
bar = (VOIDPTR)(foo + DMDOFFSET);
memset (bar, 0, size);
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
dp = (struct dmalloc_preamble *)foo;
dp -> prev = dmalloc_list;
if (dmalloc_list)
@@ -125,7 +128,7 @@ VOIDPTR dmalloc (size, file, line)
#endif
#endif
#ifdef DEBUG_REFCNT_DMALLOC_FREE
- rc_register (file, line, 0, foo + DMDOFFSET, 1);
+ rc_register (file, line, 0, foo + DMDOFFSET, 1, 0);
#endif
return bar;
}
@@ -139,7 +142,8 @@ void dfree (ptr, file, line)
log_error ("dfree %s(%d): free on null pointer.", file, line);
return;
}
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
{
unsigned char *bar = ptr;
struct dmalloc_preamble *dp, *cur;
@@ -188,12 +192,13 @@ void dfree (ptr, file, line)
}
#endif
#ifdef DEBUG_REFCNT_DMALLOC_FREE
- rc_register (file, line, 0, (unsigned char *)ptr + DMDOFFSET, 0);
+ rc_register (file, line, 0, (unsigned char *)ptr + DMDOFFSET, 0, 1);
#endif
free (ptr);
}
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
/* For allocation functions that keep their own free lists, we want to
account for the reuse of the memory. */
@@ -288,7 +293,8 @@ void dmalloc_dump_outstanding ()
}
}
#endif
-#if defined (DEBUG_MEMORY_LEAKAGE)
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
/* Don't count data that's actually on a free list
somewhere. */
if (dp -> file) {
@@ -342,7 +348,7 @@ static void print_rc_hist_entry (int i)
rc_history [i].refcnt);
}
-void dump_rc_history ()
+void dump_rc_history (void *addr)
{
int i;
@@ -357,7 +363,8 @@ void dump_rc_history ()
rc_history_count = 0;
while (rc_history [i].file) {
- print_rc_hist_entry (i);
+ if (!addr || addr == rc_history [i].addr)
+ print_rc_hist_entry (i);
++i;
if (i == RC_HISTORY_MAX)
i = 0;
@@ -365,8 +372,141 @@ void dump_rc_history ()
break;
}
}
+void rc_history_next (int d)
+{
+#if defined (RC_HISTORY_COMPRESSION)
+ int i, j = 0, m, n = 0;
+ void *ap, *rp;
+
+ /* If we are decreasing the reference count, try to find the
+ entry where the reference was made and eliminate it; then
+ we can also eliminate this reference. */
+ if (d) {
+ m = rc_history_index - 1000;
+ if (m < -1)
+ m = -1;
+ ap = rc_history [rc_history_index].addr;
+ rp = rc_history [rc_history_index].reference;
+ for (i = rc_history_index - 1; i > m; i--) {
+ if (rc_history [i].addr == ap) {
+ if (rc_history [i].reference == rp) {
+ if (n > 10) {
+ for (n = i; n <= rc_history_index; n++)
+ print_rc_hist_entry (n);
+ n = 11;
+ }
+ memmove (&rc_history [i],
+ &rc_history [i + 1],
+ (unsigned)((rc_history_index - i) *
+ sizeof (struct rc_history_entry)));
+ --rc_history_count;
+ --rc_history_index;
+ for (j = i; j < rc_history_count; j++) {
+ if (rc_history [j].addr == ap)
+ --rc_history [j].refcnt;
+ }
+ if (n > 10) {
+ for (n = i; n <= rc_history_index; n++)
+ print_rc_hist_entry (n);
+ n = 11;
+ exit (0);
+ }
+ return;
+ }
+ }
+ }
+ }
+#endif
+ if (++rc_history_index == RC_HISTORY_MAX)
+ rc_history_index = 0;
+ ++rc_history_count;
+}
#endif
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+struct caller {
+ struct dmalloc_preamble *dp;
+ int count;
+};
+
+static int dmalloc_find_entry (struct dmalloc_preamble *dp,
+ struct caller *array,
+ int min, int max)
+{
+ int middle;
+ int cmp;
+
+ middle = (min + max) / 2;
+ if (middle == min)
+ return middle;
+ if (array [middle].dp -> file == dp -> file) {
+ if (array [middle].dp -> line == dp -> line)
+ return middle;
+ else if (array [middle].dp -> line < dp -> line)
+ return dmalloc_find_entry (dp, array, middle, max);
+ else
+ return dmalloc_find_entry (dp, array, 0, middle);
+ } else if (array [middle].dp -> file < dp -> file)
+ return dmalloc_find_entry (dp, array, middle, max);
+ else
+ return dmalloc_find_entry (dp, array, 0, middle);
+}
+
+void omapi_print_dmalloc_usage_by_caller ()
+{
+ struct dmalloc_preamble *dp;
+ unsigned char *foo;
+ int ccur, cmax, i, j;
+ struct caller cp [1024];
+
+ cmax = 1024;
+ ccur = 0;
+
+ memset (cp, 0, sizeof cp);
+ for (dp = dmalloc_list; dp; dp = dp -> prev) {
+ i = dmalloc_find_entry (dp, cp, 0, ccur);
+ if ((i == ccur ||
+ cp [i].dp -> file != dp -> file ||
+ cp [i].dp -> line != dp -> line) &&
+ ccur == cmax) {
+ log_error ("no space for memory usage summary.");
+ return;
+ }
+ if (i == ccur) {
+ cp [ccur++].dp = dp;
+ cp [i].count = 1;
+ } else if (cp [i].dp -> file < dp -> file ||
+ (cp [i].dp -> file == dp -> file &&
+ cp [i].dp -> line < dp -> line)) {
+ if (i + 1 != ccur)
+ memmove (cp + i + 2, cp + i + 1,
+ (ccur - i) * sizeof *cp);
+ cp [i + 1].dp = dp;
+ cp [i + 1].count = 1;
+ ccur++;
+ } else if (cp [i].dp -> file != dp -> file ||
+ cp [i].dp -> line != dp -> line) {
+ memmove (cp + i + 1,
+ cp + i, (ccur - i) * sizeof *cp);
+ cp [i].dp = dp;
+ cp [i].count = 1;
+ ccur++;
+ } else
+ cp [i].count++;
+#if 0
+ printf ("%d\t%s:%d\n", i, dp -> file, dp -> line);
+ dump_rc_history (dp + 1);
+#endif
+ }
+ for (i = 0; i < ccur; i++) {
+ printf ("%d\t%s:%d\t%d\n", i,
+ cp [i].dp -> file, cp [i].dp -> line, cp [i].count);
+ dump_rc_history (cp [i].dp + 1);
+ }
+}
+#endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
+
isc_result_t omapi_object_allocate (omapi_object_t **o,
omapi_object_type_t *type,
size_t size,
@@ -438,10 +578,7 @@ isc_result_t omapi_object_reference (omapi_object_t **r,
}
*r = h;
h -> refcnt++;
- if (!h -> type -> freer) {
- rc_register (file, line, r, h, h -> refcnt);
- dmalloc_reuse (h, file, line, 1);
- }
+ rc_register (file, line, r, h, h -> refcnt, 0);
return ISC_R_SUCCESS;
}
@@ -452,7 +589,7 @@ isc_result_t omapi_object_dereference (omapi_object_t **h,
int inner_reference = 0;
int handle_reference = 0;
int extra_references;
- omapi_object_t *p;
+ omapi_object_t *p, *hp;
if (!h)
return ISC_R_INVALIDARG;
@@ -471,7 +608,7 @@ isc_result_t omapi_object_dereference (omapi_object_t **h,
log_error ("%s(%d): dereference of pointer with refcnt of zero!",
file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (*h);
#endif
abort ();
#else
@@ -537,31 +674,33 @@ isc_result_t omapi_object_dereference (omapi_object_t **h,
extra_references = 0;
if (!extra_references) {
+ hp = *h;
+ *h = 0;
+ hp -> refcnt--;
if (inner_reference)
omapi_object_dereference
- (&(*h) -> inner, file, line);
+ (&hp -> inner, file, line);
if (outer_reference)
omapi_object_dereference
- (&(*h) -> outer, file, line);
- (*h) -> refcnt--;
- if (!(*h) -> type -> freer)
- rc_register (file, line, h, *h, 0);
- if ((*h) -> type -> destroy)
- (*((*h) -> type -> destroy)) (*h, file, line);
- if ((*h) -> type -> freer)
- ((*h) -> type -> freer (*h, file, line));
+ (&hp -> outer, file, line);
+/* if (!hp -> type -> freer) */
+ rc_register (file, line, h, hp, 0, 1);
+ if (hp -> type -> destroy)
+ (*(hp -> type -> destroy)) (hp, file, line);
+ if (hp -> type -> freer)
+ (hp -> type -> freer (hp, file, line));
else
- dfree (*h, file, line);
+ dfree (hp, file, line);
} else {
(*h) -> refcnt--;
- if (!(*h) -> type -> freer)
+/* if (!(*h) -> type -> freer) */
rc_register (file, line,
- h, *h, (*h) -> refcnt);
+ h, *h, (*h) -> refcnt, 1);
}
} else {
(*h) -> refcnt--;
- if (!(*h) -> type -> freer)
- rc_register (file, line, h, *h, (*h) -> refcnt);
+/* if (!(*h) -> type -> freer) */
+ rc_register (file, line, h, *h, (*h) -> refcnt, 1);
}
*h = 0;
return ISC_R_SUCCESS;
@@ -602,8 +741,7 @@ isc_result_t omapi_buffer_reference (omapi_buffer_t **r,
}
*r = h;
h -> refcnt++;
- rc_register (file, line, r, h, h -> refcnt);
- dmalloc_reuse (h, file, line, 1);
+ rc_register (file, line, r, h, h -> refcnt, 0);
return ISC_R_SUCCESS;
}
@@ -627,7 +765,7 @@ isc_result_t omapi_buffer_dereference (omapi_buffer_t **h,
log_error ("%s(%d): dereference of pointer with refcnt of zero!",
file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (*h);
#endif
abort ();
#else
@@ -637,7 +775,7 @@ isc_result_t omapi_buffer_dereference (omapi_buffer_t **h,
}
--(*h) -> refcnt;
- rc_register (file, line, h, *h, (*h) -> refcnt);
+ rc_register (file, line, h, *h, (*h) -> refcnt, 1);
if ((*h) -> refcnt == 0)
dfree (*h, file, line);
*h = 0;
@@ -728,8 +866,7 @@ isc_result_t omapi_typed_data_reference (omapi_typed_data_t **r,
}
*r = h;
h -> refcnt++;
- rc_register (file, line, r, h, h -> refcnt);
- dmalloc_reuse (h, file, line, 1);
+ rc_register (file, line, r, h, h -> refcnt, 0);
return ISC_R_SUCCESS;
}
@@ -753,7 +890,7 @@ isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h,
log_error ("%s(%d): dereference of pointer with refcnt of zero!",
file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (*h);
#endif
abort ();
#else
@@ -763,7 +900,7 @@ isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h,
}
--((*h) -> refcnt);
- rc_register (file, line, h, *h, (*h) -> refcnt);
+ rc_register (file, line, h, *h, (*h) -> refcnt, 1);
if ((*h) -> refcnt <= 0 ) {
switch ((*h) -> type) {
case omapi_datatype_int:
@@ -812,8 +949,7 @@ isc_result_t omapi_data_string_reference (omapi_data_string_t **r,
}
*r = h;
h -> refcnt++;
- rc_register (file, line, r, h, h -> refcnt);
- dmalloc_reuse (h, file, line, 1);
+ rc_register (file, line, r, h, h -> refcnt, 0);
return ISC_R_SUCCESS;
}
@@ -837,7 +973,7 @@ isc_result_t omapi_data_string_dereference (omapi_data_string_t **h,
log_error ("%s(%d): dereference of pointer with refcnt of zero!",
file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (*h);
#endif
abort ();
#else
@@ -847,7 +983,7 @@ isc_result_t omapi_data_string_dereference (omapi_data_string_t **h,
}
--((*h) -> refcnt);
- rc_register (file, line, h, *h, (*h) -> refcnt);
+ rc_register (file, line, h, *h, (*h) -> refcnt, 1);
if ((*h) -> refcnt <= 0 ) {
dfree (*h, file, line);
}
@@ -885,8 +1021,7 @@ isc_result_t omapi_value_reference (omapi_value_t **r,
}
*r = h;
h -> refcnt++;
- rc_register (file, line, r, h, h -> refcnt);
- dmalloc_reuse (h, file, line, 1);
+ rc_register (file, line, r, h, h -> refcnt, 0);
return ISC_R_SUCCESS;
}
@@ -910,7 +1045,7 @@ isc_result_t omapi_value_dereference (omapi_value_t **h,
log_error ("%s(%d): dereference of pointer with refcnt of zero!",
file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (*h);
#endif
abort ();
#else
@@ -920,7 +1055,7 @@ isc_result_t omapi_value_dereference (omapi_value_t **h,
}
--((*h) -> refcnt);
- rc_register (file, line, h, *h, (*h) -> refcnt);
+ rc_register (file, line, h, *h, (*h) -> refcnt, 1);
if ((*h) -> refcnt == 0) {
if ((*h) -> name)
omapi_data_string_dereference (&(*h) -> name,
@@ -968,8 +1103,7 @@ isc_result_t omapi_addr_list_reference (omapi_addr_list_t **r,
}
*r = h;
h -> refcnt++;
- rc_register (file, line, r, h, h -> refcnt);
- dmalloc_reuse (h, file, line, 1);
+ rc_register (file, line, r, h, h -> refcnt, 0);
return ISC_R_SUCCESS;
}
@@ -993,7 +1127,7 @@ isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **h,
log_error ("%s(%d): dereference of pointer with zero refcnt!",
file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (*h);
#endif
abort ();
#else
@@ -1003,7 +1137,7 @@ isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **h,
}
--((*h) -> refcnt);
- rc_register (file, line, h, *h, (*h) -> refcnt);
+ rc_register (file, line, h, *h, (*h) -> refcnt, 1);
if ((*h) -> refcnt <= 0 ) {
dfree (*h, file, line);
}
diff --git a/omapip/array.c b/omapip/array.c
index 4823b9bb..56d8d9f2 100644
--- a/omapip/array.c
+++ b/omapip/array.c
@@ -64,6 +64,25 @@ isc_result_t omapi_array_allocate (omapi_array_t **array,
return ISC_R_SUCCESS;
}
+isc_result_t omapi_array_free (omapi_array_t **array,
+ const char *file, int line)
+{
+ isc_result_t status;
+ omapi_array_t *aptr;
+ int i;
+
+ if (!array || !*array)
+ return ISC_R_INVALIDARG;
+ aptr = *array;
+ for (i = 0; i < aptr -> count; i++)
+ if (aptr -> data [i] && aptr -> deref)
+ (*aptr -> deref) (&aptr -> data [i], file, line);
+ dfree (aptr -> data, MDL);
+ dfree (aptr, MDL);
+ *array = (omapi_array_t *)0;
+ return ISC_R_SUCCESS;
+}
+
/* Extend the size of the array by one entry (we may allocate more than that)
and store the specified value in the new array element. */
diff --git a/omapip/auth.c b/omapip/auth.c
index 2c6ba86d..1ad4150f 100644
--- a/omapip/auth.c
+++ b/omapip/auth.c
@@ -43,20 +43,20 @@
#ifndef lint
static char ocopyright[] =
-"$Id: auth.c,v 1.3 2001/05/02 17:00:32 mellon Exp $ Copyright 1998-2000 The Internet Software Consortium.";
+"$Id: auth.c,v 1.4 2001/06/27 00:30:42 mellon Exp $ Copyright 1998-2000 The Internet Software Consortium.";
#endif
#include <omapip/omapip_p.h>
OMAPI_OBJECT_ALLOC (omapi_auth_key, omapi_auth_key_t, omapi_type_auth_key)
-static struct hash_table *auth_key_hash = (struct hash_table *)0;
+struct hash_table *auth_key_hash = (struct hash_table *)0;
HASH_FUNCTIONS_DECL (omapi_auth_key, const char *, omapi_auth_key_t)
isc_result_t omapi_auth_key_new (omapi_auth_key_t **o, const char *file,
int line)
{
- return omapi_auth_key_allocate (o, MDL);
+ return omapi_auth_key_allocate (o, file, line);
}
isc_result_t omapi_auth_key_destroy (omapi_object_t *h,
@@ -105,7 +105,7 @@ isc_result_t omapi_auth_key_enter (omapi_auth_key_t *a)
auth_key_hash =
new_hash ((hash_reference)omapi_auth_key_reference,
(hash_dereference)omapi_auth_key_dereference,
- 1);
+ 1, MDL);
if (!auth_key_hash)
return ISC_R_NOMEMORY;
}
@@ -135,6 +135,9 @@ isc_result_t omapi_auth_key_lookup (omapi_object_t **h,
if (!auth_key_hash)
return ISC_R_NOTFOUND;
+ if (!ref)
+ return ISC_R_NOKEYS;
+
status = omapi_get_value_str (ref, id, "name", &name);
if (status != ISC_R_SUCCESS)
return status;
diff --git a/omapip/buffer.c b/omapip/buffer.c
index d007a23a..3d01357f 100644
--- a/omapip/buffer.c
+++ b/omapip/buffer.c
@@ -72,7 +72,7 @@ void omapi_buffer_trace_setup ()
static void trace_connection_input_input (trace_type_t *ttype,
unsigned length, char *buf)
{
- unsigned left, ol, cc = 0;
+ unsigned left, taken, cc = 0;
char *s;
int32_t connect_index;
isc_result_t status;
@@ -85,6 +85,7 @@ static void trace_connection_input_input (trace_type_t *ttype,
omapi_connection_object_t, lp) {
if (lp -> index == ntohl (connect_index)) {
omapi_connection_reference (&c, lp, MDL);
+ omapi_connection_dereference (&lp, MDL);
break;
}
} omapi_array_foreach_end (omapi_connections,
@@ -97,27 +98,30 @@ static void trace_connection_input_input (trace_type_t *ttype,
}
s = buf + sizeof connect_index;
- left = length - sizeof connect_index;;
+ left = length - sizeof connect_index;
while (left) {
- ol = left;
+ taken = 0;
status = omapi_connection_reader_trace ((omapi_object_t *)c,
- left, s, &length);
+ left, s, &taken);
if (status != ISC_R_SUCCESS) {
log_error ("trace connection input: %s",
isc_result_totext (status));
break;
}
- if (ol == left) {
+ if (!taken) {
if (cc > 0) {
log_error ("trace connection_input: %s",
"input is not being consumed.");
break;
}
cc++;
- } else
+ } else {
cc = 0;
+ left -= taken;
+ }
}
+ omapi_connection_dereference (&c, MDL);
}
static void trace_connection_input_stop (trace_type_t *ttype) { }
diff --git a/omapip/connection.c b/omapip/connection.c
index 43ad0a96..77ce113d 100644
--- a/omapip/connection.c
+++ b/omapip/connection.c
@@ -193,6 +193,7 @@ isc_result_t omapi_connect_list (omapi_object_t *c,
return ISC_R_NOPERM;
return ISC_R_UNEXPECTED;
}
+ obj -> local_addr = local_sin;
}
#if defined (HAVE_SETFD)
@@ -317,6 +318,7 @@ static void trace_connect_input (trace_type_t *ttype,
char *s = buf;
omapi_connection_object_t *obj;
isc_result_t status;
+ int i;
if (length != ((sizeof connect_index) +
(sizeof remote.sin_port) +
@@ -327,9 +329,9 @@ static void trace_connect_input (trace_type_t *ttype,
memset (&remote, 0, sizeof remote);
memset (&local, 0, sizeof local);
- memcpy (&connect_index, buf, sizeof connect_index);
+ memcpy (&connect_index, s, sizeof connect_index);
s += sizeof connect_index;
- memcpy (&listener_index, buf, sizeof listener_index);
+ memcpy (&listener_index, s, sizeof listener_index);
s += sizeof listener_index;
memcpy (&remote.sin_port, s, sizeof remote.sin_port);
s += sizeof remote.sin_port;
@@ -354,7 +356,7 @@ static void trace_connect_input (trace_type_t *ttype,
omapi_listener_reference (&listener, lp, MDL);
omapi_listener_dereference (&lp, MDL);
break;
- }
+ }
} omapi_array_foreach_end (trace_listeners,
omapi_listener_object_t, lp);
if (!listener) {
@@ -380,13 +382,19 @@ static void trace_connect_input (trace_type_t *ttype,
/* Find the matching connect object, if there is one. */
omapi_array_foreach_begin (omapi_connections,
omapi_connection_object_t, lp) {
- if (lp -> local_addr.sin_port == local.sin_port &&
- (lp -> local_addr.sin_addr.s_addr == htonl (INADDR_ANY) ||
- (lp -> local_addr.sin_addr.s_addr ==
- local.sin_addr.s_addr))) {
+ for (i = 0; (lp -> connect_list &&
+ i < lp -> connect_list -> count); i++) {
+ if (!memcmp (&remote.sin_addr,
+ &lp -> connect_list -> addresses [i].address,
+ sizeof remote.sin_addr) &&
+ (ntohs (remote.sin_port) ==
+ lp -> connect_list -> addresses [i].port))
lp -> state = omapi_connection_connected;
lp -> remote_addr = remote;
lp -> remote_addr.sin_family = AF_INET;
+#if defined (HAVE_SIN_LEN)
+ lp -> remote_addr.sin_len = sizeof remote;
+#endif
omapi_addr_list_dereference (&lp -> connect_list, MDL);
lp -> index = connect_index;
status = omapi_signal_in ((omapi_object_t *)lp,
diff --git a/omapip/dispatch.c b/omapip/dispatch.c
index be9d8260..02bab7cc 100644
--- a/omapip/dispatch.c
+++ b/omapip/dispatch.c
@@ -573,9 +573,32 @@ isc_result_t omapi_waiter_signal_handler (omapi_object_t *h,
return ISC_R_SUCCESS;
}
+ if (!strcmp (name, "disconnect")) {
+ waiter = (omapi_waiter_object_t *)h;
+ waiter -> ready = 1;
+ waiter -> waitstatus = ISC_R_CONNRESET;
+ return ISC_R_SUCCESS;
+ }
+
if (h -> inner && h -> inner -> type -> signal_handler)
return (*(h -> inner -> type -> signal_handler)) (h -> inner,
name, ap);
return ISC_R_NOTFOUND;
}
+isc_result_t omapi_io_state_foreach (isc_result_t (*func) (omapi_object_t *,
+ void *),
+ void *p)
+{
+ omapi_io_object_t *io;
+ isc_result_t status;
+
+ for (io = omapi_io_states.next; io; io = io -> next) {
+ if (io -> inner) {
+ status = (*func) (io -> inner, p);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+ }
+ return ISC_R_SUCCESS;
+}
diff --git a/omapip/generic.c b/omapip/generic.c
index a056798f..6154bcf6 100644
--- a/omapip/generic.c
+++ b/omapip/generic.c
@@ -3,7 +3,7 @@
Subroutines that support the generic object. */
/*
- * Copyright (c) 1999-2000 Internet Software Consortium.
+ * Copyright (c) 1999-2001 Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -62,8 +62,9 @@ isc_result_t omapi_generic_set_value (omapi_object_t *h,
omapi_generic_object_t *g;
omapi_value_t *new;
omapi_value_t **va;
+ u_int8_t *ca;
int vm_new;
- int i;
+ int i, vfree = -1;
isc_result_t status;
if (h -> type != omapi_type_generic)
@@ -101,8 +102,12 @@ isc_result_t omapi_generic_set_value (omapi_object_t *h,
status = (omapi_value_reference
(&(g -> values [i]), new, MDL));
omapi_value_dereference (&new, MDL);
+ g -> changed [i] = 1;
return status;
}
+ /* Notice a free slot if we pass one. */
+ else if (vfree == -1 && !g -> values [i])
+ vfree = i;
}
/* If the name isn't already attached to this object, see if an
@@ -122,32 +127,51 @@ isc_result_t omapi_generic_set_value (omapi_object_t *h,
/* Arrange for there to be space for the pointer to the new
name/value pair if necessary: */
- if (g -> nvalues == g -> va_max) {
- if (g -> va_max)
- vm_new = 2 * g -> va_max;
- else
- vm_new = 10;
- va = dmalloc (vm_new * sizeof *va, MDL);
- if (!va)
- return ISC_R_NOMEMORY;
- if (g -> va_max)
- memcpy (va, g -> values, g -> va_max * sizeof *va);
- memset (va + g -> va_max, 0,
- (vm_new - g -> va_max) * sizeof *va);
- if (g -> values)
- dfree (g -> values, MDL);
- g -> values = va;
- g -> va_max = vm_new;
+ if (vfree == -1) {
+ vfree = g -> nvalues;
+ if (vfree == g -> va_max) {
+ if (g -> va_max)
+ vm_new = 2 * g -> va_max;
+ else
+ vm_new = 10;
+ va = dmalloc (vm_new * sizeof *va, MDL);
+ if (!va)
+ return ISC_R_NOMEMORY;
+ ca = dmalloc (vm_new * sizeof *ca, MDL);
+ if (!ca) {
+ dfree (va, MDL);
+ return ISC_R_NOMEMORY;
+ }
+ if (g -> va_max) {
+ memcpy (va, g -> values,
+ g -> va_max * sizeof *va);
+ memcpy (ca, g -> changed,
+ g -> va_max * sizeof *ca);
+ }
+ memset (va + g -> va_max, 0,
+ (vm_new - g -> va_max) * sizeof *va);
+ memset (ca + g -> va_max, 0,
+ (vm_new - g -> va_max) * sizeof *ca);
+ if (g -> values)
+ dfree (g -> values, MDL);
+ if (g -> changed)
+ dfree (g -> changed, MDL);
+ g -> values = va;
+ g -> changed = ca;
+ g -> va_max = vm_new;
+ }
}
- status = omapi_value_new (&g -> values [g -> nvalues], MDL);
+ status = omapi_value_new (&g -> values [vfree], MDL);
if (status != ISC_R_SUCCESS)
return status;
- omapi_data_string_reference (&g -> values [g -> nvalues] -> name,
+ omapi_data_string_reference (&g -> values [vfree] -> name,
name, MDL);
if (value)
omapi_typed_data_reference
- (&g -> values [g -> nvalues] -> value, value, MDL);
- g -> nvalues++;
+ (&g -> values [vfree] -> value, value, MDL);
+ g -> changed [vfree] = 1;
+ if (vfree == g -> nvalues)
+ g -> nvalues++;
return ISC_R_SUCCESS;
}
@@ -200,7 +224,9 @@ isc_result_t omapi_generic_destroy (omapi_object_t *h,
file, line);
}
dfree (g -> values, file, line);
+ dfree (g -> changed, file, line);
g -> values = (omapi_value_t **)0;
+ g -> changed = (u_int8_t *)0;
g -> va_max = 0;
}
@@ -235,7 +261,8 @@ isc_result_t omapi_generic_stuff_values (omapi_object_t *c,
src = (omapi_generic_object_t *)g;
for (i = 0; i < src -> nvalues; i++) {
- if (src -> values [i] && src -> values [i] -> name -> len) {
+ if (src -> values [i] && src -> values [i] -> name -> len &&
+ src -> changed [i]) {
status = (omapi_connection_put_uint16
(c, src -> values [i] -> name -> len));
if (status != ISC_R_SUCCESS)
@@ -259,3 +286,26 @@ isc_result_t omapi_generic_stuff_values (omapi_object_t *c,
return ISC_R_SUCCESS;
}
+/* Clear the changed flags on the object. This has the effect that if
+ generic_stuff is called, any attributes that still have a cleared changed
+ flag aren't sent to the peer. This also deletes any values that are
+ null, presuming that these have now been properly handled. */
+
+isc_result_t omapi_generic_clear_flags (omapi_object_t *o)
+{
+ int i;
+ isc_result_t status;
+ omapi_generic_object_t *g;
+
+ if (o -> type != omapi_type_generic)
+ return ISC_R_INVALIDARG;
+ g = (omapi_generic_object_t *)o;
+
+ for (i = 0; i < g -> nvalues; i++) {
+ g -> changed [i] = 0;
+ if (g -> values [i] &&
+ !g -> values [i] -> value)
+ omapi_value_dereference (&g -> values [i], MDL);
+ }
+ return ISC_R_SUCCESS;
+}
diff --git a/omapip/hash.c b/omapip/hash.c
index 77fa36e9..58aea60e 100644
--- a/omapip/hash.c
+++ b/omapip/hash.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: hash.c,v 1.2 2001/05/17 19:03:57 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: hash.c,v 1.3 2001/06/27 00:30:48 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include <omapip/omapip_p.h>
@@ -72,23 +72,83 @@ void free_hash_table (ptr, file, line)
const char *file;
int line;
{
- dfree ((VOIDPTR)ptr, file, line);
+ int i;
+ struct hash_bucket *hbc, *hbn = (struct hash_bucket *)0;
+
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ for (i = 0; i < ptr -> hash_count; i++) {
+ for (hbc = ptr -> buckets [i]; hbc; hbc = hbn) {
+ hbn = hbc -> next;
+ if (ptr -> dereferencer && hbc -> value)
+ (*ptr -> dereferencer) (&hbc -> value, MDL);
+ }
+ for (hbc = ptr -> buckets [i]; hbc; hbc = hbn) {
+ hbn = hbc -> next;
+ free_hash_bucket (hbc, MDL);
+ }
+ ptr -> buckets [i] = (struct hash_bucket *)0;
+ }
+#endif
+
+ dfree ((VOIDPTR)ptr, MDL);
}
struct hash_bucket *free_hash_buckets;
+#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+struct hash_bucket *hash_bucket_hunks;
+
+void relinquish_hash_bucket_hunks ()
+{
+ struct hash_bucket *c, *n, **p;
+
+ /* Account for all the hash buckets on the free list. */
+ p = &free_hash_buckets;
+ for (c = free_hash_buckets; c; c = c -> next) {
+ for (n = hash_bucket_hunks; n; n = n -> next) {
+ if (c > n && c < n + 127) {
+ *p = c -> next;
+ n -> len++;
+ break;
+ }
+ }
+ /* If we didn't delete the hash bucket from the free list,
+ advance the pointer. */
+ if (!n)
+ p = &c -> next;
+ }
+
+ for (c = hash_bucket_hunks; c; c = n) {
+ n = c -> next;
+ if (c -> len != 126) {
+ log_info ("hashbucket %lx hash_buckets %d free %u",
+ (unsigned long)c, 127, c -> len);
+ }
+ dfree (c, MDL);
+ }
+}
+#endif
+
struct hash_bucket *new_hash_bucket (file, line)
const char *file;
int line;
{
struct hash_bucket *rval;
- int i;
+ int i = 0;
if (!free_hash_buckets) {
rval = dmalloc (127 * sizeof (struct hash_bucket),
file, line);
if (!rval)
return rval;
- for (i = 0; i < 127; i++) {
+# if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ rval -> next = hash_bucket_hunks;
+ hash_bucket_hunks = rval;
+ hash_bucket_hunks -> len = 0;
+ i++;
+ rval++;
+#endif
+ for (; i < 127; i++) {
rval -> next = free_hash_buckets;
free_hash_buckets = rval;
rval++;
@@ -104,15 +164,24 @@ void free_hash_bucket (ptr, file, line)
const char *file;
int line;
{
+ struct hash_bucket *hp;
+#if defined (DEBUG_MALLOC_POOL)
+ for (hp = free_hash_buckets; hp; hp = hp -> next) {
+ if (hp == ptr) {
+ log_error ("hash bucket freed twice!");
+ abort ();
+ }
+ }
+#endif
ptr -> next = free_hash_buckets;
free_hash_buckets = ptr;
}
struct hash_table *new_hash (hash_reference referencer,
hash_dereference dereferencer,
- int casep)
+ int casep, const char *file, int line)
{
- struct hash_table *rv = new_hash_table (DEFAULT_HASH_SIZE, MDL);
+ struct hash_table *rv = new_hash_table (DEFAULT_HASH_SIZE, file, line);
if (!rv)
return rv;
memset (&rv -> buckets [0], 0,
@@ -244,7 +313,7 @@ void delete_hash_entry (table, name, len, file, line)
} else {
table -> buckets [hashno] = bp -> next;
}
- if (table -> dereferencer) {
+ if (bp -> value && table -> dereferencer) {
foo = &bp -> value;
(*(table -> dereferencer)) (foo, file, line);
}
diff --git a/omapip/message.c b/omapip/message.c
index 41c1f21f..ffdae854 100644
--- a/omapip/message.c
+++ b/omapip/message.c
@@ -230,11 +230,13 @@ isc_result_t omapi_message_destroy (omapi_object_t *h,
if (!m -> prev && omapi_registered_messages != m)
omapi_message_unregister (h);
if (m -> id_object)
- omapi_object_dereference ((omapi_object_t **)&m -> id_object,
- file, line);
+ omapi_object_dereference (&m -> id_object, file, line);
if (m -> object)
- omapi_object_dereference ((omapi_object_t **)&m -> object,
- file, line);
+ omapi_object_dereference (&m -> object, file, line);
+ if (m -> notify_object)
+ omapi_object_dereference (&m -> notify_object, file, line);
+ if (m -> protocol_object)
+ omapi_protocol_dereference (&m -> protocol_object, file, line);
return ISC_R_SUCCESS;
}
@@ -384,7 +386,7 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
dmalloc_outstanding - previous_outstanding,
dmalloc_outstanding, dmalloc_longterm);
#endif
-#if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)) && 0
+#if defined (DEBUG_MEMORY_LEAKAGE) && 0
dmalloc_dump_outstanding ();
#endif
#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) && 0
@@ -545,12 +547,6 @@ omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po)
"unsearchable object type");
}
- if (!message -> object) {
- return omapi_protocol_send_status
- (po, message -> id_object,
- ISC_R_NOTFOUND, message -> id,
- "no lookup key specified");
- }
status = (*(type -> lookup)) (&object, message -> id_object,
message -> object);
diff --git a/omapip/omapi.3 b/omapip/omapi.3
index eacb9da3..112621df 100644
--- a/omapip/omapi.3
+++ b/omapip/omapi.3
@@ -1,59 +1,93 @@
-NAME
- OMAPI - Object Management Application Programming Interface
-
-DESCRIPTION
-
-Overview
-
- OMAPI is an programming layer designed for controlling remote
- applications, and for querying them for their state. It is currently
- used by the ISC DHCP server and this outline addresses the parts of
- OMAPI appropriate to the clients of DHCP server. It does this by also
- describing the use of a thin API layered on top of OMAPI called
- 'dhcpctl'
-
- OMAPI uses TCP/IP as the transport for server communication, and
- security can be imposed by having the client and server
- cryptographically sign messages using a shared secret.
-
- dhcpctl works by presenting the client with handles to objects that
- act as surrogates for the real objects in the server. For example a
- client will create a handle for a lease object, and will request the
- server to fill the lease handle's state. The client application can
- then pull details such as the lease expiration time from the lease
- handle.
-
- Modifications can be made to the server state by creating handles to
- new objects, or by modifying attributes of handles to existing
- objects, and then instructing the server to update itself according to
- the changes made.
-
-Usage
-
- The client application must always call dhcpctl_initialize() before
- making calls to any other dhcpctl functions. This initializes
- various internal data structures.
-
- To create the connection to the server the client must use
- dhcpctl_connect() function. As well as making the physical connection
- it will also set up the connection data structures to do
- authentication on each message, if that is required.
-
- All the dhcpctl functions return an integer value of type
- isc_result_t. A successful call will yield a result of
- ISC_R_SUCCESS. If the call fails for a reason local to the client
- (e.g. insufficient local memory, or invalid arguments to the call)
- then the return value of the dhcpctl function will show that. If the
- call succeeds but the server couldn't process the request the error
- value from the server is returned through another way, shown below.
-
- The easiest way to understand dhcpctl is to see it in action. The
- following program is fully functional, but almost all error checking
- has been removed to make is shorter and easier to understand. This
- program will query the server running on the localhost for the details
- of the lease for IP address 10.0.0.101. It will then print out the time
- the lease ends.
-
+.\" omapi.3
+.\"
+.\" Copyright (c) 2000-2001 Internet Software Consortium.
+.\" 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 in cooperation with Vixie Enterprises and Nominum, Inc.
+.\" To learn more about the Internet Software Consortium, see
+.\" ``http://www.isc.org/''. To learn more about Vixie Enterprises,
+.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
+.\" ``http://www.nominum.com''.
+.TH omapi 3
+.SH NAME
+OMAPI - Object Management Application Programming Interface
+.SH DESCRIPTION
+.PP
+OMAPI is an programming layer designed for controlling remote
+applications, and for querying them for their state. It is currently
+used by the ISC DHCP server and this outline addresses the parts of
+OMAPI appropriate to the clients of DHCP server. It does this by also
+describing the use of a thin API layered on top of OMAPI called
+'dhcpctl'
+.PP
+OMAPI uses TCP/IP as the transport for server communication, and
+security can be imposed by having the client and server
+cryptographically sign messages using a shared secret.
+.PP
+dhcpctl works by presenting the client with handles to objects that
+act as surrogates for the real objects in the server. For example a
+client will create a handle for a lease object, and will request the
+server to fill the lease handle's state. The client application can
+then pull details such as the lease expiration time from the lease
+handle.
+.PP
+Modifications can be made to the server state by creating handles to
+new objects, or by modifying attributes of handles to existing
+objects, and then instructing the server to update itself according to
+the changes made.
+.SH USAGE
+.PP
+The client application must always call dhcpctl_initialize() before
+making calls to any other dhcpctl functions. This initializes
+various internal data structures.
+.PP
+To create the connection to the server the client must use
+dhcpctl_connect() function. As well as making the physical connection
+it will also set up the connection data structures to do
+authentication on each message, if that is required.
+.PP
+All the dhcpctl functions return an integer value of type
+isc_result_t. A successful call will yield a result of
+ISC_R_SUCCESS. If the call fails for a reason local to the client
+(e.g. insufficient local memory, or invalid arguments to the call)
+then the return value of the dhcpctl function will show that. If the
+call succeeds but the server couldn't process the request the error
+value from the server is returned through another way, shown below.
+.PP
+The easiest way to understand dhcpctl is to see it in action. The
+following program is fully functional, but almost all error checking
+has been removed to make is shorter and easier to understand. This
+program will query the server running on the localhost for the details
+of the lease for IP address 10.0.0.101. It will then print out the time
+the lease ends.
+.PP
+.nf
#include <stdarg.h>
#include <sys/time.h>
#include <sys/socket.h>
@@ -66,10 +100,12 @@ Usage
int main (int argc, char **argv) {
dhcpctl_data_string ipaddrstring = NULL;
dhcpctl_data_string value = NULL;
-
- All modifications of handles and all accesses of handle data happen
- via dhcpctl_data_string objects.
-
+.fi
+.PP
+All modifications of handles and all accesses of handle data happen
+via dhcpctl_data_string objects.
+.PP
+.nf
dhcpctl_handle connection = NULL;
dhcpctl_handle lease = NULL;
isc_result_t waitstatus;
@@ -77,22 +113,28 @@ Usage
time_t thetime;
dhcpctl_initialize ();
-
- Required fist step.
-
+.fi
+.PP
+Required first step.
+.PP
+.nf
dhcpctl_connect (&connection, "127.0.0.1",
7911, 0);
-
- Sets up the connection to the server. The server normally listens on
- port 7911 unless configured to do otherwise.
-
+.fi
+.PP
+Sets up the connection to the server. The server normally listens on
+port 7911 unless configured to do otherwise.
+.PP
+.nf
dhcpctl_new_object (&lease, connection,
"lease");
-
- Here we create a handle to a lease. This call just sets up local data
- structure. The server hasn't yet made any association between the
- client's data structure and any lease it has.
-
+.fi
+.PP
+Here we create a handle to a lease. This call just sets up local data
+structure. The server hasn't yet made any association between the
+client's data structure and any lease it has.
+.PP
+.nf
memset (&ipaddrstring, 0, sizeof
ipaddrstring);
@@ -101,35 +143,43 @@ Usage
omapi_data_string_new (&ipaddrstring,
4, MDL);
-
- Create a new data string to storing in the handle.
-
+.fi
+.PP
+Create a new data string to storing in the handle.
+.PP
+.nf
memcpy(ipaddrstring->value, &convaddr.s_addr, 4);
dhcpctl_set_value (lease, ipaddrstring,
"ip-address");
-
- We're setting the ip-address attribute of the lease handle to the
- given address. We've not set any other attributes so when the server
- makes the association the ip address will be all it uses to look up
- the lease in its tables.
-
+.fi
+.PP
+We're setting the ip-address attribute of the lease handle to the
+given address. We've not set any other attributes so when the server
+makes the association the ip address will be all it uses to look up
+the lease in its tables.
+.PP
+.nf
dhcpctl_open_object (lease, connection, 0);
-
- Here we prime the connection with the request to look up the lease in
- the server and fill up the local handle with the attributes the server
- will send over in its answer.
-
+.fi
+.PP
+Here we prime the connection with the request to look up the lease in
+the server and fill up the local handle with the attributes the server
+will send over in its answer.
+.PP
+.nf
dhcpctl_wait_for_completion (lease,
&waitstatus);
-
- This call causes the message to get sent to the server (the message to
- look up the lease and send back the attribute values in the
- answer). The value in the variable waitstatus when the function
- returns will be the result from the server. If the message could
- not be processed properly by the server then the error will be
- reflected here.
-
+.fi
+.PP
+This call causes the message to get sent to the server (the message to
+look up the lease and send back the attribute values in the
+answer). The value in the variable waitstatus when the function
+returns will be the result from the server. If the message could
+not be processed properly by the server then the error will be
+reflected here.
+.PP
+.nf
if (waitstatus != ISC_R_SUCCESS) {
/* server not authoritative */
exit (0);
@@ -137,14 +187,19 @@ Usage
dhcpctl_data_string_dereference(&ipaddrstring,
MDL);
-
- Clean-up memory we no longer need.
-
+.fi
+.PP
+Clean-up memory we no longer need.
+.PP
+.nf
dhcpctl_get_value (&value, lease, "ends");
-
- Get the attribute named ``ends'' from the lease handle. This is a
- 4-byte integer of the time (in unix epoch seconds) that the lease
- will expire.
+.fi
+.PP
+Get the attribute named ``ends'' from the lease handle. This is a
+4-byte integer of the time (in unix epoch seconds) that the lease
+will expire.
+.PP
+.nf
memcpy(&thetime, value->value, value->len);
dhcpctl_data_string_dereference(&value, MDL);
@@ -153,12 +208,12 @@ Usage
ctime(&thetime));
}
-
-Authentication
-
- If the server demands authenticated connections then before opening
- the connection the user must call dhcpctl_new_authenticator.
-
+.fi
+.SH AUTHENTICATION
+If the server demands authenticated connections then before opening
+the connection the user must call dhcpctl_new_authenticator.
+.PP
+.nf
dhcpctl_handle authenticator = NULL;
const char *keyname = "a-key-name";
const char *algorithm = "hmac-md5";
@@ -169,10 +224,12 @@ Authentication
algorithm,
secret,
strlen(secret) + 1);
-
- The keyname, algorithm and secret must all match what is specified in
- the server's dhcpd.conf file:
-
+.fi
+.PP
+The keyname, algorithm and secret must all match what is specified in
+the server's dhcpd.conf file:
+.PP
+.nf
key "a-key-name" {
algorithm hmac-md5;
secret "a-shared-secret";
@@ -181,12 +238,17 @@ Authentication
# Set the omapi-key value to use
# authenticated connections
omapi-key "a-key-name";
-
- The authenticator handle that is created by the call to
- dhcpctl_new_authenticator must be given as the last (the 4th) argument
- to the call to dhcpctl_connect(). All messages will then be signed
- with the given secret string using the specified algorithm.
-
-SEE ALSO
-
- dhcpctl(3)
+.fi
+.PP
+The authenticator handle that is created by the call to
+dhcpctl_new_authenticator must be given as the last (the 4th) argument
+to the call to dhcpctl_connect(). All messages will then be signed
+with the given secret string using the specified algorithm.
+.SH SEE ALSO
+dhcpctl(3), omapi(3), dhcpd(8), dhclient(8), dhcpd.conf(5), dhclient.conf(5).
+.SH AUTHOR
+.B omapi
+was created by Ted Lemon of Nominum, Inc. Information about Nominum
+and support contracts for DHCP and BIND can be found at
+.B http://www.nominum.com. This documentation was written by James
+Brister of Nominum, Inc.
diff --git a/omapip/protocol.c b/omapip/protocol.c
index c8ae79fb..8a5890a7 100644
--- a/omapip/protocol.c
+++ b/omapip/protocol.c
@@ -343,6 +343,9 @@ isc_result_t omapi_protocol_send_message (omapi_object_t *po,
}
}
+ if (!omo) {
+ omapi_protocol_reference (&m -> protocol_object, p, MDL);
+ }
return ISC_R_SUCCESS;
}
@@ -353,6 +356,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
isc_result_t status;
omapi_protocol_object_t *p;
omapi_object_t *c;
+ omapi_message_object_t *m;
omapi_value_t *signature;
u_int16_t nlen;
u_int32_t vlen;
@@ -408,11 +412,11 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
dmalloc_outstanding - previous_outstanding,
dmalloc_outstanding, dmalloc_longterm, " long-term");
#endif
-#if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL))
+#if defined (DEBUG_MEMORY_LEAKAGE)
dmalloc_dump_outstanding ();
#endif
#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
- dump_rc_history ();
+ dump_rc_history (0);
#endif
}
@@ -664,7 +668,8 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
return status;
}
omapi_data_string_dereference (&p -> name, MDL);
- omapi_typed_data_dereference (&p -> value, MDL);
+ if (p -> value)
+ omapi_typed_data_dereference (&p -> value, MDL);
goto need_name_length;
signature_wait:
diff --git a/omapip/result.c b/omapip/result.c
index c079d7ee..8e6695ef 100644
--- a/omapip/result.c
+++ b/omapip/result.c
@@ -112,7 +112,9 @@ static const char *text[ISC_R_NRESULTS] = {
"destination address required", /* 64 */
"cross-zone update", /* 65 */
"no TSIG signature", /* 66 */
- "not equal" /* 67 */
+ "not equal", /* 67 */
+ "connection reset by peer", /* 68 */
+ "unknown attribute" /* 69 */
};
const char *isc_result_totext (isc_result_t result)
diff --git a/omapip/support.c b/omapip/support.c
index 6d2e8cc3..78fd0461 100644
--- a/omapip/support.c
+++ b/omapip/support.c
@@ -59,6 +59,19 @@ omapi_object_type_t *omapi_object_types;
int omapi_object_type_count;
static int ot_max;
+#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+void omapi_type_relinquish ()
+{
+ omapi_object_type_t *t, *n;
+
+ for (t = omapi_object_types; t; t = n) {
+ n = t -> next;
+ dfree (t, MDL);
+ }
+ omapi_object_types = (omapi_object_type_t *)0;
+}
+#endif
+
isc_result_t omapi_init (void)
{
isc_result_t status;
diff --git a/omapip/test.c b/omapip/test.c
index ddd2b364..249099e6 100644
--- a/omapip/test.c
+++ b/omapip/test.c
@@ -45,7 +45,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
-#include <isc/result.h>
+#include <isc-dhcp/result.h>
#include <sys/time.h>
#include <omapip/omapip.h>
diff --git a/omapip/toisc.c b/omapip/toisc.c
index 1823c4a7..a30dcffd 100644
--- a/omapip/toisc.c
+++ b/omapip/toisc.c
@@ -208,7 +208,7 @@ isc_result_t uerr2isc (int err)
return ISC_R_TIMEDOUT;
case ECONNRESET:
- return ISC_R_CONNREFUSED;
+ return ISC_R_CONNRESET;
case ENOBUFS:
return ISC_R_NOSPACE;
diff --git a/omapip/trace.c b/omapip/trace.c
index 197ab17a..4ff30516 100644
--- a/omapip/trace.c
+++ b/omapip/trace.c
@@ -57,6 +57,40 @@ static tracefile_header_t tracefile_header;
static int trace_playback_flag;
trace_type_t trace_time_marker;
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+extern omapi_array_t *trace_listeners;
+extern omapi_array_t *omapi_connections;
+
+void trace_free_all ()
+{
+ trace_type_t *tp;
+ int i;
+ tp = new_trace_types;
+ while (tp) {
+ new_trace_types = tp -> next;
+ if (tp -> name) {
+ dfree (tp -> name, MDL);
+ tp -> name = (char *)0;
+ }
+ dfree (tp, MDL);
+ tp = new_trace_types;
+ }
+ for (i = 0; i < trace_type_count; i++) {
+ if (trace_types [i]) {
+ if (trace_types [i] -> name)
+ dfree (trace_types [i] -> name, MDL);
+ dfree (trace_types [i], MDL);
+ }
+ }
+ dfree (trace_types, MDL);
+ trace_types = (trace_type_t **)0;
+ trace_type_count = trace_type_max = 0;
+
+ omapi_array_free (&trace_listeners, MDL);
+ omapi_array_free (&omapi_connections, MDL);
+}
+#endif
+
static isc_result_t trace_type_record (trace_type_t *,
unsigned, const char *, int);
@@ -88,6 +122,8 @@ isc_result_t trace_init (void (*set_time) (u_int32_t),
trace_index_stop_tracing, file, line);
if (!root_type)
return ISC_R_UNEXPECTED;
+ if (new_trace_types == root_type)
+ new_trace_types = new_trace_types -> next;
root_type -> index = 0;
trace_type_stash (root_type);
diff --git a/relay/dhcrelay.8 b/relay/dhcrelay.8
index b7874cc2..ae6801f8 100644
--- a/relay/dhcrelay.8
+++ b/relay/dhcrelay.8
@@ -106,18 +106,17 @@ are specified on the command line dhcrelay will identify all network
interfaces, elimininating non-broadcast interfaces if possible, and
attempt to configure each interface.
.PP
-If a relay agent is running on a system that is connected to one or
-more networks on which no DHCP servers are present, and is also
-connected to one or more networks on which DHCP servers
-.I are
-connected, it is may not be helpful for the relay agent to relay
-requests from those networks on which a DHCP server already exists.
-To avoid such a situation, the interfaces on which the relay agent
-should listen should be specified with the
+The
.B -i
-flag.
-.PP
-Note that in some cases it
+flag can be used to specify the network interfaces on which the relay
+agent should listen. In general, it must listen not only on those
+network interfaces to which clients are attached, but also on those
+network interfaces to which the server (or the router that reaches the
+server) is attached. However, in some cases it may be necessary to
+exclude some networks; in this case, you must list all those network
+interfaces that should \fInot\fR be excluded using the \fB-i\fR flag.
+.PP
+In some cases it
.I is
helpful for the relay agent to forward requests from networks on which
a DHCP server is running to other DHCP servers. This would be the
@@ -138,7 +137,7 @@ flag should be specified. This is useful when running dhcrelay under
a debugger, or when running it out of inittab on System V systems.
.PP
Dhcrelay will normally print its network configuration on startup.
-This can be annoying in a system startup script - to disable this
+This can be unhelpful in a system startup script - to disable this
behaviour, specify the
.B -q
flag.
diff --git a/server/bootp.c b/server/bootp.c
index 019876f3..2757ead3 100644
--- a/server/bootp.c
+++ b/server/bootp.c
@@ -3,7 +3,7 @@
BOOTP Protocol support. */
/*
- * Copyright (c) 1995-2000 Internet Software Consortium.
+ * Copyright (c) 1995-2001 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: bootp.c,v 1.70 2001/05/17 19:04:03 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: bootp.c,v 1.71 2001/06/27 00:31:00 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -151,7 +151,11 @@ void bootp (packet)
ack_lease (packet, lease, 0, 0, msgbuf, 0);
goto out;
}
+ /* XXX just ignore BOOTREQUESTS from unknown clients if
+ XXX we can't allocate IP addresses for them. */
+#if 0
log_info ("%s: no available leases", msgbuf);
+#endif
goto out;
}
@@ -233,7 +237,8 @@ void bootp (packet)
if (make_const_data
(&oc -> expression,
lease -> subnet -> netmask.iabuf,
- lease -> subnet -> netmask.len, 0, 0)) {
+ lease -> subnet -> netmask.len,
+ 0, 0, MDL)) {
oc -> option =
dhcp_universe.options [i];
save_option (&dhcp_universe,
diff --git a/server/class.c b/server/class.c
index 25160483..eab7d9e0 100644
--- a/server/class.c
+++ b/server/class.c
@@ -3,7 +3,7 @@
Handling for client classes. */
/*
- * Copyright (c) 1998-2000 Internet Software Consortium.
+ * Copyright (c) 1998-2001 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: class.c,v 1.30 2001/06/22 16:47:13 brister Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: class.c,v 1.31 2001/06/27 00:31:02 mellon Exp $ Copyright (c) 1998-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
@@ -64,21 +64,20 @@ int have_billing_classes;
void classification_setup ()
{
- struct executable_statement *rules;
-
/* eval ... */
- rules = (struct executable_statement *)0;
- if (!executable_statement_allocate (&rules, MDL))
+ default_classification_rules = (struct executable_statement *)0;
+ if (!executable_statement_allocate (&default_classification_rules,
+ MDL))
log_fatal ("Can't allocate check of default collection");
- rules -> op = eval_statement;
+ default_classification_rules -> op = eval_statement;
/* check-collection "default" */
- if (!expression_allocate (&rules -> data.eval, MDL))
+ if (!expression_allocate (&default_classification_rules -> data.eval,
+ MDL))
log_fatal ("Can't allocate default check expression");
- rules -> data.eval -> op = expr_check;
- rules -> data.eval -> data.check = &default_collection;
-
- default_classification_rules = rules;
+ default_classification_rules -> data.eval -> op = expr_check;
+ default_classification_rules -> data.eval -> data.check =
+ &default_collection;
}
void classify_client (packet)
@@ -142,7 +141,7 @@ int check_collection (packet, lease, collection)
(struct client_state *)0,
packet -> options, (struct option_state *)0,
lease ? &lease -> scope : &global_scope,
- class -> submatch));
+ class -> submatch, MDL));
if (status && data.len) {
nc = (struct class *)0;
if (class_hash_lookup (&nc, class -> hash,
@@ -200,13 +199,14 @@ int check_collection (packet, lease, collection)
MDL);
data_string_forget (&data, MDL);
if (!class -> hash)
- class -> hash = new_hash (0, 0, 0);
+ class -> hash = new_hash (0, 0, 0, MDL);
class_hash_add (class -> hash,
(const char *)
nc -> hash_string.data,
nc -> hash_string.len,
nc, MDL);
classify (packet, nc);
+ class_dereference (&nc, MDL);
}
}
}
@@ -221,7 +221,7 @@ void classify (packet, class)
class_reference (&packet -> classes [packet -> class_count++],
class, MDL);
else
- log_error ("too many groups for %s",
+ log_error ("too many classes match %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
diff --git a/server/confpars.c b/server/confpars.c
index 970a9680..4b78f29b 100644
--- a/server/confpars.c
+++ b/server/confpars.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: confpars.c,v 1.144 2001/06/22 16:47:14 brister Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: confpars.c,v 1.145 2001/06/27 00:31:03 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -219,6 +219,7 @@ void trace_conf_input (trace_type_t *ttype, unsigned len, char *data)
if (!leaseconf_initialized && ttype == trace_readleases_type) {
db_startup (0);
leaseconf_initialized = 1;
+ postdb_startup ();
}
}
@@ -450,12 +451,9 @@ int parse_statement (cfile, group, type, host_decl, declaration)
MDL);
/* Make the shared network name from network number. */
- n = piaddr (share -> subnets -> net);
- t = dmalloc (strlen (n) + 1, MDL);
- if (!t)
- log_fatal ("no memory for subnet name");
- strcpy (t, n);
- share -> name = t;
+ n = piaddrmask (share -> subnets -> net,
+ share -> subnets -> netmask, MDL);
+ share -> name = n;
/* Copy the authoritative parameter from the subnet,
since there is no opportunity to declare it here. */
@@ -463,6 +461,7 @@ int parse_statement (cfile, group, type, host_decl, declaration)
share -> subnets -> group -> authoritative;
enter_shared_network (share);
}
+ shared_network_dereference (&share, MDL);
return 1;
case VENDOR_CLASS:
@@ -694,6 +693,7 @@ int parse_statement (cfile, group, type, host_decl, declaration)
if (!multi) {
executable_statement_reference (&ep -> next,
et, MDL);
+ executable_statement_dereference (&et, MDL);
return declaration;
}
@@ -712,9 +712,12 @@ int parse_statement (cfile, group, type, host_decl, declaration)
MDL);
executable_statement_reference (&group -> statements,
ep, MDL);
- } else
+ executable_statement_dereference (&ep, MDL);
+ } else {
executable_statement_reference (&group -> statements,
et, MDL);
+ }
+ executable_statement_dereference (&et, MDL);
return declaration;
}
@@ -844,7 +847,7 @@ void parse_failover_peer (cfile, group, type)
}
option_cache (&cp -> address,
(struct data_string *)0, expr,
- (struct option *)0);
+ (struct option *)0, MDL);
expression_dereference (&expr, MDL);
break;
@@ -1079,9 +1082,24 @@ void parse_failover_state_declaration (struct parse *cfile,
cp = &state -> partner;
goto do_state;
+ case MCLT:
+ if (state -> i_am == primary) {
+ parse_warn (cfile,
+ "mclt not valid for primary");
+ goto bogus;
+ }
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != NUMBER) {
+ parse_warn (cfile, "expecting a number.");
+ goto bogus;
+ }
+ state -> mclt = atoi (val);
+ parse_semi (cfile);
+ break;
+
default:
- bogus:
parse_warn (cfile, "expecting state setting.");
+ bogus:
skip_to_rbrace (cfile, 1);
dhcp_failover_state_dereference (&state, MDL);
return;
@@ -1676,7 +1694,8 @@ int parse_class_declaration (cp, cfile, group, type)
int declaration = 0;
int lose = 0;
struct data_string data;
- const char *name;
+ char *name;
+ const char *tname;
struct executable_statement *stmt = (struct executable_statement *)0;
struct expression *expr;
int new = 1;
@@ -1724,20 +1743,20 @@ int parse_class_declaration (cp, cfile, group, type)
data.data = &data.buffer -> data [0];
data.terminated = 1;
- name = type ? "implicit-vendor-class" : "implicit-user-class";
+ tname = type ? "implicit-vendor-class" : "implicit-user-class";
} else if (type == 2) {
- name = val;
+ tname = val;
} else {
- name = (char *)0;
+ tname = (const char *)0;
}
- if (name) {
- char *tname;
- if (!(tname = dmalloc (strlen (val) + 1, MDL)))
- log_fatal ("No memory for class name %s.", val);
- strcpy (tname, val);
- name = tname;
- }
+ if (tname) {
+ name = dmalloc (strlen (tname) + 1, MDL);
+ if (!name)
+ log_fatal ("No memory for class name %s.", tname);
+ strcpy (name, val);
+ } else
+ name = (char *)0;
/* If this is a straight subclass, parse the hash string. */
if (type == 3) {
@@ -1764,7 +1783,8 @@ int parse_class_declaration (cp, cfile, group, type)
}
} else {
parse_warn (cfile, "Expecting string or hex list.");
- class_dereference (&pc, MDL);
+ if (pc)
+ class_dereference (&pc, MDL);
return 0;
}
}
@@ -1799,7 +1819,8 @@ int parse_class_declaration (cp, cfile, group, type)
new_hash ((hash_reference)
omapi_object_reference,
(hash_dereference)
- omapi_object_dereference, 0);
+ omapi_object_dereference,
+ 0, MDL);
add_hash (pc -> hash,
class -> hash_string.data,
class -> hash_string.len,
@@ -1844,6 +1865,8 @@ int parse_class_declaration (cp, cfile, group, type)
if (cp)
status = class_reference (cp, class, MDL);
class_dereference (&class, MDL);
+ if (pc)
+ class_dereference (&pc, MDL);
return cp ? (status == ISC_R_SUCCESS) : 1;
}
/* Give the subclass its own group. */
@@ -2357,7 +2380,7 @@ int parse_fixed_addr_param (oc, cfile)
return 0;
}
status = option_cache (oc, (struct data_string *)0, expr,
- (struct option *)0);
+ (struct option *)0, MDL);
expression_dereference (&expr, MDL);
return status;
}
@@ -2790,18 +2813,18 @@ int parse_lease_declaration (struct lease **lp, struct parse *cfile)
if (!(binding_scope_allocate
(&lease -> scope, MDL)))
log_fatal ("no memory for scope");
- binding = dmalloc (sizeof *binding, MDL);
- if (!binding)
- log_fatal ("No memory for lease %s.",
- "binding");
- memset (binding, 0, sizeof *binding);
- binding -> name =
- dmalloc (strlen (val) + 1, MDL);
- if (!binding -> name)
- log_fatal ("No memory for binding %s.",
- "name");
- strcpy (binding -> name, val);
- newbinding = 1;
+ binding = dmalloc (sizeof *binding, MDL);
+ if (!binding)
+ log_fatal ("No memory for lease %s.",
+ "binding");
+ memset (binding, 0, sizeof *binding);
+ binding -> name =
+ dmalloc (strlen (val) + 1, MDL);
+ if (!binding -> name)
+ log_fatal ("No memory for binding %s.",
+ "name");
+ strcpy (binding -> name, val);
+ newbinding = 1;
} else if (binding -> value) {
binding_value_dereference (&binding -> value,
MDL);
@@ -3141,45 +3164,48 @@ int parse_allow_deny (oc, cfile, flag)
struct expression *data = (struct expression *)0;
int status;
- if (!make_const_data (&data, &rf, 1, 0, 1))
+ if (!make_const_data (&data, &rf, 1, 0, 1, MDL))
return 0;
token = next_token (&val, (unsigned *)0, cfile);
switch (token) {
case TOKEN_BOOTP:
status = option_cache (oc, (struct data_string *)0, data,
- &server_options [SV_ALLOW_BOOTP]);
+ &server_options [SV_ALLOW_BOOTP], MDL);
break;
case BOOTING:
status = option_cache (oc, (struct data_string *)0, data,
- &server_options [SV_ALLOW_BOOTING]);
+ &server_options [SV_ALLOW_BOOTING],
+ MDL);
break;
case DYNAMIC_BOOTP:
status = option_cache (oc, (struct data_string *)0, data,
- &server_options [SV_DYNAMIC_BOOTP]);
+ &server_options [SV_DYNAMIC_BOOTP],
+ MDL);
break;
case UNKNOWN_CLIENTS:
status = (option_cache
(oc, (struct data_string *)0, data,
- &server_options [SV_BOOT_UNKNOWN_CLIENTS]));
+ &server_options [SV_BOOT_UNKNOWN_CLIENTS], MDL));
break;
case DUPLICATES:
status = option_cache (oc, (struct data_string *)0, data,
- &server_options [SV_DUPLICATES]);
+ &server_options [SV_DUPLICATES], MDL);
break;
case DECLINES:
status = option_cache (oc, (struct data_string *)0, data,
- &server_options [SV_DECLINES]);
+ &server_options [SV_DECLINES], MDL);
break;
case CLIENT_UPDATES:
status = option_cache (oc, (struct data_string *)0, data,
- &server_options [SV_CLIENT_UPDATES]);
+ &server_options [SV_CLIENT_UPDATES],
+ MDL);
break;
default:
@@ -3187,6 +3213,7 @@ int parse_allow_deny (oc, cfile, flag)
skip_to_semi (cfile);
return 0;
}
+ expression_dereference (&data, MDL);
parse_semi (cfile);
return status;
}
diff --git a/server/db.c b/server/db.c
index 474031af..515f98e8 100644
--- a/server/db.c
+++ b/server/db.c
@@ -3,7 +3,7 @@
Persistent database management routines for DHCPD... */
/*
- * Copyright (c) 1995-2000 Internet Software Consortium.
+ * Copyright (c) 1995-2001 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: db.c,v 1.65 2001/06/22 16:47:16 brister Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: db.c,v 1.66 2001/06/27 00:31:04 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -55,6 +55,7 @@ FILE *db_file;
static int counting = 0;
static int count = 0;
TIME write_time;
+int lease_file_is_corrupt = 0;
/* Write the specified lease to the current lease database file. */
@@ -68,6 +69,12 @@ int write_lease (lease)
struct binding *b;
char *s;
+ /* If the lease file is corrupt, don't try to write any more leases
+ until we've written a good lease file. */
+ if (lease_file_is_corrupt)
+ if (!new_lease_file ())
+ return 0;
+
if (counting)
++count;
errno = 0;
@@ -293,6 +300,8 @@ int write_lease (lease)
if (errors)
log_info ("write_lease: unable to write lease %s",
piaddr (lease -> ip_addr));
+ if (errors)
+ lease_file_is_corrupt = 1;
return !errors;
}
@@ -303,6 +312,12 @@ int write_host (host)
int i;
struct data_string ip_addrs;
+ /* If the lease file is corrupt, don't try to write any more leases
+ until we've written a good lease file. */
+ if (lease_file_is_corrupt)
+ if (!new_lease_file ())
+ return 0;
+
if (!db_printable (host -> name))
return 0;
@@ -429,9 +444,11 @@ int write_host (host)
if (errno) {
++errors;
}
- if (errors)
+ if (errors) {
log_info ("write_host: unable to write host %s",
host -> name);
+ lease_file_is_corrupt = 1;
+ }
return !errors;
}
@@ -441,6 +458,12 @@ int write_group (group)
int errors = 0;
int i;
+ /* If the lease file is corrupt, don't try to write any more leases
+ until we've written a good lease file. */
+ if (lease_file_is_corrupt)
+ if (!new_lease_file ())
+ return 0;
+
if (!db_printable (group -> name))
return 0;
@@ -488,9 +511,11 @@ int write_group (group)
if (errno) {
++errors;
}
- if (errors)
+ if (errors) {
log_info ("write_group: unable to write group %s",
group -> name);
+ lease_file_is_corrupt = 1;
+ }
return !errors;
}
@@ -500,6 +525,10 @@ int write_failover_state (dhcp_failover_state_t *state)
struct tm *t;
int errors = 0;
+ if (lease_file_is_corrupt)
+ if (!new_lease_file ())
+ return 0;
+
errno = 0;
fprintf (db_file, "\nfailover peer \"%s\" state {", state -> name);
if (errno)
@@ -528,6 +557,14 @@ int write_failover_state (dhcp_failover_state_t *state)
t -> tm_hour, t -> tm_min, t -> tm_sec);
if (errno)
++errors;
+
+ if (state -> i_am == secondary) {
+ errno = 0;
+ fprintf (db_file, "\n mclt %ld;",
+ (unsigned long)state -> mclt);
+ if (errno)
+ ++errors;
+ }
fprintf (db_file, "\n}\n");
if (errno)
++errors;
@@ -535,6 +572,7 @@ int write_failover_state (dhcp_failover_state_t *state)
if (errors) {
log_info ("write_failover_state: unable to write state %s",
state -> name);
+ lease_file_is_corrupt = 1;
return 0;
}
return 1;
@@ -687,6 +725,10 @@ int write_billing_class (class)
int errors = 0;
int i;
+ if (lease_file_is_corrupt)
+ if (!new_lease_file ())
+ return 0;
+
if (!class -> superclass) {
errno = 0;
fprintf (db_file, "\n billing class \"%s\";", class -> name);
@@ -733,7 +775,9 @@ int write_billing_class (class)
fprintf(db_file, ";");
#endif
- class -> dirty = 0;
+ class -> dirty = !errors;
+ if (errors)
+ lease_file_is_corrupt = 1;
return !errors;
}
@@ -803,7 +847,7 @@ void db_startup (testp)
}
}
-void new_lease_file ()
+int new_lease_file ()
{
char newfname [512];
char backfname [512];
@@ -813,6 +857,7 @@ void new_lease_file ()
/* If we already have an open database, close it. */
if (db_file) {
fclose (db_file);
+ db_file = (FILE *)0;
}
/* Make a temporary lease file... */
@@ -820,53 +865,84 @@ void new_lease_file ()
sprintf (newfname, "%s.%d", path_dhcpd_db, (int)t);
db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT, 0664);
if (db_fd < 0) {
- log_fatal ("Can't create new lease file: %m");
+ log_error ("Can't create new lease file: %m");
+ return 0;
}
if ((db_file = fdopen (db_fd, "w")) == NULL) {
- log_fatal ("Can't fdopen new lease file!");
+ log_error ("Can't fdopen new lease file!");
+ goto fail;
}
/* Write an introduction so people don't complain about time
being off. */
+ errno = 0;
fprintf (db_file, "# All times in this file are in UTC (GMT), not %s",
"your local timezone. This is\n");
+ if (errno != 0)
+ goto fail;
fprintf (db_file, "# not a bug, so please don't ask about it. %s",
"There is no portable way to\n");
+ if (errno != 0)
+ goto fail;
fprintf (db_file, "# store leases in the local timezone, so please %s",
"don't request this as a\n");
+ if (errno != 0)
+ goto fail;
fprintf (db_file, "# feature. If this is inconvenient or %s",
"confusing to you, we sincerely\n");
+ if (errno != 0)
+ goto fail;
fprintf (db_file, "# apologize. Seriously, though - don't ask.\n");
+ if (errno != 0)
+ goto fail;
fprintf (db_file, "# The format of this file is documented in the %s",
"dhcpd.leases(5) manual page.\n");
+ if (errno != 0)
+ goto fail;
fprintf (db_file, "# This lease file was written by isc-dhcp-%s\n\n",
DHCP_VERSION);
+ if (errno != 0)
+ goto fail;
/* Write out all the leases that we know of... */
counting = 0;
- write_leases ();
+ if (!write_leases ())
+ goto fail;
#if defined (TRACING)
if (!trace_playback ()) {
#endif
/* Get the old database out of the way... */
sprintf (backfname, "%s~", path_dhcpd_db);
- if (unlink (backfname) < 0 && errno != ENOENT)
- log_fatal ("Can't remove old lease database backup %s: %m",
+ if (unlink (backfname) < 0 && errno != ENOENT) {
+ log_error ("Can't remove old lease database backup %s: %m",
backfname);
- if (link (path_dhcpd_db, backfname) < 0)
- log_fatal ("Can't backup lease database %s to %s: %m",
+ goto fail;
+ }
+ if (link (path_dhcpd_db, backfname) < 0) {
+ log_error ("Can't backup lease database %s to %s: %m",
path_dhcpd_db, backfname);
+ goto fail;
+ }
#if defined (TRACING)
}
#endif
/* Move in the new file... */
- if (rename (newfname, path_dhcpd_db) < 0)
- log_fatal ("Can't install new lease database %s to %s: %m",
- newfname, path_dhcpd_db);
+ if (rename (newfname, path_dhcpd_db) < 0) {
+ log_error ("Can't install new lease database %s to %s: %m",
+ newfname, path_dhcpd_db);
+ goto fail;
+ }
counting = 1;
+ lease_file_is_corrupt = 0;
+ return 1;
+
+ fail:
+ unlink (newfname);
+ lease_file_is_corrupt = 1;
+ return 0;
}
int group_writer (struct group_object *group)
diff --git a/server/ddns.c b/server/ddns.c
index b3daa2bd..6b1a5586 100644
--- a/server/ddns.c
+++ b/server/ddns.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: ddns.c,v 1.15 2001/03/16 00:23:59 mellon Exp $ Copyright (c) 2000-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: ddns.c,v 1.16 2001/06/27 00:31:05 mellon Exp $ Copyright (c) 2000-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -52,9 +52,6 @@ static char copyright[] =
#ifdef NSUPDATE
-/* Have to use TXT records for now. */
-#define T_DHCID T_TXT
-
/* DN: No way of checking that there is enough space in a data_string's
buffer. Be certain to allocate enough!
TL: This is why the expression evaluation code allocates a *new*
@@ -68,232 +65,6 @@ static void data_string_append (struct data_string *ds1,
ds1 -> len += ds2 -> len;
}
-static isc_result_t ddns_update_a (struct data_string *ddns_fwd_name,
- struct iaddr ddns_addr,
- struct data_string *ddns_dhcid,
- unsigned long ttl)
-{
- ns_updque updqueue;
- ns_updrec *updrec;
- isc_result_t result;
- char ddns_address [16];
-
- if (ddns_addr.len != 4)
- return ISC_R_INVALIDARG;
-#ifndef NO_SNPRINTF
- snprintf (ddns_address, 16, "%d.%d.%d.%d",
- ddns_addr.iabuf[0], ddns_addr.iabuf[1],
- ddns_addr.iabuf[2], ddns_addr.iabuf[3]);
-#else
- sprintf (ddns_address, "%d.%d.%d.%d",
- ddns_addr.iabuf[0], ddns_addr.iabuf[1],
- ddns_addr.iabuf[2], ddns_addr.iabuf[3]);
-#endif
-
- /*
- * When a DHCP client or server intends to update an A RR, it first
- * prepares a DNS UPDATE query which includes as a prerequisite the
- * assertion that the name does not exist. The update section of the
- * query attempts to add the new name and its IP address mapping (an A
- * RR), and the DHCID RR with its unique client-identity.
- * -- "Interaction between DHCP and DNS"
- */
-
- ISC_LIST_INIT (updqueue);
-
- /*
- * A RR does not exist.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)0;
- updrec -> r_size = 0;
- updrec -> r_opcode = NXDOMAIN;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Add A RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, ttl);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = ADD;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Add DHCID RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID, ttl);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = ADD;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
-
- print_dns_status ((int)result, &updqueue);
-
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
-
-
- /*
- * If this update operation succeeds, the updater can conclude that it
- * has added a new name whose only RRs are the A and DHCID RR records.
- * The A RR update is now complete (and a client updater is finished,
- * while a server might proceed to perform a PTR RR update).
- * -- "Interaction between DHCP and DNS"
- */
-
- if (result == ISC_R_SUCCESS)
- return result;
-
-
- /*
- * If the first update operation fails with YXDOMAIN, the updater can
- * conclude that the intended name is in use. The updater then
- * attempts to confirm that the DNS name is not being used by some
- * other host. The updater prepares a second UPDATE query in which the
- * prerequisite is that the desired name has attached to it a DHCID RR
- * whose contents match the client identity. The update section of
- * this query deletes the existing A records on the name, and adds the
- * A record that matches the DHCP binding and the DHCID RR with the
- * client identity.
- * -- "Interaction between DHCP and DNS"
- */
-
- if (result != ISC_R_YXDOMAIN)
- return result;
-
-
- /*
- * DHCID RR exists, and matches client identity.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = YXRRSET;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Delete A RRset.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)0;
- updrec -> r_size = 0;
- updrec -> r_opcode = DELETE;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Add A RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, ttl);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = ADD;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
-
- print_dns_status ((int)result, &updqueue);
-
- /*
- * If this query succeeds, the updater can conclude that the current
- * client was the last client associated with the domain name, and that
- * the name now contains the updated A RR. The A RR update is now
- * complete (and a client updater is finished, while a server would
- * then proceed to perform a PTR RR update).
- * -- "Interaction between DHCP and DNS"
- */
-
- /*
- * If the second query fails with NXRRSET, the updater must conclude
- * that the client's desired name is in use by another host. At this
- * juncture, the updater can decide (based on some administrative
- * configuration outside of the scope of this document) whether to let
- * the existing owner of the name keep that name, and to (possibly)
- * perform some name disambiguation operation on behalf of the current
- * client, or to replace the RRs on the name with RRs that represent
- * the current client. If the configured policy allows replacement of
- * existing records, the updater submits a query that deletes the
- * existing A RR and the existing DHCID RR, adding A and DHCID RRs that
- * represent the IP address and client-identity of the new client.
- * -- "Interaction between DHCP and DNS"
- */
-
- error:
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
-
- return result;
-}
-
-
static isc_result_t ddns_update_ptr (struct data_string *ddns_fwd_name,
struct data_string *ddns_rev_name,
unsigned long ttl)
@@ -365,186 +136,6 @@ static isc_result_t ddns_update_ptr (struct data_string *ddns_fwd_name,
}
-static isc_result_t ddns_remove_a (struct data_string *ddns_fwd_name,
- struct iaddr ddns_addr,
- struct data_string *ddns_dhcid)
-{
- ns_updque updqueue;
- ns_updrec *updrec;
- isc_result_t result = SERVFAIL;
- char ddns_address [16];
-
- if (ddns_addr.len != 4)
- return ISC_R_INVALIDARG;
-
-#ifndef NO_SNPRINTF
- snprintf (ddns_address, 16, "%d.%d.%d.%d",
- ddns_addr.iabuf[0], ddns_addr.iabuf[1],
- ddns_addr.iabuf[2], ddns_addr.iabuf[3]);
-#else
- sprintf (ddns_address, "%d.%d.%d.%d",
- ddns_addr.iabuf[0], ddns_addr.iabuf[1],
- ddns_addr.iabuf[2], ddns_addr.iabuf[3]);
-#endif
-
-
- /*
- * The entity chosen to handle the A record for this client (either the
- * client or the server) SHOULD delete the A record that was added when
- * the lease was made to the client.
- *
- * In order to perform this delete, the updater prepares an UPDATE
- * query which contains two prerequisites. The first prerequisite
- * asserts that the DHCID RR exists whose data is the client identity
- * described in Section 4.3. The second prerequisite asserts that the
- * data in the A RR contains the IP address of the lease that has
- * expired or been released.
- * -- "Interaction between DHCP and DNS"
- */
-
- ISC_LIST_INIT (updqueue);
-
- /*
- * DHCID RR exists, and matches client identity.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID,0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = YXRRSET;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * A RR matches the expiring lease.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = YXRRSET;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Delete appropriate A RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = DELETE;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
- print_dns_status ((int)result, &updqueue);
-
- /*
- * If the query fails, the updater MUST NOT delete the DNS name. It
- * may be that the host whose lease on the server has expired has moved
- * to another network and obtained a lease from a different server,
- * which has caused the client's A RR to be replaced. It may also be
- * that some other client has been configured with a name that matches
- * the name of the DHCP client, and the policy was that the last client
- * to specify the name would get the name. In this case, the DHCID RR
- * will no longer match the updater's notion of the client-identity of
- * the host pointed to by the DNS name.
- * -- "Interaction between DHCP and DNS"
- */
-
- if (result != ISC_R_SUCCESS)
- goto error;
-
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
-
- /* If the deletion of the A succeeded, and there are no A records
- left for this domain, then we can blow away the DHCID record
- as well. We can't blow away the DHCID record above because
- it's possible that more than one A has been added to this
- domain name. */
- ISC_LIST_INIT (updqueue);
-
- /*
- * A RR does not exist.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)0;
- updrec -> r_size = 0;
- updrec -> r_opcode = NXRRSET;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
- /*
- * Delete appropriate DHCID RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = DELETE;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
- print_dns_status ((int)result, &updqueue);
-
- /* Fall through. */
- error:
-
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
-
- return result;
-}
-
-
static isc_result_t ddns_remove_ptr (struct data_string *ddns_rev_name)
{
ns_updque updqueue;
@@ -675,7 +266,7 @@ int ddns_updates (struct packet *packet,
specifically configured to do so. If the client asked to do its
own update and we allowed that, we don't do this test. */
if (lease -> flags & STATIC_LEASE) {
- if (!(oc = lookup_option (&fqdn_universe, packet -> options,
+ if (!(oc = lookup_option (&server_universe, packet -> options,
SV_UPDATE_STATIC_LEASES)) ||
!evaluate_boolean_option_cache (&ignorep, packet, lease,
(struct client_state *)0,
@@ -799,6 +390,11 @@ int ddns_updates (struct packet *packet,
}
in:
+ /* If we don't have a name that the client has been assigned, we
+ can just skip all this. */
+ if (!ddns_fwd_name.len)
+ goto out;
+
/*
* Compute the RR TTL.
*/
@@ -867,7 +463,16 @@ int ddns_updates (struct packet *packet,
*/
if (server_updates_a) {
memset (&ddns_dhcid, 0, sizeof ddns_dhcid);
- get_dhcid (&ddns_dhcid, lease);
+ if (lease -> uid && lease -> uid_len)
+ result = get_dhcid (&ddns_dhcid,
+ DHO_DHCP_CLIENT_IDENTIFIER,
+ lease -> uid, lease -> uid_len);
+ else
+ result = get_dhcid (&ddns_dhcid, 0,
+ lease -> hardware_addr.hbuf,
+ lease -> hardware_addr.hlen);
+ if (!result)
+ goto badfqdn;
}
/*
@@ -885,7 +490,7 @@ int ddns_updates (struct packet *packet,
*/
if (ddns_fwd_name.len && ddns_dhcid.len)
rcode1 = ddns_update_a (&ddns_fwd_name, lease -> ip_addr,
- &ddns_dhcid, ddns_ttl);
+ &ddns_dhcid, ddns_ttl, 0);
if (rcode1 == ISC_R_SUCCESS) {
if (ddns_fwd_name.len && ddns_rev_name.len)
@@ -1025,7 +630,7 @@ int ddns_removals (struct lease *lease)
in case the client did the update. */
if (!find_bound_string (&ddns_fwd_name,
lease -> scope, "ddns-client-fqdn"))
- return 0;
+ goto try_rev;
client_updated = 1;
goto try_rev;
}
@@ -1041,7 +646,11 @@ int ddns_removals (struct lease *lease)
/*
* Perform removals.
*/
- rcode = ddns_remove_a (&ddns_fwd_name, lease -> ip_addr, &ddns_dhcid);
+ if (ddns_fwd_name.len)
+ rcode = ddns_remove_a (&ddns_fwd_name,
+ lease -> ip_addr, &ddns_dhcid);
+ else
+ rcode = ISC_R_SUCCESS;
if (rcode == ISC_R_SUCCESS) {
result = 1;
@@ -1055,6 +664,11 @@ int ddns_removals (struct lease *lease)
if (client_updated)
unset (lease -> scope,
"ddns-client-fqdn");
+ /* XXX this is to compensate for a bug in
+ XXX 3.0rc8, and should be removed before
+ XXX 3.0pl1. */
+ else if (!ddns_fwd_name.len)
+ unset (lease -> scope, "ddns-text");
} else
result = 0;
}
diff --git a/server/dhcp.c b/server/dhcp.c
index 1b4f7317..095d78a7 100644
--- a/server/dhcp.c
+++ b/server/dhcp.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: dhcp.c,v 1.193 2001/05/17 19:04:05 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhcp.c,v 1.194 2001/06/27 00:31:07 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -52,6 +52,18 @@ int outstanding_pings;
static char dhcp_message [256];
+static const char *dhcp_type_names [] = {
+ "DHCPDISCOVER",
+ "DHCPOFFER",
+ "DHCPREQUEST",
+ "DHCPDECLINE",
+ "DHCPACK",
+ "DHCPNAK",
+ "DHCPRELEASE",
+ "DHCPINFORM"
+};
+const int dhcp_type_name_max = ((sizeof dhcp_type_names) / sizeof (char *));
+
#if defined (TRACING)
# define send_packet trace_packet_send
#endif
@@ -68,18 +80,6 @@ void dhcp (packet)
if (!locate_network (packet) &&
packet -> packet_type != DHCPREQUEST &&
packet -> packet_type != DHCPINFORM) {
- static const char *dhcp_type_names [] = {
- "DHCPDISCOVER",
- "DHCPOFFER",
- "DHCPREQUEST",
- "DHCPDECLINE",
- "DHCPACK",
- "DHCPNAK",
- "DHCPRELEASE",
- "DHCPINFORM"
- };
- const int dhcp_type_name_max = ((sizeof dhcp_type_names) /
- sizeof (char *));
const char *s;
char typebuf [32];
errmsg = "unknown network segment";
@@ -296,6 +296,36 @@ void dhcpdiscover (packet, ms_nulltp)
goto out;
}
+#if defined (FAILOVER_PROTOCOL)
+ if (lease && lease -> pool && lease -> pool -> failover_peer) {
+ peer = lease -> pool -> failover_peer;
+
+ /* If the lease is ours to allocate, then allocate it,
+ but set the allocatedp flag. */
+ if (lease_mine_to_reallocate (lease))
+ allocatedp = 1;
+
+ /* If the lease is active, do load balancing to see who
+ allocates the lease (if it's active, it already belongs
+ to the client, or we wouldn't have gotten it from
+ find_lease (). */
+ else if (lease -> binding_state == FTS_ACTIVE &&
+ (peer -> service_state != cooperating ||
+ load_balance_mine (packet, peer)))
+ ;
+
+ /* Otherwise, we can't let the client have this lease. */
+ else {
+#if defined (DEBUG_FIND_LEASE)
+ log_debug ("discarding %s - %s",
+ piaddr (lease -> ip_addr),
+ binding_state_print (lease -> binding_state));
+#endif
+ lease_dereference (&lease, MDL);
+ }
+ }
+#endif
+
/* If we didn't find a lease, try to allocate one... */
if (!lease) {
if (!allocate_lease (&lease, packet,
@@ -467,9 +497,14 @@ void dhcprequest (packet, ms_nulltp, ip_lease)
If it's RENEWING, we are the only server to hear it, so
we have to serve it. If it's REBINDING, it's out of
communication with the other server, so there's no point
- in waiting to serve it. */
+ in waiting to serve it. However, if the lease we're
+ offering is not a free lease, then we may be the only
+ server that can offer it, so we can't load balance if
+ the lease isn't in the free or backup state. */
if (peer -> service_state == cooperating &&
- !packet -> raw -> ciaddr.s_addr) {
+ !packet -> raw -> ciaddr.s_addr &&
+ (lease -> binding_state == FTS_FREE ||
+ lease -> binding_state == FTS_BACKUP)) {
if (!load_balance_mine (packet, peer)) {
log_debug ("%s: load balance to peer %s",
msgbuf, peer -> name);
@@ -479,13 +514,36 @@ void dhcprequest (packet, ms_nulltp, ip_lease)
/* Don't let a client allocate a lease using DHCPREQUEST
if the lease isn't ours to allocate. */
- if ((lease -> binding_state == FTS_FREE &&
- peer -> i_am == secondary) ||
- (lease -> binding_state == FTS_BACKUP &&
- peer -> i_am == primary)) {
- log_debug ("%s: expired", msgbuf);
+ if ((lease -> binding_state == FTS_FREE ||
+ lease -> binding_state == FTS_BACKUP) &&
+ !lease_mine_to_reallocate (lease)) {
+ log_debug ("%s: lease owned by peer", msgbuf);
goto out;
}
+
+ /* At this point it's possible that we will get a broadcast
+ DHCPREQUEST for a lease that we didn't offer, because
+ both we and the peer are in a position to offer it.
+ In that case, we probably shouldn't answer. In order
+ to not answer, we would have to compare the server
+ identifier sent by the client with the list of possible
+ server identifiers we can send, and if the client's
+ identifier isn't on the list, drop the DHCPREQUEST.
+ We aren't currently doing that for two reasons - first,
+ it's not clear that all clients do the right thing
+ with respect to sending the client identifier, which
+ could mean that we might simply not respond to a client
+ that is depending on us to respond. Secondly, we allow
+ the user to specify the server identifier to send, and
+ we don't enforce that the server identifier should be
+ one of our IP addresses. This is probably not a big
+ deal, but it's theoretically an issue.
+
+ The reason we care about this is that if both servers
+ send a DHCPACK to the DHCPREQUEST, they are then going
+ to send dueling BNDUPD messages, which could cause
+ trouble. I think it causes no harm, but it seems
+ wrong. */
} else
peer = (dhcp_failover_state_t *)0;
#endif
@@ -978,7 +1036,8 @@ void dhcpinform (packet, ms_nulltp)
i = DHO_DHCP_MESSAGE_TYPE;
oc = (struct option_cache *)0;
if (option_cache_allocate (&oc, MDL)) {
- if (make_const_data (&oc -> expression, &dhcpack, 1, 0, 0)) {
+ if (make_const_data (&oc -> expression,
+ &dhcpack, 1, 0, 0, MDL)) {
oc -> option = dhcp_universe.options [i];
save_option (&dhcp_universe, options, oc);
}
@@ -995,7 +1054,7 @@ void dhcpinform (packet, ms_nulltp)
((unsigned char *)
&packet -> interface -> primary_address),
sizeof packet -> interface -> primary_address,
- 0, 0)) {
+ 0, 0, MDL)) {
oc -> option =
dhcp_universe.options [i];
save_option (&dhcp_universe,
@@ -1027,7 +1086,8 @@ void dhcpinform (packet, ms_nulltp)
if (option_cache_allocate (&oc, MDL)) {
if (make_const_data (&oc -> expression,
subnet -> netmask.iabuf,
- subnet -> netmask.len, 0, 0)) {
+ subnet -> netmask.len,
+ 0, 0, MDL)) {
oc -> option = dhcp_universe.options [i];
save_option (&dhcp_universe, options, oc);
}
@@ -1190,7 +1250,8 @@ void nak_lease (packet, cip)
option_state_dereference (&options, MDL);
return;
}
- if (!make_const_data (&oc -> expression, &nak, sizeof nak, 0, 0)) {
+ if (!make_const_data (&oc -> expression, &nak, sizeof nak,
+ 0, 0, MDL)) {
log_error ("No memory for expr_const expression.");
option_cache_dereference (&oc, MDL);
option_state_dereference (&options, MDL);
@@ -1208,7 +1269,7 @@ void nak_lease (packet, cip)
}
if (!make_const_data (&oc -> expression,
(unsigned char *)dhcp_message,
- strlen (dhcp_message), 1, 0)) {
+ strlen (dhcp_message), 1, 0, MDL)) {
log_error ("No memory for expr_const expression.");
option_cache_dereference (&oc, MDL);
option_state_dereference (&options, MDL);
@@ -1228,7 +1289,7 @@ void nak_lease (packet, cip)
((unsigned char *)
&packet -> interface -> primary_address),
sizeof packet -> interface -> primary_address,
- 0, 0)) {
+ 0, 0, MDL)) {
oc -> option =
dhcp_universe.options [i];
save_option (&dhcp_universe, options, oc);
@@ -1492,83 +1553,96 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
packet -> options,
state -> options, &lease -> scope,
oc, MDL)) {
- struct lease *seek;
- if (lease -> uid_len) {
- do {
- seek = (struct lease *)0;
- find_lease_by_uid (&seek, lease -> uid,
- lease -> uid_len, MDL);
- if (!seek || (seek == lease && !seek -> n_uid))
- break;
- next = (struct lease *)0;
-
- /* Don't release expired leases, and don't
- release the lease we're going to assign. */
- next = (struct lease *)0;
- while (seek) {
- if (seek -> n_uid)
- lease_reference (&next,
- seek -> n_uid,
- MDL);
- if (seek != lease &&
- seek -> ends > cur_time)
- break;
- lease_dereference (&seek, MDL);
- if (next) {
- lease_reference (&seek, next, MDL);
- lease_dereference (&next, MDL);
- }
- }
- if (next)
- lease_dereference (&next, MDL);
- if (seek) {
- release_lease (seek, packet);
- lease_dereference (&seek, MDL);
- } else
- break;
- } while (1);
- }
- if (!lease -> uid_len ||
- (lease -> host &&
- !lease -> host -> client_identifier.len &&
- (oc = lookup_option (&server_universe, state -> options,
- SV_DUPLICATES)) &&
- !evaluate_boolean_option_cache (&ignorep, packet, lease,
- (struct client_state *)0,
- packet -> options,
- state -> options,
- &lease -> scope,
- oc, MDL))) {
- do {
- seek = (struct lease *)0;
- find_lease_by_hw_addr
- (&seek, lease -> hardware_addr.hbuf,
- lease -> hardware_addr.hlen, MDL);
- if (!seek || (seek == lease && !seek -> n_hw))
- break;
- next = (struct lease *)0;
- while (seek) {
- if (seek -> n_hw)
- lease_reference (&next,
- seek -> n_hw, MDL);
- if (seek != lease &&
- seek -> ends > cur_time)
- break;
- lease_dereference (&seek, MDL);
- if (next) {
- lease_reference (&seek, next, MDL);
- lease_dereference (&next, MDL);
- }
- }
- if (next)
- lease_dereference (&next, MDL);
- if (seek) {
- release_lease (seek, packet);
- lease_dereference (&seek, MDL);
- } else
- break;
- } while (1);
- }
+ struct lease *seek;
+ if (lease -> uid_len) {
+ do {
+ seek = (struct lease *)0;
+ find_lease_by_uid (&seek, lease -> uid,
+ lease -> uid_len, MDL);
+ if (!seek)
+ break;
+ if (seek == lease && !seek -> n_uid) {
+ lease_dereference (&seek, MDL);
+ break;
+ }
+ next = (struct lease *)0;
+
+ /* Don't release expired leases, and don't
+ release the lease we're going to assign. */
+ next = (struct lease *)0;
+ while (seek) {
+ if (seek -> n_uid)
+ lease_reference (&next, seek -> n_uid, MDL);
+ if (seek != lease &&
+ seek -> binding_state != FTS_RELEASED &&
+ seek -> binding_state != FTS_EXPIRED &&
+ seek -> binding_state != FTS_RESET &&
+ seek -> binding_state != FTS_FREE &&
+ seek -> binding_state != FTS_BACKUP)
+ break;
+ lease_dereference (&seek, MDL);
+ if (next) {
+ lease_reference (&seek, next, MDL);
+ lease_dereference (&next, MDL);
+ }
+ }
+ if (next)
+ lease_dereference (&next, MDL);
+ if (seek) {
+ release_lease (seek, packet);
+ lease_dereference (&seek, MDL);
+ } else
+ break;
+ } while (1);
+ }
+ if (!lease -> uid_len ||
+ (lease -> host &&
+ !lease -> host -> client_identifier.len &&
+ (oc = lookup_option (&server_universe, state -> options,
+ SV_DUPLICATES)) &&
+ !evaluate_boolean_option_cache (&ignorep, packet, lease,
+ (struct client_state *)0,
+ packet -> options,
+ state -> options,
+ &lease -> scope,
+ oc, MDL))) {
+ do {
+ seek = (struct lease *)0;
+ find_lease_by_hw_addr
+ (&seek, lease -> hardware_addr.hbuf,
+ lease -> hardware_addr.hlen, MDL);
+ if (!seek)
+ break;
+ if (seek == lease && !seek -> n_hw) {
+ lease_dereference (&seek, MDL);
+ break;
+ }
+ next = (struct lease *)0;
+ while (seek) {
+ if (seek -> n_hw)
+ lease_reference (&next, seek -> n_hw, MDL);
+ if (seek != lease &&
+ seek -> binding_state != FTS_RELEASED &&
+ seek -> binding_state != FTS_EXPIRED &&
+ seek -> binding_state != FTS_RESET &&
+ seek -> binding_state != FTS_FREE &&
+ seek -> binding_state != FTS_BACKUP)
+ break;
+ lease_dereference (&seek, MDL);
+ if (next) {
+ lease_reference (&seek, next, MDL);
+ lease_dereference (&next, MDL);
+ }
+ }
+ if (next)
+ lease_dereference (&next, MDL);
+ if (seek) {
+ release_lease (seek, packet);
+ lease_dereference (&seek, MDL);
+ } else
+ break;
+ } while (1);
+ }
}
@@ -1859,7 +1933,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
/* Here we're assuming that if we don't have
to update tstp, there's already an update
queued. May want to revisit this. */
- if (cur_time + lease_time > lease -> tstp)
+ if (peer -> me.state != partner_down &&
+ cur_time + lease_time > lease -> tstp)
lt -> tstp = (cur_time + lease_time +
peer -> mclt / 2);
@@ -1902,7 +1977,13 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
lt -> ends = when;
else
lt -> ends = state -> offered_expiry;
- lt -> next_binding_state = FTS_ACTIVE;
+
+ /* Don't make lease active until we actually get a
+ DHCPREQUEST. */
+ if (offer == DHCPACK)
+ lt -> next_binding_state = FTS_ACTIVE;
+ else
+ lt -> next_binding_state = lease -> binding_state;
} else {
lease_time = MAX_TIME - cur_time;
@@ -2162,7 +2243,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
oc = (struct option_cache *)0;
if (option_cache_allocate (&oc, MDL)) {
if (make_const_data (&oc -> expression,
- &state -> offer, 1, 0, 0)) {
+ &state -> offer, 1, 0, 0, MDL)) {
oc -> option =
dhcp_universe.options [i];
save_option (&dhcp_universe,
@@ -2181,7 +2262,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
((unsigned char *)
&state -> ip -> primary_address),
sizeof state -> ip -> primary_address,
- 0, 0)) {
+ 0, 0, MDL)) {
oc -> option =
dhcp_universe.options [i];
save_option (&dhcp_universe,
@@ -2225,7 +2306,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
if (option_cache_allocate (&oc, MDL)) {
if (make_const_data (&oc -> expression,
(unsigned char *)&state -> expiry,
- sizeof state -> expiry, 0, 0)) {
+ sizeof state -> expiry,
+ 0, 0, MDL)) {
oc -> option = dhcp_universe.options [i];
save_option (&dhcp_universe,
state -> options, oc);
@@ -2246,7 +2328,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
if (make_const_data (&oc -> expression,
(unsigned char *)
&state -> renewal,
- sizeof state -> renewal, 0, 0)) {
+ sizeof state -> renewal,
+ 0, 0, MDL)) {
oc -> option = dhcp_universe.options [i];
save_option (&dhcp_universe,
state -> options, oc);
@@ -2267,7 +2350,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
if (option_cache_allocate (&oc, MDL)) {
if (make_const_data (&oc -> expression,
(unsigned char *)&state -> rebind,
- sizeof state -> rebind, 0, 0)) {
+ sizeof state -> rebind,
+ 0, 0, MDL)) {
oc -> option = dhcp_universe.options [i];
save_option (&dhcp_universe,
state -> options, oc);
@@ -2308,7 +2392,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
if (make_const_data (&oc -> expression,
lease -> subnet -> netmask.iabuf,
lease -> subnet -> netmask.len,
- 0, 0)) {
+ 0, 0, MDL)) {
oc -> option = dhcp_universe.options [i];
save_option (&dhcp_universe,
state -> options, oc);
@@ -2334,7 +2418,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
((unsigned char *)
lease -> host -> name),
strlen (lease -> host -> name),
- 1, 0)) {
+ 1, 0, MDL)) {
oc -> option = dhcp_universe.options [i];
save_option (&dhcp_universe,
state -> options, oc);
@@ -2366,7 +2450,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
((unsigned char *)
h -> h_name),
strlen (h -> h_name) + 1,
- 1, 1)) {
+ 1, 1, MDL)) {
oc -> option =
dhcp_universe.options [i];
save_option (&dhcp_universe,
@@ -2394,7 +2478,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
if (make_const_data (&oc -> expression,
lease -> ip_addr.iabuf,
lease -> ip_addr.len,
- 0, 0)) {
+ 0, 0, MDL)) {
oc -> option =
dhcp_universe.options [i];
save_option (&dhcp_universe,
@@ -2829,21 +2913,29 @@ int find_lease (struct lease **lp,
log_info ("trying next lease matching client id: %s",
piaddr (uid_lease -> ip_addr));
#endif
+
+#if defined (FAILOVER_PROTOCOL)
+ /* When failover is active, it's possible that there could
+ be two "free" leases for the same uid, but only one of
+ them that's available for this failover peer to allocate. */
+ if (uid_lease -> binding_state != FTS_ACTIVE &&
+ !lease_mine_to_reallocate (uid_lease)) {
+#if defined (DEBUG_FIND_LEASE)
+ log_info ("not mine to allocate: %s",
+ piaddr (uid_lease -> ip_addr));
+#endif
+ goto n_uid;
+ }
+#endif
+
if (uid_lease -> subnet -> shared_network != share) {
#if defined (DEBUG_FIND_LEASE)
log_info ("wrong network segment: %s",
piaddr (uid_lease -> ip_addr));
#endif
- if (uid_lease -> n_uid)
- lease_reference (&next,
- uid_lease -> n_uid, MDL);
- lease_dereference (&uid_lease, MDL);
- if (next) {
- lease_reference (&uid_lease, next, MDL);
- lease_dereference (&next, MDL);
- }
- continue;
+ goto n_uid;
}
+
if ((uid_lease -> pool -> prohibit_list &&
permitted (packet, uid_lease -> pool -> prohibit_list)) ||
(uid_lease -> pool -> permit_list &&
@@ -2852,6 +2944,7 @@ int find_lease (struct lease **lp,
log_info ("not permitted: %s",
piaddr (uid_lease -> ip_addr));
#endif
+ n_uid:
if (uid_lease -> n_uid)
lease_reference (&next,
uid_lease -> n_uid, MDL);
@@ -2884,7 +2977,22 @@ int find_lease (struct lease **lp,
log_info ("trying next lease matching hw addr: %s",
piaddr (hw_lease -> ip_addr));
#endif
- if (hw_lease -> ends >= cur_time &&
+#if defined (FAILOVER_PROTOCOL)
+ /* When failover is active, it's possible that there could
+ be two "free" leases for the same uid, but only one of
+ them that's available for this failover peer to allocate. */
+ if (hw_lease -> binding_state != FTS_ACTIVE &&
+ !lease_mine_to_reallocate (hw_lease)) {
+#if defined (DEBUG_FIND_LEASE)
+ log_info ("not mine to allocate: %s",
+ piaddr (hw_lease -> ip_addr));
+#endif
+ goto n_hw;
+ }
+#endif
+
+ if (hw_lease -> binding_state != FTS_FREE &&
+ hw_lease -> binding_state != FTS_BACKUP &&
hw_lease -> uid &&
(!have_client_identifier ||
hw_lease -> uid_len != client_identifier.len ||
@@ -2894,13 +3002,7 @@ int find_lease (struct lease **lp,
log_info ("wrong client identifier: %s",
piaddr (hw_lease -> ip_addr));
#endif
- if (hw_lease -> n_hw)
- lease_reference (&next, hw_lease -> n_hw, MDL);
- lease_dereference (&hw_lease, MDL);
- if (next) {
- lease_reference (&hw_lease, next, MDL);
- lease_dereference (&next, MDL);
- }
+ goto n_hw;
continue;
}
if (hw_lease -> subnet -> shared_network != share) {
@@ -2908,13 +3010,7 @@ int find_lease (struct lease **lp,
log_info ("wrong network segment: %s",
piaddr (hw_lease -> ip_addr));
#endif
- if (hw_lease -> n_hw)
- lease_reference (&next, hw_lease -> n_hw, MDL);
- lease_dereference (&hw_lease, MDL);
- if (next) {
- lease_reference (&hw_lease, next, MDL);
- lease_dereference (&next, MDL);
- }
+ goto n_hw;
continue;
}
if ((hw_lease -> pool -> prohibit_list &&
@@ -2925,10 +3021,11 @@ int find_lease (struct lease **lp,
log_info ("not permitted: %s",
piaddr (hw_lease -> ip_addr));
#endif
- if (hw_lease -> n_hw)
- lease_reference (&next, hw_lease -> n_hw, MDL);
if (!packet -> raw -> ciaddr.s_addr)
release_lease (hw_lease, packet);
+ n_hw:
+ if (hw_lease -> n_hw)
+ lease_reference (&next, hw_lease -> n_hw, MDL);
lease_dereference (&hw_lease, MDL);
if (next) {
lease_reference (&hw_lease, next, MDL);
@@ -2995,15 +3092,11 @@ int find_lease (struct lease **lp,
(unsigned)(ip_lease -> hardware_addr.hlen - 1))))) {
/* If we're not doing failover, the only state in which
we can allocate this lease to the client is FTS_FREE.
- If we are doing failover, things are more complicated. */
- if (
-#if !defined (FAILOVER_PROTOCOL)
- (ip_lease -> binding_state != FTS_FREE &&
- ip_lease -> binding_state != FTS_BACKUP)
-#else
- !lease_mine_to_reallocate (ip_lease)
-#endif
- ) {
+ If we are doing failover, things are more complicated.
+ If the lease is free or backup, we let the caller decide
+ whether or not to give it out. */
+ if (ip_lease -> binding_state != FTS_FREE &&
+ ip_lease -> binding_state != FTS_BACKUP) {
#if defined (DEBUG_FIND_LEASE)
log_info ("rejecting lease for requested address.");
#endif
@@ -3017,6 +3110,18 @@ int find_lease (struct lease **lp,
*allocatedp = 1;
}
+ /* If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
+ is not active, and is not ours to reallocate, forget about it. */
+ if (ip_lease && (uid_lease || hw_lease) &&
+ ip_lease -> binding_state != FTS_ACTIVE &&
+ !lease_mine_to_reallocate (ip_lease) &&
+ packet -> packet_type == DHCPDISCOVER) {
+#if defined (DEBUG_FIND_LEASE)
+ log_info ("ip lease not ours to offer.");
+#endif
+ lease_dereference (&ip_lease, MDL);
+ }
+
/* 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 and (if we can) free the other. */
@@ -3042,6 +3147,7 @@ int find_lease (struct lease **lp,
it shouldn't still be using the old
one, so we can free it for allocation. */
if (uid_lease &&
+ uid_lease -> binding_state == FTS_ACTIVE &&
!packet -> raw -> ciaddr.s_addr &&
(share ==
uid_lease -> subnet -> shared_network) &&
@@ -3195,7 +3301,8 @@ int find_lease (struct lease **lp,
if (uid_lease) {
if (lease) {
if (!packet -> raw -> ciaddr.s_addr &&
- packet -> packet_type == DHCPREQUEST)
+ packet -> packet_type == DHCPREQUEST &&
+ uid_lease -> binding_state == FTS_ACTIVE)
dissociate_lease (uid_lease);
#if defined (DEBUG_FIND_LEASE)
log_info ("not choosing uid lease.");
diff --git a/server/dhcpd.8 b/server/dhcpd.8
index 1ec659b0..56827a83 100644
--- a/server/dhcpd.8
+++ b/server/dhcpd.8
@@ -559,6 +559,22 @@ a list of statements in the format of the dhcpd.conf file that will be
executed whenever a message from a client whose host declaration
references this group is processed.
.RE
+.SH THE CONTROL OBJECT
+The control object allows you to shut the server down. If the server
+is doing failover with another peer, it will make a clean transition
+into the shutdown state and notify its peer, so that the peer can go
+into partner down, and then record the "recover" state in the lease
+file so that when the server is restarted, it will automatically
+resynchronize with its peer.
+.PP
+On shutdown the server will also attempt to cleanly shut down all
+OMAPI connections. If these connections do not go down cleanly after
+five seconds, they are shut down pre-emptively. It can take as much
+as 25 seconds from the beginning of the shutdown process to the time
+that the server actually exits.
+.PP
+To shut the server down, open its control object and set the state
+attribute to 2.
.SH FILES
.B ETCDIR/dhcpd.conf, DBDIR/dhcpd.leases, RUNDIR/dhcpd.pid,
.B DBDIR/dhcpd.leases~.
diff --git a/server/dhcpd.c b/server/dhcpd.c
index 4d916517..293c27fc 100644
--- a/server/dhcpd.c
+++ b/server/dhcpd.c
@@ -43,7 +43,7 @@
#ifndef lint
static char ocopyright[] =
-"$Id: dhcpd.c,v 1.115 2001/05/02 07:08:15 mellon Exp $ Copyright 1995-2001 Internet Software Consortium.";
+"$Id: dhcpd.c,v 1.116 2001/06/27 00:31:09 mellon Exp $ Copyright 1995-2001 Internet Software Consortium.";
#endif
static char copyright[] =
@@ -181,6 +181,29 @@ static isc_result_t verify_auth (omapi_object_t *p, omapi_auth_key_t *a) {
return ISC_R_SUCCESS;
}
+static void omapi_listener_start (void *foo)
+{
+ omapi_object_t *listener;
+ isc_result_t result;
+
+ listener = (omapi_object_t *)0;
+ result = omapi_generic_new (&listener, MDL);
+ if (result != ISC_R_SUCCESS)
+ log_fatal ("Can't allocate new generic object: %s",
+ isc_result_totext (result));
+ result = omapi_protocol_listen (listener,
+ (unsigned)omapi_port, 1);
+ if (result == ISC_R_SUCCESS && omapi_key)
+ result = omapi_protocol_configure_security
+ (listener, verify_addr, verify_auth);
+ if (result != ISC_R_SUCCESS) {
+ log_error ("Can't start OMAPI protocol: %s",
+ isc_result_totext (result));
+ add_timeout (cur_time + 5, omapi_listener_start, 0, 0, 0);
+ }
+ omapi_object_dereference (&listener, MDL);
+}
+
int main (argc, argv, envp)
int argc;
char **argv, **envp;
@@ -199,7 +222,6 @@ int main (argc, argv, envp)
int quiet = 0;
char *server = (char *)0;
isc_result_t result;
- omapi_object_t *listener;
unsigned seed;
struct interface_info *ip;
struct parse *parse;
@@ -461,6 +483,13 @@ int main (argc, argv, envp)
log_fatal (" lease file when playing back a trace. **");
}
trace_file_replay (traceinfile);
+
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ free_everything ();
+ omapi_print_dmalloc_usage_by_caller ();
+#endif
+
exit (0);
}
#endif
@@ -469,12 +498,12 @@ int main (argc, argv, envp)
if (readconf () != ISC_R_SUCCESS)
log_fatal ("Configuration file errors encountered -- exiting");
+ postconf_initialization (quiet);
+
/* test option should cause an early exit */
if (cftest && !lftest)
exit(0);
- postconf_initialization (quiet);
-
group_write_hook = group_writer;
/* Start up the database... */
@@ -503,28 +532,7 @@ int main (argc, argv, envp)
#if defined (TRACING)
trace_seed_stash (trace_srandom, seed + cur_time);
#endif
-
- /* Start up a listener for the object management API protocol. */
- if (omapi_port != -1) {
- listener = (omapi_object_t *)0;
- result = omapi_generic_new (&listener, MDL);
- if (result != ISC_R_SUCCESS)
- log_fatal ("Can't allocate new generic object: %s",
- isc_result_totext (result));
- result = omapi_protocol_listen (listener,
- (unsigned)omapi_port, 1);
- if (result == ISC_R_SUCCESS && omapi_key)
- result = omapi_protocol_configure_security
- (listener, verify_addr, verify_auth);
- if (result != ISC_R_SUCCESS)
- log_fatal ("Can't start OMAPI protocol: %s",
- isc_result_totext (result));
- }
-
-#if defined (FAILOVER_PROTOCOL)
- /* Start the failover protocol. */
- dhcp_failover_startup ();
-#endif
+ postdb_startup ();
#ifndef DEBUG
if (daemon) {
@@ -588,7 +596,8 @@ int main (argc, argv, envp)
}
#endif /* !DEBUG */
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
dmalloc_cutoff_generation = dmalloc_generation;
dmalloc_longterm = dmalloc_outstanding;
dmalloc_outstanding = 0;
@@ -598,6 +607,9 @@ int main (argc, argv, envp)
dump_rc_history ();
#endif
+ omapi_set_int_value ((omapi_object_t *)dhcp_control_object,
+ (omapi_object_t *)0, "state", server_running);
+
/* Receive packets and dispatch them... */
dispatch ();
@@ -687,7 +699,8 @@ void postconf_initialization (int quiet)
result = omapi_auth_key_lookup_name (&omapi_key, s);
dfree (s, MDL);
if (result != ISC_R_SUCCESS)
- log_fatal ("Invalid OMAPI key: %s", s);
+ log_fatal ("OMAPI key %s: %s",
+ s, isc_result_totext (result));
}
oc = lookup_option (&server_universe, options, SV_LOCAL_PORT);
@@ -852,6 +865,19 @@ void postconf_initialization (int quiet)
#endif
}
+void postdb_startup (void)
+{
+ /* Initialize the omapi listener state. */
+ if (omapi_port != -1) {
+ omapi_listener_start (0);
+ }
+
+#if defined (FAILOVER_PROTOCOL)
+ /* Initialize the failover listener state. */
+ dhcp_failover_startup ();
+#endif
+}
+
/* Print usage message. */
static void usage ()
@@ -938,7 +964,7 @@ void lease_ping_timeout (vlp)
dmalloc_outstanding - previous_outstanding,
dmalloc_outstanding, dmalloc_longterm);
#endif
-#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+#if defined (DEBUG_MEMORY_LEAKAGE)
dmalloc_dump_outstanding ();
#endif
}
@@ -970,7 +996,7 @@ int dhcpd_interface_setup_hook (struct interface_info *ip, struct iaddr *ia)
/* If this interface has multiple aliases on the same
subnet, ignore all but the first we encounter. */
if (!subnet -> interface) {
- subnet -> interface = ip;
+ interface_reference (&subnet -> interface, ip, MDL);
subnet -> interface_address = *ia;
} else if (subnet -> interface != ip) {
log_error ("Multiple interfaces match the %s: %s %s",
@@ -995,6 +1021,150 @@ int dhcpd_interface_setup_hook (struct interface_info *ip, struct iaddr *ia)
"same shared network",
share -> interface -> name, ip -> name);
}
+ subnet_dereference (&subnet, MDL);
}
return 1;
}
+
+static TIME shutdown_time;
+static int omapi_connection_count;
+enum dhcp_shutdown_state shutdown_state;
+
+isc_result_t dhcp_io_shutdown (omapi_object_t *obj, void *foo)
+{
+ /* Shut down all listeners. */
+ if (shutdown_state == shutdown_listeners &&
+ obj -> type == omapi_type_listener &&
+ obj -> inner &&
+ obj -> inner -> type == omapi_type_protocol_listener) {
+ omapi_listener_destroy (obj, MDL);
+ return ISC_R_SUCCESS;
+ }
+
+ /* Shut down all existing omapi connections. */
+ if (obj -> type == omapi_type_connection &&
+ obj -> inner &&
+ obj -> inner -> type == omapi_type_protocol) {
+ if (shutdown_state == shutdown_drop_omapi_connections) {
+ omapi_disconnect (obj, 1);
+ }
+ omapi_connection_count++;
+ if (shutdown_state == shutdown_omapi_connections) {
+ omapi_disconnect (obj, 0);
+ return ISC_R_SUCCESS;
+ }
+ }
+
+ /* Shutdown all DHCP interfaces. */
+ if (obj -> type == dhcp_type_interface &&
+ shutdown_state == shutdown_dhcp) {
+ dhcp_interface_remove (obj, (omapi_object_t *)0);
+ return ISC_R_SUCCESS;
+ }
+ return ISC_R_SUCCESS;
+}
+
+static isc_result_t dhcp_io_shutdown_countdown (void *vlp)
+{
+ dhcp_failover_state_t *state;
+#if defined (FAILOVER_PROTOCOL)
+ int failover_connection_count = 0;
+#endif
+
+ oncemore:
+ if (shutdown_state == shutdown_listeners ||
+ shutdown_state == shutdown_omapi_connections ||
+ shutdown_state == shutdown_drop_omapi_connections ||
+ shutdown_state == shutdown_dhcp) {
+ omapi_connection_count = 0;
+ omapi_io_state_foreach (dhcp_io_shutdown, 0);
+ }
+
+ if ((shutdown_state == shutdown_listeners ||
+ shutdown_state == shutdown_omapi_connections ||
+ shutdown_state == shutdown_drop_omapi_connections) &&
+ omapi_connection_count == 0) {
+ shutdown_state = shutdown_dhcp;
+ shutdown_time = cur_time;
+ goto oncemore;
+ } else if (shutdown_state == shutdown_listeners &&
+ cur_time - shutdown_time > 4) {
+ shutdown_state = shutdown_omapi_connections;
+ shutdown_time = cur_time;
+ } else if (shutdown_state == shutdown_omapi_connections &&
+ cur_time - shutdown_time > 4) {
+ shutdown_state = shutdown_drop_omapi_connections;
+ shutdown_time = cur_time;
+ } else if (shutdown_state == shutdown_drop_omapi_connections &&
+ cur_time - shutdown_time > 4) {
+ shutdown_state = shutdown_dhcp;
+ shutdown_time = cur_time;
+ goto oncemore;
+ } else if (shutdown_state == shutdown_dhcp &&
+ cur_time - shutdown_time > 4) {
+ shutdown_state = shutdown_done;
+ shutdown_time = cur_time;
+ }
+
+#if defined (FAILOVER_PROTOCOL)
+ /* Set all failover peers into the shutdown state. */
+ if (shutdown_state == shutdown_dhcp) {
+ for (state = failover_states; state; state = state -> next) {
+ if (state -> me.state == normal) {
+ dhcp_failover_set_state (state, shut_down);
+ failover_connection_count++;
+ }
+ if (state -> me.state == shut_down &&
+ state -> partner.state != partner_down)
+ failover_connection_count++;
+ }
+ }
+
+ if (shutdown_state == shutdown_done) {
+ for (state = failover_states; state; state = state -> next) {
+ if (state -> me.state == shut_down) {
+ if (state -> link_to_peer)
+ dhcp_failover_link_dereference (&state -> link_to_peer,
+ MDL);
+ dhcp_failover_set_state (state, recover);
+ }
+ }
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ free_everything ();
+ omapi_print_dmalloc_usage_by_caller ();
+#endif
+ exit (0);
+ }
+#else
+ if (shutdown_state == shutdown_done) {
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ free_everything ();
+ omapi_print_dmalloc_usage_by_caller ();
+#endif
+ exit (0);
+ }
+#endif
+ if (shutdown_state == shutdown_dhcp &&
+ !failover_connection_count) {
+ shutdown_state = shutdown_done;
+ shutdown_time = cur_time;
+ goto oncemore;
+ }
+ add_timeout (cur_time + 1,
+ (void (*)(void *))dhcp_io_shutdown_countdown, 0, 0, 0);
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
+ control_object_state_t newstate)
+{
+ if (newstate == server_shutdown) {
+ shutdown_time = cur_time;
+ shutdown_state = shutdown_listeners;
+ dhcp_io_shutdown_countdown (0);
+ return ISC_R_SUCCESS;
+ }
+ return ISC_R_INVALIDARG;
+}
diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5
index b0b3dfe8..ebb57cfe 100644
--- a/server/dhcpd.conf.5
+++ b/server/dhcpd.conf.5
@@ -707,20 +707,8 @@ total number of clients within a particular class or subclass that may
hold leases at one time, and it is possible to specify automatic
subclassing based on the contents of the client packet.
.PP
-To add clients to classes based on conditional evaluation, you would
-write a conditional statement to match the clients you wanted in the
-class, and then put an
-.B add
-statement in the conditional's list of statements:
-.PP
-.nf
-if substring (option dhcp-client-identifier, 1, 3) = "RAS " {
- add "ras-clients";
-}
-.fi
-.PP
-A nearly equivalent way to do this is to simply specify the conditional
-expression as a matching expression in the class statement:
+To add clients to classes based on conditional evaluation, you can
+specify a matching expression in the class statement:
.PP
.nf
class "ras-clients" {
@@ -736,16 +724,6 @@ this:
class "ras-clients" {
}
.fi
-.PP
-Also, the
-.B add
-statement adds the client to the class as the client's scopes are being
-evaluated - after any address assignment decision has been made. This means
-that a client that's a member of a class due to an add statement will not
-be affected by pool permits related to that class - when the pool permit list
-is computed, the client will not yet be a member of the pool. This is an
-inconsistency that will probably be addressed in later versions of the DHCP
-server, but it is important to be aware of it at least for the time being.
.SH SUBCLASSES
.PP
In addition to classes, it is possible to declare subclasses. A
@@ -1150,14 +1128,24 @@ Note that the zone declarations have to correspond to authority
records in your name server - in the above example, there must be an
SOA record for "example.org." and for "17.10.10.in-addr.arpa.". For
example, if there were a subdoman "foo.example.org" with no seperate
-SOA, you could not write a zone declaration for "foo.example.org."
+SOA, you could not write a zone declaration for "foo.example.org."
+Also keep in mind that zone names in your DHCP configuration should end in a
+"."; this is the preferred syntax. If you do not end your zone name in a
+".", the DHCP server will figure it out. Also note that in the DHCP
+configuration, zone names are not encapsulated in quotes where there are in
+the DNS configuration.
.PP
You should choose your own secret key, of course. The ISC BIND 8 and
9 distributions come with a program for generating secret keys called
-dnskeygen. The version that comes with BIND 9 is likely to produce a
+dnssec-keygen. The version that comes with BIND 9 is likely to produce a
substantially more random key, so we recommend you use that one even
-if you are not using BIND 9 as your DNS server. The key above was
-generated with the command:
+if you are not using BIND 9 as your DNS server. If you are using BIND 9's
+dnssec-keygen, the above key would be created as follows:
+.nf
+ dnssec-keygen -a HMAC-MD5 -b 128 -n USER DHCP_UPDATER
+
+If you are using the BIND 8 dnskeygen program, the following command will
+generate a key as seen above:
.nf
dnskeygen -H 128 -u -c -n DHCP_UPDATER
.fi
diff --git a/server/failover.c b/server/failover.c
index 52683af5..ae7d9a79 100644
--- a/server/failover.c
+++ b/server/failover.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: failover.c,v 1.54 2001/05/17 19:04:07 mellon Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: failover.c,v 1.55 2001/06/27 00:31:12 mellon Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -52,7 +52,7 @@ static char copyright[] =
#if defined (FAILOVER_PROTOCOL)
static struct hash_table *failover_hash;
-static dhcp_failover_state_t *failover_states;
+dhcp_failover_state_t *failover_states;
static isc_result_t do_a_failover_option (omapi_object_t *,
dhcp_failover_link_t *);
dhcp_failover_listener_t *failover_listeners;
@@ -98,13 +98,15 @@ void dhcp_failover_startup ()
}
}
-void dhcp_failover_write_all_states ()
+int dhcp_failover_write_all_states ()
{
dhcp_failover_state_t *state;
for (state = failover_states; state; state = state -> next) {
- write_failover_state (state);
+ if (!write_failover_state (state))
+ return 0;
}
+ return 1;
}
isc_result_t enter_failover_peer (peer)
@@ -469,6 +471,15 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h,
return ISC_R_SUCCESS;
}
+ if ((cur_time > link -> imsg -> time &&
+ cur_time - link -> imsg -> time > 60) ||
+ (cur_time < link -> imsg -> time &&
+ link -> imsg -> time - cur_time > 60)) {
+ errmsg = "time offset too large";
+ reason = FTR_TIMEMISMATCH;
+ goto badconnect;
+ }
+
if (!(link -> imsg -> options_present & FTB_HBA) ||
link -> imsg -> hba.count != 32) {
errmsg = "invalid HBA";
@@ -797,11 +808,14 @@ isc_result_t dhcp_failover_link_destroy (omapi_object_t *h,
if (h -> type != dhcp_type_failover_link)
return ISC_R_INVALIDARG;
link = (dhcp_failover_link_t *)h;
- if (link -> imsg) {
- failover_message_dereference (&link -> imsg, MDL);
- }
+
+ if (link -> peer_address)
+ option_cache_dereference (&link -> peer_address, file, line);
+ if (link -> imsg)
+ failover_message_dereference (&link -> imsg, file, line);
if (link -> state_object)
- dhcp_failover_state_dereference (&link -> state_object, MDL);
+ dhcp_failover_state_dereference (&link -> state_object,
+ file, line);
return ISC_R_SUCCESS;
}
@@ -973,8 +987,10 @@ isc_result_t dhcp_failover_listener_signal (omapi_object_t *o,
for (s = failover_states; s; s = s -> next) {
if (dhcp_failover_state_match
(s, (u_int8_t *)&c -> remote_addr.sin_addr,
- sizeof c -> remote_addr.sin_addr))
+ sizeof c -> remote_addr.sin_addr)) {
state = s;
+ break;
+ }
}
if (!state) {
log_info ("failover: listener: no matching state");
@@ -1043,8 +1059,14 @@ isc_result_t dhcp_failover_listener_get_value (omapi_object_t *h,
isc_result_t dhcp_failover_listener_destroy (omapi_object_t *h,
const char *file, int line)
{
+ dhcp_failover_listener_t *l;
+
if (h -> type != dhcp_type_failover_listener)
return ISC_R_INVALIDARG;
+ l = (dhcp_failover_listener_t *)h;
+ if (l -> next)
+ dhcp_failover_listener_dereference (&l -> next, file, line);
+
return ISC_R_SUCCESS;
}
@@ -1251,6 +1273,15 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o,
goto badconnectack;
}
+ if ((cur_time > link -> imsg -> time &&
+ cur_time - link -> imsg -> time > 60) ||
+ (cur_time < link -> imsg -> time &&
+ link -> imsg -> time - cur_time > 60)) {
+ errmsg = "time offset too large";
+ reason = FTR_TIMEMISMATCH;
+ goto badconnectack;
+ }
+
dhcp_failover_link_reference (&state -> link_to_peer,
link, MDL);
#if 0
@@ -1344,6 +1375,8 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o,
isc_result_t dhcp_failover_state_transition (dhcp_failover_state_t *state,
const char *name)
{
+ isc_result_t status;
+
/* XXX Check these state transitions against the spec! */
if (!strcmp (name, "disconnect")) {
if (state -> link_to_peer) {
@@ -1387,7 +1420,9 @@ isc_result_t dhcp_failover_state_transition (dhcp_failover_state_t *state,
} else if (!strcmp (name, "connect")) {
switch (state -> me.state) {
case communications_interrupted:
- return dhcp_failover_set_state (state, normal);
+ status = dhcp_failover_set_state (state, normal);
+ dhcp_failover_send_updates (state);
+ return status;
case resolution_interrupted:
return dhcp_failover_set_state (state,
@@ -1584,17 +1619,31 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state,
/* Tentatively make the transition. */
saved_state = state -> me.state;
saved_stos = state -> me.stos;
- /* Keep the old stos if we're going into recover_wait. */
- if (new_state != recover_wait)
+
+ /* Keep the old stos if we're going into recover_wait or if we're
+ coming into or out of startup. */
+ if (new_state != recover_wait && new_state != startup &&
+ saved_state != startup)
state -> me.stos = cur_time;
+
+ /* If we're in shutdown, peer is in partner_down, and we're moving
+ to recover, we can skip waiting for MCLT to expire. This happens
+ when a server is moved administratively into shutdown prior to
+ actually shutting down. Of course, if there are any updates
+ pending we can't actually do this. */
+ if (new_state == recover && saved_state == shut_down &&
+ state -> partner.state == partner_down &&
+ !state -> update_queue_head && !state -> ack_queue_head)
+ state -> me.stos = cur_time - state -> mclt;
+
state -> me.state = new_state;
+ if (new_state == startup && saved_state != startup)
+ state -> saved_state = saved_state;
+ /* If we can't record the new state, we can't make a state transition. */
if (!write_failover_state (state) || !commit_leases ()) {
- /* XXX What to do? What to do? */
log_error ("Unable to record current failover state for %s",
state -> name);
- /* XXX for now, we don't make the state transition, but this is
- XXX kind of a scary choice. */
state -> me.state = saved_state;
state -> me.stos = saved_stos;
return ISC_R_IOERROR;
@@ -1627,8 +1676,6 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state,
break;
case startup:
- if (saved_state != startup)
- state -> saved_state = saved_state;
add_timeout (cur_time + 15,
dhcp_failover_startup_timeout,
state,
@@ -1647,6 +1694,8 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state,
(tvref_t)omapi_object_reference,
(tvunref_t)
omapi_object_dereference);
+ else
+ dhcp_failover_recover_done (state);
break;
case recover:
@@ -1688,6 +1737,7 @@ isc_result_t dhcp_failover_peer_state_changed (dhcp_failover_state_t *state,
enum failover_state previous_state = state -> partner.state;
enum failover_state new_state;
int startupp;
+ isc_result_t status;
new_state = msg -> server_state;
startupp = (msg -> server_flags & FTF_STARTUP) ? 1 : 0;
@@ -1925,6 +1975,7 @@ isc_result_t dhcp_failover_peer_state_changed (dhcp_failover_state_t *state,
case recover_wait:
/* XXX so we don't need to do this specially in
XXX the CONNECT and CONNECTACK handlers. */
+ dhcp_failover_send_updates (state);
dhcp_failover_set_state (state, normal);
break;
@@ -2063,6 +2114,10 @@ int dhcp_failover_pool_rebalance (dhcp_failover_state_t *state)
lq = &p -> backup;
}
+ log_info ("pool %lx total %d free %d backup %d lts %d",
+ (unsigned long)p, p -> lease_count,
+ p -> free_leases, p -> backup_leases, lts);
+
if (lts > 1) {
lease_reference (&lp, *lq, MDL);
@@ -2244,7 +2299,7 @@ int dhcp_failover_queue_update (struct lease *lease, int immediate)
if (lease -> next_pending) {
log_error ("next pending on update queue lease.");
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (lease);
#endif
abort ();
}
@@ -2619,15 +2674,37 @@ isc_result_t dhcp_failover_state_destroy (omapi_object_t *h,
if (h -> type != dhcp_type_failover_state)
return ISC_R_INVALIDARG;
s = (dhcp_failover_state_t *)h;
+
if (s -> link_to_peer)
- dhcp_failover_link_dereference (&s -> link_to_peer, MDL);
- if (s -> name)
+ dhcp_failover_link_dereference (&s -> link_to_peer, file, line);
+ if (s -> name) {
dfree (s -> name, MDL);
+ s -> name = (char *)0;
+ }
if (s -> partner.address)
- option_cache_dereference (&s -> partner.address, MDL);
+ option_cache_dereference (&s -> partner.address, file, line);
if (s -> me.address)
- option_cache_dereference (&s -> me.address, MDL);
-
+ option_cache_dereference (&s -> me.address, file, line);
+ if (s -> hba) {
+ dfree (s -> hba, file, line);
+ s -> hba = (u_int8_t *)0;
+ }
+ if (s -> update_queue_head)
+ lease_dereference (&s -> update_queue_head, file, line);
+ if (s -> update_queue_tail)
+ lease_dereference (&s -> update_queue_tail, file, line);
+ if (s -> ack_queue_head)
+ lease_dereference (&s -> ack_queue_head, file, line);
+ if (s -> ack_queue_tail)
+ lease_dereference (&s -> ack_queue_tail, file, line);
+ if (s -> send_update_done)
+ lease_dereference (&s -> send_update_done, file, line);
+ if (s -> toack_queue_head)
+ failover_message_dereference (&s -> toack_queue_head,
+ file, line);
+ if (s -> toack_queue_tail)
+ failover_message_dereference (&s -> toack_queue_tail,
+ file, line);
return ISC_R_SUCCESS;
}
@@ -2863,6 +2940,9 @@ isc_result_t dhcp_failover_state_lookup (omapi_object_t **sp,
isc_result_t status;
dhcp_failover_state_t *s;
+ if (!ref)
+ return ISC_R_NOKEYS;
+
/* First see if we were sent a handle. */
status = omapi_get_value_str (ref, id, "handle", &tv);
if (status == ISC_R_SUCCESS) {
@@ -4245,6 +4325,13 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state,
}
if (msg -> options_present & FTB_BINDING_STATUS) {
+#if defined (DEBUG_LEASE_STATE_TRANSITIONS)
+ log_info ("processing state transition for %s: %s to %s",
+ piaddr (lease -> ip_addr),
+ binding_state_print (lease -> binding_state),
+ binding_state_print (msg -> binding_status));
+#endif
+
/* If we're in normal state, make sure the state transition
we got is valid. */
if (state -> me.state == normal) {
@@ -4252,6 +4339,9 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state,
(normal_binding_state_transition_check
(lease, state, msg -> binding_status,
msg -> potential_expiry));
+ /* XXX if the transition the peer asked for isn't
+ XXX allowed, maybe we should make the transition
+ XXX into potential-conflict at this point. */
} else {
new_binding_state =
(conflict_binding_state_transition_check
@@ -4278,7 +4368,13 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state,
outbuf);
goto out;
}
- lt -> next_binding_state = new_binding_state;
+ if (new_binding_state == FTS_EXPIRED ||
+ new_binding_state == FTS_RELEASED ||
+ new_binding_state == FTS_RESET)
+ lt -> next_binding_state = FTS_FREE;
+ else
+ lt -> next_binding_state = new_binding_state;
+ msg -> binding_status = lt -> next_binding_state;
}
/* Try to install the new information. */
@@ -4287,8 +4383,10 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state,
message = "database update failed";
bad:
dhcp_failover_send_bind_ack (state, msg, reason, message);
- } else
+ } else {
+
dhcp_failover_queue_ack (state, msg);
+ }
out:
if (lt)
@@ -4334,18 +4432,24 @@ isc_result_t dhcp_failover_process_bind_ack (dhcp_failover_state_t *state,
if (msg -> options_present & FTB_POTENTIAL_EXPIRY) {
/* XXX it could be a problem to do this directly if the
XXX lease is sorted by tsfp. */
- if (lease -> binding_state == FTS_EXPIRED) {
+ if ((lease -> binding_state == FTS_EXPIRED ||
+ lease -> binding_state == FTS_RESET ||
+ lease -> binding_state == FTS_RELEASED) &&
+ (msg -> options_present & FTB_BINDING_STATUS) &&
+ msg -> binding_status == FTS_FREE)
+ {
+ lease -> tsfp = msg -> potential_expiry;
lease -> next_binding_state = FTS_FREE;
- supersede_lease (lease, (struct lease *)0, 0, 1, 0);
- write_lease (lease);
- if (state -> me.state == normal)
- commit_leases ();
+ supersede_lease (lease, (struct lease *)0, 0, 0, 0);
+ write_lease (lease);
+ if (state -> me.state == normal)
+ commit_leases ();
} else {
- lease -> tsfp = msg -> potential_expiry;
- write_lease (lease);
+ lease -> tsfp = msg -> potential_expiry;
+ write_lease (lease);
#if 0 /* XXX This might be needed. */
- if (state -> me.state == normal)
- commit_leases ();
+ if (state -> me.state == normal)
+ commit_leases ();
#endif
}
}
@@ -4692,13 +4796,22 @@ normal_binding_state_transition_check (struct lease *lease,
if (state -> i_am == secondary)
return binding_state;
- /* Otherwise, it can't do any sort of state
- transition. */
+ /* Otherwise, it can't legitimately do any sort of
+ state transition. Because the lease was free,
+ and the error has already been made, we allow the
+ peer to change its state anyway, but log a warning
+ message in hopes that the error will be fixed. */
case FTS_FREE: /* for compiler */
case FTS_EXPIRED:
case FTS_RELEASED:
case FTS_RESET:
- new_state = FTS_FREE;
+ log_error ("allowing %s%s: %s to %s",
+ "invalid peer state transition on ",
+ piaddr (lease -> ip_addr),
+ (binding_state_print
+ (lease -> binding_state)),
+ binding_state_print (binding_state));
+ new_state = binding_state;
goto out;
}
case FTS_ACTIVE:
@@ -4738,10 +4851,11 @@ normal_binding_state_transition_check (struct lease *lease,
return binding_state;
}
+ break;
case FTS_EXPIRED:
switch (binding_state) {
- case FTS_FREE:
case FTS_BACKUP:
+ case FTS_FREE:
/* Can't set a lease to free or backup until the
peer agrees that it's expired. */
if (tsfp > cur_time) {
@@ -4815,11 +4929,19 @@ normal_binding_state_transition_check (struct lease *lease,
return binding_state;
/* Otherwise, it can't do any sort of state
- transition. */
+ transition, but because the lease was free
+ we allow it to do the transition, and just
+ log the error. */
case FTS_EXPIRED:
case FTS_RELEASED:
case FTS_RESET:
- new_state = lease -> binding_state;
+ log_error ("allowing %s%s: %s to %s",
+ "invalid peer state transition on ",
+ piaddr (lease -> ip_addr),
+ (binding_state_print
+ (lease -> binding_state)),
+ binding_state_print (binding_state));
+ new_state = binding_state;
goto out;
case FTS_BACKUP:
@@ -4973,9 +5095,32 @@ static isc_result_t failover_message_reference (failover_message_t **mp,
static isc_result_t failover_message_dereference (failover_message_t **mp,
const char *file, int line)
{
- (*mp) -> refcnt--;
- if ((*mp) -> refcnt == 0) {
- dfree (*mp, MDL);
+ failover_message_t *m;
+ m = (*mp);
+ m -> refcnt--;
+ if (m -> refcnt == 0) {
+ if (m -> next)
+ failover_message_dereference (&m -> next,
+ file, line);
+ if (m -> chaddr.data)
+ dfree (m -> chaddr.data, file, line);
+ if (m -> client_identifier.data)
+ dfree (m -> client_identifier.data, file, line);
+ if (m -> hba.data)
+ dfree (m -> hba.data, file, line);
+ if (m -> message.data)
+ dfree (m -> message.data, file, line);
+ if (m -> reply_options.data)
+ dfree (m -> reply_options.data, file, line);
+ if (m -> request_options.data)
+ dfree (m -> request_options.data, file, line);
+ if (m -> vendor_class.data)
+ dfree (m -> vendor_class.data, file, line);
+ if (m -> vendor_options.data)
+ dfree (m -> vendor_options.data, file, line);
+ if (m -> ddns.data)
+ dfree (m -> ddns.data, file, line);
+ dfree (*mp, file, line);
}
*mp = 0;
return ISC_R_SUCCESS;
diff --git a/server/mdb.c b/server/mdb.c
index a0e91924..b690645f 100644
--- a/server/mdb.c
+++ b/server/mdb.c
@@ -3,7 +3,7 @@
Server-specific in-memory database support. */
/*
- * Copyright (c) 1996-2000 Internet Software Consortium.
+ * Copyright (c) 1996-2001 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: mdb.c,v 1.69 2001/06/22 16:47:17 brister Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: mdb.c,v 1.70 2001/06/27 00:31:13 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -96,6 +96,31 @@ isc_result_t enter_class(cd, dynamicp, commit)
}
+static int find_uid_statement (struct executable_statement *esp,
+ void *vp, int condp)
+{
+ struct executable_statement **evp = vp;
+
+ 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)) {
+ if (condp) {
+ log_error ("dhcp client identifier may not be %s",
+ "specified conditionally.");
+ } else if (!(*evp)) {
+ executable_statement_reference (evp, esp, MDL);
+ return 1;
+ } else {
+ log_error ("only one dhcp client identifier may be %s",
+ "specified");
+ }
+ }
+ return 0;
+}
+
isc_result_t enter_host (hd, dynamicp, commit)
struct host_decl *hd;
int dynamicp;
@@ -108,7 +133,7 @@ isc_result_t enter_host (hd, dynamicp, commit)
if (!host_name_hash) {
host_name_hash =
new_hash ((hash_reference)host_reference,
- (hash_dereference)host_dereference, 0);
+ (hash_dereference)host_dereference, 0, MDL);
if (!host_name_hash)
log_fatal ("Can't allocate host name hash");
host_hash_add (host_name_hash,
@@ -130,6 +155,16 @@ isc_result_t enter_host (hd, dynamicp, commit)
hd -> flags |= HOST_DECL_STATIC;
}
+ /* If we are updating an existing host declaration, we
+ can just delete it and add it again. */
+ if (hp && hp == hd) {
+ host_dereference (&hp, MDL);
+ delete_host (hd, 0);
+ if (!write_host (hd))
+ return ISC_R_IOERROR;
+ hd -> flags &= ~HOST_DECL_DELETED;
+ }
+
/* If there isn't already a host decl matching this
address, add it to the hash table. */
if (!hp) {
@@ -155,7 +190,7 @@ isc_result_t enter_host (hd, dynamicp, commit)
host_hw_addr_hash =
new_hash ((hash_reference)host_reference,
(hash_dereference)host_dereference,
- 0);
+ 0, MDL);
if (!host_hw_addr_hash)
log_fatal ("Can't allocate host/hw hash");
} else {
@@ -182,21 +217,16 @@ isc_result_t enter_host (hd, dynamicp, commit)
/* 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)) {
- evaluate_option_cache
- (&hd -> client_identifier, (struct packet *)0,
- (struct lease *)0, (struct client_state *)0,
- (struct option_state *)0,
- (struct option_state *)0, &global_scope,
- esp -> data.option, MDL);
- break;
- }
+ esp = (struct executable_statement *)0;
+ if (executable_statement_foreach (hd -> group -> statements,
+ find_uid_statement, &esp, 0)) {
+ evaluate_option_cache (&hd -> client_identifier,
+ (struct packet *)0,
+ (struct lease *)0,
+ (struct client_state *)0,
+ (struct option_state *)0,
+ (struct option_state *)0, &global_scope,
+ esp -> data.option, MDL);
}
/* If we got a client identifier, hash this entry by
@@ -208,7 +238,7 @@ isc_result_t enter_host (hd, dynamicp, commit)
host_uid_hash =
new_hash ((hash_reference)host_reference,
(hash_dereference)host_dereference,
- 0);
+ 0, MDL);
if (!host_uid_hash)
log_fatal ("Can't allocate host/uid hash");
@@ -299,8 +329,8 @@ isc_result_t delete_host (hd, commit)
if (hd -> interface.hlen) {
if (host_hw_addr_hash) {
if (host_hash_lookup (&hp, host_hw_addr_hash,
- hd -> interface.hbuf,
- hd -> interface.hlen, MDL)) {
+ hd -> interface.hbuf,
+ hd -> interface.hlen, MDL)) {
if (hp == hd) {
host_hash_delete (host_hw_addr_hash,
hd -> interface.hbuf,
@@ -514,21 +544,21 @@ void new_address_range (low, high, subnet, pool)
if (!lease_uid_hash) {
lease_uid_hash =
new_hash ((hash_reference)lease_reference,
- (hash_dereference)lease_dereference, 0);
+ (hash_dereference)lease_dereference, 0, MDL);
if (!lease_uid_hash)
log_fatal ("Can't allocate lease/uid hash");
}
if (!lease_ip_addr_hash) {
lease_ip_addr_hash =
new_hash ((hash_reference)lease_reference,
- (hash_dereference)lease_dereference, 0);
+ (hash_dereference)lease_dereference, 0, MDL);
if (!lease_uid_hash)
log_fatal ("Can't allocate lease/ip hash");
}
if (!lease_hw_addr_hash) {
lease_hw_addr_hash =
new_hash ((hash_reference)lease_reference,
- (hash_dereference)lease_dereference, 0);
+ (hash_dereference)lease_dereference, 0, MDL);
if (!lease_uid_hash)
log_fatal ("Can't allocate lease/hw hash");
}
@@ -616,41 +646,6 @@ void new_address_range (low, high, subnet, pool)
}
}
-
-#if defined (COMPACT_LEASES)
-struct lease *free_leases;
-
-/* If we are allocating leases in aggregations, there's really no way
- to free one, although perhaps we can maintain a free list. */
-
-isc_result_t dhcp_lease_free (omapi_object_t *lo,
- const char *file, int line)
-{
- struct lease *lease;
- if (lo -> type != dhcp_type_lease)
- return ISC_R_INVALIDARG;
- lease = (struct lease *)lo;
- lease -> next = free_leases;
- free_leases = lease;
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_lease_get (omapi_object_t **lp,
- const char *file, int line)
-{
- struct lease **lease = (struct lease **)lp;
- struct lease *lt;
-
- if (free_leases) {
- lt = free_leases;
- free_leases = lt -> next;
- *lease = lt;
- return ISC_R_SUCCESS;
- }
- return ISC_R_NOMEMORY;
-}
-#endif
-
int find_subnet (struct subnet **sp,
struct iaddr addr, const char *file, int line)
{
@@ -717,28 +712,46 @@ int subnet_inner_than (subnet, scan, warnp)
void enter_subnet (subnet)
struct subnet *subnet;
{
- struct subnet *scan, *prev = (struct subnet *)0;
+ struct subnet *scan = (struct subnet *)0;
+ struct subnet *next = (struct subnet *)0;
+ struct subnet *prev = (struct subnet *)0;
/* Check for duplicates... */
- for (scan = subnets; scan; scan = scan -> next_subnet) {
- /* 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) {
- subnet_reference (&prev -> next_subnet,
- subnet, MDL);
- } else
- subnet_reference (&subnets, subnet, MDL);
- subnet_reference (&subnet -> next_subnet, scan, MDL);
- return;
+ if (subnets)
+ subnet_reference (&next, subnets, MDL);
+ while (next) {
+ subnet_reference (&scan, next, MDL);
+ subnet_dereference (&next, MDL);
+
+ /* 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) {
+ if (prev -> next_subnet)
+ subnet_dereference (&prev -> next_subnet, MDL);
+ subnet_reference (&prev -> next_subnet, subnet, MDL);
+ subnet_dereference (&prev, MDL);
+ } else {
+ subnet_dereference (&subnets, MDL);
+ subnet_reference (&subnets, subnet, MDL);
}
- prev = scan;
+ subnet_reference (&subnet -> next_subnet, scan, MDL);
+ subnet_dereference (&scan, MDL);
+ return;
+ }
+ subnet_reference (&prev, scan, MDL);
+ subnet_dereference (&scan, MDL);
}
+ if (prev)
+ subnet_dereference (&prev, MDL);
/* XXX use the BSD radix tree code instead of a linked list. */
- subnet -> next_subnet = subnets;
- subnets = subnet;
+ if (subnets) {
+ subnet_reference (&subnet -> next_subnet, subnets, MDL);
+ subnet_dereference (&subnets, MDL);
+ }
+ subnet_reference (&subnets, subnet, MDL);
}
/* Enter a new shared network into the shared network list. */
@@ -1765,7 +1778,7 @@ void hw_hash_delete (lease)
/* Write all interesting leases to permanent storage. */
-void write_leases ()
+int write_leases ()
{
struct lease *l;
struct shared_network *s;
@@ -1805,7 +1818,8 @@ void write_leases ()
if ((gp -> flags & GROUP_OBJECT_DYNAMIC) ||
((gp -> flags & GROUP_OBJECT_STATIC) &&
(gp -> flags & GROUP_OBJECT_DELETED))) {
- write_group (gp);
+ if (!write_group (gp))
+ return 0;
++num_written;
}
}
@@ -1822,7 +1836,8 @@ void write_leases ()
hp = (struct host_decl *)hb -> value;
if (((hp -> flags & HOST_DECL_STATIC) &&
(hp -> flags & HOST_DECL_DELETED))) {
- write_host (hp);
+ if (!write_host (hp))
+ return 0;
++num_written;
}
}
@@ -1839,8 +1854,8 @@ void write_leases ()
hb; hb = hb -> next) {
hp = (struct host_decl *)hb -> value;
if ((hp -> flags & HOST_DECL_DYNAMIC)) {
- write_host (hp);
- ++num_written;
+ if (!write_host (hp))
+ ++num_written;
}
}
}
@@ -1850,7 +1865,8 @@ void write_leases ()
#if defined (FAILOVER_PROTOCOL)
/* Write all the failover states. */
- dhcp_failover_write_all_states ();
+ if (!dhcp_failover_write_all_states ())
+ return 0;
#endif
/* Write all the leases. */
@@ -1869,7 +1885,7 @@ void write_leases ()
l -> uid_len ||
(l -> binding_state != FTS_FREE)) {
if (!write_lease (l))
- log_fatal ("Can't rewrite lease database");
+ return 0;
num_written++;
}
}
@@ -1878,7 +1894,8 @@ void write_leases ()
}
log_info ("Wrote %d leases to leases file.", num_written);
if (!commit_leases ())
- log_fatal ("Can't commit leases to new database: %m");
+ return 0;
+ return 1;
}
int lease_enqueue (struct lease *comp)
@@ -2097,3 +2114,269 @@ void dump_subnets ()
HASH_FUNCTIONS (lease, const unsigned char *, struct lease)
HASH_FUNCTIONS (host, const unsigned char *, struct host_decl)
HASH_FUNCTIONS (class, const char *, struct class)
+
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+extern struct hash_table *dns_zone_hash;
+extern struct interface_info **interface_vector;
+extern int interface_count;
+dhcp_control_object_t *dhcp_control_object;
+extern struct hash_table *auth_key_hash;
+struct hash_table *universe_hash;
+struct universe **universes;
+int universe_count, universe_max;
+extern int end;
+
+#if defined (COMPACT_LEASES)
+extern struct lease *lease_hunks;
+#endif
+
+void free_everything ()
+{
+ struct subnet *sc = (struct subnet *)0, *sn = (struct subnet *)0;
+ struct shared_network *nc = (struct shared_network *)0,
+ *nn = (struct shared_network *)0;
+ struct pool *pc = (struct pool *)0, *pn = (struct pool *)0;
+ struct lease *lc = (struct lease *)0, *ln = (struct lease *)0;
+ struct interface_info *ic = (struct interface_info *)0,
+ *in = (struct interface_info *)0;
+ struct class *cc = (struct class *)0, *cn = (struct class *)0;
+ struct collection *lp;
+ void *st = (shared_networks
+ ? (shared_networks -> next
+ ? shared_networks -> next -> next : 0) : 0);
+ int i;
+
+
+ /* Get rid of all the hash tables. */
+ if (host_hw_addr_hash)
+ free_hash_table (host_hw_addr_hash, MDL);
+ host_hw_addr_hash = 0;
+ if (host_uid_hash)
+ free_hash_table (host_uid_hash, MDL);
+ host_uid_hash = 0;
+ if (lease_uid_hash)
+ free_hash_table (lease_uid_hash, MDL);
+ lease_uid_hash = 0;
+ if (lease_ip_addr_hash)
+ free_hash_table (lease_ip_addr_hash, MDL);
+ lease_ip_addr_hash = 0;
+ if (lease_hw_addr_hash)
+ free_hash_table (lease_hw_addr_hash, MDL);
+ lease_hw_addr_hash = 0;
+ if (host_name_hash)
+ free_hash_table (host_name_hash, MDL);
+ host_name_hash = 0;
+ if (dns_zone_hash)
+ free_hash_table (dns_zone_hash, MDL);
+ dns_zone_hash = 0;
+ if (auth_key_hash)
+ free_hash_table (auth_key_hash, MDL);
+ auth_key_hash = 0;
+
+ omapi_object_dereference ((omapi_object_t **)&dhcp_control_object,
+ MDL);
+
+ for (lp = collections; lp; lp = lp -> next) {
+ if (lp -> classes) {
+ class_reference (&cn, lp -> classes, MDL);
+ do {
+ if (cn) {
+ class_reference (&cc, cn, MDL);
+ class_dereference (&cn, MDL);
+ }
+ if (cc -> nic) {
+ class_reference (&cn, cc -> nic, MDL);
+ class_dereference (&cc -> nic, MDL);
+ }
+ group_dereference (&cc -> group, MDL);
+ if (cc -> hash) {
+ free_hash_table (cc -> hash, MDL);
+ cc -> hash = (struct hash_table *)0;
+ }
+ class_dereference (&cc, MDL);
+ } while (cn);
+ class_dereference (&lp -> classes, MDL);
+ }
+ }
+
+ if (interface_vector) {
+ for (i = 0; i < interface_count; i++) {
+ if (interface_vector [i])
+ interface_dereference (&interface_vector [i], MDL);
+ }
+ dfree (interface_vector, MDL);
+ interface_vector = 0;
+ }
+
+ if (interfaces) {
+ interface_reference (&in, interfaces, MDL);
+ do {
+ if (in) {
+ interface_reference (&ic, in, MDL);
+ interface_dereference (&in, MDL);
+ }
+ if (ic -> next) {
+ interface_reference (&in, ic -> next, MDL);
+ interface_dereference (&ic -> next, MDL);
+ }
+ omapi_unregister_io_object ((omapi_object_t *)ic);
+ if (ic -> shared_network) {
+ if (ic -> shared_network -> interface)
+ interface_dereference
+ (&ic -> shared_network -> interface, MDL);
+ shared_network_dereference (&ic -> shared_network, MDL);
+ }
+ interface_dereference (&ic, MDL);
+ } while (in);
+ interface_dereference (&interfaces, MDL);
+ }
+
+ /* Subnets are complicated because of the extra links. */
+ if (subnets) {
+ subnet_reference (&sn, subnets, MDL);
+ do {
+ if (sn) {
+ subnet_reference (&sc, sn, MDL);
+ subnet_dereference (&sn, MDL);
+ }
+ if (sc -> next_subnet) {
+ subnet_reference (&sn, sc -> next_subnet, MDL);
+ subnet_dereference (&sc -> next_subnet, MDL);
+ }
+ if (sc -> next_sibling)
+ subnet_dereference (&sc -> next_sibling, MDL);
+ if (sc -> shared_network)
+ shared_network_dereference (&sc -> shared_network, MDL);
+ group_dereference (&sc -> group, MDL);
+ if (sc -> interface)
+ interface_dereference (&sc -> interface, MDL);
+ subnet_dereference (&sc, MDL);
+ } while (sn);
+ subnet_dereference (&subnets, MDL);
+ }
+
+ /* So are shared networks. */
+ if (shared_networks) {
+ shared_network_reference (&nn, shared_networks, MDL);
+ do {
+ if (nn) {
+ shared_network_reference (&nc, nn, MDL);
+ shared_network_dereference (&nn, MDL);
+ }
+ if (nc -> next) {
+ shared_network_reference (&nn, nc -> next, MDL);
+ shared_network_dereference (&nc -> next, MDL);
+ }
+
+ /* As are pools. */
+ if (nc -> pools) {
+ pool_reference (&pn, nc -> pools, MDL);
+ do {
+ struct lease **lptr [5];
+
+ if (pn) {
+ pool_reference (&pc, pn, MDL);
+ pool_dereference (&pn, MDL);
+ }
+ if (pc -> next) {
+ pool_reference (&pn, pc -> next, MDL);
+ pool_dereference (&pc -> next, MDL);
+ }
+
+ lptr [FREE_LEASES] = &pc -> free;
+ lptr [ACTIVE_LEASES] = &pc -> active;
+ lptr [EXPIRED_LEASES] = &pc -> expired;
+ lptr [ABANDONED_LEASES] = &pc -> abandoned;
+ lptr [BACKUP_LEASES] = &pc -> backup;
+
+ /* As (sigh) are leases. */
+ for (i = 0; i < 5; i++) {
+ if (*lptr [i]) {
+ lease_reference (&ln, *lptr [i], MDL);
+ do {
+ if (ln) {
+ lease_reference (&lc, ln, MDL);
+ lease_dereference (&ln, MDL);
+ }
+ if (lc -> next) {
+ lease_reference (&ln, lc -> next, MDL);
+ lease_dereference (&lc -> next, MDL);
+ }
+ if (lc -> billing_class)
+ class_dereference (&lc -> billing_class,
+ MDL);
+ if (lc -> state)
+ free_lease_state (lc -> state, MDL);
+ lc -> state = (struct lease_state *)0;
+ if (lc -> n_hw)
+ lease_dereference (&lc -> n_hw, MDL);
+ if (lc -> n_uid)
+ lease_dereference (&lc -> n_uid, MDL);
+ lease_dereference (&lc, MDL);
+ } while (ln);
+ lease_dereference (lptr [i], MDL);
+ }
+ }
+ if (pc -> group)
+ group_dereference (&pc -> group, MDL);
+ if (pc -> shared_network)
+ shared_network_dereference (&pc -> shared_network,
+ MDL);
+ pool_dereference (&pc, MDL);
+ } while (pn);
+ pool_dereference (&nc -> pools, MDL);
+ }
+ /* Because of a circular reference, we need to nuke this
+ manually. */
+ group_dereference (&nc -> group, MDL);
+ shared_network_dereference (&nc, MDL);
+ } while (nn);
+ shared_network_dereference (&shared_networks, MDL);
+ }
+
+ cancel_all_timeouts ();
+ relinquish_timeouts ();
+ trace_free_all ();
+ group_dereference (&root_group, MDL);
+ executable_statement_dereference (&default_classification_rules, MDL);
+
+ shutdown_state = shutdown_drop_omapi_connections;
+ omapi_io_state_foreach (dhcp_io_shutdown, 0);
+ shutdown_state = shutdown_listeners;
+ omapi_io_state_foreach (dhcp_io_shutdown, 0);
+ shutdown_state = shutdown_dhcp;
+ omapi_io_state_foreach (dhcp_io_shutdown, 0);
+
+ omapi_object_dereference ((omapi_object_t **)&icmp_state, MDL);
+
+ free_hash_table (universe_hash, MDL);
+ for (i = 0; i < universe_count; i++) {
+ union {
+ const char *c;
+ char *s;
+ } foo;
+ if (universes [i]) {
+ if (universes [i] -> hash)
+ free_hash_table (universes [i] -> hash, MDL);
+ if (universes [i] -> name > (char *)&end) {
+ foo.c = universes [i] -> name;
+ dfree (foo.s, MDL);
+ }
+ if (universes [i] > (struct universe *)&end)
+ dfree (universes [i], MDL);
+ }
+ }
+ dfree (universes, MDL);
+
+ relinquish_free_lease_states ();
+ relinquish_free_pairs ();
+ relinquish_free_expressions ();
+ relinquish_free_binding_values ();
+ relinquish_free_option_caches ();
+ relinquish_free_packets ();
+ relinquish_lease_hunks ();
+ relinquish_hash_bucket_hunks ();
+ omapi_type_relinquish ();
+}
+#endif /* DEBUG_MEMORY_LEAKAGE */
diff --git a/server/omapi.c b/server/omapi.c
index 00ac7d71..bc2ea123 100644
--- a/server/omapi.c
+++ b/server/omapi.c
@@ -50,12 +50,16 @@
#ifndef lint
static char copyright[] =
-"$Id: omapi.c,v 1.48 2001/06/22 16:47:18 brister Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: omapi.c,v 1.49 2001/06/27 00:31:15 mellon Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <omapip/omapip_p.h>
+static isc_result_t class_lookup (omapi_object_t **,
+ omapi_object_t *, omapi_object_t *,
+ omapi_object_type_t *);
+
omapi_object_type_t *dhcp_type_lease;
omapi_object_type_t *dhcp_type_pool;
omapi_object_type_t *dhcp_type_class;
@@ -112,7 +116,7 @@ void dhcp_db_objects_setup ()
"subclass",
dhcp_subclass_set_value,
dhcp_subclass_get_value,
- dhcp_subclass_destroy,
+ dhcp_class_destroy,
dhcp_subclass_signal_handler,
dhcp_subclass_stuff_values,
dhcp_subclass_lookup,
@@ -221,44 +225,51 @@ isc_result_t dhcp_lease_set_value (omapi_object_t *h,
/* We're skipping a lot of things it might be interesting to
set - for now, we just make it possible to whack the state. */
if (!omapi_ds_strcmp (name, "state")) {
- unsigned long bar;
- status = omapi_get_int_value (&bar, value);
- if (status != ISC_R_SUCCESS)
- return status;
-
- if (bar < 1 || bar > FTS_BOOTP)
- return ISC_R_INVALIDARG;
- if (lease -> binding_state != bar) {
- lease -> next_binding_state = bar;
- if (supersede_lease (lease, 0, 1, 1, 1))
- return ISC_R_SUCCESS;
- return ISC_R_IOERROR;
- }
- return ISC_R_UNCHANGED;
+ unsigned long bar;
+ status = omapi_get_int_value (&bar, value);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ if (bar < 1 || bar > FTS_BOOTP)
+ return ISC_R_INVALIDARG;
+ if (lease -> binding_state != bar) {
+ lease -> next_binding_state = bar;
+ if (supersede_lease (lease, 0, 1, 1, 1))
+ return ISC_R_SUCCESS;
+ return ISC_R_IOERROR;
+ }
+ return ISC_R_UNCHANGED;
} else if (!omapi_ds_strcmp (name, "ip-address")) {
- return ISC_R_UNCHANGED; /* XXX return error if changed. */
+ return ISC_R_NOPERM;
} else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return ISC_R_UNCHANGED; /* XXX take change. */
} else if (!omapi_ds_strcmp (name, "hostname")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return ISC_R_UNCHANGED; /* XXX take change. */
} else if (!omapi_ds_strcmp (name, "client-hostname")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return ISC_R_UNCHANGED; /* XXX take change. */
} else if (!omapi_ds_strcmp (name, "host")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return ISC_R_UNCHANGED; /* XXX take change. */
} else if (!omapi_ds_strcmp (name, "subnet")) {
- return ISC_R_UNCHANGED; /* XXX return error if changed. */
+ return ISC_R_INVALIDARG;
} else if (!omapi_ds_strcmp (name, "pool")) {
- return ISC_R_UNCHANGED; /* XXX return error if changed. */
+ return ISC_R_NOPERM;
} else if (!omapi_ds_strcmp (name, "starts")) {
- return ISC_R_UNCHANGED; /* XXX return error if changed. */
+ return ISC_R_NOPERM;
} else if (!omapi_ds_strcmp (name, "ends")) {
- return ISC_R_UNCHANGED; /* XXX return error if changed. */
+ return ISC_R_NOPERM;
} else if (!omapi_ds_strcmp (name, "billing-class")) {
- return ISC_R_UNCHANGED; /* XXX carefully allow change. */
+ return ISC_R_UNCHANGED; /* XXX carefully allow change. */
} else if (!omapi_ds_strcmp (name, "hardware-address")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return ISC_R_UNCHANGED; /* XXX take change. */
} else if (!omapi_ds_strcmp (name, "hardware-type")) {
- return ISC_R_UNCHANGED; /* XXX take change. */
+ return ISC_R_UNCHANGED; /* XXX take change. */
+ } else if (lease -> scope) {
+ status = binding_scope_set_value (lease -> scope, 0, name, value);
+ if (status == ISC_R_SUCCESS) {
+ if (write_lease (lease) && commit_leases ())
+ return ISC_R_SUCCESS;
+ return ISC_R_IOERROR;
+ }
}
/* Try to find some inner object that can take the value. */
@@ -269,7 +280,17 @@ isc_result_t dhcp_lease_set_value (omapi_object_t *h,
return status;
}
- return ISC_R_NOTFOUND;
+ if (!lease -> scope) {
+ if (!binding_scope_allocate (&lease -> scope, MDL))
+ return ISC_R_NOMEMORY;
+ }
+ status = binding_scope_set_value (lease -> scope, 1, name, value);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ if (write_lease (lease) && commit_leases ())
+ return ISC_R_SUCCESS;
+ return ISC_R_IOERROR;
}
@@ -333,6 +354,10 @@ isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id,
(value, name, lease -> hardware_addr.hbuf [0],
MDL);
return ISC_R_NOTFOUND;
+ } else if (lease -> scope) {
+ status = binding_scope_get_value (value, lease -> scope, name);
+ if (status != ISC_R_NOTFOUND)
+ return status;
}
/* Try to find some inner object that can take the value. */
@@ -342,7 +367,7 @@ isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id,
if (status == ISC_R_SUCCESS)
return status;
}
- return ISC_R_NOTFOUND;
+ return ISC_R_UNKNOWNATTRIBUTE;
}
isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line)
@@ -403,6 +428,20 @@ isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line)
class_dereference
(&lease -> billing_class, file, line);
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ /* XXX we should never be destroying a lease with a next
+ XXX pointer except on exit... */
+ if (lease -> next)
+ lease_dereference (&lease -> next, file, line);
+ if (lease -> n_hw)
+ lease_dereference (&lease -> n_hw, file, line);
+ if (lease -> n_uid)
+ lease_dereference (&lease -> n_uid, file, line);
+ if (lease -> next_pending)
+ lease_dereference (&lease -> next_pending, file, line);
+#endif
+
return ISC_R_SUCCESS;
}
@@ -417,19 +456,8 @@ isc_result_t dhcp_lease_signal_handler (omapi_object_t *h,
return ISC_R_INVALIDARG;
lease = (struct lease *)h;
- if (!strcmp (name, "updated")) {
- if (lease -> hardware_addr.hlen == 0 ||
- lease -> hardware_addr.hlen > 17)
- return ISC_R_INVALIDARG;
- if (!write_lease (lease) || !commit_leases ()
-#if defined (FAILOVER_PROTOCOL)
- || !dhcp_failover_queue_update (lease, 1)
-#endif
- ) {
- return ISC_R_IOERROR;
- }
- updatep = 1;
- }
+ if (!strcmp (name, "updated"))
+ return ISC_R_SUCCESS;
/* Try to find some inner object that can take the value. */
if (h -> inner && h -> inner -> type -> signal_handler) {
@@ -438,8 +466,6 @@ isc_result_t dhcp_lease_signal_handler (omapi_object_t *h,
if (status == ISC_R_SUCCESS)
return status;
}
- if (updatep)
- return ISC_R_SUCCESS;
return ISC_R_NOTFOUND;
}
@@ -629,6 +655,12 @@ isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
if (status != ISC_R_SUCCESS)
return status;
+ if (lease -> scope) {
+ status = binding_scope_stuff_values (c, lease -> scope);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+
/* Write out the inner object, if any. */
if (h -> inner && h -> inner -> type -> stuff_values) {
status = ((*(h -> inner -> type -> stuff_values))
@@ -647,6 +679,9 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp,
isc_result_t status;
struct lease *lease;
+ if (!ref)
+ return ISC_R_NOKEYS;
+
/* First see if we were sent a handle. */
status = omapi_get_value_str (ref, id, "handle", &tv);
if (status == ISC_R_SUCCESS) {
@@ -777,7 +812,7 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h,
omapi_data_string_t *name,
omapi_typed_data_t *value)
{
- struct host_decl *host;
+ struct host_decl *host, *hp;
isc_result_t status;
int foo;
@@ -885,7 +920,9 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h,
if (!omapi_ds_strcmp (name, "ip-address")) {
if (host -> fixed_addr)
- return ISC_R_EXISTS;
+ option_cache_dereference (&host -> fixed_addr, MDL);
+ if (!value)
+ return ISC_R_SUCCESS;
if (value -> type == omapi_datatype_data ||
value -> type == omapi_datatype_string) {
struct data_string ds;
@@ -898,7 +935,7 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h,
value -> u.buffer.value, ds.len);
if (!option_cache (&host -> fixed_addr,
&ds, (struct expression *)0,
- (struct option *)0)) {
+ (struct option *)0, MDL)) {
data_string_forget (&ds, MDL);
return ISC_R_NOMEMORY;
}
@@ -960,7 +997,7 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h,
return status;
}
- return ISC_R_NOTFOUND;
+ return ISC_R_UNKNOWNATTRIBUTE;
}
@@ -1030,7 +1067,7 @@ isc_result_t dhcp_host_get_value (omapi_object_t *h, omapi_object_t *id,
if (status == ISC_R_SUCCESS)
return status;
}
- return ISC_R_NOTFOUND;
+ return ISC_R_UNKNOWNATTRIBUTE;
}
isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line)
@@ -1042,9 +1079,26 @@ isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line)
return ISC_R_INVALIDARG;
host = (struct host_decl *)h;
- /* Currently, this is completely hopeless - have to complete
- reference counting support for server OMAPI objects. */
- /* XXX okay, that's completed - now what? */
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ if (host -> n_ipaddr)
+ host_dereference (&host -> n_ipaddr, file, line);
+ if (host -> n_dynamic)
+ host_dereference (&host -> n_dynamic, file, line);
+ if (host -> name) {
+ dfree (host -> name, file, line);
+ host -> name = (char *)0;
+ }
+ data_string_forget (&host -> client_identifier, file, line);
+ if (host -> fixed_addr)
+ option_cache_dereference (&host -> fixed_addr, file, line);
+ if (host -> group)
+ group_dereference (&host -> group, file, line);
+ if (host -> named_group)
+ omapi_object_dereference ((omapi_object_t **)
+ &host -> named_group, file, line);
+ data_string_forget (&host -> auth_key_id, file, line);
+#endif
return ISC_R_SUCCESS;
}
@@ -1202,6 +1256,9 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp,
isc_result_t status;
struct host_decl *host;
+ if (!ref)
+ return ISC_R_NOKEYS;
+
/* First see if we were sent a handle. */
status = omapi_get_value_str (ref, id, "handle", &tv);
if (status == ISC_R_SUCCESS) {
@@ -1453,7 +1510,7 @@ isc_result_t dhcp_pool_set_value (omapi_object_t *h,
return status;
}
- return ISC_R_NOTFOUND;
+ return ISC_R_UNKNOWNATTRIBUTE;
}
@@ -1477,19 +1534,54 @@ isc_result_t dhcp_pool_get_value (omapi_object_t *h, omapi_object_t *id,
if (status == ISC_R_SUCCESS)
return status;
}
- return ISC_R_NOTFOUND;
+ return ISC_R_UNKNOWNATTRIBUTE;
}
isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line)
{
struct pool *pool;
isc_result_t status;
+ struct permit *pc, *pn;
if (h -> type != dhcp_type_pool)
return ISC_R_INVALIDARG;
pool = (struct pool *)h;
- /* Can't destroy pools yet. */
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ if (pool -> next)
+ pool_dereference (&pool -> next, file, line);
+ if (pool -> group)
+ group_dereference (&pool -> group, file, line);
+ if (pool -> shared_network)
+ shared_network_dereference (&pool -> shared_network, file, line);
+ if (pool -> active)
+ lease_dereference (&pool -> active, file, line);
+ if (pool -> expired)
+ lease_dereference (&pool -> expired, file, line);
+ if (pool -> free)
+ lease_dereference (&pool -> free, file, line);
+ if (pool -> backup)
+ lease_dereference (&pool -> backup, file, line);
+ if (pool -> abandoned)
+ lease_dereference (&pool -> abandoned, file, line);
+#if defined (FAILOVER_PROTOCOL)
+ if (pool -> failover_peer)
+ dhcp_failover_state_dereference (&pool -> failover_peer,
+ file, line);
+#endif
+ for (pc = pool -> permit_list; pc; pc = pn) {
+ pn = pc -> next;
+ free_permit (pc, file, line);
+ }
+ pool -> permit_list = (struct permit *)0;
+
+ for (pc = pool -> prohibit_list; pc; pc = pn) {
+ pn = pc -> next;
+ free_permit (pc, file, line);
+ }
+ pool -> prohibit_list = (struct permit *)0;
+#endif
return ISC_R_SUCCESS;
}
@@ -1706,7 +1798,7 @@ class_set_value (omapi_object_t *h,
return status;
}
- return ISC_R_NOTFOUND;
+ return ISC_R_UNKNOWNATTRIBUTE;
}
@@ -1751,19 +1843,54 @@ isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id,
return status;
}
- return ISC_R_NOTFOUND;
+ return ISC_R_UNKNOWNATTRIBUTE;
}
isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line)
{
struct class *class;
isc_result_t status;
+ int i;
- if (h -> type != dhcp_type_class)
+ if (h -> type != dhcp_type_class || h -> type != dhcp_type_subclass)
return ISC_R_INVALIDARG;
class = (struct class *)h;
- /* Can't destroy class yet. */
+ if (class -> nic)
+ class_dereference (&class -> nic, file, line);
+ if (class -> superclass)
+ class_dereference (&class -> superclass, file, line);
+ if (class -> name) {
+ dfree (class -> name, file, line);
+ class -> name = (char *)0;
+ }
+ if (class -> billed_leases) {
+ for (i = 0; i < class -> lease_limit; i++) {
+ if (class -> billed_leases [i]) {
+ lease_dereference (&class -> billed_leases [i],
+ file, line);
+ }
+ }
+ dfree (class -> billed_leases, file, line);
+ class -> billed_leases = (struct lease **)0;
+ }
+ if (class -> hash) {
+ free_hash_table (class -> hash, file, line);
+ class -> hash = (struct hash_table *)0;
+ }
+ data_string_forget (&class -> hash_string, file, line);
+
+ if (class -> expr)
+ expression_dereference (&class -> expr, file, line);
+ if (class -> submatch)
+ expression_dereference (&class -> submatch, file, line);
+ if (class -> group)
+ group_dereference (&class -> group, file, line);
+ if (class -> statements)
+ executable_statement_dereference (&class -> statements,
+ file, line);
+ if (class -> superclass)
+ class_dereference (&class -> superclass, file, line);
return ISC_R_SUCCESS;
}
@@ -1802,7 +1929,8 @@ class_signal_handler(omapi_object_t *h,
new_hash ((hash_reference)
omapi_object_reference,
(hash_dereference)
- omapi_object_dereference, 0);
+ omapi_object_dereference,
+ 0, MDL);
}
add_hash (class -> superclass -> hash,
class -> hash_string.data,
@@ -1874,9 +2002,9 @@ isc_result_t dhcp_class_stuff_values (omapi_object_t *c,
return ISC_R_SUCCESS;
}
-isc_result_t class_lookup (omapi_object_t **lp,
- omapi_object_t *id, omapi_object_t *ref,
- omapi_object_type_t *typewanted)
+static isc_result_t class_lookup (omapi_object_t **lp,
+ omapi_object_t *id, omapi_object_t *ref,
+ omapi_object_type_t *typewanted)
{
omapi_value_t *nv = (omapi_value_t *)0;
omapi_value_t *hv = (omapi_value_t *)0;
@@ -1920,7 +2048,8 @@ isc_result_t class_lookup (omapi_object_t **lp,
}
class_hash_lookup (&subclass, class -> hash,
- (const char *)hv -> value -> u.buffer.value,
+ (const char *)
+ hv -> value -> u.buffer.value,
hv -> value -> u.buffer.len, MDL);
omapi_value_dereference (&hv, MDL);
@@ -2034,25 +2163,7 @@ isc_result_t dhcp_subclass_get_value (omapi_object_t *h, omapi_object_t *id,
return status;
}
- return ISC_R_NOTFOUND;
-}
-
-isc_result_t dhcp_subclass_destroy (omapi_object_t *h,
- const char *file, int line)
-{
- struct class *subclass;
- isc_result_t status;
-
- if (h -> type != dhcp_type_class)
- return ISC_R_INVALIDARG;
- subclass = (struct class *)h;
- if (subclass -> name != 0)
- return ISC_R_INVALIDARG;
-
-
- /* XXXJAB Can't destroy subclasss yet. */
-
- return ISC_R_SUCCESS;
+ return ISC_R_UNKNOWNATTRIBUTE;
}
isc_result_t dhcp_subclass_signal_handler (omapi_object_t *h,
@@ -2158,4 +2269,217 @@ isc_result_t dhcp_subclass_remove (omapi_object_t *lp,
return ISC_R_SUCCESS;
}
+isc_result_t binding_scope_set_value (struct binding_scope *scope, int createp,
+ omapi_data_string_t *name,
+ omapi_typed_data_t *value)
+{
+ struct binding *bp;
+ char *nname;
+ struct binding_value *nv;
+ nname = dmalloc (name -> len + 1, MDL);
+ if (!nname)
+ return ISC_R_NOMEMORY;
+ memcpy (nname, name -> value, name -> len);
+ nname [name -> len] = 0;
+ bp = find_binding (scope, nname);
+ if (!bp && !createp) {
+ dfree (nname, MDL);
+ return ISC_R_UNKNOWNATTRIBUTE;
+ }
+ if (!value) {
+ dfree (nname, MDL);
+ if (!bp)
+ return ISC_R_UNKNOWNATTRIBUTE;
+ binding_value_dereference (&bp -> value, MDL);
+ return ISC_R_SUCCESS;
+ }
+
+ nv = (struct binding_value *)0;
+ if (!binding_value_allocate (&nv, MDL)) {
+ dfree (nname, MDL);
+ return ISC_R_NOMEMORY;
+ }
+ switch (value -> type) {
+ case omapi_datatype_int:
+ nv -> type = binding_numeric;
+ nv -> value.intval = value -> u.integer;
+ break;
+
+ case omapi_datatype_string:
+ case omapi_datatype_data:
+ if (!buffer_allocate (&nv -> value.data.buffer,
+ value -> u.buffer.len, MDL)) {
+ binding_value_dereference (&nv, MDL);
+ dfree (nname, MDL);
+ return ISC_R_NOMEMORY;
+ }
+ memcpy (&nv -> value.data.buffer -> data [1],
+ value -> u.buffer.value, value -> u.buffer.len);
+ nv -> value.data.len = value -> u.buffer.len;
+ break;
+
+ case omapi_datatype_object:
+ binding_value_dereference (&nv, MDL);
+ dfree (nname, MDL);
+ return ISC_R_INVALIDARG;
+ }
+
+ if (!bp) {
+ bp = dmalloc (sizeof *bp, MDL);
+ if (!bp) {
+ binding_value_dereference (&nv, MDL);
+ dfree (nname, MDL);
+ return ISC_R_NOMEMORY;
+ }
+ memset (bp, 0, sizeof *bp);
+ bp -> name = nname;
+ nname = (char *)0;
+ bp -> next = scope -> bindings;
+ scope -> bindings = bp;
+ } else {
+ if (bp -> value)
+ binding_value_dereference (&bp -> value, MDL);
+ dfree (nname, MDL);
+ }
+ binding_value_reference (&bp -> value, nv, MDL);
+ binding_value_dereference (&nv, MDL);
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t binding_scope_get_value (omapi_value_t **value,
+ struct binding_scope *scope,
+ omapi_data_string_t *name)
+{
+ struct binding *bp;
+ omapi_typed_data_t *td;
+ isc_result_t status;
+ char *nname;
+ nname = dmalloc (name -> len + 1, MDL);
+ if (!nname)
+ return ISC_R_NOMEMORY;
+ memcpy (nname, name -> value, name -> len);
+ nname [name -> len] = 0;
+ bp = find_binding (scope, nname);
+ dfree (nname, MDL);
+ if (!bp)
+ return ISC_R_UNKNOWNATTRIBUTE;
+ if (!bp -> value)
+ return ISC_R_UNKNOWNATTRIBUTE;
+
+ switch (bp -> value -> type) {
+ case binding_boolean:
+ td = (omapi_typed_data_t *)0;
+ status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
+ bp -> value -> value.boolean);
+ break;
+
+ case binding_numeric:
+ td = (omapi_typed_data_t *)0;
+ status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
+ (int)
+ bp -> value -> value.intval);
+ break;
+
+ case binding_data:
+ td = (omapi_typed_data_t *)0;
+ status = omapi_typed_data_new (MDL, &td, omapi_datatype_data,
+ bp -> value -> value.data.len);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ memcpy (&td -> u.buffer.value [0],
+ bp -> value -> value.data.data,
+ bp -> value -> value.data.len);
+ break;
+
+ /* Can't return values for these two (yet?). */
+ case binding_dns:
+ case binding_function:
+ return ISC_R_INVALIDARG;
+ }
+
+ if (status != ISC_R_SUCCESS)
+ return status;
+ status = omapi_value_new (value, MDL);
+ if (status != ISC_R_SUCCESS) {
+ omapi_typed_data_dereference (&td, MDL);
+ return status;
+ }
+
+ omapi_data_string_reference (&(*value) -> name, name, MDL);
+ omapi_typed_data_reference (&(*value) -> value, td, MDL);
+ omapi_typed_data_dereference (&td, MDL);
+
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t binding_scope_stuff_values (omapi_object_t *c,
+ struct binding_scope *scope)
+{
+ struct binding *bp;
+ unsigned len;
+ isc_result_t status;
+
+ for (bp = scope -> bindings; bp; bp = bp -> next) {
+ if (bp -> value) {
+ if (bp -> value -> type == binding_dns ||
+ bp -> value -> type == binding_function)
+ continue;
+
+ /* Stuff the name. */
+ len = strlen (bp -> name);
+ status = omapi_connection_put_uint16 (c, len);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ status = omapi_connection_copyin (c,
+ (unsigned char *)bp -> name,
+ len);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ switch (bp -> value -> type) {
+ case binding_boolean:
+ status = omapi_connection_put_uint32 (c,
+ sizeof (u_int32_t));
+ if (status != ISC_R_SUCCESS)
+ return status;
+ status = (omapi_connection_put_uint32
+ (c,
+ ((u_int32_t)(bp -> value -> value.boolean))));
+ break;
+
+ case binding_data:
+ status = (omapi_connection_put_uint32
+ (c, bp -> value -> value.data.len));
+ if (status != ISC_R_SUCCESS)
+ return status;
+ if (bp -> value -> value.data.len) {
+ status = (omapi_connection_copyin
+ (c, bp -> value -> value.data.data,
+ bp -> value -> value.data.len));
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+ break;
+
+ case binding_numeric:
+ status = (omapi_connection_put_uint32
+ (c, sizeof (u_int32_t)));
+ if (status != ISC_R_SUCCESS)
+ return status;
+ status = (omapi_connection_put_uint32
+ (c, ((u_int32_t)
+ (bp -> value -> value.intval))));
+ break;
+
+
+ /* NOTREACHED */
+ case binding_dns:
+ case binding_function:
+ break;
+ }
+ }
+ }
+ return ISC_R_SUCCESS;
+}
+
/* vim: set tabstop=8: */
diff --git a/server/salloc.c b/server/salloc.c
index d4460bed..bdd324a5 100644
--- a/server/salloc.c
+++ b/server/salloc.c
@@ -3,7 +3,7 @@
Memory allocation for the DHCP server... */
/*
- * Copyright (c) 1996-2000 Internet Software Consortium.
+ * Copyright (c) 1996-2001 Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,21 +43,112 @@
#ifndef lint
static char copyright[] =
-"$Id: salloc.c,v 1.3 2001/06/22 16:47:20 brister Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: salloc.c,v 1.4 2001/06/27 00:31:16 mellon Exp $ Copyright (c) 1996-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <omapip/omapip_p.h>
+#if defined (COMPACT_LEASES)
+struct lease *free_leases;
+
+# if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+struct lease *lease_hunks;
+
+void relinquish_lease_hunks ()
+{
+ struct lease *c, *n, **p, *f;
+ int i;
+
+ /* Account for all the leases on the free list. */
+ for (n = lease_hunks; n; n = n -> next) {
+ for (i = 1; i < n -> starts + 1; i++) {
+ p = &free_leases;
+ for (c = free_leases; c; c = c -> next) {
+ if (c == &n [i]) {
+ *p = c -> next;
+ n -> ends++;
+ break;
+ }
+ p = &c -> next;
+ }
+ if (!c) {
+ log_info ("lease %s refcnt %d",
+ piaddr (n [i].ip_addr), n [i].refcnt);
+ dump_rc_history (&n [i]);
+ }
+ }
+ }
+
+ for (c = lease_hunks; c; c = n) {
+ n = c -> next;
+ if (c -> ends != c -> starts) {
+ log_info ("lease hunk %lx leases %ld free %ld",
+ (unsigned long)c, (unsigned long)c -> starts,
+ (unsigned long)c -> ends);
+ }
+ dfree (c, MDL);
+ }
+
+ /* Free all the rogue leases. */
+ for (c = free_leases; c; c = n) {
+ n = c -> next;
+ dfree (c, MDL);
+ }
+}
+#endif
+
struct lease *new_leases (n, file, line)
unsigned n;
const char *file;
int line;
{
- struct lease *rval = dmalloc (n * sizeof (struct lease), file, line);
+ struct lease *rval;
+#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ rval = dmalloc ((n + 1) * sizeof (struct lease), file, line);
+ memset (rval, 0, sizeof (struct lease));
+ rval -> starts = n;
+ rval -> next = lease_hunks;
+ lease_hunks = rval;
+ rval++;
+#else
+ rval = dmalloc (n * sizeof (struct lease), file, line);
+#endif
return rval;
}
+/* If we are allocating leases in aggregations, there's really no way
+ to free one, although perhaps we can maintain a free list. */
+
+isc_result_t dhcp_lease_free (omapi_object_t *lo,
+ const char *file, int line)
+{
+ struct lease *lease;
+ if (lo -> type != dhcp_type_lease)
+ return ISC_R_INVALIDARG;
+ lease = (struct lease *)lo;
+ memset (lease, 0, sizeof (struct lease));
+ lease -> next = free_leases;
+ free_leases = lease;
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t dhcp_lease_get (omapi_object_t **lp,
+ const char *file, int line)
+{
+ struct lease **lease = (struct lease **)lp;
+ struct lease *lt;
+
+ if (free_leases) {
+ lt = free_leases;
+ free_leases = lt -> next;
+ *lease = lt;
+ return ISC_R_SUCCESS;
+ }
+ return ISC_R_NOMEMORY;
+}
+#endif /* COMPACT_LEASES */
+
OMAPI_OBJECT_ALLOC (lease, struct lease, dhcp_type_lease)
OMAPI_OBJECT_ALLOC (class, struct class, dhcp_type_class)
OMAPI_OBJECT_ALLOC (subclass, struct class, dhcp_type_subclass)
@@ -140,6 +231,20 @@ void free_lease_state (ptr, file, line)
dmalloc_reuse (free_lease_states, (char *)0, 0, 0);
}
+#if defined (DEBUG_MEMORY_LEAKAGE) || \
+ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+void relinquish_free_lease_states ()
+{
+ struct lease_state *cs, *ns;
+
+ for (cs = free_lease_states; cs; cs = ns) {
+ ns = cs -> next;
+ dfree (cs, MDL);
+ }
+ free_lease_states = (struct lease_state *)0;
+}
+#endif
+
struct permit *new_permit (file, line)
const char *file;
int line;
@@ -157,5 +262,7 @@ void free_permit (permit, file, line)
const char *file;
int line;
{
+ if (permit -> type == permit_class)
+ class_dereference (&permit -> class, MDL);
dfree (permit, file, line);
}
diff --git a/server/stables.c b/server/stables.c
index 894a43a9..746108cd 100644
--- a/server/stables.c
+++ b/server/stables.c
@@ -3,7 +3,7 @@
Tables of information only used by server... */
/*
- * Copyright (c) 1995-1999 Internet Software Consortium.
+ * Copyright (c) 1995-2001 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: stables.c,v 1.25 2001/01/25 08:37:03 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: stables.c,v 1.26 2001/06/27 00:31:17 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -189,258 +189,258 @@ struct option agent_options [256] = {
{ "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 },
+ { "#4", "X", &agent_universe, 4 },
+ { "#5", "X", &agent_universe, 5 },
+ { "#6", "X", &agent_universe, 6 },
+ { "#7", "X", &agent_universe, 7 },
+ { "#8", "X", &agent_universe, 8 },
+ { "#9", "X", &agent_universe, 9 },
+ { "#10", "X", &agent_universe, 10 },
+ { "#11", "X", &agent_universe, 11 },
+ { "#12", "X", &agent_universe, 12 },
+ { "#13", "X", &agent_universe, 13 },
+ { "#14", "X", &agent_universe, 14 },
+ { "#15", "X", &agent_universe, 15 },
+ { "#16", "X", &agent_universe, 16 },
+ { "#17", "X", &agent_universe, 17 },
+ { "#18", "X", &agent_universe, 18 },
+ { "#19", "X", &agent_universe, 19 },
+ { "#20", "X", &agent_universe, 20 },
+ { "#21", "X", &agent_universe, 21 },
+ { "#22", "X", &agent_universe, 22 },
+ { "#23", "X", &agent_universe, 23 },
+ { "#24", "X", &agent_universe, 24 },
+ { "#25", "X", &agent_universe, 25 },
+ { "#26", "X", &agent_universe, 26 },
+ { "#27", "X", &agent_universe, 27 },
+ { "#28", "X", &agent_universe, 28 },
+ { "#29", "X", &agent_universe, 29 },
+ { "#30", "X", &agent_universe, 30 },
+ { "#31", "X", &agent_universe, 31 },
+ { "#32", "X", &agent_universe, 32 },
+ { "#33", "X", &agent_universe, 33 },
+ { "#34", "X", &agent_universe, 34 },
+ { "#35", "X", &agent_universe, 35 },
+ { "#36", "X", &agent_universe, 36 },
+ { "#37", "X", &agent_universe, 37 },
+ { "#38", "X", &agent_universe, 38 },
+ { "#39", "X", &agent_universe, 39 },
+ { "#40", "X", &agent_universe, 40 },
+ { "#41", "X", &agent_universe, 41 },
+ { "#42", "X", &agent_universe, 42 },
+ { "#43", "X", &agent_universe, 43 },
+ { "#44", "X", &agent_universe, 44 },
+ { "#45", "X", &agent_universe, 45 },
+ { "#46", "X", &agent_universe, 46 },
+ { "#47", "X", &agent_universe, 47 },
+ { "#48", "X", &agent_universe, 48 },
+ { "#49", "X", &agent_universe, 49 },
+ { "#50", "X", &agent_universe, 50 },
+ { "#51", "X", &agent_universe, 51 },
+ { "#52", "X", &agent_universe, 52 },
+ { "#53", "X", &agent_universe, 53 },
+ { "#54", "X", &agent_universe, 54 },
+ { "#55", "X", &agent_universe, 55 },
+ { "#56", "X", &agent_universe, 56 },
+ { "#57", "X", &agent_universe, 57 },
+ { "#58", "X", &agent_universe, 58 },
+ { "#59", "X", &agent_universe, 59 },
+ { "#60", "X", &agent_universe, 60 },
+ { "#61", "X", &agent_universe, 61 },
+ { "#62", "X", &agent_universe, 62 },
+ { "#63", "X", &agent_universe, 63 },
+ { "#64", "X", &agent_universe, 64 },
+ { "#65", "X", &agent_universe, 65 },
+ { "#66", "X", &agent_universe, 66 },
+ { "#67", "X", &agent_universe, 67 },
+ { "#68", "X", &agent_universe, 68 },
+ { "#69", "X", &agent_universe, 69 },
+ { "#70", "X", &agent_universe, 70 },
+ { "#71", "X", &agent_universe, 71 },
+ { "#72", "X", &agent_universe, 72 },
+ { "#73", "X", &agent_universe, 73 },
+ { "#74", "X", &agent_universe, 74 },
+ { "#75", "X", &agent_universe, 75 },
+ { "#76", "X", &agent_universe, 76 },
+ { "#77", "X", &agent_universe, 77 },
+ { "#78", "X", &agent_universe, 78 },
+ { "#79", "X", &agent_universe, 79 },
+ { "#80", "X", &agent_universe, 80 },
+ { "#81", "X", &agent_universe, 81 },
+ { "#82", "X", &agent_universe, 82 },
+ { "#83", "X", &agent_universe, 83 },
+ { "#84", "X", &agent_universe, 84 },
+ { "#85", "X", &agent_universe, 85 },
+ { "#86", "X", &agent_universe, 86 },
+ { "#87", "X", &agent_universe, 87 },
+ { "#88", "X", &agent_universe, 88 },
+ { "#89", "X", &agent_universe, 89 },
+ { "#90", "X", &agent_universe, 90 },
+ { "#91", "X", &agent_universe, 91 },
+ { "#92", "X", &agent_universe, 92 },
+ { "#93", "X", &agent_universe, 93 },
+ { "#94", "X", &agent_universe, 94 },
+ { "#95", "X", &agent_universe, 95 },
+ { "#96", "X", &agent_universe, 96 },
+ { "#97", "X", &agent_universe, 97 },
+ { "#98", "X", &agent_universe, 98 },
+ { "#99", "X", &agent_universe, 99 },
+ { "#100", "X", &agent_universe, 100 },
+ { "#101", "X", &agent_universe, 101 },
+ { "#102", "X", &agent_universe, 102 },
+ { "#103", "X", &agent_universe, 103 },
+ { "#104", "X", &agent_universe, 104 },
+ { "#105", "X", &agent_universe, 105 },
+ { "#106", "X", &agent_universe, 106 },
+ { "#107", "X", &agent_universe, 107 },
+ { "#108", "X", &agent_universe, 108 },
+ { "#109", "X", &agent_universe, 109 },
+ { "#110", "X", &agent_universe, 110 },
+ { "#111", "X", &agent_universe, 111 },
+ { "#112", "X", &agent_universe, 112 },
+ { "#113", "X", &agent_universe, 113 },
+ { "#114", "X", &agent_universe, 114 },
+ { "#115", "X", &agent_universe, 115 },
+ { "#116", "X", &agent_universe, 116 },
+ { "#117", "X", &agent_universe, 117 },
+ { "#118", "X", &agent_universe, 118 },
+ { "#119", "X", &agent_universe, 119 },
+ { "#120", "X", &agent_universe, 120 },
+ { "#121", "X", &agent_universe, 121 },
+ { "#122", "X", &agent_universe, 122 },
+ { "#123", "X", &agent_universe, 123 },
+ { "#124", "X", &agent_universe, 124 },
+ { "#125", "X", &agent_universe, 125 },
+ { "#126", "X", &agent_universe, 126 },
+ { "#127", "X", &agent_universe, 127 },
+ { "#128", "X", &agent_universe, 128 },
+ { "#129", "X", &agent_universe, 129 },
+ { "#130", "X", &agent_universe, 130 },
+ { "#131", "X", &agent_universe, 131 },
+ { "#132", "X", &agent_universe, 132 },
+ { "#133", "X", &agent_universe, 133 },
+ { "#134", "X", &agent_universe, 134 },
+ { "#135", "X", &agent_universe, 135 },
+ { "#136", "X", &agent_universe, 136 },
+ { "#137", "X", &agent_universe, 137 },
+ { "#138", "X", &agent_universe, 138 },
+ { "#139", "X", &agent_universe, 139 },
+ { "#140", "X", &agent_universe, 140 },
+ { "#141", "X", &agent_universe, 141 },
+ { "#142", "X", &agent_universe, 142 },
+ { "#143", "X", &agent_universe, 143 },
+ { "#144", "X", &agent_universe, 144 },
+ { "#145", "X", &agent_universe, 145 },
+ { "#146", "X", &agent_universe, 146 },
+ { "#147", "X", &agent_universe, 147 },
+ { "#148", "X", &agent_universe, 148 },
+ { "#149", "X", &agent_universe, 149 },
+ { "#150", "X", &agent_universe, 150 },
+ { "#151", "X", &agent_universe, 151 },
+ { "#152", "X", &agent_universe, 152 },
+ { "#153", "X", &agent_universe, 153 },
+ { "#154", "X", &agent_universe, 154 },
+ { "#155", "X", &agent_universe, 155 },
+ { "#156", "X", &agent_universe, 156 },
+ { "#157", "X", &agent_universe, 157 },
+ { "#158", "X", &agent_universe, 158 },
+ { "#159", "X", &agent_universe, 159 },
+ { "#160", "X", &agent_universe, 160 },
+ { "#161", "X", &agent_universe, 161 },
+ { "#162", "X", &agent_universe, 162 },
+ { "#163", "X", &agent_universe, 163 },
+ { "#164", "X", &agent_universe, 164 },
+ { "#165", "X", &agent_universe, 165 },
+ { "#166", "X", &agent_universe, 166 },
+ { "#167", "X", &agent_universe, 167 },
+ { "#168", "X", &agent_universe, 168 },
+ { "#169", "X", &agent_universe, 169 },
+ { "#170", "X", &agent_universe, 170 },
+ { "#171", "X", &agent_universe, 171 },
+ { "#172", "X", &agent_universe, 172 },
+ { "#173", "X", &agent_universe, 173 },
+ { "#174", "X", &agent_universe, 174 },
+ { "#175", "X", &agent_universe, 175 },
+ { "#176", "X", &agent_universe, 176 },
+ { "#177", "X", &agent_universe, 177 },
+ { "#178", "X", &agent_universe, 178 },
+ { "#179", "X", &agent_universe, 179 },
+ { "#180", "X", &agent_universe, 180 },
+ { "#181", "X", &agent_universe, 181 },
+ { "#182", "X", &agent_universe, 182 },
+ { "#183", "X", &agent_universe, 183 },
+ { "#184", "X", &agent_universe, 184 },
+ { "#185", "X", &agent_universe, 185 },
+ { "#186", "X", &agent_universe, 186 },
+ { "#187", "X", &agent_universe, 187 },
+ { "#188", "X", &agent_universe, 188 },
+ { "#189", "X", &agent_universe, 189 },
+ { "#190", "X", &agent_universe, 190 },
+ { "#191", "X", &agent_universe, 191 },
+ { "#192", "X", &agent_universe, 192 },
+ { "#193", "X", &agent_universe, 193 },
+ { "#194", "X", &agent_universe, 194 },
+ { "#195", "X", &agent_universe, 195 },
+ { "#196", "X", &agent_universe, 196 },
+ { "#197", "X", &agent_universe, 197 },
+ { "#198", "X", &agent_universe, 198 },
+ { "#199", "X", &agent_universe, 199 },
+ { "#200", "X", &agent_universe, 200 },
+ { "#201", "X", &agent_universe, 201 },
+ { "#202", "X", &agent_universe, 202 },
+ { "#203", "X", &agent_universe, 203 },
+ { "#204", "X", &agent_universe, 204 },
+ { "#205", "X", &agent_universe, 205 },
+ { "#206", "X", &agent_universe, 206 },
+ { "#207", "X", &agent_universe, 207 },
+ { "#208", "X", &agent_universe, 208 },
+ { "#209", "X", &agent_universe, 209 },
+ { "#210", "X", &agent_universe, 210 },
+ { "#211", "X", &agent_universe, 211 },
+ { "#212", "X", &agent_universe, 212 },
+ { "#213", "X", &agent_universe, 213 },
+ { "#214", "X", &agent_universe, 214 },
+ { "#215", "X", &agent_universe, 215 },
+ { "#216", "X", &agent_universe, 216 },
+ { "#217", "X", &agent_universe, 217 },
+ { "#218", "X", &agent_universe, 218 },
+ { "#219", "X", &agent_universe, 219 },
+ { "#220", "X", &agent_universe, 220 },
+ { "#221", "X", &agent_universe, 221 },
+ { "#222", "X", &agent_universe, 222 },
+ { "#223", "X", &agent_universe, 223 },
+ { "#224", "X", &agent_universe, 224 },
+ { "#225", "X", &agent_universe, 225 },
+ { "#226", "X", &agent_universe, 226 },
+ { "#227", "X", &agent_universe, 227 },
+ { "#228", "X", &agent_universe, 228 },
+ { "#229", "X", &agent_universe, 229 },
+ { "#230", "X", &agent_universe, 230 },
+ { "#231", "X", &agent_universe, 231 },
+ { "#232", "X", &agent_universe, 232 },
+ { "#233", "X", &agent_universe, 233 },
+ { "#234", "X", &agent_universe, 234 },
+ { "#235", "X", &agent_universe, 235 },
+ { "#236", "X", &agent_universe, 236 },
+ { "#237", "X", &agent_universe, 237 },
+ { "#238", "X", &agent_universe, 238 },
+ { "#239", "X", &agent_universe, 239 },
+ { "#240", "X", &agent_universe, 240 },
+ { "#241", "X", &agent_universe, 241 },
+ { "#242", "X", &agent_universe, 242 },
+ { "#243", "X", &agent_universe, 243 },
+ { "#244", "X", &agent_universe, 244 },
+ { "#245", "X", &agent_universe, 245 },
+ { "#246", "X", &agent_universe, 246 },
+ { "#247", "X", &agent_universe, 247 },
+ { "#248", "X", &agent_universe, 248 },
+ { "#249", "X", &agent_universe, 249 },
+ { "#250", "X", &agent_universe, 250 },
+ { "#251", "X", &agent_universe, 251 },
+ { "#252", "X", &agent_universe, 252 },
+ { "#253", "X", &agent_universe, 253 },
+ { "#254", "X", &agent_universe, 254 },
+ { "#end", "e", &agent_universe, 255 },
};
struct universe server_universe;
@@ -481,7 +481,7 @@ struct option server_options [256] = {
{ "limited-broadcast-address", "I", &server_universe, 33 },
{ "remote-port", "S", &server_universe, 34 },
{ "local-address", "I", &server_universe, 35 },
- { "omapi-key", "t", &server_universe, 36 },
+ { "omapi-key", "d", &server_universe, 36 },
{ "stash-agent-options", "f", &server_universe, 37 },
{ "ddns-ttl", "T", &server_universe, 38 },
{ "ddns-update-style", "Nddns-styles.", &server_universe, 39 },
@@ -490,217 +490,217 @@ struct option server_options [256] = {
{ "ping-check", "f", &server_universe, 42 },
{ "update-static-leases", "f", &server_universe, 43 },
{ "log-facility", "Nsyslog-facilities.", &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 },
+ { "#45", "X", &server_universe, 45 },
+ { "#46", "X", &server_universe, 46 },
+ { "#47", "X", &server_universe, 47 },
+ { "#48", "X", &server_universe, 48 },
+ { "#49", "X", &server_universe, 49 },
+ { "#50", "X", &server_universe, 50 },
+ { "#51", "X", &server_universe, 51 },
+ { "#52", "X", &server_universe, 52 },
+ { "#53", "X", &server_universe, 53 },
+ { "#54", "X", &server_universe, 54 },
+ { "#55", "X", &server_universe, 55 },
+ { "#56", "X", &server_universe, 56 },
+ { "#57", "X", &server_universe, 57 },
+ { "#58", "X", &server_universe, 58 },
+ { "#59", "X", &server_universe, 59 },
+ { "#60", "X", &server_universe, 60 },
+ { "#61", "X", &server_universe, 61 },
+ { "#62", "X", &server_universe, 62 },
+ { "#63", "X", &server_universe, 63 },
+ { "#64", "X", &server_universe, 64 },
+ { "#65", "X", &server_universe, 65 },
+ { "#66", "X", &server_universe, 66 },
+ { "#67", "X", &server_universe, 67 },
+ { "#68", "X", &server_universe, 68 },
+ { "#69", "X", &server_universe, 69 },
+ { "#70", "X", &server_universe, 70 },
+ { "#71", "X", &server_universe, 71 },
+ { "#72", "X", &server_universe, 72 },
+ { "#73", "X", &server_universe, 73 },
+ { "#74", "X", &server_universe, 74 },
+ { "#75", "X", &server_universe, 75 },
+ { "#76", "X", &server_universe, 76 },
+ { "#77", "X", &server_universe, 77 },
+ { "#78", "X", &server_universe, 78 },
+ { "#79", "X", &server_universe, 79 },
+ { "#80", "X", &server_universe, 80 },
+ { "#81", "X", &server_universe, 81 },
+ { "#82", "X", &server_universe, 82 },
+ { "#83", "X", &server_universe, 83 },
+ { "#84", "X", &server_universe, 84 },
+ { "#85", "X", &server_universe, 85 },
+ { "#86", "X", &server_universe, 86 },
+ { "#87", "X", &server_universe, 87 },
+ { "#88", "X", &server_universe, 88 },
+ { "#89", "X", &server_universe, 89 },
+ { "#90", "X", &server_universe, 90 },
+ { "#91", "X", &server_universe, 91 },
+ { "#92", "X", &server_universe, 92 },
+ { "#93", "X", &server_universe, 93 },
+ { "#94", "X", &server_universe, 94 },
+ { "#95", "X", &server_universe, 95 },
+ { "#96", "X", &server_universe, 96 },
+ { "#97", "X", &server_universe, 97 },
+ { "#98", "X", &server_universe, 98 },
+ { "#99", "X", &server_universe, 99 },
+ { "#100", "X", &server_universe, 100 },
+ { "#101", "X", &server_universe, 101 },
+ { "#102", "X", &server_universe, 102 },
+ { "#103", "X", &server_universe, 103 },
+ { "#104", "X", &server_universe, 104 },
+ { "#105", "X", &server_universe, 105 },
+ { "#106", "X", &server_universe, 106 },
+ { "#107", "X", &server_universe, 107 },
+ { "#108", "X", &server_universe, 108 },
+ { "#109", "X", &server_universe, 109 },
+ { "#110", "X", &server_universe, 110 },
+ { "#111", "X", &server_universe, 111 },
+ { "#112", "X", &server_universe, 112 },
+ { "#113", "X", &server_universe, 113 },
+ { "#114", "X", &server_universe, 114 },
+ { "#115", "X", &server_universe, 115 },
+ { "#116", "X", &server_universe, 116 },
+ { "#117", "X", &server_universe, 117 },
+ { "#118", "X", &server_universe, 118 },
+ { "#119", "X", &server_universe, 119 },
+ { "#120", "X", &server_universe, 120 },
+ { "#121", "X", &server_universe, 121 },
+ { "#122", "X", &server_universe, 122 },
+ { "#123", "X", &server_universe, 123 },
+ { "#124", "X", &server_universe, 124 },
+ { "#125", "X", &server_universe, 125 },
+ { "#126", "X", &server_universe, 126 },
+ { "#127", "X", &server_universe, 127 },
+ { "#128", "X", &server_universe, 128 },
+ { "#129", "X", &server_universe, 129 },
+ { "#130", "X", &server_universe, 130 },
+ { "#131", "X", &server_universe, 131 },
+ { "#132", "X", &server_universe, 132 },
+ { "#133", "X", &server_universe, 133 },
+ { "#134", "X", &server_universe, 134 },
+ { "#135", "X", &server_universe, 135 },
+ { "#136", "X", &server_universe, 136 },
+ { "#137", "X", &server_universe, 137 },
+ { "#138", "X", &server_universe, 138 },
+ { "#139", "X", &server_universe, 139 },
+ { "#140", "X", &server_universe, 140 },
+ { "#141", "X", &server_universe, 141 },
+ { "#142", "X", &server_universe, 142 },
+ { "#143", "X", &server_universe, 143 },
+ { "#144", "X", &server_universe, 144 },
+ { "#145", "X", &server_universe, 145 },
+ { "#146", "X", &server_universe, 146 },
+ { "#147", "X", &server_universe, 147 },
+ { "#148", "X", &server_universe, 148 },
+ { "#149", "X", &server_universe, 149 },
+ { "#150", "X", &server_universe, 150 },
+ { "#151", "X", &server_universe, 151 },
+ { "#152", "X", &server_universe, 152 },
+ { "#153", "X", &server_universe, 153 },
+ { "#154", "X", &server_universe, 154 },
+ { "#155", "X", &server_universe, 155 },
+ { "#156", "X", &server_universe, 156 },
+ { "#157", "X", &server_universe, 157 },
+ { "#158", "X", &server_universe, 158 },
+ { "#159", "X", &server_universe, 159 },
+ { "#160", "X", &server_universe, 160 },
+ { "#161", "X", &server_universe, 161 },
+ { "#162", "X", &server_universe, 162 },
+ { "#163", "X", &server_universe, 163 },
+ { "#164", "X", &server_universe, 164 },
+ { "#165", "X", &server_universe, 165 },
+ { "#166", "X", &server_universe, 166 },
+ { "#167", "X", &server_universe, 167 },
+ { "#168", "X", &server_universe, 168 },
+ { "#169", "X", &server_universe, 169 },
+ { "#170", "X", &server_universe, 170 },
+ { "#171", "X", &server_universe, 171 },
+ { "#172", "X", &server_universe, 172 },
+ { "#173", "X", &server_universe, 173 },
+ { "#174", "X", &server_universe, 174 },
+ { "#175", "X", &server_universe, 175 },
+ { "#176", "X", &server_universe, 176 },
+ { "#177", "X", &server_universe, 177 },
+ { "#178", "X", &server_universe, 178 },
+ { "#179", "X", &server_universe, 179 },
+ { "#180", "X", &server_universe, 180 },
+ { "#181", "X", &server_universe, 181 },
+ { "#182", "X", &server_universe, 182 },
+ { "#183", "X", &server_universe, 183 },
+ { "#184", "X", &server_universe, 184 },
+ { "#185", "X", &server_universe, 185 },
+ { "#186", "X", &server_universe, 186 },
+ { "#187", "X", &server_universe, 187 },
+ { "#188", "X", &server_universe, 188 },
+ { "#189", "X", &server_universe, 189 },
+ { "#190", "X", &server_universe, 190 },
+ { "#191", "X", &server_universe, 191 },
+ { "#192", "X", &server_universe, 192 },
+ { "#193", "X", &server_universe, 193 },
+ { "#194", "X", &server_universe, 194 },
+ { "#195", "X", &server_universe, 195 },
+ { "#196", "X", &server_universe, 196 },
+ { "#197", "X", &server_universe, 197 },
+ { "#198", "X", &server_universe, 198 },
+ { "#199", "X", &server_universe, 199 },
+ { "#200", "X", &server_universe, 200 },
+ { "#201", "X", &server_universe, 201 },
+ { "#202", "X", &server_universe, 202 },
+ { "#203", "X", &server_universe, 203 },
+ { "#204", "X", &server_universe, 204 },
+ { "#205", "X", &server_universe, 205 },
+ { "#206", "X", &server_universe, 206 },
+ { "#207", "X", &server_universe, 207 },
+ { "#208", "X", &server_universe, 208 },
+ { "#209", "X", &server_universe, 209 },
+ { "#210", "X", &server_universe, 210 },
+ { "#211", "X", &server_universe, 211 },
+ { "#212", "X", &server_universe, 212 },
+ { "#213", "X", &server_universe, 213 },
+ { "#214", "X", &server_universe, 214 },
+ { "#215", "X", &server_universe, 215 },
+ { "#216", "X", &server_universe, 216 },
+ { "#217", "X", &server_universe, 217 },
+ { "#218", "X", &server_universe, 218 },
+ { "#219", "X", &server_universe, 219 },
+ { "#220", "X", &server_universe, 220 },
+ { "#221", "X", &server_universe, 221 },
+ { "#222", "X", &server_universe, 222 },
+ { "#223", "X", &server_universe, 223 },
+ { "#224", "X", &server_universe, 224 },
+ { "#225", "X", &server_universe, 225 },
+ { "#226", "X", &server_universe, 226 },
+ { "#227", "X", &server_universe, 227 },
+ { "#228", "X", &server_universe, 228 },
+ { "#229", "X", &server_universe, 229 },
+ { "#230", "X", &server_universe, 230 },
+ { "#231", "X", &server_universe, 231 },
+ { "#232", "X", &server_universe, 232 },
+ { "#233", "X", &server_universe, 233 },
+ { "#234", "X", &server_universe, 234 },
+ { "#235", "X", &server_universe, 235 },
+ { "#236", "X", &server_universe, 236 },
+ { "#237", "X", &server_universe, 237 },
+ { "#238", "X", &server_universe, 238 },
+ { "#239", "X", &server_universe, 239 },
+ { "#240", "X", &server_universe, 240 },
+ { "#241", "X", &server_universe, 241 },
+ { "#242", "X", &server_universe, 242 },
+ { "#243", "X", &server_universe, 243 },
+ { "#244", "X", &server_universe, 244 },
+ { "#245", "X", &server_universe, 245 },
+ { "#246", "X", &server_universe, 246 },
+ { "#247", "X", &server_universe, 247 },
+ { "#248", "X", &server_universe, 248 },
+ { "#249", "X", &server_universe, 249 },
+ { "#250", "X", &server_universe, 250 },
+ { "#251", "X", &server_universe, 251 },
+ { "#252", "X", &server_universe, 252 },
+ { "#253", "X", &server_universe, 253 },
+ { "#254", "X", &server_universe, 254 },
+ { "option-end", "e", &server_universe, 255 },
};
struct enumeration_value ddns_styles_values [] = {
@@ -806,7 +806,7 @@ void initialize_server_option_spaces()
agent_universe.store_tag = putUChar;
agent_universe.store_length = putUChar;
universes [agent_universe.index] = &agent_universe;
- agent_universe.hash = new_hash (0, 0, 1);
+ agent_universe.hash = new_hash (0, 0, 1, MDL);
if (!agent_universe.hash)
log_fatal ("Can't allocate agent option hash table.");
for (i = 0; i < 256; i++) {
@@ -833,7 +833,7 @@ void initialize_server_option_spaces()
server_universe.store_length = putUChar;
server_universe.index = universe_count++;
universes [server_universe.index] = &server_universe;
- server_universe.hash = new_hash (0, 0, 1);
+ server_universe.hash = new_hash (0, 0, 1, MDL);
if (!server_universe.hash)
log_fatal ("Can't allocate server option hash table.");
for (i = 0; i < 256; i++) {
diff --git a/tests/failover/dhcp-1.cf b/tests/failover/dhcp-1.cf
index eff2e3cd..12515991 100644
--- a/tests/failover/dhcp-1.cf
+++ b/tests/failover/dhcp-1.cf
@@ -4,16 +4,19 @@ lease-file-name "dhcp-1.leases";
pid-file-name "dhcp-1.pid";
ddns-update-style none;
local-port 50002;
+remote-port 50003;
+omapi-port 50004;
+omapi-key FOO;
default-lease-time 600;
max-lease-time 600;
failover peer "foo" {
primary;
- address 204.152.187.24;
+ address 10.0.0.1;
port 51000;
- peer address 204.152.187.41;
- peer port 51000;
+ peer address 10.0.0.1;
+ peer port 51001;
max-response-delay 7;
max-unacked-updates 10;
mclt 100;
@@ -57,6 +60,10 @@ option domain-name "connectathon.org.";
option SUNW.root-server-ip-address 172.16.113.1;
option SUNW.root-server-hostname "sundhcp-server17-1";
+class "sniffer" {
+ match if option host-name = "sniffer";
+}
+
key FOO {
algorithm HMAC-MD5.SIG-ALG.REG.INT;
secret ABCD;
@@ -81,9 +88,35 @@ subnet 204.152.186.128 netmask 255.255.255.192 {
not authoritative;
}
+shared-network LOCAL {
+ subnet 127.0.0.0 netmask 255.255.255.0 {
+ }
+ subnet 10.0.2.0 netmask 255.255.255.0 {
+ pool {
+ deny dynamic bootp clients;
+ failover peer "foo";
+ range 10.0.2.100 10.0.2.200;
+ }
+ }
+}
+
+shared-network LOCAL {
+ subnet 127.0.0.0 netmask 255.255.255.0 {
+ }
+ subnet 10.0.2.0 netmask 255.255.255.0 {
+ pool {
+ deny dynamic bootp clients;
+ failover peer "foo";
+ range 10.0.2.100 10.0.2.200;
+ }
+ }
+}
+
shared-network NET-187 {
subnet 204.152.187.0 netmask 255.255.255.0 {
}
+ subnet 205.140.116.224 netmask 255.255.255.248 {
+ }
subnet 10.0.1.0 netmask 255.255.255.0 {
pool {
deny dynamic bootp clients;
@@ -96,9 +129,16 @@ shared-network NET-187 {
subnet 10.0.0.0 netmask 255.255.255.0 {
pool {
deny dynamic bootp clients;
+ deny members of "sniffer";
failover peer "foo";
range 10.0.0.10 10.0.0.200;
}
+ pool {
+ deny dynamic bootp clients;
+ allow members of "sniffer";
+ failover peer "foo";
+ range 10.0.0.9 10.0.0.9;
+ }
option routers 10.0.0.1;
option domain-name "bisbee.fugue.com";
option domain-name-servers 10.0.0.1;
diff --git a/tests/failover/dhcp-2.cf b/tests/failover/dhcp-2.cf
index 193c558b..cbc47f46 100644
--- a/tests/failover/dhcp-2.cf
+++ b/tests/failover/dhcp-2.cf
@@ -3,6 +3,8 @@ authoritative;
lease-file-name "dhcp-2.leases";
pid-file-name "dhcp-2.pid";
local-port 50000;
+remote-port 50001;
+omapi-port 50005;
ddns-update-style none;
@@ -11,9 +13,9 @@ max-lease-time 600;
failover peer "foo" {
secondary;
- address 204.152.187.41;
- port 51000;
- peer address 204.152.187.24;
+ address 10.0.0.1;
+ port 51001;
+ peer address 10.0.0.1;
peer port 51000;
max-response-delay 7;
max-unacked-updates 10;
@@ -56,6 +58,10 @@ option domain-name "connectathon.org.";
option SUNW.root-server-ip-address 172.16.113.1;
option SUNW.root-server-hostname "sundhcp-server17-1";
+class "sniffer" {
+ match if option host-name = "sniffer";
+}
+
key FOO {
algorithm HMAC-MD5.SIG-ALG.REG.INT;
secret ABCD;
@@ -80,7 +86,19 @@ subnet 204.152.186.128 netmask 255.255.255.192 {
not authoritative;
}
-shared-network {
+shared-network LOCAL {
+ subnet 127.0.0.0 netmask 255.255.255.0 {
+ }
+ subnet 10.0.2.0 netmask 255.255.255.0 {
+ pool {
+ deny dynamic bootp clients;
+ failover peer "foo";
+ range 10.0.2.100 10.0.2.200;
+ }
+ }
+}
+
+shared-network 187-NET {
subnet 204.152.187.0 netmask 255.255.255.0 {
}
subnet 10.0.1.0 netmask 255.255.255.0 {
@@ -95,9 +113,16 @@ shared-network {
subnet 10.0.0.0 netmask 255.255.255.0 {
pool {
deny dynamic bootp clients;
+ deny members of "sniffer";
failover peer "foo";
range 10.0.0.10 10.0.0.200;
}
+ pool {
+ deny dynamic bootp clients;
+ allow members of "sniffer";
+ failover peer "foo";
+ range 10.0.0.9 10.0.0.9;
+ }
option routers 10.0.0.1;
option domain-name "bisbee.fugue.com";
option domain-name-servers 10.0.0.1;
diff --git a/tests/failover/new-failover b/tests/failover/new-failover
index c43d87fb..65d82e01 100755
--- a/tests/failover/new-failover
+++ b/tests/failover/new-failover
@@ -4,8 +4,8 @@ foo=10
while [ $foo -lt 100 ]; do
cat >>dhcp-1.leases <<~
lease 10.0.0.$foo {
- starts 4 2001/04/19 02:19:16;
- ends 5 2001/04/21 02:29:16;
+ starts 4 2001/05/01 02:19:16;
+ ends 5 2021/05/03 02:29:16;
binding state active;
next binding state free;
hardware ethernet 08:00:46:06:6c:23;
@@ -16,7 +16,7 @@ lease 10.0.0.$foo {
cat >>dhcp-2.leases <<~
lease 10.0.0.$foo {
starts 4 2001/04/19 02:19:16;
- ends 5 2001/04/21 02:29:16;
+ ends 5 2021/04/21 02:29:16;
binding state active;
next binding state free;
hardware ethernet 08:00:46:06:6c:23;