## Defaults...
SCRIPT = none
+USERBINDIR = /usr/bin
BINDIR = /usr/sbin
CLIENTBINDIR=/sbin
ADMMANDIR = /usr/share/man/cat8
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
LIBDIR=/usr/local/lib
INCDIR=/usr/local/include
LIBS =
-COPTS = $(BINDDEF)
+COPTS = $(BINDDEF) $(CC_OPTIONS)
DEBUG = -g
RANLIB = ranlib
MKDEP = mkdep
##--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--
#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
#FFMANEXT = .4
#LIBMANDIR = /usr/share/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/share/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /etc
#VARDB = /etc
#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
#FFMANEXT = .4
#LIBMANDIR = /usr/share/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/share/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /etc
#VARDB = /etc
## DEC Alpha/OSF1
##--alphaosf--
-#COPTS = -std
+#COPTS = -std $(CC_OPTIONS)
#INSTALL=/usr/ucb/installbsd -c
#MANINSTALL=/usr/ucb/installbsd -c
#CF = cf/alphaosf.h
##--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
# -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--
# -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--
#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
#FFMANEXT = .5
#LIBMANDIR = /usr/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /var/run
#VARDB = /var/state/dhcp
## 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
#FFMANEXT = .5
#LIBMANDIR = /usr/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /var/run
#VARDB = /var/state/dhcp
## 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
#FFMANEXT = .5
#LIBMANDIR = /usr/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /var/run
#VARDB = /var/state/dhcp
## 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
#FFMANEXT = .5
#LIBMANDIR = /usr/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/man1
+#USRMANEXT = .1
#MANCAT = man
#VARRUN = /var/run
#VARDB = /var/state/dhcp
#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
#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
#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
#FFMANEXT = .5
#LIBMANDIR = /usr/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/man/man1
+#USRMANEXT = .1
#VARRUN = /etc
#MANINSTALL = /bin/true
#INSTALL = cp
##--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
#FFMANEXT = .5
#LIBMANDIR = /usr/local/man/man3
#LIBMANEXT = .3
+#USRMANDIR = /usr/local/man/man1
+#USRMANEXT = .1
#MANCAT = man
#INSTALL = install
#MANINSTALL = install
## HP-UX
##--hpux-cc--
-#COPTS = $(BINDDEF)
+#COPTS = $(BINDDEF) $(CC_OPTIONS)
#LFLAGS = -Wl,+vnocompatwarnings
#INSTALL = install -i
#MANINSTALL = install -i
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
#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"
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;
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,
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 */
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) {
}
} 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;
} 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;
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,
#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"
/* 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;
/* 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;
}
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
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;
const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
struct iaddrlist *ap;
struct option_cache *oc;
+ char obuf [1024];
#ifdef DEBUG_PACKET
dump_packet (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;
}
}
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;
}
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
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);
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));
? &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)
if (client -> alias)
script_write_params (client, "alias_",
client -> alias);
+ script_write_params (client, "old_", client -> active);
script_go (client);
}
{
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);
+}
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
#!/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.
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
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.
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
# 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.
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
#!/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.
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
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
#!/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.
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
#!/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.
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
#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"
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);
#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;
}
}
*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;
}
*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 ();
int line;
{
int size;
+ struct group *g;
if (!ptr) {
log_error ("%s(%d): null pointer", 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;
}
}
*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;
}
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 ();
}
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;
}
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)
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)
}
*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;
}
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)
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)
}
*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;
}
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;
}
*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;
}
*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;
}
}
*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;
}
}
(*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 ();
}
*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;
}
}
(*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 ();
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;
}
*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;
}
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 ();
}
*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);
}
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;
}
}
*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;
}
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 ();
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);
int line;
{
int size;
+ struct dns_zone *d;
if (!ptr) {
log_error ("%s(%d): null pointer", 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;
}
}
*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;
}
}
*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;
}
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
#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,
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;
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) {
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,
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;
}
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;
}
#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"
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"))
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"))
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).
#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;
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);
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;
}
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) {
}
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)
#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"
struct timeout *timeouts;
static struct timeout *free_timeouts;
-int interfaces_invalidated;
-
void set_time (u_int32_t t)
{
/* Do any outstanding timeouts. */
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
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
#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"
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);
} 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;
}
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;
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);
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 ();
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)
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;
* 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. */
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)
#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"
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],
unsigned bufix;
struct hardware *from;
{
- struct ether_header eh;
+ struct isc_ether_header eh;
memcpy (&eh, buf + bufix, ETHER_HEADER_SIZE);
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
#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"
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;
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"));
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"));
(&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))) {
(&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;
}
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");
}
(*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;
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 ();
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:
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);
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))
{
}
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;
+}
#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;
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,
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)
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) { }
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
#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"
}
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;
+}
+
#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"
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;
}
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;
}
#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
{
static char optbuf [32768]; /* XXX */
int hunksize = 0;
+ int opthunk = 0;
+ int hunkinc = 0;
int numhunk = -1;
int numelem = 0;
char fmtbuf [32];
const unsigned char *dp = data;
struct in_addr foo;
char comma;
+ unsigned long tval;
if (emit_commas)
comma = ',';
}
fmtbuf [l + 1] = 0;
break;
+ case 'd':
case 't':
fmtbuf [l] = 't';
fmtbuf [l + 1] = 0;
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,
}
/* 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);
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));
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;
struct option_state *options;
struct binding_scope **scope;
unsigned code;
+ const char *file;
+ int line;
{
struct option_cache *oc;
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;
}
}
(*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);
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 ();
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
}
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
#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"
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);
}
/* 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);
}
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",
#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"
} 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);
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);
case IP_ADDRESS:
type = 'I';
break;
+ case DOMAIN_NAME:
+ type = 'd';
+ goto no_arrays;
case TEXT:
type = 't';
no_arrays:
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 */
int i;
struct dns_zone *zone;
isc_result_t status;
+ char *s;
token = peek_token (&val, (unsigned *)0, cfile);
switch (token) {
}
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;
dns_zone_dereference (&zone, MDL);
return 0;
}
+ dns_zone_dereference (&zone, MDL);
return 1;
/* Also not really a statement, but same idea as above. */
key -> name, isc_result_totext (status));
goto bad;
}
+ omapi_auth_key_dereference (&key, MDL);
return 1;
rbad:
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. */
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,
} 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;
}
} 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,
return 0;
}
} else
- (*result) -> data.ie.false = (struct executable_statement *)0;
+ (*result) -> data.ie.fc = (struct executable_statement *)0;
return 1;
}
*expr, MDL);
expression_dereference (expr, MDL);
expression_reference (expr, nexp, MDL);
+ expression_dereference (&nexp, MDL);
goto concat_another;
}
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;
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;
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;
}
}
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;
} 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') {
}
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)) {
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;
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;
} 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;
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;
}
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;
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;
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;
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;
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;
}
#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"
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++ = '\\';
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;
#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"
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;
{ "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;
{ "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 [] = {
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++) {
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++) {
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++) {
}
/* 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);
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
#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"
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;
}
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 =
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;
}
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;
}
}
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;
struct option_state *cfg_options;
struct binding_scope **scope;
struct expression *expr;
+ const char *file;
+ int line;
{
struct binding_value *bv;
int status;
if (result)
binding_value_reference (result,
binding -> value,
- MDL);
+ file, line);
return 1;
} else
return 0;
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;
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))
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;
/* 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 ();
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
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;
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;
!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;
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.",
}
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;
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;
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
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;
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,
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
result -> data += data.len - len;
result -> len = len;
}
+ data_string_forget (&data, MDL);
}
#if defined (DEBUG_EXPRESSIONS)
/* 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;
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;
/* 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;
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],
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))
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... */
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);
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",
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;
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;
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;
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;
}
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;
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;
/* 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;
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);
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,
(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,
}
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);
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.",
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.",
"evaluate_data_expression");
else
data_string_copy (result, &bv -> value.data,
- MDL);
+ file, line);
binding_value_dereference (&bv, MDL);
}
#if defined (DEBUG_EXPRESSIONS)
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,
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,
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)
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)
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)
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.",
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,
/* 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 ();
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 ();
}
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 ();
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
;;
AIX)
sysname=aix;;
+ Darwin)
+ sysname=darwin;;
Rhapsody)
sysname=rhapsody;;
ULTRIX)
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)
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"
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
# 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
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; \
$(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)
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)
#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 **);
.\"
.\" 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.
.\"
.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
}
.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.
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)
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)
/* 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,
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);
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,
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)
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)
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;
}
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);
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
-#include <isc/result.h>
+#include <isc-dhcp/result.h>
#include "dhcpctl.h"
#include "dhcpd.h"
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);
}
/* 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) {
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",
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);
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;
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
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;
}
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;
}
exit (0);
}
+
+/* Sigh */
+isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
+ control_object_state_t newstate)
+{
+ return ISC_R_SUCCESS;
+}
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")) {
} 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
#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
#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>
#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
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 */
+
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
#define PTRSIZE_64BIT
#endif
+#define SOCKLEN_T int
+
#ifdef NEED_PRAND_CONF
const char *cmds[] = {
"/bin/ps -axlw 2>&1",
#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. */
/*
#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)
(((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];
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,
int lease_count;
int free_leases;
int backup_leases;
+ int index;
#if defined (FAILOVER_PROTOCOL)
dhcp_failover_state_t *failover_peer;
#endif
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. */
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. */
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. */
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 *,
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,
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 *));
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 *,
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 *,
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)
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);
/* 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));
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)
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;
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 *));
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 *));
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 */
/* 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 *));
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 *));
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)
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);
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 *);
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;
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)
/* 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));
RECOVER_WAIT = 608,
SERVER = 609,
CONNECT = 610,
- REMOVE = 611
+ REMOVE = 611,
+ REFRESH = 612,
+ DOMAIN_NAME = 613
};
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
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
#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
*/
/*
- * $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
#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.
*/
#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))
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
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
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;
}
+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);
#ifndef _OMAPIP_H_
#define _OMAPIP_H_
-#include <isc/result.h>
+#include <isc-dhcp/result.h>
typedef unsigned int omapi_handle_t;
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) \
{ \
#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 *, \
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]) { \
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 *,
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 *,
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 *,
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
#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);
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);
#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>
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;
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;
typedef struct __omapi_generic_object {
OMAPI_OBJECT_PREAMBLE;
omapi_value_t **values;
+ u_int8_t *changed;
int nvalues, va_max;
} omapi_generic_object_t;
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__ */
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);
#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
} op;
union {
struct {
- struct executable_statement *true, *false;
+ struct executable_statement *tc, *fc;
struct expression *expr;
} ie;
struct expression *eval;
/* Current version of ISC DHCP Distribution. */
-#define DHCP_VERSION "V3.1-unreleased"
+#define DHCP_VERSION "V3.0rc8pl2"
*/
#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)
#include "minires/minires.h"
#include "arpa/nameser.h"
-#include <isc/dst.h>
+#include <isc-dhcp/dst.h>
#define BOUNDS_CHECK(ptr, count) \
do { \
*/
#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)
#include "minires/minires.h"
#include "arpa/nameser.h"
-#include <isc/dst.h>
+#include <isc-dhcp/dst.h>
time_t trace_mr_time (time_t *);
#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 */
/*
#include <stdlib.h>
#include <string.h>
-#include <isc/list.h>
+#include <isc-dhcp/list.h>
#include "minires/minires.h"
#include "arpa/nameser.h"
#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>
*
* 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);
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;
#include "minires/minires.h"
#include "arpa/nameser.h"
-#include <isc/dst.h>
+#include <isc-dhcp/dst.h>
/* res_nsendsigned */
isc_result_t
if (dstkey == NULL) {
free(nstatp);
free(newmsg);
- return ISC_R_INVALIDARG;
+ return ISC_R_BADKEY;
}
nstatp->nscount = 1;
#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 */
/*
#include <stdlib.h>
#include <string.h>
-#include <isc/list.h>
+#include <isc-dhcp/list.h>
#include "minires/minires.h"
#include "arpa/nameser.h"
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);
/* 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);
$(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; \
$(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]$$//'`; \
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
#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;
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)
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)
#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;
}
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;
}
#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. */
}
}
#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) {
rc_history [i].refcnt);
}
-void dump_rc_history ()
+void dump_rc_history (void *addr)
{
int i;
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;
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,
}
*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;
}
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;
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
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;
}
*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;
}
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
}
--(*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;
}
*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;
}
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
}
--((*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:
}
*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;
}
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
}
--((*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);
}
}
*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;
}
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
}
--((*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,
}
*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;
}
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
}
--((*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);
}
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. */
#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,
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;
}
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;
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;
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,
}
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) { }
return ISC_R_NOPERM;
return ISC_R_UNEXPECTED;
}
+ obj -> local_addr = local_sin;
}
#if defined (HAVE_SETFD)
char *s = buf;
omapi_connection_object_t *obj;
isc_result_t status;
+ int i;
if (length != ((sizeof connect_index) +
(sizeof remote.sin_port) +
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;
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) {
/* 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,
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;
+}
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
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)
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
/* 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;
}
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;
}
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)
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;
+}
#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>
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++;
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,
} else {
table -> buckets [hashno] = bp -> next;
}
- if (table -> dereferencer) {
+ if (bp -> value && table -> dereferencer) {
foo = &bp -> value;
(*(table -> dereferencer)) (foo, file, line);
}
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;
}
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
"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);
-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>
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;
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);
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);
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);
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";
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";
# 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.
}
}
+ if (!omo) {
+ omapi_protocol_reference (&m -> protocol_object, p, MDL);
+ }
return ISC_R_SUCCESS;
}
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;
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
}
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:
"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)
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;
#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>
return ISC_R_TIMEDOUT;
case ECONNRESET:
- return ISC_R_CONNREFUSED;
+ return ISC_R_CONNRESET;
case ENOBUFS:
return ISC_R_NOSPACE;
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);
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);
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
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.
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
#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"
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;
}
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,
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
#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 */
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)
(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,
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);
}
}
}
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));
#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"
if (!leaseconf_initialized && ttype == trace_readleases_type) {
db_startup (0);
leaseconf_initialized = 1;
+ postdb_startup ();
}
}
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. */
share -> subnets -> group -> authoritative;
enter_shared_network (share);
}
+ shared_network_dereference (&share, MDL);
return 1;
case VENDOR_CLASS:
if (!multi) {
executable_statement_reference (&ep -> next,
et, MDL);
+ executable_statement_dereference (&et, MDL);
return 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;
}
}
option_cache (&cp -> address,
(struct data_string *)0, expr,
- (struct option *)0);
+ (struct option *)0, MDL);
expression_dereference (&expr, MDL);
break;
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;
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;
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) {
}
} else {
parse_warn (cfile, "Expecting string or hex list.");
- class_dereference (&pc, MDL);
+ if (pc)
+ class_dereference (&pc, MDL);
return 0;
}
}
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,
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. */
return 0;
}
status = option_cache (oc, (struct data_string *)0, expr,
- (struct option *)0);
+ (struct option *)0, MDL);
expression_dereference (&expr, MDL);
return status;
}
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);
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:
skip_to_semi (cfile);
return 0;
}
+ expression_dereference (&data, MDL);
parse_semi (cfile);
return status;
}
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
#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"
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. */
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;
if (errors)
log_info ("write_lease: unable to write lease %s",
piaddr (lease -> ip_addr));
+ if (errors)
+ lease_file_is_corrupt = 1;
return !errors;
}
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;
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;
}
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;
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;
}
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)
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;
if (errors) {
log_info ("write_failover_state: unable to write state %s",
state -> name);
+ lease_file_is_corrupt = 1;
return 0;
}
return 1;
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);
fprintf(db_file, ";");
#endif
- class -> dirty = 0;
+ class -> dirty = !errors;
+ if (errors)
+ lease_file_is_corrupt = 1;
return !errors;
}
}
}
-void new_lease_file ()
+int new_lease_file ()
{
char newfname [512];
char backfname [512];
/* If we already have an open database, close it. */
if (db_file) {
fclose (db_file);
+ db_file = (FILE *)0;
}
/* Make a temporary 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)
#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"
#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*
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)
}
-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;
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,
}
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.
*/
*/
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;
}
/*
*/
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)
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;
}
/*
* 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;
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;
}
#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"
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
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";
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,
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);
/* 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
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);
}
((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,
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);
}
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);
}
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);
((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);
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);
+ }
}
/* 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);
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;
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,
((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,
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);
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);
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);
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);
((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);
((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,
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,
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 &&
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);
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 ||
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) {
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 &&
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);
(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
*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. */
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) &&
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.");
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~.
#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[] =
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;
int quiet = 0;
char *server = (char *)0;
isc_result_t result;
- omapi_object_t *listener;
unsigned seed;
struct interface_info *ip;
struct parse *parse;
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
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... */
#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) {
}
#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;
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 ();
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);
#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 ()
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 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",
"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;
+}
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" {
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
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
#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"
#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;
}
}
-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)
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";
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;
}
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");
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;
}
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
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) {
} 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,
/* 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;
break;
case startup:
- if (saved_state != startup)
- state -> saved_state = saved_state;
add_timeout (cur_time + 15,
dhcp_failover_startup_timeout,
state,
(tvref_t)omapi_object_reference,
(tvunref_t)
omapi_object_dereference);
+ else
+ dhcp_failover_recover_done (state);
break;
case recover:
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;
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;
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);
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 ();
}
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;
}
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) {
}
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) {
(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
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. */
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)
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
}
}
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:
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) {
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:
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;
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
#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"
}
+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;
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,
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) {
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 {
/* 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
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");
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,
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");
}
}
}
-
-#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)
{
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. */
/* Write all interesting leases to permanent storage. */
-void write_leases ()
+int write_leases ()
{
struct lease *l;
struct shared_network *s;
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;
}
}
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;
}
}
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;
}
}
}
#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. */
l -> uid_len ||
(l -> binding_state != FTS_FREE)) {
if (!write_lease (l))
- log_fatal ("Can't rewrite lease database");
+ return 0;
num_written++;
}
}
}
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)
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 */
#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;
"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,
/* 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. */
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;
}
(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. */
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)
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;
}
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) {
if (status == ISC_R_SUCCESS)
return status;
}
- if (updatep)
- return ISC_R_SUCCESS;
return ISC_R_NOTFOUND;
}
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))
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) {
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;
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;
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;
}
return status;
}
- return ISC_R_NOTFOUND;
+ return ISC_R_UNKNOWNATTRIBUTE;
}
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)
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;
}
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) {
return status;
}
- return ISC_R_NOTFOUND;
+ return ISC_R_UNKNOWNATTRIBUTE;
}
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;
}
return status;
}
- return ISC_R_NOTFOUND;
+ return ISC_R_UNKNOWNATTRIBUTE;
}
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;
}
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,
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;
}
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);
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,
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: */
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
#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)
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;
const char *file;
int line;
{
+ if (permit -> type == permit_class)
+ class_dereference (&permit -> class, MDL);
dfree (permit, file, line);
}
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
#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"
{ "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;
{ "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 },
{ "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 [] = {
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++) {
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++) {
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;
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;
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;
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;
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;
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;
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;
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 {
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;
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;
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;