--- /dev/null
+Objects that need to be tracked:
+
+Node Names
+ - A node name is the name of a node attached to a network.
+ - Nodes can be any type of hardware that is attached to a
+ network and requires one or more addresses.
+ - Node names may be associated with a specific hardware
+ address or set of hardware addresses.
+ - Node names may also be associated with a specific IP address
+ or set of IP addresses.
+
+Interfaces
+ - An interface is known by its hardware address, which must be
+ unique. This works for Ethernet, but may be complicated by
+ PPP (?). What about IBM token ring and FDDI?
+ - An interface may be associated with a specific node name,
+ a specific address, or both.
+
+IP Addresses
+ - An interface may be associated with a single IP address.
+ 4.4BSD supports IP aliasing so that a single interface can
+ have multiple addresses, but this probably isn't worth
+ supporting explicitly.
+
+Transitions
+ - A machine may be moved to a different net
+ - If the machine's personality hasn't changed, we may want
+ to assign it a new IP address but keep the same node name.
+ - If the machine's personality *has* changed, we need to
+ assign it both a new node name and a new IP address.
+ - A machine's hardware may be upgraded.
+ - The new machine should get the old IP Address and Node Name.
+ - The old machine may need a new IP address and Node Name.
+
+Static Configuration File
+ - Addresses which server may assign to arbitrary hosts
+ - Addresses which are statically assigned to particular
+ hardware, but which server may need to provide
+ - Allowable lease length for a given address
+
+Dynamic Server Database
+ - Addresses which have been dynamically assigned
+ - The hardware addresses to which they have been assigned
+ - The lease expiry time on each assigned address
+
+Sample static configuration file:
+
+# One 12-bit subnet, may assign addresses 240 through 4190.
+network 16.3.16.0 netmask 255.255.240.0
+ address-range 240 through 4190;
+# One 4-bit subnet, may assign addresses 2 through 6.
+network 192.5.5.16 netmask 255.255.255.240
+ address-range 192.5.5.2 through 192.5.5.6;
+# 16 12-bit subnets, may assign addresses 128 through 4190 of each network.
+# Address ranges are shared with listed servers [TBI].
+networks 16.1.0.0 through 16.1.240.0 netmask 255.255.240.0
+ address-range 0.128 through 31.240
+ shared-with dhcp-1.pa.dec.com, dhcp-2.pa.dec.com, dhcp-3.pa.dec.com;
+
+
+
+Sample database file:
+
+# January 12, 1996, 16:42:37
+timestamp 1049897235;
+lease 204.254.239.7 starts 1049897235 ends 1049957235
+ hardware ethernet 08:00:2b:4c:29:35
+ uid 08:00:2b:4c:29:35 host minuet class decstations;
+lease 204.254.239.8 starts 1049897235 ends 1049957235
+ hardware ethernet 08:00:2b:22:09:27
+ uid 08:00:2b:22:09:27 class decstations;
+lease 204.254.239.9 starts 1049897235 ends 1049957235
+ hardware ethernet 08:00:42:29:09:42
+ uid 08:00:42:29:09:42;
+lease 204.254.239.240 starts 1049897235 ends 1049957235
+ uid 50:50:50:3a:6b:69:6d:62:61 host kimba-ppp;
+
+
--- /dev/null
+SRCS = dhcpd.c options.c errwarn.c convert.c conflex.c confpars.c \
+ tree.c memory.c bootp.c dhcp.c alloc.c print.c socket.c \
+ hash.c tables.c
+PROG = dhcpd
+
+.include <bsd.prog.mk>
+
+CFLAGS += -DDEBUG -g
--- /dev/null
+/* alloc.c
+
+ Memory allocation...
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 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;
+
+VOIDPTR dmalloc (size, name)
+ int size;
+ char *name;
+{
+ VOIDPTR foo = (VOIDPTR)malloc (size);
+ if (!foo)
+ warn ("No memory for %s.\n");
+ return foo;
+}
+
+void dfree (ptr, name)
+ VOIDPTR ptr;
+ char *name;
+{
+ free (ptr);
+}
+
+struct packet *new_packet (name)
+ char *name;
+{
+ struct packet *rval;
+ rval = (struct packet *)dmalloc (sizeof (struct packet), name);
+ return rval;
+}
+
+struct dhcp_packet *new_dhcp_packet (name)
+ char *name;
+{
+ struct dhcp_packet *rval;
+ rval = (struct dhcp_packet *)dmalloc (sizeof (struct dhcp_packet),
+ name);
+ return rval;
+}
+
+struct tree *new_tree (name)
+ char *name;
+{
+ struct tree *rval = dmalloc (sizeof (struct tree), name);
+ return rval;
+}
+
+struct tree_cache *new_tree_cache (name)
+ char *name;
+{
+ struct tree_cache *rval = dmalloc (sizeof (struct tree_cache), name);
+ return rval;
+}
+
+struct hash_table *new_hash_table (count, name)
+ int count;
+ char *name;
+{
+ struct hash_table *rval = dmalloc (sizeof (struct hash_table)
+ - (DEFAULT_HASH_SIZE
+ * sizeof (struct hash_bucket *))
+ + (count
+ * sizeof (struct hash_bucket *)),
+ name);
+ rval -> hash_count = count;
+ return rval;
+}
+
+struct hash_bucket *new_hash_bucket (name)
+ char *name;
+{
+ struct hash_bucket *rval = dmalloc (sizeof (struct hash_bucket), name);
+ return rval;
+}
+
+struct lease *new_leases (n, name)
+ int n;
+ char *name;
+{
+ struct lease *rval = dmalloc (n * sizeof (struct lease), name);
+ return rval;
+}
+
+struct lease *new_lease (name)
+ char *name;
+{
+ struct lease *rval = dmalloc (sizeof (struct lease), name);
+ return rval;
+}
+
+struct subnet *new_subnet (name)
+ char *name;
+{
+ struct subnet *rval = dmalloc (sizeof (struct subnet), name);
+ return rval;
+}
+
+void free_subnet (ptr, name)
+ struct subnet *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_lease (ptr, name)
+ struct lease *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_hash_bucket (ptr, name)
+ struct hash_bucket *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_hash_table (ptr, name)
+ struct hash_table *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_tree_cache (ptr, name)
+ struct tree_cache *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_packet (ptr, name)
+ struct packet *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_dhcp_packet (ptr, name)
+ struct dhcp_packet *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_tree (ptr, name)
+ struct tree *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
--- /dev/null
+/* bootp.c
+
+ BOOTP Protocol support. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+void bootp (packet)
+ struct packet *packet;
+{
+ int result;
+ struct host_decl *hp = find_host_by_addr (packet -> raw -> htype,
+ packet -> raw -> chaddr,
+ packet -> raw -> hlen);
+ struct dhcp_packet *reply;
+ struct sockaddr_in to;
+
+ /* If the packet is from a host we don't know, drop it on
+ the floor. XXX */
+ if (!hp) {
+ note ("Can't find record for BOOTP host %s",
+ print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr));
+ return;
+ }
+ /* If we don't have a fixed address for it, drop it on the floor.
+ XXX */
+ if (!hp -> fixed_addr || !tree_evaluate (hp -> fixed_addr)) {
+ note ("No fixed address for BOOTP host %s (%s)",
+ print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr),
+ hp -> name);
+ return;
+ }
+ reply = new_dhcp_packet ("bootp");
+ if (!reply) {
+ free_dhcp_packet (packet -> raw, "bootp");
+ free_packet (packet, "bootp");
+ return;
+ }
+ /* Take the fields that we care about... */
+ reply -> op = BOOTREPLY;
+ reply -> htype = packet -> raw -> htype;
+ reply -> hlen = packet -> raw -> hlen;
+ memcpy (reply -> chaddr, packet -> raw -> chaddr, reply -> hlen);
+ memset (&reply -> chaddr [reply -> hlen], 0,
+ (sizeof reply -> chaddr) - reply -> hlen);
+ reply -> hops = packet -> raw -> hops;
+ reply -> xid = packet -> raw -> xid;
+ reply -> secs = packet -> raw -> secs;
+ reply -> flags = 0;
+ reply -> ciaddr = packet -> raw -> ciaddr;
+ if (!tree_evaluate (hp -> fixed_addr))
+ warn ("tree_evaluate failed.");
+ debug ("fixed_addr: %x %d %d %d %d %x",
+ *(int *)(hp -> fixed_addr -> value), hp -> fixed_addr -> len,
+ hp -> fixed_addr -> buf_size, hp -> fixed_addr -> timeout,
+ hp -> fixed_addr -> tree);
+ memcpy (&reply -> yiaddr, hp -> fixed_addr -> value,
+ sizeof reply -> yiaddr);
+ reply -> siaddr.s_addr = pick_interface (packet);
+ reply -> giaddr = packet -> raw -> giaddr;
+ if (hp -> server_name) {
+ strncpy (reply -> sname, hp -> server_name,
+ (sizeof reply -> sname) - 1);
+ reply -> sname [(sizeof reply -> sname) - 1] = 0;
+ }
+ if (hp -> filename) {
+ strncpy (reply -> file, hp -> filename,
+ (sizeof reply -> file) - 1);
+ reply -> file [(sizeof reply -> file) - 1] = 0;
+ }
+ reply -> options [0] = 0;
+ /* XXX gateways? */
+ to.sin_port = server_port;
+
+#if 0
+ if (packet -> raw -> flags & BOOTP_BROADCAST)
+#endif
+ to.sin_addr.s_addr = INADDR_BROADCAST;
+#if 0
+ else
+ to.sin_addr.s_addr = INADDR_ANY;
+#endif
+
+ memset (reply -> options, 0, sizeof (reply -> options));
+ /* If we got the magic cookie, send it back. */
+ if (packet -> options_valid)
+ memcpy (reply -> options, packet -> raw -> options, 4);
+ to.sin_port = packet -> client.sin_port;
+ to.sin_family = AF_INET;
+ to.sin_len = sizeof to;
+ memset (to.sin_zero, 0, sizeof to.sin_zero);
+
+ note ("Sending bootp reply to %s, port %d",
+ inet_ntoa (to.sin_addr), htons (to.sin_port));
+
+ errno = 0;
+ result = sendto (packet -> client_sock, reply,
+ ((char *)(&reply -> options) - (char *)reply) + 64,
+ 0, (struct sockaddr *)&to, sizeof to);
+ if (result < 0)
+ warn ("sendto: %m");
+}
--- /dev/null
+/* cdefs.h
+
+ Standard C definitions... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#if defined (__GNUC__) || defined (__STDC__)
+#define PROTO(x) x
+#define KandR(x)
+#define ANSI_DECL(x) x
+#define INLINE inline
+#else
+#define PROTO(x) ()
+#define KandR(x) x
+#define ANSI_DECL(x)
+#define INLINE
+#endif
--- /dev/null
+/* bsdos.h
+
+ System dependencies for BSD/os... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <paths.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <limits.h>
+
+#include <netdb.h>
+extern int h_errno;
+
+#include <net/if.h>
+
+/* Time stuff... */
+#include <sys/time.h>
+#define TIME struct timeval
+#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
+#define TIME_DIFF_US(high, low) \
+ (((high) -> tv_sec - (low) -> tv_sec) * 1000000 \
+ + ((high) -> tv_usec - (low) -> tv_usec))
+#define SET_TIME(x, y) (((x) -> tv_sec = ((y) / 1000000)), \
+ ((x) -> tv_usec = ((y) % 1000000)))
+#define DELAY() usleep (2000)
+#define DELAY_ONE_SECOND() usleep (1000000)
+
+/* Login stuff... */
+#include <utmp.h>
+#include <sys/syslimits.h>
+#define _PATH_LOGIN "/usr/bin/login"
+#define SETLOGIN(x) setlogin (x)
+#define SETUID(x) setuid (x)
+#define SETGID(x) (setgroups (0, &x), setgid (x))
+#define USER_MAX UT_NAMESIZE
+
+/* Varargs stuff... */
+#include <stdarg.h>
+#define VA_DOTDOTDOT ...
+#define va_dcl
+#define VA_start(list, last) va_start (list, last)
+
+#define _PATH_MPOOL_PID "/var/run/mpoold.pid"
+
+#define EOL '\n'
+#define VOIDPTR void *
+
+/* Time stuff... */
+#include <sys/time.h>
+#define TIME struct timeval
+#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
+#define TIME_DIFF(high, low) \
+ (((high) -> tv_sec == (low) -> tv_sec) \
+ ? ((high) -> tv_usec > (low) -> tv_usec \
+ ? 1 : (((high) -> tv_usec == (low) -> tv_usec) ? 0 : -1)) \
+ : (high) -> tv_sec - (low) -> tv_sec)
+#define SET_TIME(x, y) (((x) -> tv_sec = ((y))), ((x) -> tv_usec = 0))
+#define ADD_TIME(d, s1, s2) { \
+ (d) -> tv_usec = (s1) -> tv_usec + (s2) -> tv_usec; \
+ if ((d) -> tv_usec > 1000000 || (d) -> tv_usec < -1000000) { \
+ (d) -> tv_sec = (d) -> tv_usec / 1000000; \
+ (d) -> tv_usec %= 1000000; \
+ } else \
+ (d) -> tv_sec = 0; \
+ (d) -> tv_sec += (s1) -> tv_sec + (s2) -> tv_sec; \
+ }
+#define SET_MAX_TIME(x) (((x) -> tv_sec = INT_MAX), \
+ ((x) -> tv_usec = 999999))
--- /dev/null
+/* netbsd.h
+
+ System dependencies for NetBSD... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <paths.h>
+#include <errno.h>
+#include <unistd.h>
+#include <setjmp.h>
+#include <limits.h>
+
+#include <sys/wait.h>
+#include <signal.h>
+
+#include <netdb.h>
+extern int h_errno;
+
+#include <net/if.h>
+
+/* Varargs stuff... */
+#include <stdarg.h>
+#define VA_DOTDOTDOT ...
+#define va_dcl
+#define VA_start(list, last) va_start (list, last)
+
+#define _PATH_DHCPD_PID "/var/run/dhcpd.pid"
+
+#define EOL '\n'
+#define VOIDPTR void *
+
+/* Time stuff... */
+#include <sys/time.h>
+#define TIME time_t
+#define GET_TIME(x) time ((x))
+#define TIME_DIFF(high, low) (*(high) - *(low))
+#define SET_TIME(x, y) (*(x) = (y))
+#define ADD_TIME(d, s1, s2) (*(d) = *(s1) + *(s2))
+#define SET_MAX_TIME(x) (*(x) = INT_MAX)
--- /dev/null
+/* sunos4.h
+
+ System dependencies for SunOS 4 (tested on 4.1.4)... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <limits.h>
+
+#include <netdb.h>
+extern int h_errno;
+
+#include <net/if.h>
+
+/* Varargs stuff... */
+#include <varargs.h>
+#define VA_DOTDOTDOT va_alist
+#define VA_start(list, last) va_start (list)
+
+#define vsnprintf(buf, size, fmt, list) vsprintf (buf, fmt, list)
+
+#define EOL '\n'
+#define VOIDPTR void *
+
+/* Time stuff... */
+#include <sys/time.h>
+#define TIME struct timeval
+#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
+#define TIME_DIFF(high, low) \
+ (((high) -> tv_sec == (low) -> tv_sec) \
+ ? ((high) -> tv_usec > (low) -> tv_usec \
+ ? 1 : (((high) -> tv_usec == (low) -> tv_usec) ? 0 : -1)) \
+ : (high) -> tv_sec - (low) -> tv_sec)
+#define SET_TIME(x, y) (((x) -> tv_sec = ((y))), ((x) -> tv_usec = 0))
+#define ADD_TIME(d, s1, s2) { \
+ (d) -> tv_usec = (s1) -> tv_usec + (s2) -> tv_usec; \
+ if ((d) -> tv_usec > 1000000 || (d) -> tv_usec < -1000000) { \
+ (d) -> tv_sec = (d) -> tv_usec / 1000000; \
+ (d) -> tv_usec %= 1000000; \
+ } else \
+ (d) -> tv_sec = 0; \
+ (d) -> tv_sec += (s1) -> tv_sec + (s2) -> tv_sec; \
+ }
+#define SET_MAX_TIME(x) (((x) -> tv_sec = INT_MAX), \
+ ((x) -> tv_usec = 999999))
--- /dev/null
+/* alloc.c
+
+ Memory allocation...
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 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;
+
+VOIDPTR dmalloc (size, name)
+ int size;
+ char *name;
+{
+ VOIDPTR foo = (VOIDPTR)malloc (size);
+ if (!foo)
+ warn ("No memory for %s.\n");
+ return foo;
+}
+
+void dfree (ptr, name)
+ VOIDPTR ptr;
+ char *name;
+{
+ free (ptr);
+}
+
+struct packet *new_packet (name)
+ char *name;
+{
+ struct packet *rval;
+ rval = (struct packet *)dmalloc (sizeof (struct packet), name);
+ return rval;
+}
+
+struct dhcp_packet *new_dhcp_packet (name)
+ char *name;
+{
+ struct dhcp_packet *rval;
+ rval = (struct dhcp_packet *)dmalloc (sizeof (struct dhcp_packet),
+ name);
+ return rval;
+}
+
+struct tree *new_tree (name)
+ char *name;
+{
+ struct tree *rval = dmalloc (sizeof (struct tree), name);
+ return rval;
+}
+
+struct tree_cache *new_tree_cache (name)
+ char *name;
+{
+ struct tree_cache *rval = dmalloc (sizeof (struct tree_cache), name);
+ return rval;
+}
+
+struct hash_table *new_hash_table (count, name)
+ int count;
+ char *name;
+{
+ struct hash_table *rval = dmalloc (sizeof (struct hash_table)
+ - (DEFAULT_HASH_SIZE
+ * sizeof (struct hash_bucket *))
+ + (count
+ * sizeof (struct hash_bucket *)),
+ name);
+ rval -> hash_count = count;
+ return rval;
+}
+
+struct hash_bucket *new_hash_bucket (name)
+ char *name;
+{
+ struct hash_bucket *rval = dmalloc (sizeof (struct hash_bucket), name);
+ return rval;
+}
+
+struct lease *new_leases (n, name)
+ int n;
+ char *name;
+{
+ struct lease *rval = dmalloc (n * sizeof (struct lease), name);
+ return rval;
+}
+
+struct lease *new_lease (name)
+ char *name;
+{
+ struct lease *rval = dmalloc (sizeof (struct lease), name);
+ return rval;
+}
+
+struct subnet *new_subnet (name)
+ char *name;
+{
+ struct subnet *rval = dmalloc (sizeof (struct subnet), name);
+ return rval;
+}
+
+void free_subnet (ptr, name)
+ struct subnet *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_lease (ptr, name)
+ struct lease *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_hash_bucket (ptr, name)
+ struct hash_bucket *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_hash_table (ptr, name)
+ struct hash_table *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_tree_cache (ptr, name)
+ struct tree_cache *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_packet (ptr, name)
+ struct packet *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_dhcp_packet (ptr, name)
+ struct dhcp_packet *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
+
+void free_tree (ptr, name)
+ struct tree *ptr;
+ char *name;
+{
+ dfree ((VOIDPTR)ptr, name);
+}
--- /dev/null
+/* conflex.c
+
+ Lexical scanner for dhcpd config file... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+#include "dhctoken.h"
+#include <ctype.h>
+
+static int line;
+static int lpos;
+int tlpos;
+int tline;
+static int token;
+static int ugflag;
+static char *tval;
+static char tokbuf [1500];
+
+static int get_char PROTO ((FILE *));
+static int get_token PROTO ((FILE *));
+static void skip_to_eol PROTO ((FILE *));
+static int read_string PROTO ((FILE *));
+static int read_number PROTO ((int, FILE *));
+static int read_num_or_atom PROTO ((int, FILE *));
+static int intern PROTO ((char *, int));
+
+static int get_char (cfile)
+ FILE *cfile;
+{
+ char c = getc (cfile);
+ if (!ugflag) {
+ if (c == EOL) {
+ line++;
+ lpos = 1;
+ } else {
+ lpos++;
+ }
+ } else
+ ugflag = 0;
+ return c;
+}
+
+static int get_token (cfile)
+ FILE *cfile;
+{
+ int c;
+ int i;
+ int ttok;
+
+ do {
+ c = get_char (cfile);
+ if (isascii (c) && isspace (c))
+ continue;
+ if (c == '#') {
+ skip_to_eol (cfile);
+ continue;
+ }
+ tlpos = lpos;
+ tline = line;
+ if (c == '"') {
+ ttok = read_string (cfile);
+ break;
+ }
+ if (isascii (c) && isdigit (c)) {
+ ttok = read_number (c, cfile);
+ break;
+ } else if (isascii (c) && isalpha (c)) {
+ ttok = read_num_or_atom (c, cfile);
+ break;
+ } else {
+ tval = 0;
+ ttok = c;
+ break;
+ }
+ } while (1);
+ return ttok;
+}
+
+int next_token (rval, cfile)
+ char **rval;
+ FILE *cfile;
+{
+ int rv;
+
+ if (token) {
+ rv = token;
+ token = 0;
+ } else {
+ rv = get_token (cfile);
+ }
+ if (rval)
+ *rval = tval;
+ return rv;
+}
+
+int peek_token (rval, cfile)
+ char **rval;
+ FILE *cfile;
+{
+ if (!token)
+ token = get_token (cfile);
+ if (rval)
+ *rval = tval;
+ return token;
+}
+
+static void skip_to_eol (cfile)
+ FILE *cfile;
+{
+ int c;
+ do {
+ c = get_char (cfile);
+ if (c == EOF)
+ return;
+ if (c == EOL) {
+ ungetc (c, cfile);
+ ugflag = 1;
+ return;
+ }
+ } while (1);
+}
+
+static int read_string (cfile)
+ FILE *cfile;
+{
+ int i;
+ int bs = 0;
+ int c;
+
+ for (i = 0; i < sizeof tokbuf; i++) {
+ c = get_char (cfile);
+ if (c == EOF) {
+ parse_warn ("eof in string constant");
+ break;
+ }
+ if (bs) {
+ bs = 0;
+ tokbuf [i] = c;
+ } else if (c == '\\')
+ bs = 1;
+ else if (c == '"')
+ break;
+ else
+ tokbuf [i] = c;
+ }
+ /* Normally, I'd feel guilty about this, but we're talking about
+ strings that'll fit in a DHCP packet here... */
+ if (i == sizeof tokbuf) {
+ parse_warn ("string constant larger than internal buffer");
+ --i;
+ }
+ tokbuf [i] = 0;
+ tval = tokbuf;
+ return STRING;
+}
+
+static int read_number (c, cfile)
+ int c;
+ FILE *cfile;
+{
+ int seenx = 0;
+ int i = 0;
+ tokbuf [i++] = c;
+ for (; i < sizeof tokbuf; i++) {
+ c = get_char (cfile);
+ if (!seenx && c == 'x')
+ seenx = 1;
+ else if (!isascii (c) || !isxdigit (c)) {
+ ungetc (c, cfile);
+ ugflag = 1;
+ break;
+ }
+ tokbuf [i] = c;
+ }
+ if (i == sizeof tokbuf) {
+ parse_warn ("numeric token larger than internal buffer");
+ --i;
+ }
+ tokbuf [i] = 0;
+ tval = tokbuf;
+ return NUMBER;
+}
+
+static int read_num_or_atom (c, cfile)
+ int c;
+ FILE *cfile;
+{
+ int i = 0;
+ int rv = NUMBER_OR_ATOM;
+ tokbuf [i++] = c;
+ for (; i < sizeof tokbuf; i++) {
+ c = get_char (cfile);
+ if (!isascii (c) ||
+ (c != '-' && c != '_' && !isalnum (c))) {
+ ungetc (c, cfile);
+ ugflag = 1;
+ break;
+ }
+ if (!isxdigit (c))
+ rv = ATOM;
+ tokbuf [i] = c;
+ }
+ if (i == sizeof tokbuf) {
+ parse_warn ("token larger than internal buffer");
+ --i;
+ }
+ tokbuf [i] = 0;
+ tval = tokbuf;
+ return intern (tval, rv);
+}
+
+static int intern (atom, dfv)
+ char *atom;
+ int dfv;
+{
+ switch (atom [0]) {
+ case 'h':
+ if (!strcasecmp (atom + 1, "ost"))
+ return HOST;
+ if (!strcasecmp (atom + 1, "ardware"))
+ return HARDWARE;
+ break;
+ case 'f':
+ if (!strcasecmp (atom + 1, "ilename"))
+ return FILENAME;
+ if (!strcasecmp (atom + 1, "ixed-address"))
+ return FIXED_ADDR;
+ break;
+ case 'e':
+ if (!strcasecmp (atom + 1, "thernet"))
+ return ETHERNET;
+ break;
+ case 'o':
+ if (!strcasecmp (atom + 1, "ption"))
+ return OPTION;
+ break;
+ }
+ return dfv;
+}
--- /dev/null
+/* convert.c
+
+ Safe copying of option values into and out of the option buffer, which
+ can't be assumed to be aligned. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+unsigned long getULong (buf)
+ unsigned char *buf;
+{
+ unsigned long ibuf;
+
+ memcpy (&ibuf, buf, sizeof (unsigned long));
+ return ntohl (ibuf);
+}
+
+long getLong (buf)
+ unsigned char *buf;
+{
+ long ibuf;
+
+ memcpy (&ibuf, buf, sizeof (long));
+ return ntohl (ibuf);
+}
+
+unsigned short getUShort (buf)
+ unsigned char *buf;
+{
+ unsigned short ibuf;
+
+ memcpy (&ibuf, buf, sizeof (unsigned short));
+ return ntohs (ibuf);
+}
+
+short getShort (buf)
+ unsigned char *buf;
+{
+ short ibuf;
+
+ memcpy (&ibuf, buf, sizeof (short));
+ return ntohs (ibuf);
+}
+
+void putULong (obuf, val)
+ unsigned char *obuf;
+ unsigned long val;
+{
+ unsigned long tmp = htonl (val);
+ memcpy (obuf, &tmp, sizeof tmp);
+}
+
+void putLong (obuf, val)
+ unsigned char *obuf;
+ long val;
+{
+ long tmp = htonl (val);
+ memcpy (obuf, &tmp, sizeof tmp);
+}
+
+void putUShort (obuf, val)
+ unsigned char *obuf;
+ unsigned short val;
+{
+ unsigned short tmp = htonl (val);
+ memcpy (obuf, &tmp, sizeof tmp);
+}
+
+void putShort (obuf, val)
+ unsigned char *obuf;
+ short val;
+{
+ short tmp = htonl (val);
+ memcpy (obuf, &tmp, sizeof tmp);
+}
+
--- /dev/null
+/* errwarn.c
+
+ Errors and warnings... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 RadioMail Corporation. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+#include <syslog.h>
+#include <errno.h>
+
+static void do_percentm PROTO ((char *obuf, char *ibuf));
+
+static char mbuf [1024];
+static char fbuf [1024];
+
+/* Log an error message, then exit... */
+
+int error (ANSI_DECL(char *) fmt, VA_DOTDOTDOT)
+ KandR (char *fmt;)
+ va_dcl
+{
+ va_list list;
+ extern int logged_in;
+
+ do_percentm (fbuf, fmt);
+
+ VA_start (list, fmt);
+ vsnprintf (mbuf, sizeof mbuf, fbuf, list);
+ va_end (list);
+#ifndef DEBUG
+ syslog (LOG_ERR, mbuf);
+#else
+ write (1, mbuf, strlen (mbuf));
+ write (1, "\n", 1);
+#endif
+
+ cleanup ();
+ exit (1);
+}
+
+/* Log a warning message... */
+
+int warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+ KandR (char *fmt;)
+ va_dcl
+{
+ va_list list;
+
+ do_percentm (fbuf, fmt);
+
+ VA_start (list, fmt);
+ vsnprintf (mbuf, sizeof mbuf, fbuf, list);
+ va_end (list);
+#ifndef DEBUG
+ syslog (LOG_ERR, mbuf);
+#else
+ write (1, mbuf, strlen (mbuf));
+ write (1, "\n", 1);
+#endif
+ return 0;
+}
+
+/* Log a note... */
+
+int note (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+ KandR (char *fmt;)
+ va_dcl
+{
+ va_list list;
+
+ do_percentm (fbuf, fmt);
+
+ VA_start (list, fmt);
+ vsnprintf (mbuf, sizeof mbuf, fbuf, list);
+ va_end (list);
+#ifndef DEBUG
+ syslog (LOG_INFO, mbuf);
+#else
+ write (1, mbuf, strlen (mbuf));
+ write (1, "\n", 1);
+#endif
+ return 0;
+}
+
+/* Log a debug message... */
+
+int debug (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+ KandR (char *fmt;)
+ va_dcl
+{
+ va_list list;
+
+ do_percentm (fbuf, fmt);
+
+ VA_start (list, fmt);
+ vsnprintf (mbuf, sizeof mbuf, fbuf, list);
+ va_end (list);
+#ifndef DEBUG
+ syslog (LOG_DEBUG, mbuf);
+#else
+ write (1, mbuf, strlen (mbuf));
+ write (1, "\n", 1);
+#endif
+ return 0;
+}
+
+/* Find %m in the input string and substitute an error message string. */
+
+static void do_percentm (obuf, ibuf)
+ char *obuf;
+ char *ibuf;
+{
+ char *s = ibuf;
+ char *p = obuf;
+ int infmt = 0;
+
+ while (*s)
+ {
+ if (infmt)
+ {
+ if (*s == 'm')
+ {
+ strcpy (p - 1, strerror (errno));
+ p += strlen (p);
+ ++s;
+ }
+ else
+ *p++ = *s++;
+ infmt = 0;
+ }
+ else
+ {
+ if (*s == '%')
+ infmt = 1;
+ *p++ = *s++;
+ }
+ }
+ *p = 0;
+}
+
+
+int parse_warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+ KandR (char *fmt;)
+ va_dcl
+{
+ extern int tline, tlpos;
+ va_list list;
+
+ do_percentm (mbuf, fmt);
+ snprintf (fbuf, sizeof fbuf, "dhcpd.conf line %d char %d: %s",
+ tline, tlpos, mbuf);
+
+ VA_start (list, fmt);
+ vsnprintf (mbuf, sizeof mbuf, fbuf, list);
+ va_end (list);
+#ifndef DEBUG
+ syslog (LOG_ERROR, mbuf);
+#else
+ write (1, mbuf, strlen (mbuf));
+ write (1, "\n", 1);
+#endif
+ return 0;
+}
--- /dev/null
+/* hash.c
+
+ Routines for manipulating hash tables... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+struct hash_table *new_hash ()
+{
+ struct hash_table *rv = new_hash_table (DEFAULT_HASH_SIZE, "new_hash");
+ if (!rv)
+ return rv;
+ memset (&rv -> buckets, 0,
+ DEFAULT_HASH_SIZE * sizeof (struct hash_bucket *));
+ return rv;
+}
+
+static INLINE do_hash (name, len, size)
+ char *name;
+ int len;
+ int size;
+{
+ register int accum = 0;
+ register unsigned char *s = (unsigned char *)name;
+ int i = len;
+ if (i) {
+ while (i--) {
+ /* Add the character in... */
+ accum += *s++;
+ /* Add carry back in... */
+ while (accum > 255) {
+ accum = (accum & 255) + (accum >> 8);
+ }
+ }
+ } else {
+ while (*s) {
+ /* Add the character in... */
+ accum += *s++;
+ /* Add carry back in... */
+ while (accum > 255) {
+ accum = (accum & 255) + (accum >> 8);
+ }
+ }
+ }
+ return accum % size;
+}
+
+void add_hash (table, name, len, pointer)
+ struct hash_table *table;
+ int len;
+ char *name;
+ unsigned char *pointer;
+{
+ int hashno = do_hash (name, len, table -> hash_count);
+ struct hash_bucket *bp = new_hash_bucket ("add_hash");
+ if (!bp) {
+ warn ("Can't add %s to hash table.", name);
+ return;
+ }
+ bp -> name = name;
+ bp -> value = pointer;
+ bp -> next = table -> buckets [hashno];
+ table -> buckets [hashno] = bp;
+}
+
+void delete_hash_entry (table, name, len)
+ struct hash_table *table;
+ int len;
+ char *name;
+{
+ int hashno = do_hash (name, len, table -> hash_count);
+ struct hash_bucket *bp, *pbp = (struct hash_bucket *)0;
+
+ /* Go through the list looking for an entry that matches;
+ if we find it, delete it. */
+ for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
+ if ((!bp -> len && !strcmp (bp -> name, name)) ||
+ (bp -> len == len &&
+ !memcmp (bp -> name, name, len))) {
+ if (pbp) {
+ pbp -> next = bp -> next;
+ } else {
+ table -> buckets [hashno] = bp -> next;
+ }
+ free_hash_bucket (bp, "delete_hash_entry");
+ break;
+ }
+ }
+}
+
+unsigned char *hash_lookup (table, name, len)
+ struct hash_table *table;
+ char *name;
+ int len;
+{
+ int hashno = do_hash (name, len, table -> hash_count);
+ struct hash_bucket *bp;
+
+ if (len) {
+ for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
+ if (len == bp -> len
+ && !memcmp (bp -> name, name, len))
+ return bp -> value;
+ } else {
+ for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
+ if (!strcmp (bp -> name, name))
+ return bp -> value;
+ }
+ return (unsigned char *)0;
+}
+
--- /dev/null
+/* memory.c
+
+ Memory-resident database... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+static struct host_decl *hosts;
+static struct hash_table *subnet_hash;
+static struct hash_table *lease_uid_hash;
+static struct hash_table *lease_ip_addr_hash;
+static struct hash_table *lease_hw_addr_hash;
+static struct lease *dangling_leases;
+
+void enter_host (hd)
+ struct host_decl *hd;
+{
+ hd -> n_name = hosts;
+ hd -> n_haddr = hosts;
+ hd -> n_cid = hosts;
+
+ hosts = hd;
+}
+
+struct host_decl *find_host_by_name (name)
+ char *name;
+{
+ struct host_decl *foo;
+
+ for (foo = hosts; foo; foo = foo -> n_name)
+ if (!strcmp (name, foo -> name))
+ return foo;
+ return (struct host_decl *)0;
+}
+
+struct host_decl *find_host_by_addr (htype, haddr, hlen)
+ int htype;
+ unsigned char *haddr;
+ int hlen;
+{
+ struct host_decl *foo;
+ int i;
+
+ for (foo = hosts; foo; foo = foo -> n_haddr)
+ for (i = 0; i < foo -> interface_count; i++)
+ if (foo -> interfaces [i].htype == htype &&
+ foo -> interfaces [i].hlen == hlen &&
+ !memcmp (foo -> interfaces [i].haddr, haddr, hlen))
+ return foo;
+ return (struct host_decl *)0;
+}
+
+void new_address_range (low, high, netmask)
+ struct in_addr low, high, netmask;
+{
+ struct lease *address_range, *lp, *plp;
+ struct subnet *subnet;
+ struct in_addr net;
+ int i, max;
+ char lowbuf [16], highbuf [16], netbuf [16];
+
+ /* Initialize the hash table if it hasn't been done yet. */
+ if (!subnet_hash)
+ subnet_hash = new_hash ();
+ if (!lease_uid_hash)
+ lease_uid_hash = new_hash ();
+ if (!lease_ip_addr_hash)
+ lease_ip_addr_hash = new_hash ();
+ if (!lease_hw_addr_hash)
+ lease_hw_addr_hash = new_hash ();
+
+ /* Make sure that high and low addresses are in same subnet. */
+ net.s_addr = SUBNET (low, netmask);
+ if (net.s_addr != SUBNET (high, netmask)) {
+ strcpy (lowbuf, inet_ntoa (low));
+ strcpy (highbuf, inet_ntoa (high));
+ strcpy (netbuf, inet_ntoa (netmask));
+ error ("Address range %s to %s, netmask %s spans %s!",
+ lowbuf, highbuf, netbuf, "multiple subnets");
+ }
+
+ /* See if this subnet is already known - if not, make a new one. */
+ subnet = find_subnet (net);
+ if (!subnet) {
+ subnet = new_subnet ("new_address_range");
+ if (!subnet)
+ error ("No memory for new subnet");
+ subnet -> net = net;
+ subnet -> netmask = netmask;
+ subnet -> leases = (struct lease *)0;
+ enter_subnet (subnet);
+ }
+
+ /* Get the high and low host addresses... */
+ max = HOST_ADDR (high, netmask);
+ i = HOST_ADDR (low, netmask);
+
+ /* Allow range to be specified high-to-low as well as low-to-high. */
+ if (i > max) {
+ max = i;
+ i = HOST_ADDR (high, netmask);
+ }
+
+ /* Get a lease structure for each address in the range. */
+ address_range = new_leases (max - i + 1, "new_address_range");
+ if (!address_range) {
+ strcpy (lowbuf, inet_ntoa (low));
+ strcpy (highbuf, inet_ntoa (high));
+ error ("No memory for address range %s-%s.", lowbuf, highbuf);
+ }
+ memset (address_range, 0, (sizeof *address_range) * (max - i + 1));
+
+ /* Fill out the lease structures with some minimal information. */
+ for (; i <= max; i++) {
+ address_range [i].ip_addr.s_addr = IP_ADDR (subnet -> net, i);
+ address_range [i].starts =
+ address_range [i].timestamp = MIN_TIME;
+ address_range [i].ends = MIN_TIME;
+ address_range [i].contain = subnet;
+
+ /* Link this entry into the list. */
+ address_range [i].next = subnet -> leases;
+ address_range [i].prev = (struct lease *)0;
+ subnet -> leases = &address_range [i];
+ address_range [i].next -> prev = subnet -> leases;
+ add_hash (lease_ip_addr_hash,
+ (char *)&address_range [i].ip_addr,
+ sizeof address_range [i].ip_addr,
+ (unsigned char *)&address_range [i]);
+ }
+
+ /* Find out if any dangling leases are in range... */
+ plp = (struct lease *)0;
+ for (lp = dangling_leases; lp; lp = lp -> next) {
+ struct in_addr lnet;
+ int lhost;
+
+ lnet.s_addr = SUBNET (lp -> ip_addr, subnet -> netmask);
+ lhost = HOST_ADDR (lp -> ip_addr, subnet -> netmask);
+
+ /* If it's in range, fill in the real lease structure with
+ the dangling lease's values, and remove the lease from
+ the list of dangling leases. */
+ if (lnet.s_addr == subnet -> net.s_addr &&
+ lhost >= i && lhost <= max) {
+ if (plp) {
+ plp -> next = lp -> next;
+ } else {
+ dangling_leases = lp -> next;
+ }
+ lp -> next = (struct lease *)0;
+ supersede_lease (&address_range [lhost - i], lp);
+ free_lease (lp, "new_address_range");
+ } else
+ plp = lp;
+ }
+}
+
+struct subnet *find_subnet (subnet)
+ struct in_addr subnet;
+{
+ struct subnet *rv;
+
+ return (struct subnet *)hash_lookup (subnet_hash,
+ (char *)&subnet, sizeof subnet);
+}
+
+/* Enter a new subnet into the subnet hash. */
+
+void enter_subnet (subnet)
+ struct subnet *subnet;
+{
+ add_hash (subnet_hash, (char *)&subnet -> net,
+ sizeof subnet -> net, (unsigned char *)subnet);
+}
+
+/* Enter a lease into the system. This is called by the parser each
+ time it reads in a new lease. If the subnet for that lease has
+ already been read in (usually the case), just update that lease;
+ otherwise, allocate temporary storage for the lease and keep it around
+ until we're done reading in the config file. */
+
+void enter_lease (lease)
+ struct lease *lease;
+{
+ struct lease *comp = find_lease_by_ip_addr (lease -> ip_addr);
+
+ /* If we don't have a place for this lease yet, save it for
+ later. */
+ if (!comp) {
+ comp = new_lease ("enter_lease");
+ if (!comp) {
+ error ("No memory for lease %s\n",
+ inet_ntoa (lease -> ip_addr));
+ }
+ *comp = *lease;
+ lease -> next = dangling_leases;
+ lease -> prev = (struct lease *)0;
+ dangling_leases = lease;
+ } else {
+ supersede_lease (comp, lease);
+ }
+}
+
+/* Replace the data in an existing lease with the data in a new lease;
+ adjust hash tables to suit, and insertion sort the lease into the
+ list of leases by expiry time so that we can always find the oldest
+ lease. */
+
+void supersede_lease (comp, lease)
+ struct lease *comp, *lease;
+{
+ int enter_uid = 0;
+ int enter_hwaddr = 0;
+ struct subnet *parent;
+ struct lease *lp;
+
+ /* If the existing lease hasn't expired and has a different
+ unique identifier or, if it doesn't have a unique
+ identifier, a different hardware address, then the two
+ leases are in conflict. */
+ if (comp -> ends > cur_time &&
+ ((comp -> uid &&
+ (comp -> uid_len != lease -> uid_len ||
+ memcmp (comp -> uid, lease -> uid, comp -> uid_len))) ||
+ (!comp -> uid &&
+ ((comp -> hardware_addr.htype !=
+ lease -> hardware_addr.htype) ||
+ (comp -> hardware_addr.hlen !=
+ lease -> hardware_addr.hlen) ||
+ memcmp (comp -> hardware_addr.haddr,
+ lease -> hardware_addr.haddr,
+ comp -> hardware_addr.hlen))))) {
+ warn ("Lease conflict at %s",
+ inet_ntoa (comp -> ip_addr));
+ } else {
+ /* If there's a Unique ID, dissociate it from the hash
+ table if necessary, and always free it. */
+ if (comp -> uid) {
+ if (comp -> uid_len != lease -> uid_len ||
+ memcmp (comp -> uid, lease -> uid,
+ comp -> uid_len)) {
+ delete_hash_entry (lease_uid_hash,
+ comp -> uid,
+ comp -> uid_len);
+ enter_uid = 1;
+ }
+ free (comp -> uid);
+ }
+ if (comp -> hardware_addr.htype &&
+ (comp -> hardware_addr.hlen !=
+ lease -> hardware_addr.hlen) ||
+ (comp -> hardware_addr.htype !=
+ lease -> hardware_addr.htype) ||
+ memcmp (comp -> hardware_addr.haddr,
+ lease -> hardware_addr.haddr,
+ comp -> hardware_addr.hlen)) {
+ delete_hash_entry (lease_hw_addr_hash,
+ comp -> hardware_addr.haddr,
+ comp -> hardware_addr.hlen);
+ enter_hwaddr = 1;
+ }
+
+ /* Copy the data files, but not the linkages. */
+ comp -> starts = lease -> starts;
+ comp -> ends = lease -> ends;
+ comp -> timestamp = lease -> timestamp;
+ comp -> uid = lease -> uid;
+ comp -> uid_len = lease -> uid_len;
+ comp -> host = lease -> host;
+ comp -> hardware_addr = lease -> hardware_addr;
+ comp -> state = lease -> state;
+
+ /* Record the lease in the uid hash if necessary. */
+ if (enter_uid && lease -> uid) {
+ add_hash (lease_uid_hash, lease -> uid,
+ lease -> uid_len, (unsigned char *)lease);
+ }
+
+ /* Record it in the hardware address hash if necessary. */
+ if (enter_hwaddr && lease -> hardware_addr.htype) {
+ add_hash (lease_hw_addr_hash,
+ lease -> hardware_addr.haddr,
+ lease -> hardware_addr.hlen,
+ (unsigned char *)lease);
+ }
+
+ /* Remove the lease from its current place in the list. */
+ if (comp -> prev) {
+ comp -> prev -> next = comp -> next;
+ } else {
+ comp -> contain -> leases = comp -> next;
+ }
+ if (comp -> next) {
+ comp -> next -> prev = comp -> prev;
+ }
+
+ /* Find the last insertion point... */
+ if (comp == comp -> contain -> insertion_point ||
+ !comp -> contain -> insertion_point) {
+ lp = comp -> contain -> leases;
+ } else {
+ lp = comp -> contain -> insertion_point;
+ }
+
+ if (!lp) {
+ /* Nothing on the list yet? Just make comp the
+ head of the list. */
+ comp -> contain -> leases = comp;
+ } else if (lp -> ends <= comp -> ends) {
+ /* Skip down the list until we run out of list
+ or find a place for comp. */
+ while (lp -> next && lp -> ends < comp -> ends) {
+ lp = lp -> next;
+ }
+ if (lp -> ends < comp -> ends) {
+ /* If we ran out of list, put comp
+ at the end. */
+ lp -> next = comp;
+ comp -> prev = lp;
+ comp -> next = (struct lease *)0;
+ } else {
+ /* If we didn't, put it between lp and
+ the previous item on the list. */
+ comp -> prev = lp -> prev;
+ comp -> prev -> next = comp;
+ comp -> next = lp;
+ lp -> prev = comp;
+ }
+ } else {
+ /* Skip ip the list until we run out of list
+ or find a place for comp. */
+ while (lp -> prev && lp -> ends > comp -> ends) {
+ lp = lp -> prev;
+ }
+ if (lp -> ends > comp -> ends) {
+ /* If we ran out of list, put comp
+ at the beginning. */
+ lp -> prev = comp;
+ comp -> next = lp;
+ comp -> prev = (struct lease *)0;
+ comp -> contain -> leases = comp;
+ } else {
+ /* If we didn't, put it between lp and
+ the next item on the list. */
+ comp -> next = lp -> next;
+ comp -> next -> prev = comp;
+ comp -> prev = lp;
+ lp -> next = comp;
+ }
+ }
+ comp -> contain -> insertion_point = comp;
+ }
+}
--- /dev/null
+/* options.c
+
+ DHCP options parsing and reassembly. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#define DHCP_OPTION_DATA
+#include "dhcpd.h"
+
+/* Parse all available options out of the specified packet. */
+
+void parse_options (packet)
+ struct packet *packet;
+{
+ /* Initially, zero all option pointers. */
+ memset (packet -> options, 0, sizeof (packet -> options));
+
+ /* If we don't see the magic cookie, there's nothing to parse. */
+ if (memcmp (packet -> raw -> options, DHCP_OPTIONS_COOKIE, 4)) {
+ packet -> options_valid = 0;
+ return;
+ }
+
+ /* Go through the options field, up to the end of the packet
+ or the End field. */
+ parse_option_buffer (packet, &packet -> raw -> options [4],
+ packet -> packet_length - DHCP_FIXED_LEN);
+ /* If we parsed a DHCP Option Overload option, parse more
+ options out of the buffer(s) containing them. */
+ if (packet -> options_valid
+ && packet -> options [DHO_DHCP_OPTION_OVERLOAD].data) {
+ if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 1)
+ parse_option_buffer (packet,
+ packet -> raw -> file,
+ sizeof packet -> raw -> file);
+ if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 2)
+ parse_option_buffer (packet,
+ packet -> raw -> sname,
+ sizeof packet -> raw -> sname);
+ }
+}
+
+/* Parse options out of the specified buffer, storing addresses of option
+ values in packet -> options and setting packet -> options_valid if no
+ errors are encountered. */
+
+void parse_option_buffer (packet, buffer, length)
+ struct packet *packet;
+ unsigned char *buffer;
+ int length;
+{
+ unsigned char *s, *t;
+ unsigned char *end = buffer + length;
+ int len;
+ int code;
+
+ for (s = buffer; *s != DHO_END && s < end; ) {
+ code = s [0];
+ /* Pad options don't have a length - just skip them. */
+ if (code == DHO_PAD) {
+ ++s;
+ continue;
+ }
+ /* All other fields (except end, see above) have a
+ one-byte length. */
+ len = s [1];
+ /* If the length is outrageous, the options are bad. */
+ if (s + len + 2 > end) {
+ warn ("Option %s length %d overflows input buffer.",
+ dhcp_options [code].name,
+ len);
+ packet -> options_valid = 0;
+ return;
+ }
+ /* If we haven't seen this option before, just make
+ space for it and copy it there. */
+ if (!packet -> options [code].data) {
+ if (!(t = (unsigned char *)malloc (len + 1)))
+ error ("Can't allocate storage for option %s.",
+ dhcp_options [code].name);
+ /* Copy and NUL-terminate the option (in case it's an
+ ASCII string. */
+ memcpy (t, &s [2], len);
+ t [len] = 0;
+ packet -> options [code].len = len;
+ packet -> options [code].data = t;
+ } else {
+ /* If it's a repeat, concatenate it to whatever
+ we last saw. This is really only required
+ for clients, but what the heck... */
+ t = (unsigned char *)
+ malloc (len + packet -> options [code].len);
+ if (!t)
+ error ("Can't expand storage for option %s.",
+ dhcp_options [code].name);
+ memcpy (t, packet -> options [code].data,
+ packet -> options [code].len);
+ memcpy (t + packet -> options [code].len,
+ &s [2], len);
+ packet -> options [code].len += len;
+ t [packet -> options [code].len] = 0;
+ free (packet -> options [code].data);
+ packet -> options [code].data = t;
+ }
+ s += len + 2;
+ }
+ packet -> options_valid = 1;
+}
+
+/* Cons up options based on client-supplied desired option list (if any)
+ and selected server option list. */
+
+void cons_options (inpacket, outpacket, hp, overload)
+ struct packet *inpacket;
+ struct dhcp_packet *outpacket;
+ struct host_decl *hp;
+ int overload; /* Overload flags that may be set. */
+{
+ option_mask options_have; /* Options we can send. */
+ option_mask options_want; /* Options client wants. */
+ option_mask options_done; /* Options we've already encoded. */
+ option_mask temp; /* Working option mask. */
+ unsigned char *priority_list;
+ int priority_len;
+ unsigned char *buffer = inpacket -> raw -> options;
+ int buflen, bufix;
+ int reserved = 3; /* Reserved space for overload. */
+ unsigned char *overload_ptr = (unsigned char *)0;
+ int stored_length [256];
+ int missed = 0;
+ int missed_code;
+ int missed_length;
+ int result;
+ int i;
+
+ /* If there's no place to overload with options, don't save space
+ for an overload option. */
+ if (!overload)
+ reserved = 0;
+
+ /* Zero out the stored-lengths array. */
+ memset (stored_length, 0, sizeof stored_length);
+
+ /* If the client has provided a maximum DHCP message size,
+ use that. Otherwise, we use the default MTU size (576 bytes). */
+ /* XXX Maybe it would be safe to assume that we can send a packet
+ to the client that's as big as the one it sent us, even if it
+ didn't specify a large MTU. */
+ if (inpacket -> options [DHO_DHCP_MAX_MESSAGE_SIZE].data)
+ buflen = (getUShort (inpacket -> options
+ [DHO_DHCP_MAX_MESSAGE_SIZE].data)
+ - DHCP_FIXED_LEN);
+ else
+ buflen = 576 - DHCP_FIXED_LEN;
+
+ /* If the client has provided a list of options that it wishes
+ returned, use it to prioritize. */
+ if (inpacket -> options [DHO_DHCP_PARAMETER_REQUEST_LIST].data) {
+ priority_list =
+ inpacket -> options
+ [DHO_DHCP_PARAMETER_REQUEST_LIST].data;
+ priority_len =
+ inpacket -> options
+ [DHO_DHCP_PARAMETER_REQUEST_LIST].len;
+ } else {
+ /* Otherwise, prioritize based on the default priority list. */
+ priority_list = dhcp_option_default_priority_list;
+ priority_len = sizeof_dhcp_option_default_priority_list;
+ }
+
+ /* Make a bitmask of all the options the client wants. */
+ OPTION_ZERO (options_want);
+ for (i = 0; i < priority_len; i++)
+ OPTION_SET (options_want, priority_list [i]);
+
+ /* Make a bitmask of all the options we have available. */
+ OPTION_ZERO (options_have);
+ for (i = 0; i < 256; i++)
+ if (hp -> options [i])
+ OPTION_SET (options_have, i);
+
+ again:
+ /* Try copying out options that fit easily. */
+ for (i = 0; i < priority_len; i++) {
+ /* Code for next option to try to store. */
+ int code = priority_list [i];
+
+ /* Number of bytes left to store (some may already
+ have been stored by a previous pass). */
+ int length;
+
+ /* If no data is available for this option, skip it. */
+ if (!hp -> options [code])
+ continue;
+
+ /* Don't look at options that have already been stored. */
+ if (OPTION_ISSET (options_done, code))
+ continue;
+
+ /* Find the value of the option... */
+ if (!tree_evaluate (hp -> options [code]))
+ continue;
+
+ /* We should now have a constant length for the option. */
+ length = (hp -> options [code] -> len - stored_length [code]);
+
+ /* If there's no space for this option, skip it. */
+ if ((bufix + OPTION_SPACE (length) + reserved) > buflen) {
+ /* If this is the first missed option, remember it. */
+ if (++missed == 1) {
+ missed_code = code;
+ missed_length = length;
+ }
+ continue;
+ }
+
+ /* Otherwise, store the option. */
+ result = store_option (outpacket, code,
+ buffer + bufix,
+ buflen - bufix - reserved,
+ stored_length);
+ bufix += result;
+
+ /* The following test should always succeed because of
+ preconditioning above. */
+ if (stored_length [code] == hp -> options [code] -> len)
+ OPTION_SET (options_done, code);
+ else {
+ warn ("%s: Only stored %d out of %d bytes.",
+ dhcp_options [code].name,
+ stored_length [code],
+ hp -> options [code] -> len);
+ if (++missed == 1) {
+ missed_code = code;
+ missed_length = hp -> options [code] -> len
+ - stored_length [code];
+ }
+ }
+ }
+
+ /* If we didn't miss any options, we're done. */
+ /* XXX Maybe we want to try to encode options the client didn't
+ request but that we have available? */
+ if (!missed)
+ return;
+
+ /* If we did miss one or more options, they must not have fit.
+ It's possible, though, that there's only one option left to
+ store, and that it would fit if we weren't reserving space
+ for the overload option. In that case, we want to avoid
+ overloading. */
+ if (reserved && missed == 1
+ && (bufix + OPTION_SPACE (missed_length) <= buflen)) {
+ result = store_option (outpacket, missed_code,
+ buffer + bufix, buflen - bufix,
+ stored_length);
+ bufix += result;
+ /* This test should always fail -- we'll send bad
+ data if it doesn't. */
+ if (stored_length [missed_code]
+ == hp -> options [missed_code] -> len) {
+ OPTION_SET (options_done, missed_code);
+ } else {
+ warn ("%s (last): Only stored %d out of %d bytes.",
+ dhcp_options [missed_code].name,
+ stored_length [missed_code],
+ hp -> options [missed_code] -> len);
+ }
+ return;
+ }
+
+ /* We've crammed in all the options that completely fit in
+ the current buffer, but maybe we can fit part of the next
+ option into the current buffer and part into the next. */
+ if (bufix + OPTION_SPACE (missed_length) + reserved
+ < buflen + (overload & 1 ? 128 : 0) + (overload & 2 ? 64 : 0)) {
+ result = store_option (outpacket, missed_code,
+ buffer + bufix,
+ buflen - bufix - reserved,
+ stored_length);
+ bufix += result;
+
+ /* This test should never fail. */
+ if (stored_length [missed_code]
+ == hp -> options [missed_code] -> len) {
+ OPTION_SET (options_done, missed_code);
+ warn ("%s: Unexpected completed store.",
+ dhcp_options [missed_code].name);
+ }
+ }
+
+ /* Okay, nothing else is going to fit in the current buffer
+ except possibly the override option. Store that. */
+ if (reserved) {
+ buffer [bufix++] = DHO_DHCP_OPTION_OVERLOAD;
+ buffer [bufix++] = 1;
+ overload_ptr = buffer + bufix;
+ buffer [bufix++] = 0;
+ /* If there's space, store an End option code. */
+ if (bufix < buflen)
+ buffer [bufix++] = DHO_END;
+ /* If there's still space, pad it. */
+ while (bufix < buflen)
+ buffer [bufix++] = DHO_PAD;
+ }
+
+ /* If we've fallen through to here, we still have options to
+ store, and may be able to overload options into the file
+ and server name fields of the DHCP packet. */
+
+ /* We should have stored an overload option by now if we're
+ going to need it, so if this test fails, there's a programming
+ error somewhere above. */
+ if (overload && !overload_ptr) {
+ warn ("Need to overload, but didn't store overload option!");
+ return;
+ }
+
+ /* Can we use the file buffer? */
+ if (overload & 1) {
+ buffer = inpacket -> raw -> file;
+ buflen = sizeof inpacket -> raw -> file;
+ bufix = 0;
+ overload &= ~1;
+ goto again;
+ }
+ /* Can we use the sname buffer? */
+ if (overload & 2) {
+ buffer = inpacket -> raw -> sname;
+ buflen = sizeof inpacket -> raw -> sname;
+ bufix = 0;
+ overload &= ~2;
+ goto again;
+ }
+
+ warn ("Insufficient packet space for all options.");
+}
+
+/* Copy the option data specified by code from the packet structure's
+ option array into an option buffer specified by buf and buflen,
+ updating stored_length[code] to reflect the amount of code's option
+ data that has been stored so far. Return 1 if all the option data
+ has been stored. */
+
+int store_option (packet, code, buffer, buflen, stored_length)
+ struct packet *packet;
+ unsigned char code;
+ unsigned char *buffer;
+ int buflen;
+ int *stored_length;
+{
+ int length = packet -> options [code].len - stored_length [code];
+ int bufix = 0;
+ int rv = 1;
+ if (length > buflen) {
+ rv = 0;
+ length = buflen;
+ }
+
+ /* If the option's length is more than 255, we must store it
+ in multiple hunks. Store 255-byte hunks first. */
+ /* XXX Might a client lose its cookies if options aren't
+ chunked out so that each chunk is aligned to the size
+ of the data being represented? */
+ while (length) {
+ unsigned char incr = length > 255 ? 255 : length;
+ buffer [bufix] = code;
+ buffer [bufix + 1] = incr;
+ memcpy (buffer + bufix + 2, (packet -> options [code].data
+ + stored_length [code]), incr);
+ length -= incr;
+ stored_length [code] += incr;
+ bufix += 2 + incr;
+ }
+ return rv;
+}
+
+/* Format the specified option so that a human can easily read it. */
+
+char *pretty_print_option (code, data, len)
+ unsigned char code;
+ unsigned char *data;
+ int len;
+{
+ static char optbuf [32768]; /* XXX */
+ int hunksize = 0;
+ int numhunk = -1;
+ int numelem = 0;
+ char fmtbuf [32];
+ int i, j;
+ char *op = optbuf;
+ unsigned char *dp = data;
+ struct in_addr foo;
+
+ /* Figure out the size of the data. */
+ for (i = 0; dhcp_options [code].format [i]; i++) {
+ if (!numhunk) {
+ warn ("%s: Excess information in format string: %s\n",
+ dhcp_options [code].name,
+ &(dhcp_options [code].format [i]));
+ break;
+ }
+ numelem++;
+ fmtbuf [i] = dhcp_options [code].format [i];
+ switch (dhcp_options [code].format [i]) {
+ case 'A':
+ --numelem;
+ fmtbuf [i] = 0;
+ numhunk = 0;
+ break;
+ case 't':
+ fmtbuf [i] = 't';
+ fmtbuf [i + 1] = 0;
+ numhunk = -2;
+ break;
+ case 'I':
+ case 'l':
+ case 'L':
+ hunksize += 4;
+ break;
+ case 's':
+ case 'S':
+ hunksize += 2;
+ break;
+ case 'b':
+ case 'B':
+ case 'f':
+ hunksize++;
+ break;
+ case 'e':
+ break;
+ default:
+ warn ("%s: garbage in format string: %s\n",
+ dhcp_options [code].name,
+ &(dhcp_options [code].format [i]));
+ break;
+ }
+ }
+
+ /* Check for too few bytes... */
+ if (hunksize > len) {
+ warn ("%s: expecting at least %d bytes; got %d",
+ dhcp_options [code].name,
+ hunksize, len);
+ return "<error>";
+ }
+ /* Check for too many bytes... */
+ if (numhunk == -1 && hunksize < len)
+ warn ("%s: %d extra bytes",
+ dhcp_options [code].name,
+ len - hunksize);
+
+ /* If this is an array, compute its size. */
+ if (!numhunk)
+ numhunk = len / hunksize;
+ /* See if we got an exact number of hunks. */
+ if (numhunk > 0 && numhunk * hunksize < len)
+ warn ("%s: %d extra bytes at end of array\n",
+ dhcp_options [code].name,
+ len - numhunk * hunksize);
+
+ /* A one-hunk array prints the same as a single hunk. */
+ if (numhunk < 0)
+ numhunk = 1;
+
+printf ("numhunk = %d numelem = %d\n", numhunk, numelem);
+ /* Cycle through the array (or hunk) printing the data. */
+ for (i = 0; i < numhunk; i++) {
+ for (j = 0; j < numelem; j++) {
+ switch (fmtbuf [j]) {
+ case 't':
+ strcpy (op, dp);
+ break;
+ case 'I':
+ foo.s_addr = htonl (getULong (dp));
+ strcpy (op, inet_ntoa (foo));
+ dp += 4;
+ break;
+ case 'l':
+ sprintf (op, "%ld", getLong (dp));
+ dp += 4;
+ break;
+ case 'L':
+ sprintf (op, "%ld", getULong (dp));
+ dp += 4;
+ break;
+ case 's':
+ sprintf (op, "%d", getShort (dp));
+ dp += 2;
+ break;
+ case 'S':
+ sprintf (op, "%d", getUShort (dp));
+ dp += 2;
+ break;
+ case 'b':
+ sprintf (op, "%d", *(char *)dp++);
+ break;
+ case 'B':
+ sprintf (op, "%d", *dp++);
+ break;
+ case 'f':
+ strcpy (op, *dp++ ? "true" : "false");
+ break;
+ default:
+ warn ("Unexpected format code %c", fmtbuf [j]);
+ }
+ op += strlen (op);
+ *op++ = ' ';
+ }
+ }
+ *--op = 0;
+ return optbuf;
+}
+
+
+
--- /dev/null
+/* print.c
+
+ Turn data structures into printable text. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+char *print_hw_addr (htype, hlen, data)
+ int htype;
+ int hlen;
+ unsigned char *data;
+{
+ static char habuf [49];
+ char *s;
+ int i;
+
+ s = habuf;
+ for (i = 0; i < hlen; i++) {
+ sprintf (s, "%x", data [i]);
+ s += strlen (s);
+ *s++ = ':';
+ }
+ *--s = 0;
+ return habuf;
+}
+
--- /dev/null
+/* socket.c
+
+ BSD socket interface code... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+#include <sys/ioctl.h>
+
+/* List of sockets we're accepting packets on... */
+struct socklist {
+ struct socklist *next;
+ struct sockaddr_in addr;
+ int sock;
+} *sockets;
+
+/* Return the list of IP addresses associated with each network interface. */
+
+u_int32_t *get_interface_list (count)
+ int *count;
+{
+ u_int32_t *intbuf = (u_int32_t *)0;
+ static char buf [8192];
+ struct ifconf ic;
+ int i;
+ int sock;
+ int ifcount = 0;
+ int ifix = 0;
+
+ /* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
+ if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ error ("Can't create addrlist socket");
+
+ /* Get the interface configuration information... */
+ ic.ifc_len = sizeof buf;
+ ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
+ i = ioctl(sock, SIOCGIFCONF, &ic);
+ close (sock);
+ if (i < 0)
+ error ("ioctl: SIOCGIFCONF: %m");
+
+ again:
+ /* Cycle through the list of interfaces looking for IP addresses.
+ Go through twice; once to count the number if addresses, and a
+ second time to copy them into an array of addresses. */
+ for (i = 0; i < ic.ifc_len;) {
+ struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
+ i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
+ if (ifp -> ifr_addr.sa_family == AF_INET) {
+ struct sockaddr_in *foo =
+ (struct sockaddr_in *)(&ifp -> ifr_addr);
+ /* We don't want the loopback interface. */
+ if (foo -> sin_addr.s_addr == INADDR_LOOPBACK)
+ continue;
+ if (intbuf)
+ intbuf [ifix++] = foo -> sin_addr.s_addr;
+ else
+ ++ifcount;
+ }
+ }
+ /* If we haven't already filled our array, allocate it and go
+ again. */
+ if (!intbuf) {
+ intbuf = (u_int32_t *)dmalloc ((ifcount + 1)
+ * sizeof (u_int32_t),
+ "get_interface_list");
+ if (!intbuf)
+ return intbuf;
+ goto again;
+ }
+ *count = ifcount;
+ return intbuf;
+}
+
+void listen_on (port, address)
+ u_int16_t port;
+ u_int32_t address;
+{
+ struct sockaddr_in name;
+ int sock;
+ struct socklist *tmp;
+ int flag;
+
+ name.sin_family = AF_INET;
+ name.sin_port = port;
+ name.sin_addr.s_addr = address;
+ memset (name.sin_zero, 0, sizeof (name.sin_zero));
+
+ /* List addresses on which we're listening. */
+ note ("Receiving on %s, port %d",
+ inet_ntoa (name.sin_addr), htons (name.sin_port));
+ if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ error ("Can't create dhcp socket: %m");
+
+ flag = 1;
+ if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
+ &flag, sizeof flag) < 0)
+ error ("Can't set SO_REUSEADDR option on dhcp socket: %m");
+
+ if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
+ &flag, sizeof flag) < 0)
+ error ("Can't set SO_BROADCAST option on dhcp socket: %m");
+
+ if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
+ error ("Can't bind to dhcp address: %m");
+
+ tmp = (struct socklist *)dmalloc (sizeof (struct socklist),
+ "listen_on");
+ if (!tmp)
+ error ("Can't allocate memory for socket list.");
+ tmp -> addr = name;
+ tmp -> sock = sock;
+ tmp -> next = sockets;
+ sockets = tmp;
+}
+
+unsigned char packbuf [65536]; /* Should cover the gnarliest MTU... */
+
+void dispatch ()
+{
+ struct sockaddr_in from;
+ int fromlen = sizeof from;
+ fd_set r, w, x;
+ struct socklist *l;
+ int max = 0;
+ int count;
+ int result;
+
+ FD_ZERO (&r);
+ FD_ZERO (&w);
+ FD_ZERO (&x);
+
+ do {
+ /* Set up the read mask. */
+ for (l = sockets; l; l = l -> next) {
+ FD_SET (l -> sock, &r);
+ FD_SET (l -> sock, &x);
+ if (l -> sock > max)
+ max = l -> sock;
+ }
+
+ /* Wait for a packet or a timeout... XXX */
+ count = select (max + 1, &r, &w, &x, (struct timeval *)0);
+
+ /* Not likely to be transitory... */
+ if (count < 0)
+ error ("select: %m");
+
+ for (l = sockets; l; l = l -> next) {
+ if (!FD_ISSET (l -> sock, &r))
+ continue;
+ if ((result =
+ recvfrom (l -> sock, packbuf, sizeof packbuf, 0,
+ (struct sockaddr *)&from, &fromlen))
+ < 0) {
+ warn ("recvfrom failed on %s: %m",
+ inet_ntoa (l -> addr.sin_addr));
+ sleep (5);
+ continue;
+ }
+ note ("request from %s, port %d",
+ inet_ntoa (from.sin_addr),
+ htons (from.sin_port));
+ do_packet (packbuf, result, &from, fromlen, l -> sock);
+ }
+ } while (1);
+}
+
--- /dev/null
+/* tables.c
+
+ Tables of information... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+/* DHCP Option names, formats and codes, from RFC1533.
+
+ Format codes:
+
+ e - end of data
+ I - IP address
+ l - 32-bit signed integer
+ L - 32-bit unsigned integer
+ s - 16-bit signed integer
+ S - 16-bit unsigned integer
+ b - 8-bit signed integer
+ B - 8-bit unsigned integer
+ t - ASCII text
+ f - flag (true or false)
+ A - array of whatever precedes (e.g., IA means array of IP addresses)
+*/
+
+struct universe dhcp_universe;
+struct option dhcp_options [256] = {
+ "pad", "", &dhcp_universe, 0,
+ "subnet-mask", "I", &dhcp_universe, 1,
+ "time-offset", "l", &dhcp_universe, 2,
+ "routers", "IA", &dhcp_universe, 3,
+ "time-servers", "IA", &dhcp_universe, 4,
+ "name-servers", "IA", &dhcp_universe, 5,
+ "domain-name-servers", "IA", &dhcp_universe, 6,
+ "log-servers", "IA", &dhcp_universe, 7,
+ "cookie-servers", "IA", &dhcp_universe, 8,
+ "lpr-servers", "IA", &dhcp_universe, 9,
+ "impress-servers", "IA", &dhcp_universe, 10,
+ "resource-location-servers", "IA", &dhcp_universe, 11,
+ "host-name", "t", &dhcp_universe, 12,
+ "boot-size", "S", &dhcp_universe, 13,
+ "merit-dump", "t", &dhcp_universe, 14,
+ "domain-name", "t", &dhcp_universe, 15,
+ "swap-server", "I", &dhcp_universe, 16,
+ "root-path", "t", &dhcp_universe, 17,
+ "extensions-path", "t", &dhcp_universe, 18,
+ "ip-forwarding", "f", &dhcp_universe, 19,
+ "non-local-source-routing", "f", &dhcp_universe, 20,
+ "policy-filter", "IIA", &dhcp_universe, 21,
+ "max-dgram-reassembly", "S", &dhcp_universe, 22,
+ "default-ip-ttl", "B", &dhcp_universe, 23,
+ "path-mtu-aging-timeout", "L", &dhcp_universe, 24,
+ "path-mtu-plateau-table", "SA", &dhcp_universe, 25,
+ "interface-mtu", "S", &dhcp_universe, 26,
+ "all-subnets-local", "f", &dhcp_universe, 27,
+ "broadcast-address", "I", &dhcp_universe, 28,
+ "perform-mask-discovery", "f", &dhcp_universe, 29,
+ "mask-supplier", "f", &dhcp_universe, 30,
+ "router-discovery", "f", &dhcp_universe, 31,
+ "router-solicitation-address", "I", &dhcp_universe, 32,
+ "static-routes", "IIA", &dhcp_universe, 33,
+ "trailer-encapsulation", "f", &dhcp_universe, 34,
+ "arp-cache-timeout", "L", &dhcp_universe, 35,
+ "ieee802.3-encapsulation", "f", &dhcp_universe, 36,
+ "default-tcp-ttl", "B", &dhcp_universe, 37,
+ "tcp-keepalive-interval", "L", &dhcp_universe, 38,
+ "tcp-keepalive-garbage", "f", &dhcp_universe, 39,
+ "nis-domain", "t", &dhcp_universe, 40,
+ "nis-servers", "IA", &dhcp_universe, 41,
+ "ntp-servers", "IA", &dhcp_universe, 42,
+ "vendor-encapsulated-options", "t", &dhcp_universe, 43,
+ "netbios-name-servers", "IA", &dhcp_universe, 44,
+ "netbios-dd-server", "IA", &dhcp_universe, 45,
+ "netbios-node-type", "B", &dhcp_universe, 46,
+ "netbios-scope", "t", &dhcp_universe, 47,
+ "font-servers", "IA", &dhcp_universe, 48,
+ "x-display-manager", "IA", &dhcp_universe, 49,
+ "dhcp-requested-address", "I", &dhcp_universe, 50,
+ "dhcp-lease-time", "L", &dhcp_universe, 51,
+ "dhcp-option-overload", "B", &dhcp_universe, 52,
+ "dhcp-message-type", "B", &dhcp_universe, 53,
+ "dhcp-server-identifier", "I", &dhcp_universe, 54,
+ "dhcp-parameter-request-list", "BA", &dhcp_universe, 55,
+ "dhcp-message", "t", &dhcp_universe, 56,
+ "dhcp-max-message-size", "S", &dhcp_universe, 57,
+ "dhcp-renewal-time", "L", &dhcp_universe, 58,
+ "dhcp-rebinding-time", "L", &dhcp_universe, 59,
+ "dhcp-class-identifier", "t", &dhcp_universe, 60,
+ "dhcp-client-identifier", "t", &dhcp_universe, 61,
+ "option-62", "", &dhcp_universe, 62,
+ "option-63", "", &dhcp_universe, 63,
+ "option-64", "", &dhcp_universe, 64,
+ "option-65", "", &dhcp_universe, 65,
+ "option-66", "", &dhcp_universe, 66,
+ "option-67", "", &dhcp_universe, 67,
+ "option-68", "", &dhcp_universe, 68,
+ "option-69", "", &dhcp_universe, 69,
+ "option-70", "", &dhcp_universe, 70,
+ "option-71", "", &dhcp_universe, 71,
+ "option-72", "", &dhcp_universe, 72,
+ "option-73", "", &dhcp_universe, 73,
+ "option-74", "", &dhcp_universe, 74,
+ "option-75", "", &dhcp_universe, 75,
+ "option-76", "", &dhcp_universe, 76,
+ "option-77", "", &dhcp_universe, 77,
+ "option-78", "", &dhcp_universe, 78,
+ "option-79", "", &dhcp_universe, 79,
+ "option-80", "", &dhcp_universe, 80,
+ "option-81", "", &dhcp_universe, 81,
+ "option-82", "", &dhcp_universe, 82,
+ "option-83", "", &dhcp_universe, 83,
+ "option-84", "", &dhcp_universe, 84,
+ "option-85", "", &dhcp_universe, 85,
+ "option-86", "", &dhcp_universe, 86,
+ "option-87", "", &dhcp_universe, 87,
+ "option-88", "", &dhcp_universe, 88,
+ "option-89", "", &dhcp_universe, 89,
+ "option-90", "", &dhcp_universe, 90,
+ "option-91", "", &dhcp_universe, 91,
+ "option-92", "", &dhcp_universe, 92,
+ "option-93", "", &dhcp_universe, 93,
+ "option-94", "", &dhcp_universe, 94,
+ "option-95", "", &dhcp_universe, 95,
+ "option-96", "", &dhcp_universe, 96,
+ "option-97", "", &dhcp_universe, 97,
+ "option-98", "", &dhcp_universe, 98,
+ "option-99", "", &dhcp_universe, 99,
+ "option-100", "", &dhcp_universe, 100,
+ "option-101", "", &dhcp_universe, 101,
+ "option-102", "", &dhcp_universe, 102,
+ "option-103", "", &dhcp_universe, 103,
+ "option-104", "", &dhcp_universe, 104,
+ "option-105", "", &dhcp_universe, 105,
+ "option-106", "", &dhcp_universe, 106,
+ "option-107", "", &dhcp_universe, 107,
+ "option-108", "", &dhcp_universe, 108,
+ "option-109", "", &dhcp_universe, 109,
+ "option-110", "", &dhcp_universe, 110,
+ "option-111", "", &dhcp_universe, 111,
+ "option-112", "", &dhcp_universe, 112,
+ "option-113", "", &dhcp_universe, 113,
+ "option-114", "", &dhcp_universe, 114,
+ "option-115", "", &dhcp_universe, 115,
+ "option-116", "", &dhcp_universe, 116,
+ "option-117", "", &dhcp_universe, 117,
+ "option-118", "", &dhcp_universe, 118,
+ "option-119", "", &dhcp_universe, 119,
+ "option-120", "", &dhcp_universe, 120,
+ "option-121", "", &dhcp_universe, 121,
+ "option-122", "", &dhcp_universe, 122,
+ "option-123", "", &dhcp_universe, 123,
+ "option-124", "", &dhcp_universe, 124,
+ "option-125", "", &dhcp_universe, 125,
+ "option-126", "", &dhcp_universe, 126,
+ "option-127", "", &dhcp_universe, 127,
+ "option-128", "", &dhcp_universe, 128,
+ "option-129", "", &dhcp_universe, 129,
+ "option-130", "", &dhcp_universe, 130,
+ "option-131", "", &dhcp_universe, 131,
+ "option-132", "", &dhcp_universe, 132,
+ "option-133", "", &dhcp_universe, 133,
+ "option-134", "", &dhcp_universe, 134,
+ "option-135", "", &dhcp_universe, 135,
+ "option-136", "", &dhcp_universe, 136,
+ "option-137", "", &dhcp_universe, 137,
+ "option-138", "", &dhcp_universe, 138,
+ "option-139", "", &dhcp_universe, 139,
+ "option-140", "", &dhcp_universe, 140,
+ "option-141", "", &dhcp_universe, 141,
+ "option-142", "", &dhcp_universe, 142,
+ "option-143", "", &dhcp_universe, 143,
+ "option-144", "", &dhcp_universe, 144,
+ "option-145", "", &dhcp_universe, 145,
+ "option-146", "", &dhcp_universe, 146,
+ "option-147", "", &dhcp_universe, 147,
+ "option-148", "", &dhcp_universe, 148,
+ "option-149", "", &dhcp_universe, 149,
+ "option-150", "", &dhcp_universe, 150,
+ "option-151", "", &dhcp_universe, 151,
+ "option-152", "", &dhcp_universe, 152,
+ "option-153", "", &dhcp_universe, 153,
+ "option-154", "", &dhcp_universe, 154,
+ "option-155", "", &dhcp_universe, 155,
+ "option-156", "", &dhcp_universe, 156,
+ "option-157", "", &dhcp_universe, 157,
+ "option-158", "", &dhcp_universe, 158,
+ "option-159", "", &dhcp_universe, 159,
+ "option-160", "", &dhcp_universe, 160,
+ "option-161", "", &dhcp_universe, 161,
+ "option-162", "", &dhcp_universe, 162,
+ "option-163", "", &dhcp_universe, 163,
+ "option-164", "", &dhcp_universe, 164,
+ "option-165", "", &dhcp_universe, 165,
+ "option-166", "", &dhcp_universe, 166,
+ "option-167", "", &dhcp_universe, 167,
+ "option-168", "", &dhcp_universe, 168,
+ "option-169", "", &dhcp_universe, 169,
+ "option-170", "", &dhcp_universe, 170,
+ "option-171", "", &dhcp_universe, 171,
+ "option-172", "", &dhcp_universe, 172,
+ "option-173", "", &dhcp_universe, 173,
+ "option-174", "", &dhcp_universe, 174,
+ "option-175", "", &dhcp_universe, 175,
+ "option-176", "", &dhcp_universe, 176,
+ "option-177", "", &dhcp_universe, 177,
+ "option-178", "", &dhcp_universe, 178,
+ "option-179", "", &dhcp_universe, 179,
+ "option-180", "", &dhcp_universe, 180,
+ "option-181", "", &dhcp_universe, 181,
+ "option-182", "", &dhcp_universe, 182,
+ "option-183", "", &dhcp_universe, 183,
+ "option-184", "", &dhcp_universe, 184,
+ "option-185", "", &dhcp_universe, 185,
+ "option-186", "", &dhcp_universe, 186,
+ "option-187", "", &dhcp_universe, 187,
+ "option-188", "", &dhcp_universe, 188,
+ "option-189", "", &dhcp_universe, 189,
+ "option-190", "", &dhcp_universe, 190,
+ "option-191", "", &dhcp_universe, 191,
+ "option-192", "", &dhcp_universe, 192,
+ "option-193", "", &dhcp_universe, 193,
+ "option-194", "", &dhcp_universe, 194,
+ "option-195", "", &dhcp_universe, 195,
+ "option-196", "", &dhcp_universe, 196,
+ "option-197", "", &dhcp_universe, 197,
+ "option-198", "", &dhcp_universe, 198,
+ "option-199", "", &dhcp_universe, 199,
+ "option-200", "", &dhcp_universe, 200,
+ "option-201", "", &dhcp_universe, 201,
+ "option-202", "", &dhcp_universe, 202,
+ "option-203", "", &dhcp_universe, 203,
+ "option-204", "", &dhcp_universe, 204,
+ "option-205", "", &dhcp_universe, 205,
+ "option-206", "", &dhcp_universe, 206,
+ "option-207", "", &dhcp_universe, 207,
+ "option-208", "", &dhcp_universe, 208,
+ "option-209", "", &dhcp_universe, 209,
+ "option-210", "", &dhcp_universe, 210,
+ "option-211", "", &dhcp_universe, 211,
+ "option-212", "", &dhcp_universe, 212,
+ "option-213", "", &dhcp_universe, 213,
+ "option-214", "", &dhcp_universe, 214,
+ "option-215", "", &dhcp_universe, 215,
+ "option-216", "", &dhcp_universe, 216,
+ "option-217", "", &dhcp_universe, 217,
+ "option-218", "", &dhcp_universe, 218,
+ "option-219", "", &dhcp_universe, 219,
+ "option-220", "", &dhcp_universe, 220,
+ "option-221", "", &dhcp_universe, 221,
+ "option-222", "", &dhcp_universe, 222,
+ "option-223", "", &dhcp_universe, 223,
+ "option-224", "", &dhcp_universe, 224,
+ "option-225", "", &dhcp_universe, 225,
+ "option-226", "", &dhcp_universe, 226,
+ "option-227", "", &dhcp_universe, 227,
+ "option-228", "", &dhcp_universe, 228,
+ "option-229", "", &dhcp_universe, 229,
+ "option-230", "", &dhcp_universe, 230,
+ "option-231", "", &dhcp_universe, 231,
+ "option-232", "", &dhcp_universe, 232,
+ "option-233", "", &dhcp_universe, 233,
+ "option-234", "", &dhcp_universe, 234,
+ "option-235", "", &dhcp_universe, 235,
+ "option-236", "", &dhcp_universe, 236,
+ "option-237", "", &dhcp_universe, 237,
+ "option-238", "", &dhcp_universe, 238,
+ "option-239", "", &dhcp_universe, 239,
+ "option-240", "", &dhcp_universe, 240,
+ "option-241", "", &dhcp_universe, 241,
+ "option-242", "", &dhcp_universe, 242,
+ "option-243", "", &dhcp_universe, 243,
+ "option-244", "", &dhcp_universe, 244,
+ "option-245", "", &dhcp_universe, 245,
+ "option-246", "", &dhcp_universe, 246,
+ "option-247", "", &dhcp_universe, 247,
+ "option-248", "", &dhcp_universe, 248,
+ "option-249", "", &dhcp_universe, 249,
+ "option-250", "", &dhcp_universe, 250,
+ "option-251", "", &dhcp_universe, 251,
+ "option-252", "", &dhcp_universe, 252,
+ "option-253", "", &dhcp_universe, 253,
+ "option-254", "", &dhcp_universe, 254,
+ "option-end", "e", &dhcp_universe, 255,
+};
+
+/* Default dhcp option priority list (this is ad hoc and should not be
+ mistaken for a carefully crafted and optimized list). */
+unsigned char dhcp_option_default_priority_list [] = {
+ DHO_SUBNET_MASK,
+ DHO_TIME_OFFSET,
+ DHO_ROUTERS,
+ DHO_TIME_SERVERS,
+ DHO_NAME_SERVERS,
+ DHO_DOMAIN_NAME_SERVERS,
+ DHO_LOG_SERVERS,
+ DHO_COOKIE_SERVERS,
+ DHO_LPR_SERVERS,
+ DHO_IMPRESS_SERVERS,
+ DHO_RESOURCE_LOCATION_SERVERS,
+ DHO_HOST_NAME,
+ DHO_BOOT_SIZE,
+ DHO_MERIT_DUMP,
+ DHO_DOMAIN_NAME,
+ DHO_SWAP_SERVER,
+ DHO_ROOT_PATH,
+ DHO_EXTENSIONS_PATH,
+ DHO_IP_FORWARDING,
+ DHO_NON_LOCAL_SOURCE_ROUTING,
+ DHO_POLICY_FILTER,
+ DHO_MAX_DGRAM_REASSEMBLY,
+ DHO_DEFAULT_IP_TTL,
+ DHO_PATH_MTU_AGING_TIMEOUT,
+ DHO_PATH_MTU_PLATEAU_TABLE,
+ DHO_INTERFACE_MTU,
+ DHO_ALL_SUBNETS_LOCAL,
+ DHO_BROADCAST_ADDRESS,
+ DHO_PERFORM_MASK_DISCOVERY,
+ DHO_MASK_SUPPLIER,
+ DHO_ROUTER_DISCOVERY,
+ DHO_ROUTER_SOLICITATION_ADDRESS,
+ DHO_STATIC_ROUTES,
+ DHO_TRAILER_ENCAPSULATION,
+ DHO_ARP_CACHE_TIMEOUT,
+ DHO_IEEE802_3_ENCAPSULATION,
+ DHO_DEFAULT_TCP_TTL,
+ DHO_TCP_KEEPALIVE_INTERVAL,
+ DHO_TCP_KEEPALIVE_GARBAGE,
+ DHO_NIS_DOMAIN,
+ DHO_NIS_SERVERS,
+ DHO_NTP_SERVERS,
+ DHO_VENDOR_ENCAPSULATED_OPTIONS,
+ DHO_NETBIOS_NAME_SERVERS,
+ DHO_NETBIOS_DD_SERVER,
+ DHO_NETBIOS_NODE_TYPE,
+ DHO_NETBIOS_SCOPE,
+ DHO_FONT_SERVERS,
+ DHO_X_DISPLAY_MANAGER,
+ DHO_DHCP_REQUESTED_ADDRESS,
+ DHO_DHCP_LEASE_TIME,
+ DHO_DHCP_OPTION_OVERLOAD,
+ DHO_DHCP_MESSAGE_TYPE,
+ DHO_DHCP_SERVER_IDENTIFIER,
+ DHO_DHCP_PARAMETER_REQUEST_LIST,
+ DHO_DHCP_MESSAGE,
+ DHO_DHCP_MAX_MESSAGE_SIZE,
+ DHO_DHCP_RENEWAL_TIME,
+ DHO_DHCP_REBINDING_TIME,
+ DHO_DHCP_CLASS_IDENTIFIER,
+ DHO_DHCP_CLIENT_IDENTIFIER,
+};
+
+int sizeof_dhcp_option_default_priority_list =
+ sizeof dhcp_option_default_priority_list;
+
+
+struct hash_table universe_hash;
+
+void initialize_universes()
+{
+ int i;
+
+ dhcp_universe.name = "dhcp";
+ dhcp_universe.hash = new_hash ();
+ if (!dhcp_universe.hash)
+ error ("Can't allocate dhcp option hash table.");
+ for (i = 0; i < 256; i++) {
+ dhcp_universe.options [i] = &dhcp_options [i];
+ add_hash (dhcp_universe.hash, dhcp_options [i].name, 0,
+ (unsigned char *)&dhcp_options [i]);
+ }
+ universe_hash.hash_count = DEFAULT_HASH_SIZE;
+ add_hash (&universe_hash, dhcp_universe.name, 0,
+ (unsigned char *)&dhcp_universe);
+}
--- /dev/null
+/* tree.c
+
+ Routines for manipulating parse trees... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+static TIME tree_evaluate_recurse PROTO ((int *, unsigned char **, int *,
+ struct tree *));
+static TIME do_host_lookup PROTO ((int *, unsigned char **, int *,
+ struct dns_host_entry *));
+static void do_data_copy PROTO ((int *, unsigned char **, int *,
+ unsigned char *, int));
+
+pair cons (car, cdr)
+ caddr_t car;
+ pair cdr;
+{
+ pair foo = (pair)dmalloc (sizeof *foo, "cons");
+ if (!foo)
+ error ("no memory for cons.");
+ foo -> car = car;
+ foo -> cdr = cdr;
+ return foo;
+}
+
+struct tree_cache *tree_cache (tree)
+ struct tree *tree;
+{
+ struct tree_cache *tc;
+
+ tc = new_tree_cache ("tree_cache");
+ if (!tc)
+ return 0;
+ tc -> value = (char *)0;
+ tc -> len = tc -> buf_size = 0;
+ tc -> timeout = 0;
+ tc -> tree = tree;
+ return tc;
+}
+
+struct tree *tree_host_lookup (name)
+ char *name;
+{
+ struct tree *nt;
+ nt = new_tree ("tree_host_lookup");
+ if (!nt)
+ error ("No memory for host lookup tree node.");
+ nt -> op = TREE_HOST_LOOKUP;
+ nt -> data.host_lookup.host = enter_dns_host (name);
+ return nt;
+}
+
+struct dns_host_entry *enter_dns_host (name)
+ char *name;
+{
+ struct dns_host_entry *dh;
+
+ if (!(dh = (struct dns_host_entry *)dmalloc
+ (sizeof (struct dns_host_entry), "enter_dns_host"))
+ || !(dh -> hostname = dmalloc (strlen (name) + 1,
+ "enter_dns_host")))
+ error ("Can't allocate space for new host.");
+ strcpy (dh -> hostname, name);
+ dh -> data = (unsigned char *)0;
+ dh -> data_len = 0;
+ dh -> timeout = 0;
+ return dh;
+}
+
+struct tree *tree_const (data, len)
+ unsigned char *data;
+ int len;
+{
+ struct tree *nt;
+ if (!(nt = new_tree ("tree_const"))
+ || !(nt -> data.const_val.data =
+ (unsigned char *)dmalloc (len, "tree_const")))
+ error ("No memory for constant data tree node.");
+ nt -> op = TREE_CONST;
+ memcpy (nt -> data.const_val.data, data, len);
+ nt -> data.const_val.len = len;
+ return nt;
+}
+
+struct tree *tree_concat (left, right)
+ struct tree *left, *right;
+{
+ struct tree *nt;
+
+ /* If we're concatenating a null tree to a non-null tree, just
+ return the non-null tree; if both trees are null, return
+ a null tree. */
+ if (!left)
+ return right;
+ if (!right)
+ return left;
+
+ /* If both trees are constant, combine them. */
+ if (left -> op = TREE_CONST && right -> op == TREE_CONST) {
+ unsigned char *buf = dmalloc (left -> data.const_val.len
+ + right -> data.const_val.len,
+ "tree_concat");
+ if (!buf)
+ error ("No memory to concatenate constants.");
+ memcpy (buf, left -> data.const_val.data,
+ left -> data.const_val.len);
+ memcpy (buf + left -> data.const_val.len,
+ right -> data.const_val.data,
+ right -> data.const_val.len);
+ dfree (left -> data.const_val.data, "tree_concat");
+ dfree (right -> data.const_val.data, "tree_concat");
+ left -> data.const_val.data = buf;
+ left -> data.const_val.len += right -> data.const_val.len;
+ free_tree (right, "tree_concat");
+ return left;
+ }
+
+ /* Otherwise, allocate a new node to concatenate the two. */
+ if (!(nt = new_tree ("tree_concat")))
+ error ("No memory for data tree concatenation node.");
+ nt -> op = TREE_CONCAT;
+ nt -> data.concat.left = left;
+ nt -> data.concat.right = right;
+ return nt;
+}
+
+struct tree *tree_limit (tree, limit)
+ struct tree *tree;
+ int limit;
+{
+ struct tree *rv;
+
+ /* If the tree we're limiting is constant, limit it now. */
+ if (tree -> op == TREE_CONST) {
+ if (tree -> data.const_val.len > limit)
+ tree -> data.const_val.len = limit;
+ return tree;
+ }
+
+ /* Otherwise, put in a node which enforces the limit on evaluation. */
+ rv = new_tree ("tree_limit");
+ if (!rv)
+ return (struct tree *)0;
+ rv -> op = TREE_LIMIT;
+ rv -> data.limit.tree = tree;
+ rv -> data.limit.limit = limit;
+ return rv;
+}
+
+int tree_evaluate (tree_cache)
+ struct tree_cache *tree_cache;
+{
+ unsigned char *bp = tree_cache -> value;
+ int bc = tree_cache -> buf_size;
+ int bufix = 0;
+
+ /* If there's no tree associated with this cache, it evaluates
+ to a constant and that was detected at startup. */
+ if (!tree_cache -> tree)
+ return 1;
+
+ /* Try to evaluate the tree without allocating more memory... */
+ tree_cache -> timeout = tree_evaluate_recurse (&bufix, &bp, &bc,
+ tree_cache -> tree);
+
+ /* No additional allocation needed? */
+ if (bufix <= bc) {
+ tree_cache -> len = bufix;
+ return 1;
+ }
+
+ /* If we can't allocate more memory, return with what we
+ have (maybe nothing). */
+ if (!(bp = (unsigned char *)dmalloc (bufix, "tree_evaluate")))
+ return 0;
+
+ /* Record the change in conditions... */
+ bc = bufix;
+ bufix = 0;
+
+ /* Note that the size of the result shouldn't change on the
+ second call to tree_evaluate_recurse, since we haven't
+ changed the ``current'' time. */
+ tree_evaluate_recurse (&bufix, &bp, &bc, tree_cache -> tree);
+
+ /* Free the old buffer if needed, then store the new buffer
+ location and size and return. */
+ if (tree_cache -> value)
+ dfree (tree_cache -> value, "tree_evaluate");
+ tree_cache -> value = bp;
+ tree_cache -> len = bufix;
+ tree_cache -> buf_size = bc;
+ return 1;
+}
+
+static TIME tree_evaluate_recurse (bufix, bufp, bufcount, tree)
+ int *bufix;
+ unsigned char **bufp;
+ int *bufcount;
+ struct tree *tree;
+{
+ int limit;
+ TIME t1, t2;
+
+ switch (tree -> op) {
+ case TREE_CONCAT:
+ t1 = tree_evaluate_recurse (bufix, bufp, bufcount,
+ tree -> data.concat.left);
+ t2 = tree_evaluate_recurse (bufix, bufp, bufcount,
+ tree -> data.concat.right);
+ if (t1 > t2)
+ return t2;
+ return t1;
+
+ case TREE_HOST_LOOKUP:
+ return do_host_lookup (bufix, bufp, bufcount,
+ tree -> data.host_lookup.host);
+
+ case TREE_CONST:
+ do_data_copy (bufix, bufp, bufcount,
+ tree -> data.const_val.data,
+ tree -> data.const_val.len);
+ t1 = MAX_TIME;
+ return t1;
+
+ case TREE_LIMIT:
+ limit = *bufix + tree -> data.limit.limit;
+ t1 = tree_evaluate_recurse (bufix, bufp, bufcount,
+ tree -> data.limit.tree);
+ *bufix = limit;
+ return t1;
+
+ default:
+ warn ("Bad node id in tree: %d.");
+ t1 = MAX_TIME;
+ return t1;
+ }
+}
+
+static TIME do_host_lookup (bufix, bufp, bufcount, dns)
+ int *bufix;
+ unsigned char **bufp;
+ int *bufcount;
+ struct dns_host_entry *dns;
+{
+ struct hostent *h;
+ int i;
+ int new_len;
+
+ debug ("time: now = %d dns = %d %d diff = %d",
+ cur_time, dns -> timeout, cur_time - dns -> timeout);
+
+ /* If the record hasn't timed out, just copy the data and return. */
+ if (cur_time <= dns -> timeout) {
+ debug ("easy copy: %x %d %x",
+ dns -> data, dns -> data_len, *(int *)(dns -> data));
+ do_data_copy (bufix, bufp, bufcount,
+ dns -> data, dns -> data_len);
+ return dns -> timeout;
+ }
+ debug ("Looking up %s", dns -> hostname);
+
+ /* Otherwise, look it up... */
+ h = gethostbyname (dns -> hostname);
+ if (!h) {
+ switch (h_errno) {
+ case HOST_NOT_FOUND:
+ warn ("%s: host unknown.", dns -> hostname);
+ break;
+ case TRY_AGAIN:
+ warn ("%s: temporary name server failure",
+ dns -> hostname);
+ break;
+ case NO_RECOVERY:
+ warn ("%s: name server failed", dns -> hostname);
+ break;
+ case NO_DATA:
+ warn ("%s: no A record associated with address",
+ dns -> hostname);
+ }
+
+ /* Okay to try again after a minute. */
+ return cur_time + 60;
+ }
+
+ debug ("Lookup succeeded; first address is %x",
+ h -> h_addr_list [0]);
+
+ /* Count the number of addresses we got... */
+ for (i = 0; h -> h_addr_list [i]; i++)
+ ;
+
+ /* Do we need to allocate more memory? */
+ new_len = i * h -> h_length;
+ if (dns -> buf_len < i) {
+ unsigned char *buf =
+ (unsigned char *)dmalloc (new_len, "do_host_lookup");
+ /* If we didn't get more memory, use what we have. */
+ if (!buf) {
+ new_len = dns -> buf_len;
+ if (!dns -> buf_len) {
+ dns -> timeout = cur_time + 60;
+ return dns -> timeout;
+ }
+ } else {
+ dfree (dns -> data, "do_host_lookup");
+ dns -> data = buf;
+ dns -> buf_len = new_len;
+ }
+ }
+
+ /* Addresses are conveniently stored one to the buffer, so we
+ have to copy them out one at a time... :'( */
+ for (i = 0; i < new_len / h -> h_length; i++)
+ memcpy (dns -> data + h -> h_length * i,
+ h -> h_addr_list [i], h -> h_length);
+ debug ("dns -> data: %x h -> h_addr_list [0]: %x",
+ *(int *)(dns -> data), h -> h_addr_list [0]);
+ dns -> data_len = new_len;
+
+ /* Set the timeout for an hour from now.
+ XXX This should really use the time on the DNS reply. */
+ dns -> timeout = cur_time + 3600;
+
+ debug ("hard copy: %x %d %x",
+ dns -> data, dns -> data_len, *(int *)(dns -> data));
+ do_data_copy (bufix, bufp, bufcount, dns -> data, dns -> data_len);
+ return dns -> timeout;
+}
+
+static void do_data_copy (bufix, bufp, bufcount, data, len)
+ int *bufix;
+ unsigned char **bufp;
+ int *bufcount;
+ unsigned char *data;
+ int len;
+{
+ int space = *bufcount - *bufix;
+
+ /* If there's more space than we need, use only what we need. */
+ if (space > len)
+ space = len;
+
+ /* Copy as much data as will fit, then increment the buffer index
+ by the amount we actually had to copy, which could be more. */
+ if (space > 0)
+ memcpy (*bufp + *bufix, data, space);
+ *bufix += len;
+}
--- /dev/null
+/* conf.y
+
+ Dhcpd configuration file grammar... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+%{
+#include "dhcpd.h"
+%}
+
+%token HOST HARDWARE ETHERNET FILENAME FIXED_ADDRESS STRING
+%token OCTET COLON DOT SEMI TOKEN OPTION
+
+%start config
+
+%%
+config : config_items
+ ;
+
+
+config_items: /* blank */
+ | config_item
+ | config_items config_item
+ ;
+
+config_item: host_decl
+ ;
+
+host_decl: HOST hostname packet_decls SEMI
+ ;
+
+hostname: token
+ | token DOT hostname
+ ;
+
+packet_decls: /* empty */
+ | packet_decl
+ | packet_decls packet_decl
+ ;
+
+packet_decl: hardware_decl
+ | filename_decl
+ | fixed_addr_decl
+ | option_decl
+ ;
+
+hardware_decl: HARDWARE ETHERNET OCTET COLON OCTET COLON OCTET
+ COLON OCTET COLON OCTET COLON OCTET
+ ;
+
+filename_decl: FILENAME STRING
+ ;
+
+fixed_addr_decl: FIXED_ADDRESS host_address
+ ;
+
+host_address: hostname
+ | ip_address
+ ;
+
+ip_address: OCTET DOT OCTET
+ | OCTET DOT OCTET DOT OCTET DOT OCTET
+ ;
+
+option_decl: OPTION token STRING
+ ;
+
+token: reserved_word
+ | TOKEN
+ ;
+
+reserved_word: HOST
+ | HARDWARE
+ | ETHERNET
+ | FILENAME
+ | FIXED_ADDRESS
+ | OPTION
+ ;
+
--- /dev/null
+/* conflex.c
+
+ Lexical scanner for dhcpd config file... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+#include "dhctoken.h"
+#include <ctype.h>
+
+static int line;
+static int lpos;
+int tlpos;
+int tline;
+static int token;
+static int ugflag;
+static char *tval;
+static char tokbuf [1500];
+
+static int get_char PROTO ((FILE *));
+static int get_token PROTO ((FILE *));
+static void skip_to_eol PROTO ((FILE *));
+static int read_string PROTO ((FILE *));
+static int read_number PROTO ((int, FILE *));
+static int read_num_or_atom PROTO ((int, FILE *));
+static int intern PROTO ((char *, int));
+
+static int get_char (cfile)
+ FILE *cfile;
+{
+ char c = getc (cfile);
+ if (!ugflag) {
+ if (c == EOL) {
+ line++;
+ lpos = 1;
+ } else {
+ lpos++;
+ }
+ } else
+ ugflag = 0;
+ return c;
+}
+
+static int get_token (cfile)
+ FILE *cfile;
+{
+ int c;
+ int i;
+ int ttok;
+
+ do {
+ c = get_char (cfile);
+ if (isascii (c) && isspace (c))
+ continue;
+ if (c == '#') {
+ skip_to_eol (cfile);
+ continue;
+ }
+ tlpos = lpos;
+ tline = line;
+ if (c == '"') {
+ ttok = read_string (cfile);
+ break;
+ }
+ if (isascii (c) && isdigit (c)) {
+ ttok = read_number (c, cfile);
+ break;
+ } else if (isascii (c) && isalpha (c)) {
+ ttok = read_num_or_atom (c, cfile);
+ break;
+ } else {
+ tval = 0;
+ ttok = c;
+ break;
+ }
+ } while (1);
+ return ttok;
+}
+
+int next_token (rval, cfile)
+ char **rval;
+ FILE *cfile;
+{
+ int rv;
+
+ if (token) {
+ rv = token;
+ token = 0;
+ } else {
+ rv = get_token (cfile);
+ }
+ if (rval)
+ *rval = tval;
+ return rv;
+}
+
+int peek_token (rval, cfile)
+ char **rval;
+ FILE *cfile;
+{
+ if (!token)
+ token = get_token (cfile);
+ if (rval)
+ *rval = tval;
+ return token;
+}
+
+static void skip_to_eol (cfile)
+ FILE *cfile;
+{
+ int c;
+ do {
+ c = get_char (cfile);
+ if (c == EOF)
+ return;
+ if (c == EOL) {
+ ungetc (c, cfile);
+ ugflag = 1;
+ return;
+ }
+ } while (1);
+}
+
+static int read_string (cfile)
+ FILE *cfile;
+{
+ int i;
+ int bs = 0;
+ int c;
+
+ for (i = 0; i < sizeof tokbuf; i++) {
+ c = get_char (cfile);
+ if (c == EOF) {
+ parse_warn ("eof in string constant");
+ break;
+ }
+ if (bs) {
+ bs = 0;
+ tokbuf [i] = c;
+ } else if (c == '\\')
+ bs = 1;
+ else if (c == '"')
+ break;
+ else
+ tokbuf [i] = c;
+ }
+ /* Normally, I'd feel guilty about this, but we're talking about
+ strings that'll fit in a DHCP packet here... */
+ if (i == sizeof tokbuf) {
+ parse_warn ("string constant larger than internal buffer");
+ --i;
+ }
+ tokbuf [i] = 0;
+ tval = tokbuf;
+ return STRING;
+}
+
+static int read_number (c, cfile)
+ int c;
+ FILE *cfile;
+{
+ int seenx = 0;
+ int i = 0;
+ tokbuf [i++] = c;
+ for (; i < sizeof tokbuf; i++) {
+ c = get_char (cfile);
+ if (!seenx && c == 'x')
+ seenx = 1;
+ else if (!isascii (c) || !isxdigit (c)) {
+ ungetc (c, cfile);
+ ugflag = 1;
+ break;
+ }
+ tokbuf [i] = c;
+ }
+ if (i == sizeof tokbuf) {
+ parse_warn ("numeric token larger than internal buffer");
+ --i;
+ }
+ tokbuf [i] = 0;
+ tval = tokbuf;
+ return NUMBER;
+}
+
+static int read_num_or_atom (c, cfile)
+ int c;
+ FILE *cfile;
+{
+ int i = 0;
+ int rv = NUMBER_OR_ATOM;
+ tokbuf [i++] = c;
+ for (; i < sizeof tokbuf; i++) {
+ c = get_char (cfile);
+ if (!isascii (c) ||
+ (c != '-' && c != '_' && !isalnum (c))) {
+ ungetc (c, cfile);
+ ugflag = 1;
+ break;
+ }
+ if (!isxdigit (c))
+ rv = ATOM;
+ tokbuf [i] = c;
+ }
+ if (i == sizeof tokbuf) {
+ parse_warn ("token larger than internal buffer");
+ --i;
+ }
+ tokbuf [i] = 0;
+ tval = tokbuf;
+ return intern (tval, rv);
+}
+
+static int intern (atom, dfv)
+ char *atom;
+ int dfv;
+{
+ switch (atom [0]) {
+ case 'h':
+ if (!strcasecmp (atom + 1, "ost"))
+ return HOST;
+ if (!strcasecmp (atom + 1, "ardware"))
+ return HARDWARE;
+ break;
+ case 'f':
+ if (!strcasecmp (atom + 1, "ilename"))
+ return FILENAME;
+ if (!strcasecmp (atom + 1, "ixed-address"))
+ return FIXED_ADDR;
+ break;
+ case 'e':
+ if (!strcasecmp (atom + 1, "thernet"))
+ return ETHERNET;
+ break;
+ case 'o':
+ if (!strcasecmp (atom + 1, "ption"))
+ return OPTION;
+ break;
+ }
+ return dfv;
+}
--- /dev/null
+/* confpars.c
+
+ Parser for dhcpd config file... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+#include "dhctoken.h"
+
+static TIME parsed_time;
+
+/* conf-file :== statements
+ declarations :== <nil> | declaration | declarations declaration */
+
+void readconf (void)
+{
+ FILE *cfile;
+ char *val;
+ int token;
+
+ /* Set up the initial dhcp option universe. */
+ initialize_universes ();
+
+ if ((cfile = fopen (_PATH_DHCPD_CONF, "r")) == NULL)
+ error ("Can't open %s: %m", _PATH_DHCPD_CONF);
+ do {
+ token = peek_token (&val, cfile);
+ if (token == EOF)
+ break;
+ parse_statement (cfile);
+ } while (1);
+}
+
+/* statement :== host_statement */
+
+void parse_statement (cfile)
+ FILE *cfile;
+{
+ char *val;
+ jmp_buf bc;
+
+ switch (next_token (&val, cfile)) {
+ case HOST:
+ if (!setjmp (bc)) {
+ struct host_decl *hd =
+ parse_host_statement (cfile, &bc);
+ if (hd) {
+ enter_host (hd);
+ }
+ }
+ break;
+ case LEASE:
+ if (!setjmp (bc)) {
+ struct lease *lease =
+ parse_lease_statement (cfile, &bc);
+ enter_lease (lease);
+ }
+ break;
+ case TIMESTAMP:
+ if (!setjmp (bc)) {
+ parsed_time = parse_timestamp (cfile, &bc);
+ }
+ break;
+ case RANGE:
+ if (!setjmp (bc)) {
+ parse_address_range (cfile, &bc);
+ }
+ break;
+ default:
+ parse_warn ("expecting a declaration.");
+ skip_to_semi (cfile);
+ break;
+ }
+}
+
+void skip_to_semi (cfile)
+ FILE *cfile;
+{
+ int token;
+ char *val;
+
+ do {
+ token = next_token (&val, cfile);
+ } while (token != SEMI && token != EOF);
+}
+
+/* host_statement :== HOST hostname declarations SEMI
+ host_declarations :== <nil> | host_declaration
+ | host_declarations host_declaration */
+
+struct host_decl *parse_host_statement (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ char *val;
+ int token;
+ struct host_decl tmp, *perm;
+
+ memset (&tmp, 0, sizeof tmp);
+ tmp.name = parse_host_name (cfile, bc);
+ do {
+ token = peek_token (&val, cfile);
+ if (token == SEMI) {
+ token = next_token (&val, cfile);
+ break;
+ }
+ parse_host_decl (cfile, bc, &tmp);
+ } while (1);
+ perm = (struct host_decl *)malloc (sizeof (struct host_decl));
+ if (!perm)
+ error ("can't allocate host decl struct for %s.", tmp.name);
+ *perm = tmp;
+ return perm;
+}
+
+/* host_name :== identifier | host_name DOT identifier */
+
+char *parse_host_name (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ char *val;
+ int token;
+ int len = 0;
+ char *s;
+ char *t;
+ pair c = (pair)0;
+
+ /* Read a dotted hostname... */
+ do {
+ /* Read a token, which should be an identifier. */
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting an identified in hostname");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ /* Store this identifier... */
+ if (!(s = (char *)malloc (strlen (val) + 1)))
+ error ("can't allocate temp space for hostname.");
+ strcpy (s, val);
+ c = cons ((caddr_t)s, c);
+ len += strlen (s) + 1;
+ /* Look for a dot; if it's there, keep going, otherwise
+ we're done. */
+ token = peek_token (&val, cfile);
+ if (token == DOT)
+ token = next_token (&val, cfile);
+ } while (token == DOT);
+
+ /* Assemble the hostname together into a string. */
+ if (!(s = (char *)malloc (len)))
+ error ("can't allocate space for hostname.");
+ t = s + len;
+ *--t = 0;
+ while (c) {
+ pair cdr = c -> cdr;
+ int l = strlen ((char *)(c -> car));
+ t -= l;
+ memcpy (t, (char *)(c -> car), l);
+ /* Free up temp space. */
+ free (c -> car);
+ free (c);
+ c = cdr;
+ if (t != s)
+ *--t = '.';
+ }
+ return s;
+}
+
+/* host_declaration :== hardware_declaration | filename_declaration
+ | fixed_addr_declaration | option_declaration */
+
+void parse_host_decl (cfile, bc, decl)
+ FILE *cfile;
+ jmp_buf *bc;
+ struct host_decl *decl;
+{
+ char *val;
+ int token;
+
+ token = next_token (&val, cfile);
+ switch (token) {
+ case HARDWARE:
+ parse_hardware_decl (cfile, bc, decl);
+ break;
+ case FILENAME:
+ parse_filename_decl (cfile, bc, decl);
+ break;
+ case FIXED_ADDR:
+ parse_fixed_addr_decl (cfile, bc, decl);
+ break;
+ case OPTION:
+ parse_option_decl (cfile, bc, decl);
+ break;
+ default:
+ parse_warn ("expecting a dhcp option declaration.");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ break;
+ }
+}
+
+/* hardware_decl :== HARDWARE ETHERNET NUMBER COLON NUMBER COLON NUMBER COLON
+ NUMBER COLON NUMBER COLON NUMBER */
+
+void parse_hardware_decl (cfile, bc, decl)
+ FILE *cfile;
+ jmp_buf *bc;
+ struct host_decl *decl;
+{
+ char *val;
+ int token;
+ struct hardware hw;
+
+ hw = parse_hardware_addr (cfile, bc);
+
+ /* Find space for the new interface... */
+ if (decl -> interfaces) {
+ decl -> interfaces =
+ (struct hardware *)realloc (decl -> interfaces,
+ ++decl -> interface_count *
+ sizeof (struct hardware));
+ } else {
+ decl -> interfaces =
+ (struct hardware *)malloc (sizeof (struct hardware));
+ decl -> interface_count = 1;
+ }
+ if (!decl -> interfaces)
+ error ("no memory for hardware interface info.");
+
+ /* Copy out the information... */
+ decl -> interfaces [decl -> interface_count - 1].htype = hw.htype;
+ decl -> interfaces [decl -> interface_count - 1].hlen = hw.hlen;
+ memcpy (decl -> interfaces [decl -> interface_count - 1].haddr,
+ &hw.haddr, hw.hlen);
+}
+
+struct hardware parse_hardware_addr (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ char *val;
+ int token;
+ int hlen;
+ struct hardware rv;
+
+ token = next_token (&val, cfile);
+ switch (token) {
+ case ETHERNET:
+ rv.htype = ARPHRD_ETHER;
+ hlen = 6;
+ parse_numeric_aggregate (cfile, bc,
+ (unsigned char *)&rv.haddr, &hlen,
+ COLON, 16, 8);
+ rv.hlen = hlen;
+ break;
+ default:
+ parse_warn ("expecting a network hardware type");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ return rv;
+}
+
+/* filename_decl :== FILENAME STRING */
+
+void parse_filename_decl (cfile, bc, decl)
+ FILE *cfile;
+ jmp_buf *bc;
+ struct host_decl *decl;
+{
+ char *val;
+ int token;
+ char *s;
+
+ token = next_token (&val, cfile);
+ if (token != STRING) {
+ parse_warn ("filename must be a string");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ s = (char *)malloc (strlen (val));
+ if (!s)
+ error ("no memory for filename.");
+ strcpy (s, val);
+ decl -> filename = s;
+}
+
+/* ip_addr_or_hostname :== ip_address | hostname
+ ip_address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
+
+ Parse an ip address or a hostname. If uniform is zero, put in
+ a TREE_LIMIT node to catch hostnames that evaluate to more than
+ one IP address. */
+
+struct tree *parse_ip_addr_or_hostname (cfile, bc, uniform)
+ FILE *cfile;
+ jmp_buf *bc;
+ int uniform;
+{
+ char *val;
+ int token;
+ unsigned char addr [4];
+ int len = sizeof addr;
+ char *name;
+ struct tree *rv;
+
+ token = peek_token (&val, cfile);
+ if (is_identifier (token)) {
+ name = parse_host_name (cfile, bc);
+ rv = tree_host_lookup (name);
+ if (!uniform)
+ rv = tree_limit (rv, 4);
+ } else if (token == NUMBER) {
+ parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
+ rv = tree_const (addr, len);
+ } else {
+ parse_warn ("%s (%d): expecting IP address or hostname",
+ val, token);
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ return rv;
+}
+
+
+/* fixed_addr_declaration :== FIXED_ADDR ip_addr_or_hostname */
+
+void parse_fixed_addr_decl (cfile, bc, decl)
+ FILE *cfile;
+ jmp_buf *bc;
+ struct host_decl *decl;
+{
+ decl -> fixed_addr =
+ tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
+}
+
+/* option_declaration :== OPTION identifier DOT identifier <syntax> |
+ OPTION identifier <syntax>
+
+ Option syntax is handled specially through format strings, so it
+ would be painful to come up with BNF for it. However, it always
+ starts as above. */
+
+void parse_option_decl (cfile, bc, decl)
+ FILE *cfile;
+ jmp_buf *bc;
+ struct host_decl *decl;
+{
+ char *val;
+ int token;
+ unsigned char buf [4];
+ char *vendor;
+ char *fmt;
+ struct universe *universe;
+ struct option *option;
+ struct tree *tree = (struct tree *)0;
+
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting identifier after option keyword.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ vendor = dmalloc (strlen (val) + 1, "parse_option_decl");
+ strcpy (vendor, val);
+ token = peek_token (&val, cfile);
+ if (token == DOT) {
+ /* Go ahead and take the DOT token... */
+ token = next_token (&val, cfile);
+
+ /* The next token should be an identifier... */
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting identifier after '.'");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Look up the option name hash table for the specified
+ vendor. */
+ universe = (struct universe *)hash_lookup (&universe_hash,
+ vendor, 0);
+ /* If it's not there, we can't parse the rest of the
+ statement. */
+ if (!universe) {
+ parse_warn ("no vendor named %s.", vendor);
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ } else {
+ /* Use the default hash table, which contains all the
+ standard dhcp option names. */
+ val = vendor;
+ universe = &dhcp_universe;
+ }
+
+ /* Look up the actual option info... */
+ option = (struct option *)hash_lookup (universe -> hash, val, 0);
+
+ /* If we didn't get an option structure, it's an undefined option. */
+ if (!option) {
+ if (val == vendor)
+ parse_warn ("no option named %s", val);
+ else
+ parse_warn ("no option named %s for vendor %s",
+ val, vendor);
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Free the initial identifier token. */
+ free (vendor);
+
+ /* Parse the option data... */
+ do {
+ /* Set a flag if this is an array of a simple type (i.e.,
+ not an array of pairs of IP addresses, or something
+ like that. */
+ int uniform = option -> format [1] == 'A';
+
+ for (fmt = option -> format; *fmt; fmt++) {
+ if (*fmt == 'A')
+ break;
+ switch (*fmt) {
+ case 't': /* Text string... */
+ token = next_token (&val, cfile);
+ if (token != STRING
+ && !is_identifier (token)) {
+ parse_warn ("expecting string.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tree = tree_concat (tree,
+ tree_const (val,
+ strlen (val)));
+ break;
+
+ case 'I': /* IP address or hostname. */
+ tree = tree_concat (tree,
+ parse_ip_addr_or_hostname
+ (cfile, bc, uniform));
+ break;
+
+ case 'L': /* Unsigned 32-bit integer... */
+ case 'l': /* Signed 32-bit integer... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ need_number:
+ parse_warn ("expecting number.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ convert_num (buf, val, 0, 32);
+ tree = tree_concat (tree, tree_const (buf, 4));
+ break;
+ case 's': /* Signed 16-bit integer. */
+ case 'S': /* Unsigned 16-bit integer. */
+ token = next_token (&val, cfile);
+ if (token != NUMBER)
+ goto need_number;
+ convert_num (buf, val, 0, 16);
+ tree = tree_concat (tree, tree_const (buf, 2));
+ break;
+ case 'b': /* Signed 8-bit integer. */
+ case 'B': /* Unsigned 8-bit integer. */
+ token = next_token (&val, cfile);
+ if (token != NUMBER)
+ goto need_number;
+ convert_num (buf, val, 0, 8);
+ tree = tree_concat (tree, tree_const (buf, 1));
+ break;
+ case 'f': /* Boolean flag. */
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting identifier.");
+ bad_flag:
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ if (!strcasecmp (val, "true")
+ || !strcasecmp (val, "on"))
+ buf [0] = 1;
+ else if (!strcasecmp (val, "false")
+ || !strcasecmp (val, "off"))
+ buf [0] = 0;
+ else {
+ parse_warn ("expecting boolean.");
+ goto bad_flag;
+ }
+ tree = tree_concat (tree, tree_const (buf, 1));
+ break;
+ default:
+ warn ("Bad format %c in parse_option_decl.",
+ *fmt);
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ }
+ if (*fmt == 'A') {
+ token = peek_token (&val, cfile);
+ if (token == COMMA) {
+ token = next_token (&val, cfile);
+ continue;
+ }
+ break;
+ }
+ } while (*fmt == 'A');
+
+ if (decl -> options [option -> code]) {
+ parse_warn ("duplicate option code %d (%s).",
+ option -> code, option -> name);
+ }
+ decl -> options [option -> code] = tree_cache (tree);
+}
+
+/* timestamp :== TIMESTAMP date
+
+ Timestamps are actually not used in dhcpd.conf, which is a static file,
+ but rather in the database file and the journal file. */
+
+TIME parse_timestamp (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ return parse_date (cfile, bc);
+}
+
+/* lease_decl :== LEASE ip_address lease_modifiers
+ lease_modifiers :== <nil>
+ | lease_modifier
+ | lease_modifier lease_modifiers
+ lease_modifier :== STARTS date
+ | ENDS date
+ | UID hex_numbers
+ | HOST identifier
+ | CLASS identifier
+ | TIMESTAMP number */
+
+struct lease *parse_lease_statement (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ char *val;
+ int token;
+ unsigned char addr [4];
+ int len = sizeof addr;
+ char *name;
+ unsigned char *uid;
+ int seenmask = 0;
+ int seenbit;
+ char tbuf [32];
+ char ubuf [1024];
+ static struct lease lease;
+
+ /* Get the address for which the lease has been issued. */
+ parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
+ memcpy (&lease.ip_addr, addr, len);
+
+ do {
+ token = next_token (&val, cfile);
+ if (token == SEMI)
+ break;
+ strncpy (val, tbuf, sizeof tbuf);
+ tbuf [(sizeof tbuf) - 1] = 0;
+
+ /* Parse any of the times associated with the lease. */
+ if (token == STARTS || token == ENDS || token == TIMESTAMP) {
+ TIME t;
+ t = parse_date (cfile, bc);
+ switch (token) {
+ case STARTS:
+ seenbit = 1;
+ lease.starts = t;
+ break;
+
+ case ENDS:
+ seenbit = 2;
+ lease.ends = t;
+ break;
+
+ case TIMESTAMP:
+ seenbit = 4;
+ lease.timestamp = t;
+ break;
+ }
+ } else {
+ switch (token) {
+ /* Colon-seperated hexadecimal octets... */
+ case UID:
+ seenbit = 8;
+ lease.uid_len = 0;
+ parse_numeric_aggregate (cfile, bc, ubuf,
+ &lease.uid_len,
+ ':', 16, 8);
+ lease.uid = (unsigned char *)
+ malloc (lease.uid_len);
+ if (!lease.uid) {
+ error ("No memory for lease uid");
+ }
+ memcpy (lease.uid, ubuf, lease.uid_len);
+ break;
+
+ case HOST:
+ seenbit = 16;
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ lease.host =
+ find_host_by_name (val);
+ if (!lease.host)
+ parse_warn ("lease host ``%s'' is %s",
+ lease.host,
+ "no longer known.");
+ break;
+
+ case CLASS:
+ seenbit = 32;
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ /* for now, we aren't using this. */
+ break;
+
+ case HARDWARE:
+ seenbit = 64;
+ lease.hardware_addr
+ = parse_hardware_addr (cfile, bc);
+ break;
+
+ default:
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ }
+ if (seenmask & seenbit) {
+ parse_warn ("Too many %s declarations in lease %s\n",
+ tbuf, inet_ntoa (lease.ip_addr));
+ } else
+ seenmask |= seenbit;
+ } while (1);
+ return &lease;
+}
+
+/* address_range :== RANGE ip_address ip_address ip_address */
+
+void parse_address_range (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ struct in_addr low, high, mask;
+ unsigned char addr [4];
+ int len = sizeof addr;
+
+ /* Get the bottom address in the range... */
+ parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
+ memcpy (&low, addr, len);
+
+ /* Get the top address in the range... */
+ parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
+ memcpy (&high, addr, len);
+
+ /* Get the netmask of the subnet containing the range... */
+ parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
+ memcpy (&mask, addr, len);
+
+ /* Create the new address range... */
+ new_address_range (low, high, mask);
+}
+
+/* date :== NUMBER NUMBER/NUMBER/NUMBER NUMBER:NUMBER:NUMBER
+
+ Dates are always in GMT; first number is day of week; next is
+ year/month/day; next is hours:minutes:seconds on a 24-hour
+ clock. */
+
+TIME parse_date (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ TIME t;
+ struct tm tm;
+ char *val;
+ int token;
+
+ /* Day of week... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric day of week expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_wday = atoi (token);
+
+ /* Year... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric year expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_year = atoi (token);
+ if (tm.tm_year > 1900)
+ tm.tm_year -= 1900;
+
+ /* Slash seperating year from month... */
+ token = next_token (&val, cfile);
+ if (token != SLASH) {
+ parse_warn ("expected slash seperating year from month.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Month... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric month expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_mon = atoi (token);
+
+ /* Slash seperating month from day... */
+ token = next_token (&val, cfile);
+ if (token != SLASH) {
+ parse_warn ("expected slash seperating month from day.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Month... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric day of month expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_mday = atoi (token);
+
+ /* Hour... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric hour expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_hour = atoi (token);
+
+ /* Colon seperating hour from minute... */
+ token = next_token (&val, cfile);
+ if (token != COLON) {
+ parse_warn ("expected colon seperating hour from minute.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Minute... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric minute expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_min = atoi (token);
+
+ /* Colon seperating minute from second... */
+ token = next_token (&val, cfile);
+ if (token != COLON) {
+ parse_warn ("expected colon seperating hour from minute.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Minute... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric minute expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_sec = atoi (token);
+
+ tm.tm_zone = "GMT";
+ tm.tm_isdst = 0;
+ tm.tm_gmtoff = 0;
+
+ /* XXX */ /* We assume that mktime does not use tm_yday. */
+ tm.tm_yday = 0;
+
+ return mktime (&tm);
+}
+
+/* No BNF for numeric aggregates - that's defined by the caller. What
+ this function does is to parse a sequence of numbers seperated by
+ the token specified in seperator. If max is zero, any number of
+ numbers will be parsed; otherwise, exactly max numbers are
+ expected. Base and size tell us how to internalize the numbers
+ once they've been tokenized. */
+
+unsigned char *parse_numeric_aggregate (cfile, bc, buf,
+ max, seperator, base, size)
+ FILE *cfile;
+ jmp_buf *bc;
+ unsigned char *buf;
+ int *max;
+ int seperator;
+ int base;
+ int size;
+{
+ char *val;
+ int token;
+ unsigned char *bufp = buf, *s, *t;
+ int count = 0;
+ pair c = (pair)0;
+
+ if (!bufp && *max) {
+ bufp = (unsigned char *)malloc (*max * size / 8);
+ if (!bufp)
+ error ("can't allocate space for numeric aggregate");
+ } else
+ s = bufp;
+
+ do {
+ if (count) {
+ token = peek_token (&val, cfile);
+ if (token != seperator) {
+ if (!*max)
+ break;
+ parse_warn ("too few numbers.");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ token = next_token (&val, cfile);
+ }
+ token = next_token (&val, cfile);
+ /* Allow NUMBER_OR_ATOM if base is 16. */
+ if (token != NUMBER &&
+ (base != 16 || token != NUMBER_OR_ATOM)) {
+ parse_warn ("expecting numeric value.");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ /* If we can, convert the number now; otherwise, build
+ a linked list of all the numbers. */
+ if (s) {
+ convert_num (s, val, base, size);
+ s += size / 8;
+ } else {
+ t = (char *)malloc (strlen (val) + 1);
+ if (!t)
+ error ("no temp space for number.");
+ strcpy (t, val);
+ c = cons (t, c);
+ }
+ } while (++count != *max);
+
+ /* If we had to cons up a list, convert it now. */
+ if (c) {
+ bufp = (unsigned char *)malloc (count * size / 8);
+ if (!bufp)
+ error ("can't allocate space for numeric aggregate.");
+ s = bufp;
+ *max = count;
+ }
+ while (c) {
+ pair cdr = c -> cdr;
+ convert_num (s, (char *)(c -> car), base, size);
+ s += size / 8;
+ /* Free up temp space. */
+ free (c -> car);
+ free (c);
+ c = cdr;
+ }
+ return bufp;
+}
+
+void convert_num (buf, str, base, size)
+ unsigned char *buf;
+ char *str;
+ int base;
+ int size;
+{
+ char *ptr = str;
+ int negative = 0;
+ u_int32_t val = 0;
+ int tval;
+ int max;
+
+ if (*ptr == '-') {
+ negative = 1;
+ ++ptr;
+ }
+
+ /* If base wasn't specified, figure it out from the data. */
+ if (!base) {
+ if (ptr [0] == '0') {
+ if (ptr [1] == 'x') {
+ base = 16;
+ ptr += 2;
+ } else if (isascii (ptr [1]) && isdigit (ptr [1])) {
+ base = 8;
+ ptr += 1;
+ } else {
+ base = 10;
+ }
+ } else {
+ base = 10;
+ }
+ }
+
+ do {
+ tval = *ptr++;
+ /* XXX assumes ASCII... */
+ if (tval >= 'a')
+ tval = tval - 'a' + 10;
+ else if (tval >= 'A')
+ tval = tval - 'A' + 10;
+ else if (tval >= '0')
+ tval -= '0';
+ else {
+ warn ("Bogus number: %s.", str);
+ break;
+ }
+ if (tval >= base) {
+ warn ("Bogus number: %s: digit %d not in base %d\n",
+ str, tval, base);
+ break;
+ }
+ val = val * base + tval;
+ } while (*ptr);
+
+ if (negative)
+ max = (1 << (size - 1));
+ else
+ max = (1 << size) - 1;
+ if (val > max) {
+ switch (base) {
+ case 8:
+ warn ("value %s%lo exceeds max (%d) for precision.",
+ negative ? "-" : "", val, max);
+ break;
+ case 16:
+ warn ("value %s%lx exceeds max (%d) for precision.",
+ negative ? "-" : "", val, max);
+ break;
+ default:
+ warn ("value %s%ld exceeds max (%d) for precision.",
+ negative ? "-" : "", val, max);
+ break;
+ }
+ }
+
+ if (negative) {
+ switch (size) {
+ case 8:
+ *buf = -(unsigned long)val;
+ break;
+ case 16:
+ putShort (buf, -(unsigned long)val);
+ break;
+ case 32:
+ putLong (buf, -(unsigned long)val);
+ break;
+ default:
+ warn ("Unexpected integer size: %d\n");
+ break;
+ }
+ } else {
+ switch (size) {
+ case 8:
+ *buf = (u_int8_t)val;
+ break;
+ case 16:
+ putUShort (buf, (u_int16_t)val);
+ break;
+ case 32:
+ putULong (buf, val);
+ break;
+ default:
+ warn ("Unexpected integer size: %d\n");
+ break;
+ }
+ }
+}
--- /dev/null
+/* convert.c
+
+ Safe copying of option values into and out of the option buffer, which
+ can't be assumed to be aligned. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+unsigned long getULong (buf)
+ unsigned char *buf;
+{
+ unsigned long ibuf;
+
+ memcpy (&ibuf, buf, sizeof (unsigned long));
+ return ntohl (ibuf);
+}
+
+long getLong (buf)
+ unsigned char *buf;
+{
+ long ibuf;
+
+ memcpy (&ibuf, buf, sizeof (long));
+ return ntohl (ibuf);
+}
+
+unsigned short getUShort (buf)
+ unsigned char *buf;
+{
+ unsigned short ibuf;
+
+ memcpy (&ibuf, buf, sizeof (unsigned short));
+ return ntohs (ibuf);
+}
+
+short getShort (buf)
+ unsigned char *buf;
+{
+ short ibuf;
+
+ memcpy (&ibuf, buf, sizeof (short));
+ return ntohs (ibuf);
+}
+
+void putULong (obuf, val)
+ unsigned char *obuf;
+ unsigned long val;
+{
+ unsigned long tmp = htonl (val);
+ memcpy (obuf, &tmp, sizeof tmp);
+}
+
+void putLong (obuf, val)
+ unsigned char *obuf;
+ long val;
+{
+ long tmp = htonl (val);
+ memcpy (obuf, &tmp, sizeof tmp);
+}
+
+void putUShort (obuf, val)
+ unsigned char *obuf;
+ unsigned short val;
+{
+ unsigned short tmp = htonl (val);
+ memcpy (obuf, &tmp, sizeof tmp);
+}
+
+void putShort (obuf, val)
+ unsigned char *obuf;
+ short val;
+{
+ short tmp = htonl (val);
+ memcpy (obuf, &tmp, sizeof tmp);
+}
+
--- /dev/null
+/* db.c
+
+ IP Address Allocation database... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+/*
+ The IP Address Allocation Database tracks addresses that have been
+ allocated from the free pool as specified in dhcpd.conf. The
+ database is maintained in two parts to maintain integrity: the
+ journal file and the data file.
+
+ Both files are free-form flat files similar to dhcpd.conf, but with
+ a more limited syntax - all that can be specified are leases and
+ who they belong to.
+
+ When dhcpd starts up, it reads the entire data file into memory.
+ It then reads the journal file into memory and makes corrections to
+ the data based on journal entries.
+
+ While dhcpd is running, it periodically records the current time,
+ forks (if possible) and dumps the recorded time and its internal
+ database of temporarily assigned addresses into a temporary file.
+ It then removes any existing backup file, renames the existing file
+ with the backup filename, and then renames the new temporary file
+ with the real data file name. The link syscall is not present on
+ most systems, so a synchronous ``rename'' that guarantees that
+ exactly one file will be the master database may not be possible.
+ Therefore the recovery routine needs to know what to do if it finds
+ a backup and a temporary file, but no database file.
+
+ Whenever a client requests that an address be allocated to it, or
+ requests a lease renewal, and the server is able to satisfy the
+ request, it writes a record into the journal file indicating what
+ has been requested and waits for that information to reach the
+ disk. Once the file's dirty buffers have been flushed, the server
+ responds to the request, and logs another record in the journal
+ indicating that it has done so.
+
+ Entries in the journal file are logged along with the time at which
+ the logging occurred. When the server forks to dump the database,
+ it records the current time before forking. The copy of the server
+ that writes out the database records the time read prior to forking
+ in the new data file. The copy of the server that continues to
+ serve DHCP requests ensures that any journal entries subsequent to
+ the fork have time stamps that are greater than the time read
+ before forking. When recovering from a crash, the server discards
+ any entries in the journal which have time stamps earlier than the
+ time stamp on the data file.
+
+ When recovering from a crash, dhcpd may find a journal entry for a
+ request, but no entry indicating that it was satisfied. There is
+ no automatic way to recover from this, since the server may have
+ sent out a response, so in this case the server must notify
+ sysadmin of the problem and leave it to them to solve it.
+
+ In addition to the actual data files, we also keep a running log of
+ ``interesting'' events, which we mail to the dhcp-admin alias every
+ morning at 7:00 AM. This log can be tailed by paranoid sysadmins
+ or in times of network trouble. */
+
+/* Initialize the internal database, perform crash recovery as needed. */
+
+void dbinit ()
+{
+ FILE *dbfile;
+
+ /* We are assuming that on entry, there is no other dhcpd
+ running on this machine. If there were, there would be the
+ potential for serious database corruption. The main code
+ currently assures that there is only one server running by
+ listening on the bootps port with INADDR_ANY. Unices that
+ I'm familiar with will only allow one process to do this,
+ even if the SO_REUSEADDR option is set. 'twouldn't surprise
+ me terribly, though, if this didn't work for some other
+ operating system. Beware. XXX */
+
+ /* Look for a file under the official database name.
+ Failing that, look for a file under the backup name.
+ If we find neither, we assume that the database is empty. */
+
+ if ((dbfile = fopen (_PATH_DHCP_DB, "r")) != NULL
+ (dbfile = fopen (_PATH_DHCP_DB_BACKUP, "r") != NULL)) {
+
+ /* Read in the data file, making a list of assigned
+ addresses that have been removed from dhcpd.conf. */
+
+ }
+
+ /* Open the journal file and read through any entries which
+ are out of date. */
+
+ /* Now read entries that postdate the last database sync,
+ keeping track of incomplete entries (when we're done, there
+ should never be more than one such entry. */
+
+ /* Now expire any leases that have lapsed since we last ran. */
+
+ /* ...and we're done... */
+}
--- /dev/null
+/* dhcp.c
+
+ DHCP Protocol support. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+void dhcp (packet)
+ struct packet *packet;
+{
+}
--- /dev/null
+/* dhcp.h
+
+ Protocol structures... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#define DHCP_UDP_OVERHEAD (14 + /* Ethernet header */ \
+ 20 + /* IP header */ \
+ 8) /* UDP header */
+#define DHCP_SNAME_LEN 64
+#define DHCP_FILE_LEN 128
+#define DHCP_FIXED_LEN (236 + DHCP_UDP_OVERHEAD) /* Everything but
+ options. */
+#define DHCP_MTU_MAX 1500
+#define DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
+
+struct dhcp_packet {
+ u_int8_t op; /* Message opcode/type */
+ u_int8_t htype; /* Hardware addr type (see net/if_types.h) */
+ u_int8_t hlen; /* Hardware addr length */
+ u_int8_t hops; /* Number of relay agent hops from client */
+ u_int32_t xid; /* Transaction ID */
+ u_int16_t secs; /* Seconds since client started looking */
+ u_int16_t flags; /* Flag bits */
+ struct in_addr ciaddr; /* Client IP address (if already in use) */
+ struct in_addr yiaddr; /* Client IP address */
+ struct in_addr siaddr; /* IP address of next server to talk to */
+ struct in_addr giaddr; /* DHCP relay agent IP address */
+ char chaddr [16]; /* Client hardware address */
+ char sname [64]; /* Server name */
+ char file [128]; /* Boot filename */
+ char options [DHCP_OPTION_LEN]; /* Optional parameters
+ (actual length dependent on MTU). */
+};
+
+/* BOOTP (rfc951) message types */
+#define BOOTREQUEST 1
+#define BOOTREPLY 2
+
+/* Possible values for flags field... */
+#define BOOTP_BROADCAST 32768L
+
+/* Magic cookie validating dhcp options field (and bootp vendor
+ extensions field). */
+#define DHCP_OPTIONS_COOKIE "\143\202\123\143"
+
+/* DHCP Option codes: */
+
+#define DHO_PAD 0
+#define DHO_SUBNET_MASK 1
+#define DHO_TIME_OFFSET 2
+#define DHO_ROUTERS 3
+#define DHO_TIME_SERVERS 4
+#define DHO_NAME_SERVERS 5
+#define DHO_DOMAIN_NAME_SERVERS 6
+#define DHO_LOG_SERVERS 7
+#define DHO_COOKIE_SERVERS 8
+#define DHO_LPR_SERVERS 9
+#define DHO_IMPRESS_SERVERS 10
+#define DHO_RESOURCE_LOCATION_SERVERS 11
+#define DHO_HOST_NAME 12
+#define DHO_BOOT_SIZE 13
+#define DHO_MERIT_DUMP 14
+#define DHO_DOMAIN_NAME 15
+#define DHO_SWAP_SERVER 16
+#define DHO_ROOT_PATH 17
+#define DHO_EXTENSIONS_PATH 18
+#define DHO_IP_FORWARDING 19
+#define DHO_NON_LOCAL_SOURCE_ROUTING 20
+#define DHO_POLICY_FILTER 21
+#define DHO_MAX_DGRAM_REASSEMBLY 22
+#define DHO_DEFAULT_IP_TTL 23
+#define DHO_PATH_MTU_AGING_TIMEOUT 24
+#define DHO_PATH_MTU_PLATEAU_TABLE 25
+#define DHO_INTERFACE_MTU 26
+#define DHO_ALL_SUBNETS_LOCAL 27
+#define DHO_BROADCAST_ADDRESS 28
+#define DHO_PERFORM_MASK_DISCOVERY 29
+#define DHO_MASK_SUPPLIER 30
+#define DHO_ROUTER_DISCOVERY 31
+#define DHO_ROUTER_SOLICITATION_ADDRESS 32
+#define DHO_STATIC_ROUTES 33
+#define DHO_TRAILER_ENCAPSULATION 34
+#define DHO_ARP_CACHE_TIMEOUT 35
+#define DHO_IEEE802_3_ENCAPSULATION 36
+#define DHO_DEFAULT_TCP_TTL 37
+#define DHO_TCP_KEEPALIVE_INTERVAL 38
+#define DHO_TCP_KEEPALIVE_GARBAGE 39
+#define DHO_NIS_DOMAIN 40
+#define DHO_NIS_SERVERS 41
+#define DHO_NTP_SERVERS 42
+#define DHO_VENDOR_ENCAPSULATED_OPTIONS 43
+#define DHO_NETBIOS_NAME_SERVERS 44
+#define DHO_NETBIOS_DD_SERVER 45
+#define DHO_NETBIOS_NODE_TYPE 46
+#define DHO_NETBIOS_SCOPE 47
+#define DHO_FONT_SERVERS 48
+#define DHO_X_DISPLAY_MANAGER 49
+#define DHO_DHCP_REQUESTED_ADDRESS 50
+#define DHO_DHCP_LEASE_TIME 51
+#define DHO_DHCP_OPTION_OVERLOAD 52
+#define DHO_DHCP_MESSAGE_TYPE 53
+#define DHO_DHCP_SERVER_IDENTIFIER 54
+#define DHO_DHCP_PARAMETER_REQUEST_LIST 55
+#define DHO_DHCP_MESSAGE 56
+#define DHO_DHCP_MAX_MESSAGE_SIZE 57
+#define DHO_DHCP_RENEWAL_TIME 58
+#define DHO_DHCP_REBINDING_TIME 59
+#define DHO_DHCP_CLASS_IDENTIFIER 60
+#define DHO_DHCP_CLIENT_IDENTIFIER 61
+#define DHO_END 255
+
+/* DHCP message types. */
+#define DHCPDISCOVER 1
+#define DHCPOFFER 2
+#define DHCPREQUEST 3
+#define DHCPDECLINE 4
+#define DHCPACK 5
+#define DHCPNAK 6
+#define DHCPRELEASE 7
--- /dev/null
+/* dhcpd.c
+
+ DHCP Server Daemon. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+static void usage PROTO ((void));
+
+TIME cur_time;
+
+u_int32_t *server_addrlist;
+int server_addrcount;
+u_int16_t server_port;
+
+int main (argc, argv, envp)
+ int argc;
+ char **argv, **envp;
+{
+ struct in_addr addr;
+ int port = 0;
+ int i;
+ struct sockaddr_in name;
+ u_int32_t *addrlist = (u_int32_t *)0;
+ int addrcount = 0;
+ struct tree *addrtree = (struct tree *)0;
+ struct servent *ent;
+ int sock;
+ int pid;
+ int result;
+ int flag;
+
+ openlog ("dhcpd", LOG_NDELAY, LOG_DAEMON);
+#ifndef DEBUG
+ setlogmask (LOG_UPTO (LOG_INFO));
+
+ /* Become a daemon... */
+ if ((pid = fork ()) < 0)
+ error ("Can't fork daemon: %m");
+ else if (pid)
+ exit (0);
+ /* Become session leader and get pid... */
+ pid = setsid ();
+#endif
+ for (i = 1; i < argc; i++) {
+ if (!strcmp (argv [i], "-p")) {
+ if (++i == argc)
+ usage ();
+ server_port = htons (atoi (argv [i]));
+ debug ("binding to user-specified port %d\n",
+ ntohs (server_port));
+#if 0
+ } else if (!strcmp (argv [i], "-a")) {
+ if (++i == argc)
+ usage ();
+ if (inet_aton (argv [i], &addr)) {
+ addrtree =
+ tree_concat (addrtree,
+ tree_const
+ ((unsigned char *)&addr,
+ sizeof addr));
+ } else {
+ addrtree = tree_concat (addrtree,
+ tree_host_lookup
+ (argv [i]));
+ }
+#endif
+ } else
+ usage ();
+ }
+
+ /* Default to the DHCP/BOOTP port. */
+ if (!server_port)
+ {
+ ent = getservbyname ("dhcp", "udp");
+ if (!ent)
+ server_port = htons (67);
+ else
+ server_port = ent -> s_port;
+ endservent ();
+ }
+
+ /* Get the current time... */
+ GET_TIME (&cur_time);
+
+ /* Read the dhcpd.conf file... */
+ readconf ();
+
+#if 0
+ /* If addresses were specified on the command line, resolve them;
+ otherwise, just get a list of the addresses that are configured
+ on this host and listen on all of them. */
+ if (addrtree) {
+ tree_evaluate ((unsigned char **)&addrlist,
+ &addrcount, addrtree);
+ addrcount /= 4;
+ if (!addrcount)
+ error ("Server addresses resolve to nothing.");
+ } else {
+/* addrlist = get_interface_list (&addrcount); */
+#endif
+ addr.s_addr = 0;
+ addrlist = (u_int32_t *)&(addr.s_addr);
+ addrcount = 1;
+#if 0
+ }
+#endif
+
+ server_addrlist = get_interface_list (&server_addrcount);
+
+ /* Listen on the specified (or default) port on each specified
+ (or default) IP address. */
+ for (i = 0; i < addrcount; i++) {
+ listen_on (server_port, addrlist [i]);
+ }
+
+ /* Write a pid file. */
+ if ((i = open (_PATH_DHCPD_PID, O_WRONLY | O_CREAT)) >= 0) {
+ char obuf [20];
+ sprintf (obuf, "%d\n", getpid ());
+ write (i, obuf, strlen (obuf));
+ close (i);
+ }
+
+ /* Receive packets and dispatch them... */
+ dispatch ();
+}
+
+/* Print usage message. */
+
+static void usage ()
+{
+ error ("Usage: dhcpd [-p <port>] [-a <ip-addr>]");
+}
+
+void cleanup ()
+{
+}
+
+void do_packet (packbuf, len, from, fromlen, sock)
+ unsigned char *packbuf;
+ int len;
+ struct sockaddr_in *from;
+ int fromlen;
+ int sock;
+{
+ struct packet *tp;
+ struct dhcp_packet *tdp;
+
+ if (!(tp = new_packet ("do_packet")))
+ return;
+ if (!(tdp = new_dhcp_packet ("do_packet"))) {
+ free_packet (tp, "do_packet");
+ return;
+ }
+ memcpy (tdp, packbuf, len);
+ memset (tp, 0, sizeof *tp);
+ tp -> raw = tdp;
+ tp -> packet_length = len;
+ tp -> client = *from;
+ tp -> client_len = fromlen;
+ tp -> client_sock = sock;
+ parse_options (tp);
+ if (tp -> options_valid &&
+ tp -> options [DHO_DHCP_MESSAGE_TYPE].data)
+ dhcp (tp);
+ else
+ bootp (tp);
+}
+
+dump_packet (tp)
+ struct packet *tp;
+{
+ struct dhcp_packet *tdp = tp -> raw;
+
+ debug ("op = %d htype = %d hlen = %d hops = %d",
+ tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops);
+ debug ("xid = %x secs = %d flags = %x",
+ tdp -> xid, tdp -> secs, tdp -> flags);
+ debug ("ciaddr = %s yiaddr = %s",
+ inet_ntoa (tdp -> ciaddr), inet_ntoa (tdp -> yiaddr));
+ debug ("siaddr = %s giaddr = %s",
+ inet_ntoa (tdp -> siaddr), inet_ntoa (tdp -> giaddr));
+ debug ("chaddr = %02.2x:%02.2x:%02.2x:%02.2x:%02.2x:%02.2x",
+ ((unsigned char *)(tdp -> chaddr)) [0],
+ ((unsigned char *)(tdp -> chaddr)) [1],
+ ((unsigned char *)(tdp -> chaddr)) [2],
+ ((unsigned char *)(tdp -> chaddr)) [3],
+ ((unsigned char *)(tdp -> chaddr)) [4],
+ ((unsigned char *)(tdp -> chaddr)) [5]);
+ if (tp -> options_valid) {
+ int i;
+
+ for (i = 0; i < 256; i++) {
+ if (tp -> options [i].data)
+ printf (" %s = %s\n",
+ dhcp_options [i].name,
+ pretty_print_option
+ (i, tp -> options [i].data,
+ tp -> options [i].len));
+ }
+ }
+}
+
+/* Based on the contents of packet, figure out which interface address
+ to use from server_addrlist. Currently just picks the first
+ interface. */
+
+u_int32_t pick_interface (packet)
+ struct packet *packet;
+{
+ if (server_addrlist)
+ return server_addrlist [0];
+ return 0;
+}
--- /dev/null
+host minuet
+ hardware ethernet 08:00:2b:35:0c:18
+ filename "/tftpboot/netbsd.minuet"
+ fixed-address minuet.fugue.com;
+
+host allegro
+ hardware ethernet 08:00:2b:1c:07:b6
+ filename "/tftpboot/netbsd.allegro"
+ fixed-address allegro.fugue.com;
+
+host fantasia
+ hardware ethernet 8:0:7:26:c0:a5
+ fixed-address fantasia.fugue.com
+ option routers prelude.fugue.com
+ option name-servers toccata.fugue.com, passacaglia.fugue.com
+ option domain-name "fugue.com";
+
--- /dev/null
+/* dhcpd.h
+
+ Definitions for dhcpd... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#include <sys/types.h>
+#include <syslog.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include "dhcp.h"
+#include "cdefs.h"
+#include "osdep.h"
+#include "tree.h"
+#include "hash.h"
+
+/* A dhcp packet and the pointers to its option values. */
+struct packet {
+ struct dhcp_packet *raw;
+ int packet_length;
+ int packet_type;
+ int options_valid;
+ struct sockaddr_in client;
+ int client_len;
+ int client_sock;
+ struct {
+ int len;
+ unsigned char *data;
+ } options [256];
+};
+
+struct hardware {
+ u_int8_t htype;
+ u_int8_t hlen;
+ u_int8_t haddr [16];
+};
+
+/* A dhcp host declaration structure. */
+struct host_decl {
+ struct host_decl *n_name, *n_haddr, *n_cid;
+ char *name;
+ struct hardware *interfaces;
+ int interface_count;
+ char *filename;
+ char *server_name;
+ struct tree_cache *fixed_addr;
+ struct tree_cache *options [256];
+};
+
+/* A dhcp lease declaration structure. */
+struct lease {
+ struct lease *next;
+ struct lease *prev;
+ struct in_addr ip_addr;
+ TIME starts, ends, timestamp;
+ unsigned char *uid;
+ int uid_len;
+ struct host_decl *host;
+ struct subnet *contain;
+ struct hardware hardware_addr;
+ int state;
+};
+
+struct subnet {
+ struct in_addr net;
+ struct in_addr netmask;
+ struct lease *leases;
+ struct lease *insertion_point;
+};
+
+/* Bitmask of dhcp option codes. */
+typedef unsigned char option_mask [16];
+
+/* DHCP Option mask manipulation macros... */
+#define OPTION_ZERO(mask) (memset (mask, 0, 16))
+#define OPTION_SET(mask, bit) (mask [bit >> 8] |= (1 << (bit & 7)))
+#define OPTION_CLR(mask, bit) (mask [bit >> 8] &= ~(1 << (bit & 7)))
+#define OPTION_ISSET(mask, bit) (mask [bit >> 8] & (1 << (bit & 7)))
+#define OPTION_ISCLR(mask, bit) (!OPTION_ISSET (mask, bit))
+
+/* An option occupies its length plus two header bytes (code and
+ length) for every 255 bytes that must be stored. */
+#define OPTION_SPACE(x) ((x) + 2 * ((x) / 255 + 1))
+
+/* Default path to dhcpd config file. */
+#ifndef _PATH_DHCPD_CONF
+#ifdef DEBUG
+#define _PATH_DHCPD_CONF "dhcpd.conf"
+#else
+#define _PATH_DHCPD_CONF "/etc/dhcpd.conf"
+#endif
+#endif
+
+/* Subnet macros... */
+#define SUBNET(addr, mask) ((addr).s_addr & (netmask).s_addr)
+#define IP_ADDR(net, host) ((net).s_addr | i)
+#define HOST_ADDR(addr, mask) ((addr).s_addr & ~(netmask).s_addr)
+#define MAX_TIME 0x7fffffff
+#define MIN_TIME 0
+
+/* External definitions... */
+
+/* options.c */
+
+void parse_options PROTO ((struct packet *));
+void parse_option_buffer PROTO ((struct packet *, unsigned char *, int));
+void cons_options PROTO ((struct packet *, struct dhcp_packet *,
+ struct host_decl *, int));
+char *pretty_print_option PROTO ((unsigned char, unsigned char *, int));
+
+/* errwarn.c */
+int error PROTO ((char *, ...));
+int warn PROTO ((char *, ...));
+int note PROTO ((char *, ...));
+int debug PROTO ((char *, ...));
+int parse_warn PROTO ((char *, ...));
+
+/* dhcpd.c */
+TIME cur_time;
+extern u_int32_t *server_addrlist;
+extern int server_addrcount;
+extern u_int16_t server_port;
+int main PROTO ((int, char **, char **));
+void cleanup PROTO ((void));
+void do_packet PROTO ((unsigned char *, int, struct sockaddr_in *, int, int));
+u_int32_t pick_interface PROTO ((struct packet *));
+
+
+/* conflex.c */
+int next_token PROTO ((char **, FILE *));
+int peek_token PROTO ((char **, FILE *));
+
+/* confpars.c */
+void readconf PROTO ((void));
+void parse_statement PROTO ((FILE *));
+void skip_to_semi PROTO ((FILE *));
+struct host_decl *parse_host_statement PROTO ((FILE *, jmp_buf *));
+char *parse_host_name PROTO ((FILE *, jmp_buf *));
+void parse_host_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
+void parse_hardware_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
+struct hardware parse_hardware_addr PROTO ((FILE *, jmp_buf *));
+void parse_filename_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
+void parse_fixed_addr_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
+void parse_option_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
+TIME parse_timestamp PROTO ((FILE *, jmp_buf *));
+TIME parse_date PROTO ((FILE *, jmp_buf *));
+struct lease *parse_lease_statement PROTO ((FILE *, jmp_buf *));
+void parse_address_range PROTO ((FILE *, jmp_buf *));
+unsigned char *parse_numeric_aggregate PROTO ((FILE *, jmp_buf *,
+ unsigned char *, int *,
+ int, int, int));
+void convert_num PROTO ((unsigned char *, char *, int, int));
+
+/* tree.c */
+pair cons PROTO ((caddr_t, pair));
+struct tree_cache *tree_cache PROTO ((struct tree *));
+struct tree *tree_host_lookup PROTO ((char *));
+struct dns_host_entry *enter_dns_host PROTO ((char *));
+struct tree *tree_const PROTO ((unsigned char *, int));
+struct tree *tree_concat PROTO ((struct tree *, struct tree *));
+struct tree *tree_limit PROTO ((struct tree *, int));
+int tree_evaluate PROTO ((struct tree_cache *));
+
+/* dhcp.c */
+void dhcp PROTO ((struct packet *));
+
+/* bootp.c */
+void bootp PROTO ((struct packet *));
+
+/* memory.c */
+void enter_host PROTO ((struct host_decl *));
+struct host_decl *find_host_by_name PROTO ((char *name));
+struct host_decl *find_host_by_addr PROTO ((int, unsigned char *, int));
+extern struct subnet *find_subnet (struct in_addr);
+void enter_subnet (struct subnet *);
+void enter_lease PROTO ((struct lease *));
+void supersede_lease PROTO ((struct lease *, struct lease *));
+struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
+struct lease *find_lease_by_ip_addr PROTO ((struct in_addr));
+struct lease *find_next_expiring_lease PROTO ((void));
+
+/* alloc.c */
+VOIDPTR dmalloc PROTO ((int, char *));
+void dfree PROTO ((VOIDPTR, char *));
+struct packet *new_packet PROTO ((char *));
+struct dhcp_packet *new_dhcp_packet PROTO ((char *));
+struct tree *new_tree PROTO ((char *));
+struct tree_cache *new_tree_cache PROTO ((char *));
+struct hash_table *new_hash_table PROTO ((int, char *));
+struct hash_bucket *new_hash_bucket PROTO ((char *));
+struct lease *new_lease PROTO ((char *));
+struct lease *new_leases (int, char *);
+struct subnet *new_subnet PROTO ((char *));
+void free_subnet PROTO ((struct subnet *, char *));
+void free_lease PROTO ((struct lease *, char *));
+void free_hash_bucket PROTO ((struct hash_bucket *, char *));
+void free_hash_table PROTO ((struct hash_table *, char *));
+void free_tree_cache PROTO ((struct tree_cache *, char *));
+void free_packet PROTO ((struct packet *, char *));
+void free_dhcp_packet PROTO ((struct dhcp_packet *, char *));
+void free_tree PROTO ((struct tree *, char *));
+
+/* print.c */
+char *print_hw_addr PROTO ((int, int, unsigned char *));
+
+/* socket.c */
+u_int32_t *get_interface_list PROTO ((int *));
+void listen_on PROTO ((u_int16_t, u_int32_t));
+void dispatch PROTO ((void));
+
+/* hash.c */
+struct hash_table *new_hash PROTO ((void));
+void add_hash PROTO ((struct hash_table *, char *, int, unsigned char *));
+void delete_hash_entry PROTO ((struct hash_table *, char *, int));
+unsigned char *hash_lookup PROTO ((struct hash_table *, char *, int));
+
+/* tables.c */
+extern struct option dhcp_options [256];
+extern unsigned char dhcp_option_default_priority_list [];
+extern int sizeof_dhcp_option_default_priority_list;
+extern struct hash_table universe_hash;
+extern struct universe dhcp_universe;
+void initialize_universes PROTO ((void));
+
--- /dev/null
+/* dhctoken.h
+
+ Tokens for config file lexer and parser. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#define SEMI ';'
+#define DOT '.'
+#define COLON ':'
+#define COMMA ','
+#define SLASH '/'
+
+#define FIRST_TOKEN HOST
+#define HOST 256
+#define HARDWARE 257
+#define FILENAME 258
+#define FIXED_ADDR 259
+#define OPTION 260
+#define ETHERNET 261
+#define STRING 262
+#define NUMBER 263
+#define NUMBER_OR_ATOM 264
+#define ATOM 265
+#define TIMESTAMP 266
+#define STARTS 267
+#define ENDS 268
+#define UID 269
+#define CLASS 270
+#define LEASE 271
+#define RANGE 272
+#define LAST_TOKEN RANGE
+
+#define is_identifier(x) ((x) >= FIRST_TOKEN && \
+ (x) <= FIRST_TOKEN && \
+ (x) != STRING && \
+ (x) != NUMBER)
--- /dev/null
+
+CURRENT_MEETING_REPORT_
+
+Reported by Walt Wimer/CMU
+
+Minutes of the Dynamic Host Configuration Working Group (DHC)
+
+The DHC Working Group met on 7 December and 9 December at the 31st IETF.
+
+
+Document Status
+
+The most recent Internet-Draft of the DHCP specification includes
+several changes based on the results of the latest interoperability
+testing. Based on the results of that testing, and a review of the
+Standards process RFC, the working group decided it would be appropriate
+to ask that DHCP be considered for ``Draft Standard'' status. As soon
+as a revision of the current Internet-Draft is completed, the
+specification for DHCP will be submitted for review.
+
+A few, minor changes have been made to RFC 1541 based on questions
+raised during the latest interoperability testing. Two new options have
+been defined since RFC 1533: 62, NetWare/IP domain and 63, NetWare/IP
+option.
+
+The working group agreed that the minimum lease requirement (one hour)
+should be made advisory rather than mandatory.
+
+
+Implementations
+
+The following list of implementations was compiled from information
+given by working group attendees.
+
+ _____________________________________________________________________
+ || | | | ||
+ || Vendor |Client |Server |Relay agent ||
+ ||___________________|___________________|_______________|_____________||
+ || FTP Software |DOS/Windows |Windows | ||
+ ||___________________|___________________|NT_(beta)______|_____________||
+ || SunSoft |DOS/Windows |Solaris 2.0 |in server ||
+ ||___________________|Solaris_(beta?)____|_______________|_____________||
+ || Microsoft |DOS/Windows |NT |in server ||
+ || |NT | | ||
+ ||___________________|Windows95_beta_____|_______________|_____________||
+ || Competitive |??? |Solaris | ||
+ ||_Automation________|___________________|_______________|_____________||
+ || Apple |Newton | | ||
+ ||___________________|Mac_(beta)_________|_______________|_____________||
+ || WIDE project |Unix, BSD386 |Unix, BSD386 |Unix, BSD386 ||
+ ||_(free,_avail_2/95)|News,_SunOS________|News,_SunOS____|News,_SunOS_ ||
+ ||_Silicon_Graphics__|IRIX_(soon)________|IRIX___________|_____________||
+ || Hewlett Packard |X-terminal |HP/UX (June 95)|in server ||
+ ||___________________|___________________|_______________|HP_router____||
+ || IBM |OS/2 (soon) |OS/2 (soon) | ||
+ || |AIX (soon) |AIX (soon) | ||
+ ||___________________|___________________|AS/400_(soon)__|_____________||
+ || cisco Systems |Terminal server? | |routers ||
+ || |(proxy for | | ||
+ ||___________________|terminal_clients?)_|_______________|_____________||
+ || Novell |NetWare/IP |NetWare/IP | ||
+ ||___________________|(spring)___________|(later)________|_____________||
+ || Shiva |Proxy for | | ||
+ ||___________________|dial-in_clients____|_______________|_____________||
+
+
+Future Interoperability Test
+
+There was some discussion of a future interoperability test. Suggested
+venues include Bucknell University (summer '95), CMU (no specific time),
+next IETF (March '95) and remote via the Internet (?!?!). The working
+group will hold a discussion about the next interoperability testing via
+electronic mail.
+
+
+Outstanding Issues
+
+The working group discussed some outstanding issues and generated some
+solutions:
+
+
+ o New options: TFTP server address, bootfile name, to be registered
+ with IANA.
+
+ o Some clients will already have an IP address, not otherwise
+ registered or managed by DHCP. Those clients will only want local
+ configuration parameters, not an address. A new DHCP message,
+ DHCPINFORM, will be defined for parameter requests.
+
+ o There was some question about the definition and interpretation of
+ ``client identifiers.'' The working group confirmed that a
+ ``client identifier'' is an opaque, unique identifier. Text will
+ be added to the protocol specification to clarify this issue and to
+ advise that ``client identifiers'' must be unique. ``Client
+ identifier'' type 0 will indicate ``an opaque string of
+ characters.''
+
+
+The issue of security was discussed. The primary concern is to detect
+and avoid spoof/unauthorized servers. Some sites are also concerned
+about unauthorized clients. The consensus was that a public key
+identification and authorization mechanism should be developed as an
+optional DHCP service.
+
+Ralph Droms presented a preliminary proposal for a server-server
+protocol to allow automatic management of DHCP bindings by multiple DHCP
+servers at a single site. The goals are to increase availability and
+reliability through redundancy of address allocation and binding
+servers, and through load sharing. The basic model, based on a proposal
+by Jeff Mogul, is to assign each allocatable address and allocated
+binding to a specific ``owner'' server. That owner has modification
+privileges, while all other servers have read-only privileges. Servers
+use TCP connections and a simple protocol to replicate copies of new
+bindings and transfer ownership of addresses to balance the pool of
+available addresses.
+
+The hard part is bindings that are released early, prior to expiration.
+Those released bindings must be reported to all other servers, so those
+servers do not respond with stale data in the future. However, servers
+may be inaccessible. The proposed solution was to add an ``owner''
+option; clients would select responses from the ``owner'' in favor of
+all other responses.
+
+The suggestion was made that multiple DHCP servers might be able to use
+an underlying distributed database like DNS, NIS+ or Oracle. Questions
+were raised about the scalability of the proposed scheme -- suppose many
+clients send simultaneous update requests, how often should updates be
+replicated, what about combinatoric explosion with the number of
+servers?
+
+
+IPv6 Issues
+
+The second meeting began with a discussion of several IPv6 issues. IPv6
+address configuration has three basic forms:
+
+
+ 1. Intra-link scope address (client forms address all on its own)
+
+ 2. ``Stateless'' servers (e.g., in routers using some simple
+ assignment algorithm)
+ 3. Stateful servers (`a la IPv4 DHCP)
+
+
+Regardless of how addresses are managed, IPv6 will need some other
+mechanism(s) to obtain other configuration parameters. Some members of
+the IPv6 design team claim there will be no other parameters.
+
+The following action items were identified:
+
+
+ o Someone to enumerate all IPv6 network layer parameters.
+ Mike Carney volunteered.
+
+ o Extensions/changes to DHCP protocol format for IPv6.
+ Walt Wimer volunteered.
+
+
+Dynamic Addressing
+
+Next, the working group discussed the problem of dynamic updates to DNS
+from DHCP information (dynamic addressing). For simple registration of
+DNS hostnames for individual DHCP clients, what should we do? Should
+client be responsible for contacting DNS server directly, or should DHCP
+server contact DNS on behalf of client? It will be necessary to clarify
+DNS configuration/update mechanism with DNS Working Group. One solution
+to the question of who does the update would be to define a DHCP option
+for client to say whether it will do the registration with DNS directly
+or whether client wants DHCP server to take care of it. DHCP server may
+need a way to veto the client's preference. This permits a simple
+client (such as an embedded hub, probe, etc.) to let the DHCP server do
+everything (DHCP server probably has necessary credentials to update DNS
+while client probably does not). Or, a more sophisticated client can
+update its ``home'' DNS directly (for example, a mobile notebook
+computer belonging to XYZ, Inc. can be taken to an IETF get a local IP
+address from the IETF DHCP server, but then directly update XYZ.COM's
+DNS server in order to maintain an XYZ.COM name). The problem of name
+collisions was unresolved - should the client or the server be
+responsible? Masataka Ohta volunteered to do a DHCP-to-DNS interaction
+proposal
+
+
+DHCP and SNMP
+
+Finally, the working group considered DHCP and SNMP. The working group
+chair asked if there were any MIB writers in the audience. The scribe
+thought there was a volunteer but did not catch the name.
+
--- /dev/null
+
+CURRENT_MEETING_REPORT_
+
+Reported by Rob Austein/Epilogue Technology
+
+Minutes of the Domain Name System Working Group (DNS)
+
+
+Documents
+
+Three new DNS-related Informational RFCs have come out recently.
+RFC 1535 (also known as ``the EDU.COM emergency RFC'') details problems
+with a widely-used but ill-advised DNS search heuristic, and proposes a
+solution. RFC 1536 details common DNS implementation errors, with
+proposed solutions; this document was accepted as a DNS Working Group
+project at the 27th IETF (Amsterdam), completed, and accepted on the
+mailing list. RFC 1537 details common DNS configuration errors; while
+it was never formally accepted as a DNS Working Group document, it was
+reviewed by the working group members. These three RFCs are closely
+related and cross-reference each other, so, on advice of the RFC Editor,
+the DNS Working Group Chair approved ``fast track'' publication of these
+documents on behalf of the Working Group. If anybody has serious
+problems with these documents, blame it on the Chair.
+
+Dave Perkins reported on the current status of the DNS MIB documents on
+behalf of the Network Management Area Directorate (NMDIR). Basically,
+there are no remaining hard problems, just some remaining detail work.
+One of the authors, Rob Austein, has received a detailed list of
+remaining concerns, none of which appear to be show-stoppers. It should
+be possible to get these documents out the door before the 29th IETF in
+Seattle. Dave pointed out two design issues that are not objections but
+of which he thinks the DNS Working Group should be aware:
+
+
+ 1. Due to SNMP protocol limitations, the length limits on DNS names
+ used as indices to ``conceptual tables'' in the MIBs will be
+ shorter than the DNS name length limit of 255 octets. Based on
+ analysis of current usage, this should not be a problem, so we'll
+ flag it with a warning statement in the document but otherwise
+ leave it alone.
+ 2. The most recent versions of the documents (not yet released as
+ Internet-Drafts) use the SNMPv2 SMI rather than the SNMPv1 SMI, in
+ order to clear up some problems with unsigned 32-bit integers.
+ NMDIR wants to be sure that the DNS Working Group realizes that
+ this means only SNMPv2-capable implementations will be able to use
+ these MIBs.
+
+
+DNS Security Sub-Group
+
+James Galvin gave a report on the meeting held by the DNS Security
+``sub-group'' (a spin off from the DNS Working Group at the 26th IETF in
+Columbus).
+
+
+ The DNS Security design team of the DNS Working Group met for
+ one morning at the Houston IETF. The discussion began with a
+ call for threats that the members of the group were most
+ concerned about. The list included the following:
+
+ o disclosure of the data - some expressed a desire to be
+ able to encrypt the data in responses
+
+ o modification of the data
+
+ o masquerade of the origin of the data
+
+ o masquerade of a secondary - some expressed a desire to be
+ able to reliably identify both peers in a zone transfer;
+ this would provide the basis for controlling access to
+ zone transfers
+
+ During the discussion of these threats it was agreed to accept
+ the following assumptions:
+
+ 1. DNS data is ``public''
+ 2. backward/co-existence compatibility is required
+
+ With respect to the first, accepting it set aside any further
+ discussion of the threat of disclosure of the data. The second
+ assumption is included explicitly to remind everyone that we do
+ not want parallel DNS systems in the Internet.
+ In addition, it was explicitly agreed that we would not address
+ authentication of secondaries or access control issues. Thus,
+ the current list of desired security services is:
+
+ o data integrity
+ o data origin authentication
+
+ It was noted that a digital signature mechanism would support
+ the desired services.
+ The meeting continued with a brainstorming period during which
+ the desired functional requirements of a secure DNS were
+ collected. This list does not represent mandatory
+ functionality but, rather, it is desired functionality. It was
+ agreed that this list was subject to discussion on the mailing
+ list for a period of time that would conclude on November 30.
+ The requirements are listed here in no particular order.
+
+ o sites must be able to support at least their internal
+ users in the presence of external network failures
+
+ o it should be possible for a site to pre-configure other
+ authoritative servers without having to query the
+ ``system'' to find the server
+
+ o it should be possible to request services only from
+ security enhanced servers, only from non-security enhanced
+ servers, or to indicate that either is acceptable
+
+ o it should be possible to recognize security enhanced
+ responses
+
+ o it should be possible to assign cryptographic keys (make
+ use of the security services) to leaf nodes in the DNS
+ tree, i.e., fully qualified domain names
+
+ o it should be possible to not trust secondary servers
+
+ o a mechanism must exist for revoking cryptographic keys
+ that works within the DNS time-to-live framework
+
+ o security services should be supported with no additional
+ DNS queries beyond what would be required if security was
+ not supported
+
+ o it must be possible to ensure that cached data expires
+ according to its TTL
+
+ The meeting concluded with agreement on the following three
+ milestones.
+
+ 1. The desired functional requirements are to be reviewed and
+ agreed upon by November 30.
+
+ 2. Strawman proposals that meet as many of the desired
+ requirements as possible are due by January 31, 1994.
+
+ 3. The group would produce a single, draft proposal at the
+ next IETF meeting, March 1994.
+
+
+
+The DNS Security effort will be spun off as a separate working group in
+the Service Applications Area (SAP), as soon as James can get the
+charter approved. The DNS Security mailing list is
+dns-security@tis.com; requests to subscribe should be sent to
+dns-security-request@tis.com.
+
+Discussion of the incremental zone transfer protocol
+(draft-ietf-dns-ixfr-00.txt) was deferred because none of the authors
+were present at the meeting. Comments on this draft should be sent to
+the authors and/or the Namedroppers mailing list.
+
+
+
+DNS Efforts to Support SIPP
+
+Sue Thomson gave a brief report on current DNS efforts to support SIPP
+(the merger of the SIP and PIP proposals). See the latest version of
+the Internet-Draft, draft-ietf-sip-sippdns-nn.txt, for details.
+
+
+DNS Reliability Issues - Boeing
+
+Ed King gave a presentation on DNS reliability issues in Boeing's
+production environment. Ed has to support DNS on a corporate network
+with thousands of subnets and DNS software from many vendors in a
+production environment that never shuts down and where an interruption
+to DNS services due to a power hit can leave hundreds of engineers
+sitting idle waiting for their workstations to finish booting. Much of
+the problem is that each vendor has their own slightly different (and
+often more than slightly broken) interface between DNS, local host
+tables, and the vendor's own pet name resolution mechanism. Replacing
+or repairing all the DNS software in an environment isn't economically
+feasible, so the most constructive approach seems to be to write a ``DNS
+Requirements'' document to use as a reference when pressuring vendors to
+fix their DNS implementations. The DNS portion of the Host Requirements
+documents (RFC 1123 section 6.1) and the newly published DNS ``Common
+Errors'' Informational RFCs are good starting points, but companies like
+Boeing need a document that has the force of a standard and that goes
+into more detail on interface design issues than Host Requirements does.
+
+No definite decision was reached as a result of Ed's presentation, but
+watch Namedroppers for further discussion and probably a call to form a
+working group.
+
+
+DNS Support for DHC and Mobile Hosts
+
+Masataka Ohta gave a presentation on a possible way to implement some of
+the DNS support needed for dynamic host configuration and mobile hosts.
+The presentation went into more detail than there is room for in these
+minutes, so expect to see a summary of this on the Namedroppers list.
+
+
+The Future of the DNS Working Group
+
+Dave Crocker spoke about the future of the DNS Working Group. As has
+been discussed at previous meetings, the DNS Working Group as currently
+organized doesn't really fit well into the current IETF organizational
+framework. Accordingly, Dave asks that DNS reorganize itself more along
+the current IETF pattern. The proposal is to move the ``permanent''
+functions of the DNS Working Group (DNS oversight within the IETF,
+mostly) into the SAP Area Directorate, that Dave will be forming ``Real
+Soon Now,'' while reincarnating specific closed-ended tasks as separate
+working groups within the SAP Area. The SAP Area Directorate will hold
+open meetings at regular intervals, so that there will still be a forum
+for overall DNS design work. For formal purposes, the current DNS
+Working Group will probably be retroactively construed as having been
+the DNS MIB Working Group, and will be closed down as soon as the DNS
+MIB documents hit the streets. As a practical matter, and in the
+Chair's opinion, the current DNS Working Group will effectively
+reconstitute itself as the attendees of the DNS portion of the SAP Area
+Directorate open meetings. Dave expects to have the reorganization
+completed by the 29th IETF in Seattle.
+
+The discussion that followed Dave's statement made it clear that there
+are people with strong feelings on both sides of this issue (keep the
+DNS Working Group as it is versus reorganize per Dave's plan). Unless
+somebody feels strongly enough about this to make a formal appeal, the
+reorganization will probably go through.
+
+
+Attendees
+
+Steve Alexander stevea@lachman.com
+Garrett Alexander gda@tycho.ncsc.mil
+Robert Austein sra@epilogue.com
+Anders Baardsgaad anders@cc.uit.no
+Alireza Bahreman bahreman@bellcore.com
+William Barns barns@gateway.mitre.org
+Stephen Crocker crocker@tis.com
+Donald Eastlake dee@skidrow.lkg.dec.com
+Havard Eidnes havard.eidnes@runit.sintef.no
+Erik Fair fair@apple.com
+Roger Fajman raf@cu.nih.gov
+Patrik Faltstrom paf@nada.kth.se
+Antonio Fernandez afa@thumper.bellcore.com
+James Fielding jamesf@arl.army.mil
+James Galvin galvin@tis.com
+Chris Gorsuch chrisg@lobby.ti.com
+Ronald Jacoby rj@sgi.com
+Rick Jones raj@cup.hp.com
+Charlie Kaufman kaufman@zk3.dec.com
+Elizabeth Kaufman kaufman@biomded.med.yale.edu
+Stephen Kent kent@bbn.com
+Edwin King eek@atc.boeing.com
+Paul Lambert paul_lambert@email.mot.com
+Walter Lazear lazear@gateway.mitre.org
+Lars-Johan Liman liman@ebone.net
+John Linn linn@security.ov.com
+Jun Matsukata jm@eng.isas.ac.jp
+Paul Mockapetris pvm@darpa.mil
+Sath Nelakonda sath@lachman.com
+Masataka Ohta mohta@cc.titech.ac.jp
+Michael Patton map@bbn.com
+Jon Postel postel@isi.edu
+Jeffrey Schiller jis@mit.edu
+Richard Schmalgemeier rgs@merit.edu
+Michael St. Johns stjohns@arpa.mil
+John Stewart jstewart@cnri.reston.va.us
+Theodore Ts'o tytso@mit.edu
+Walter Wimer walter.wimer@andrew.cmu.edu
+David Woodgate David.Woodgate@its.csiro.au
+Weiping Zhao zhao@nacsis.ac.jp
+
--- /dev/null
+
+Network Working Group R. Droms
+INTERNET DRAFT Bucknell University
+Obsoletes: draft-ietf-dhc-dhcp-02.txt September 1995
+ Expires March 1996
+
+
+ Dynamic Host Configuration Protocol
+ <draft-ietf-dhc-dhcp-03.txt>
+
+Status of this memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its areas,
+ and its working groups. Note that other groups may also distribute
+ working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as ``work in progress.''
+
+ To learn the current status of any Internet-Draft, please check the
+ ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
+ Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
+ munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
+ ftp.isi.edu (US West Coast).
+
+Abstract
+
+ The Dynamic Host Configuration Protocol (DHCP) provides a framework
+ for passing configuration information to hosts on a TCP/IP network.
+ DHCP is based on the Bootstrap Protocol (BOOTP) [7], adding the
+ capability of automatic allocation of reusable network addresses and
+ additional configuration options [19]. DHCP captures the behavior of
+ BOOTP relay agents [7, 21], and DHCP participants can interoperate
+ with BOOTP participants [9].
+
+
+Table of Contents
+
+ 1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . 2
+ 1.1 Related Work. . . . . . . . . . . . . . . . . . . . . . . . . 4
+ 1.2 Problem definition and issues . . . . . . . . . . . . . . . . 4
+ 1.3 Requirements. . . . . . . . . . . . . . . . . . . . . . . . . 5
+ 1.4 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 6
+ 1.5 Design goals. . . . . . . . . . . . . . . . . . . . . . . . . 6
+ 2. Protocol Summary. . . . . . . . . . . . . . . . . . . . . . . 8
+ 2.1 Configuration parameters repository . . . . . . . . . . . . . 10
+ 2.2 Dynamic allocation of network addresses . . . . . . . . . . . 11
+ 3. The Client-Server Protocol. . . . . . . . . . . . . . . . . . 12
+ 3.1 Client-server interaction - allocating a network address. . . 13
+ 3.2 Client-server interaction - reusing a previously allocated
+ network address . . . . . . . . . . . . . . . . . . . . . . . 17
+ 3.3 Interpretation and representation of time values. . . . . . . 20
+ 3.4 Obtaining parameters with externally configured network
+ address . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
+ 3.5 Client parameters in DHCP . . . . . . . . . . . . . . . . . . 20
+ 3.6 Use of DHCP in clients with multiple interfaces . . . . . . . 21
+ 3.7 When clients should use DHCP. . . . . . . . . . . . . . . . . 22
+ 4. Specification of the DHCP client-server protocol. . . . . . . 22
+ 4.1 Constructing and sending DHCP messages. . . . . . . . . . . . 22
+ 4.2 DHCP server administrative controls . . . . . . . . . . . . . 24
+ 4.3 DHCP server behavior. . . . . . . . . . . . . . . . . . . . . 25
+ 4.4 DHCP client behavior. . . . . . . . . . . . . . . . . . . . . 33
+ 5. References . . . . . . . . . . . . . . . . . . . . . . . . . .40
+ 6. Security Considerations. . . . . . . . . . . . . . . . . . . .42
+ 7. Author's Address . . . . . . . . . . . . . . . . . . . . . . .42
+ A. Host Configuration Parameters . . . . . . . . . . . . . . . .43
+ B. Changes to draft-ietf-dhc-dhcp-02.txt. . . . . . . . . . . . .44
+
+List of Figures
+
+ 1. Format of a DHCP message . . . . . . . . . . . . . . . . . . . 9
+ 2. Format of the 'flags' field. . . . . . . . . . . . . . . . . . 10
+ 3. Timeline diagram of messages exchanged between DHCP client and
+ servers when allocating a new network address. . . . . . . . . 15
+ 4. Timeline diagram of messages exchanged between DHCP client and
+ servers when reusing a previously allocated network address. . 18
+ 5. State-transition diagram for DHCP clients. . . . . . . . . . . 34
+
+List of Tables
+
+ 1. Description of fields in a DHCP message. . . . . . . . . . . . 12
+ 2. DHCP messages. . . . . . . . . . . . . . . . . . . . . . . . . 14
+ 3. Fields and options used by DHCP servers. . . . . . . . . . . . 27
+ 4. Client messages from various states. . . . . . . . . . . . . . 33
+ 5. Fields and options used by DHCP clients. . . . . . . . . . . . 37
+
+1. Introduction
+
+ The Dynamic Host Configuration Protocol (DHCP) provides configuration
+ parameters to Internet hosts. DHCP consists of two components: a
+ protocol for delivering host-specific configuration parameters from a
+ DHCP server to a host and a mechanism for allocation of network
+ addresses to hosts.
+
+ DHCP is built on a client-server model, where designated DHCP server
+ hosts allocate network addresses and deliver configuration parameters
+ to dynamically configured hosts. Throughout the remainder of this
+ document, the term "server" refers to a host providing initialization
+ parameters through DHCP, and the term "client" refers to a host
+ requesting initialization parameters from a DHCP server.
+
+ A host should not act as a DHCP server unless explicitly configured
+ to do so by a system administrator. The diversity of hardware and
+ protocol implementations in the Internet would preclude reliable
+ operation if random hosts were allowed to respond to DHCP requests.
+ For example, IP requires the setting of many parameters within the
+ protocol implementation software. Because IP can be used on many
+ dissimilar kinds of network hardware, values for those parameters
+ cannot be guessed or assumed to have correct defaults. Also,
+ distributed address allocation schemes depend on a polling/defense
+ mechanism for discovery of addresses that are already in use. IP
+ hosts may not always be able to defend their network addresses, so
+ that such a distributed address allocation scheme cannot be
+ guaranteed to avoid allocation of duplicate network addresses.
+
+ DHCP supports three mechanisms for IP address allocation. In
+ "automatic allocation", DHCP assigns a permanent IP address to a
+ client. In "dynamic allocation", DHCP assigns an IP address to a
+ client for a limited period of time (or until the client explicitly
+ relinquishes the address). In "manual allocation", a client's IP
+ address is assigned by the network administrator, and DHCP is used
+ simply to convey the assigned address to the client. A particular
+ network will use one or more of these mechanisms, depending on the
+ policies of the network administrator.
+
+ Dynamic allocation is the only one of the three mechanisms that
+ allows automatic reuse of an address that is no longer needed by the
+ client to which it was assigned. Thus, dynamic allocation is
+ particularly useful for assigning an address to a client that will be
+ connected to the network only temporarily or for sharing a limited
+ pool of IP addresses among a group of clients that do not need
+ permanent IP addresses. Dynamic allocation may also be a good choice
+ for assigning an IP address to a new client being permanently
+ connected to a network where IP addresses are sufficiently scarce
+ that it is important to reclaim them when old clients are retired.
+ Manual allocation allows DHCP to be used to eliminate the error-prone
+ process of manually configuring hosts with IP addresses in
+ environments where (for whatever reasons) it is desirable to manage
+ IP address assignment outside of the DHCP mechanisms.
+
+ The format of DHCP messages is based on the format of BOOTP messages,
+ to capture the BOOTP relay agent behavior described as part of the
+ BOOTP specification [7, 21] and to allow interoperability of existing
+ BOOTP clients with DHCP servers. Using BOOTP relay agents eliminates
+ the necessity of having a DHCP server on each physical network
+ segment.
+
+1.1 Related Work
+
+ There are several Internet protocols and related mechanisms that
+ address some parts of the dynamic host configuration problem. The
+
+ Reverse Address Resolution Protocol (RARP) [10] (through the
+ extensions defined in the Dynamic RARP (DRARP) [5]) explicitly
+ addresses the problem of network address discovery, and includes an
+ automatic IP address assignment mechanism. The Trivial File Transfer
+ Protocol (TFTP) [20] provides for transport of a boot image from a
+ boot server. The Internet Control Message Protocol (ICMP) [16]
+ provides for informing hosts of additional routers via "ICMP
+ redirect" messages. ICMP also can provide subnet mask information
+ through the "ICMP mask request" message and other information through
+ the (obsolete) "ICMP information request" message. Hosts can locate
+ routers through the ICMP router discovery mechanism [8].
+
+ BOOTP is a transport mechanism for a collection of configuration
+ information. BOOTP is also extensible, and official extensions [17]
+ have been defined for several configuration parameters. Morgan has
+ proposed extensions to BOOTP for dynamic IP address assignment [15].
+ The Network Information Protocol (NIP), used by the Athena project at
+ MIT, is a distributed mechanism for dynamic IP address assignment
+ [19]. The Resource Location Protocol RLP [1] provides for location
+ of higher level services. Sun Microsystems diskless workstations use
+ a boot procedure that employs RARP, TFTP and an RPC mechanism called
+ "bootparams" to deliver configuration information and operating
+ system code to diskless hosts. (Sun Microsystems, Sun Workstation
+ and SunOS are trademarks of Sun Microsystems, Inc.) Some Sun
+ networks also use DRARP and an auto-installation mechanism to
+ automate the configuration of new hosts in an existing network.
+
+ In other related work, the path minimum transmission unit (MTU)
+ discovery algorithm can determine the MTU of an arbitrary internet
+ path [14]. The Address Resolution Protocol (ARP) has been proposed
+ as a transport protocol for resource location and selection [6].
+ Finally, the Host Requirements RFCs [3, 4] mention specific
+ requirements for host reconfiguration and suggest a scenario for
+ initial configuration of diskless hosts.
+
+1.2 Problem definition and issues
+
+ DHCP is designed to supply DHCP clients with the configuration
+ parameters defined in the Host Requirements RFCs. After obtaining
+ parameters via DHCP, a DHCP client should be able to exchange packets
+ with any other host in the Internet. The TCP/IP stack parameters
+ supplied by DHCP are listed in Appendix A.
+
+ Not all of these parameters are required for a newly initialized
+ client. A client and server may negotiate for the transmission of
+ only those parameters required by the client or specific to a
+ particular subnet.
+
+ DHCP allows but does not require the configuration of client
+ parameters not directly related to the IP protocol. DHCP also does
+ not address registration of newly configured clients with the Domain
+ Name System (DNS) [12, 13].
+
+ DHCP is not intended for use in configuring routers.
+
+1.3 Requirements
+
+ Throughout this document, the words that are used to define the
+ significance of particular requirements are capitalized. These words
+ are:
+
+ o "MUST"
+
+ This word or the adjective "REQUIRED" means that the
+ item is an absolute requirement of this specification.
+
+ o "MUST NOT"
+
+ This phrase means that the item is an absolute prohibition
+ of this specification.
+
+ o "SHOULD"
+
+ This word or the adjective "RECOMMENDED" means that there
+ may exist valid reasons in particular circumstances to ignore
+ this item, but the full implications should be understood and
+ the case carefully weighed before choosing a different course.
+
+ o "SHOULD NOT"
+
+ This phrase means that there may exist valid reasons in
+ particular circumstances when the listed behavior is acceptable
+ or even useful, but the full implications should be understood
+ and the case carefully weighed before implementing any behavior
+ described with this label.
+
+ o "MAY"
+
+ This word or the adjective "OPTIONAL" means that this item is
+ truly optional. One vendor may choose to include the item
+ because a particular marketplace requires it or because it
+ enhances the product, for example; another vendor may omit the
+ same item.
+
+1.4 Terminology
+
+ This document uses the following terms:
+
+ o "DHCP client"
+
+ A DHCP client is an Internet host using DHCP to obtain
+ configuration parameters such as a network address.
+
+ o "DHCP server"
+
+ A DHCP server is an Internet host that returns configuration
+ parameters to DHCP clients.
+
+ o "BOOTP relay agent"
+
+ A BOOTP relay agent or relay agent is an Internet host or router that
+ passes DHCP messages between DHCP clients and DHCP servers. DHCP is
+ designed to use the same relay agent behavior as specified in
+ the BOOTP protocol specification.
+
+ o "binding"
+
+ A binding is a collection of configuration parameters, including
+ at least an IP address, associated with or "bound to" a DHCP
+ client. Bindings are managed by DHCP servers.
+
+1.5 Design goals
+
+ The following list gives general design goals for DHCP.
+
+ o DHCP should be a mechanism rather than a policy. DHCP must
+ allow local system administrators control over configuration
+ parameters where desired; e.g., local system administrators
+ should be able to enforce local policies concerning allocation
+ and access to local resources where desired.
+
+ o Clients should require no manual configuration. Each client should
+ be able to discover appropriate local configuration parameters
+ without user intervention and incorporate those parameters into
+ its own configuration.
+
+ o Networks should require no manual configuration for individual
+ clients. Under normal circumstances, the network manager should
+ not have to enter any per-client configuration parameters.
+
+ o DHCP should not require a server on each subnet. To allow for
+ scale and economy, DHCP must work across routers or through the
+ intervention of BOOTP relay agents.
+
+ o A DHCP client must be prepared to receive multiple responses to a
+ request for configuration parameters. Some installations may
+ include multiple, overlapping DHCP servers to enhance
+ reliability and increase performance.
+
+ o DHCP must coexist with statically configured, non-participating
+ hosts and with existing network protocol implementations.
+
+ o DHCP must interoperate with the BOOTP relay agent behavior as
+ described by RFC 951 and by RFC 1542 [21].
+
+ o DHCP must provide service to existing BOOTP clients.
+
+ The following list gives design goals specific to the transmission of
+ the network layer parameters. DHCP must:
+
+ o Guarantee that any specific network address will not be in
+ use by more than one DHCP client at a time,
+
+ o Retain DHCP client configuration across DHCP client reboot. A DHCP
+ client should, whenever possible, be assigned the same configuration
+ parameters (e.g., network address) in response to each request,
+
+ o Retain DHCP client configuration across server reboots, and, whenever
+ possible, a DHCP client should be assigned the same configuration
+ parameters despite restarts of the DHCP mechanism,
+
+ o Allow automatic assignment of configuration parameters to new
+ clients to avoid hand configuration for new clients,
+
+ o Support fixed or permanent allocation of configuration
+ parameters to specific clients.
+
+2. Protocol Summary
+
+ From the client's point of view, DHCP is an extension of the BOOTP
+ mechanism. This behavior allows existing BOOTP clients to
+ interoperate with DHCP servers without requiring any change to the
+ clients' initialization software. RFC 1533 [2] details the
+ interactions between BOOTP and DHCP clients and servers [9]. There
+ are some new, optional transactions that optimize the interaction
+ between DHCP clients and servers that are described in sections 3 and
+ 4.
+
+ Figure 1 gives the format of a DHCP message and table 1 describes
+ each of the fields in the DHCP message. The numbers in parentheses
+ indicate the size of each field in octets. The names for the fields
+ given in the figure will be used throughout this document to refer to
+ the fields in DHCP messages.
+
+ There are two primary differences between DHCP and BOOTP. First,
+ DHCP defines mechanisms through which clients can be assigned a
+ network address for a finite lease, allowing for serial reassignment
+ of network addresses to different clients. Second, DHCP provides the
+ mechanism for a client to acquire all of the IP configuration
+ parameters that it needs in order to operate.
+
+ DHCP introduces a small change in terminology intended to clarify the
+ meaning of one of the fields. What was the "vendor extensions" field
+ in BOOTP has been re-named the "options" field in DHCP. Similarly,
+ the tagged data items that were used inside the BOOTP "vendor
+ extensions" field, which were formerly referred to as "vendor
+ extensions," are now termed simply "options."
+
+ DHCP defines a new 'client identifier' option that is used to pass an
+ explicit client identifier to a DHCP server. This change eliminates
+ the overloading of the 'chaddr' field in BOOTP messages, where
+ 'chaddr' is used both as a hardware address for transmission of BOOTP
+ reply messages and as a client identifier. The 'client identifier'
+ is an opaque key, not to be interpreted by the server; for example,
+ the 'client identifier' may contain a hardware address, identical to
+ the contents of the 'chaddr' field, or it may contain another type of
+ identifier, such as a DNS name. If the client uses a 'client
+ identifier' in one message, it MUST use that same identifier in all
+ subsequent messages, to ensure that all servers correctly identify
+ the client.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | op (1) | htype (1) | hlen (1) | hops (1) |
+ +---------------+---------------+---------------+---------------+
+ | xid (4) |
+ +-------------------------------+-------------------------------+
+ | secs (2) | flags (2) |
+ +-------------------------------+-------------------------------+
+ | ciaddr (4) |
+ +---------------------------------------------------------------+
+ | yiaddr (4) |
+ +---------------------------------------------------------------+
+ | siaddr (4) |
+ +---------------------------------------------------------------+
+ | giaddr (4) |
+ +---------------------------------------------------------------+
+ | |
+ | chaddr (16) |
+ | |
+ | |
+ +---------------------------------------------------------------+
+ | |
+ | sname (64) |
+ +---------------------------------------------------------------+
+ | |
+ | file (128) |
+ +---------------------------------------------------------------+
+ | |
+ | options (variable) |
+ +---------------------------------------------------------------+
+
+ Figure 1: Format of a DHCP message
+
+ DHCP clarifies the interpretation of the 'siaddr' field as the
+ address of the server to use in the next step of the client's
+ bootstrap process. A DHCP server may return its own address in the
+ 'siaddr' field, if the server is prepared to supply the next
+ bootstrap service (e.g., delivery of an operating system executable
+ image). A DHCP server always returns its own address in the 'server
+ identifier' option.
+
+ The 'options' field is now variable length. A DHCP client must be
+ prepared to receive DHCP messages with an 'options' field of at least
+ length 312 octets. This requirement implies that a DHCP client must
+ be prepared to receive a message of up to 576 octets, the minimum IP
+ datagram size an IP host must be prepared to accept [3]. DHCP
+ clients may negotiate the use of larger DHCP messages through the
+
+ 'maximum DHCP message size' option. The options field may be further
+ extended into the 'file' and 'sname' fields.
+
+ In the case of a client using DHCP for initial configuration (before
+ the client's TCP/IP software has been completely configured), DHCP
+ requires creative use of the client's TCP/IP software and liberal
+ interpretation of RFC 1122. The TCP/IP software SHOULD accept and
+ forward to the IP layer any IP packets delivered to the client's
+ hardware address before the IP address is configured; DHCP servers
+ and BOOTP relay agents may not be able to deliver DHCP messages to
+ clients that cannot accept hardware unicast datagrams before the
+ TCP/IP software is configured.
+
+ To work around some clients that cannot accept IP unicast datagrams
+ before the TCP/IP software is configured as discussed in the previous
+ paragraph, DHCP uses the 'flags' field [21]. The leftmost bit is
+ defined as the BROADCAST (B) flag. The semantics of this flag are
+ discussed in section 4.1 of this document. The remaining bits of the
+ flags field are reserved for future use. They MUST be set to zero by
+ clients and ignored by servers and relay agents. Figure 2 gives the
+ format of the 'flags' field.
+
+ 1 1 1 1 1 1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |B| MBZ |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ B: BROADCAST flag
+
+ MBZ: MUST BE ZERO (reserved for future use)
+
+ Figure 2: Format of the 'flags' field
+
+
+2.1 Configuration parameters repository
+
+ The first service provided by DHCP is to provide persistent storage
+ of network parameters for network clients. The model of DHCP
+ persistent storage is that the DHCP service stores a key-value entry
+ for each client, where the key is some unique identifier (for
+ example, an IP subnet number and a unique identifier within the
+ subnet) and the value contains the configuration parameters for the
+ client.
+
+ For example, the key might be the pair (IP-subnet-number, hardware-
+ address) (note that the "hardware-address" should be typed by the
+ type of hardware to accommodate possible duplication of hardware
+ addresses resulting from bit-ordering problems in a mixed-media,
+ bridged network) allowing for serial or concurrent reuse of a
+ hardware address on different subnets, and for hardware addresses
+ that may not be globally unique. Alternately, the key might be the
+ pair (IP-subnet-number, hostname), allowing the server to assign
+ parameters intelligently to a DHCP client that has been moved to a
+ different subnet or has changed hardware addresses (perhaps because
+ the network interface failed and was replaced). The protocol defines
+ that the key will be (IP-subnet-number, hardware-address) unless the
+ client explicitly supplies an identifier.
+
+ A client can query the DHCP service to retrieve its configuration
+ parameters. The client interface to the configuration parameters
+ repository consists of protocol messages to request configuration
+ parameters and responses from the server carrying the configuration
+ parameters.
+
+2.2 Dynamic allocation of network addresses
+
+ The second service provided by DHCP is the allocation of temporary or
+ permanent network (IP) addresses to clients. The basic mechanism for
+ the dynamic allocation of network addresses is simple: a client
+ requests the use of an address for some period of time. The
+ allocation mechanism (the collection of DHCP servers) guarantees not
+ to reallocate that address within the requested time and attempts to
+ return the same network address each time the client requests an
+ address. In this document, the period over which a network address
+ is allocated to a client is referred to as a "lease" [11]. The
+ client may extend its lease with subsequent requests. The client may
+ issue a message to release the address back to the server when the
+ client no longer needs the address. The client may ask for a
+ permanent assignment by asking for an infinite lease. Even when
+ assigning "permanent" addresses, a server may choose to give out
+ lengthy but non-infinite leases to allow detection of the fact that
+ the client has been retired.
+
+ In some environments it will be necessary to reassign network
+ addresses due to exhaustion of available addresses. In such
+ environments, the allocation mechanism will reuse addresses whose
+ lease has expired. The server should use whatever information is
+ available in the configuration information repository to choose an
+ address to reuse. For example, the server may choose the least
+ recently assigned address. As a consistency check, the allocating
+ server SHOULD probe the reused address before allocating the address,
+ e.g., with an ICMP echo request, and the client SHOULD probe the
+ newly received address, e.g., with ARP.
+
+ FIELD OCTETS DESCRIPTION
+ ----- ------ -----------
+
+ op 1 Message op code / message type.
+ 1 = BOOTREQUEST, 2 = BOOTREPLY
+ htype 1 Hardware address type, see ARP section in "Assigned
+ Numbers" RFC; e.g., '1' = 10mb ethernet.
+ hlen 1 Hardware address length (e.g. '6' for 10mb
+ ethernet).
+ hops 1 Client sets to zero, optionally used by relay agents
+ when booting via a relay agent.
+ xid 4 Transaction ID, a random number chosen by the
+ client, used by the client and server to associate
+ messages and responses between a client and a
+ server.
+ secs 2 Filled in by client, seconds elapsed since client
+ began address acquisition or renewal process.
+ flags 2 Flags (see figure 2).
+ ciaddr 4 Client IP address; only filled in if client is in
+ BOUND, RENEW or REBINDING state and can respond to ARP
+ requests.
+ yiaddr 4 'your' (client) IP address.
+ siaddr 4 IP address of next server to use in bootstrap;
+ returned in DHCPOFFER, DHCPACK by server.
+ giaddr 4 Relay agent IP address, used in booting via a
+ relay agent.
+ chaddr 16 Client hardware address.
+ sname 64 Optional server host name, null terminated string.
+ file 128 Boot file name, null terminated string; "generic"
+ name or null in DHCPDISCOVER, fully qualified
+ directory-path name in DHCPOFFER.
+ options var Optional parameters field. See the options
+ documents for a list of defined options.
+
+ Table 1: Description of fields in a DHCP message
+
+3. The Client-Server Protocol
+
+ DHCP uses the BOOTP message format defined in RFC 951 and given in
+ table 1 and figure 1. The 'op' field of each DHCP message sent from
+ a client to a server contains BOOTREQUEST. BOOTREPLY is used in the
+ 'op' field of each DHCP message sent from a server to a client.
+
+ The first four octets of the 'options' field of the DHCP message
+ contain the (decimal) values 99, 130, 83 and 99, respectively (this
+ is the same magic cookie as is defined in RFC 1497 [17]). The
+ remainder of the 'options' field consists a list of tagged parameters
+ that are called "options". All of the "vendor extensions" listed in
+ RFC 1497 are also DHCP options. RFC 1533 gives the complete set of
+ options defined for use with DHCP.
+
+ Several options have been defined so far. One particular option -
+ the "DHCP message type" option - must be included in every DHCP
+ message. This option defines the "type" of the DHCP message.
+ Additional options may be allowed, required, or not allowed,
+ depending on the DHCP message type.
+
+ Throughout this document, DHCP messages that include a 'DHCP message
+ type' option will be referred to by the type of the message; e.g., a
+ DHCP message with 'DHCP message type' option type 1 will be referred
+ to as a "DHCPDISCOVER" message.
+
+3.1 Client-server interaction - allocating a network address
+
+ The following summary of the protocol exchanges between clients and
+ servers refers to the DHCP messages described in table 2. The
+ timeline diagram in figure 3 shows the timing relationships in a
+ typical client-server interaction. If the client already knows its
+ address, some steps may be omitted; this abbreviated interaction is
+ described in section 3.2.
+
+ 1. The client broadcasts a DHCPDISCOVER message on its local physical
+ subnet. The DHCPDISCOVER message MAY include options that suggest
+ values for the network address and lease duration. BOOTP relay
+ agents may pass the message on to DHCP servers not on the same
+ physical subnet.
+
+ 2. Each server may respond with a DHCPOFFER message that includes an
+ available network address in the 'yiaddr' field (and other
+ configuration parameters in DHCP options). Servers need not
+ reserve the offered network address, although the protocol will
+ work more efficiently if the server avoids allocating the offered
+ network address to another client. When allocating a new address
+ (i.e., 'ciaddr' == 0), servers SHOULD check that the offered
+ network address is not already in use; e.g., the server may probe
+ the offered address with an ICMP Echo Request. Servers SHOULD be
+ implemented so that network administrators MAY choose to disable
+ probes of newly allocated addresses. The server transmits the
+ DHCPOFFER message to the client, using the BOOTP relay agent if
+ necessary.
+
+ 3. The client receives one or more DHCPOFFER messages from one or
+ more servers. The client may choose to wait for multiple
+ responses. The client chooses one server from which to request
+ configuration parameters, based on the configuration parameters
+ offered in the DHCPOFFER messages. The client broadcasts a
+ DHCPREQUEST message that MUST include the 'server identifier'
+ option to indicate which server it has selected, and that MAY
+ include other options specifying desired configuration values.
+ The 'requested IP address' option MUST be set to the value of
+ 'yiaddr' in the DHCPOFFER message from the server. This
+ DHCPREQUEST message is broadcast and relayed through DHCP/BOOTP
+ relay agents. To help ensure that any BOOTP relay agents forward
+ the DHCPREQUEST message to the same set of DHCP servers that
+ received the original DHCPDISCOVER message, the DHCPREQUEST
+ message MUST use the same value in the DHCP message header's
+ 'secs' field and be sent to the same IP broadcast address as the
+ original DHCPDISCOVER message. The client times out and
+ retransmits the DHCPDISCOVER message if the client receives no
+ DHCPOFFER messages.
+
+ Message Use
+ ------- ---
+
+ DHCPDISCOVER - Client broadcast to locate available servers.
+
+ DHCPOFFER - Server to client in response to DHCPDISCOVER with
+ offer of configuration parameters.
+
+ DHCPREQUEST - Client message to servers either (a) requesting
+ offered parameters from one server and implicitly
+ declining offers from all others, (b) confirming
+ correctness of previously allocated address after,
+ e.g., system reboot, or (c) extending the lease on a
+ particular network address.
+
+ DHCPACK - Server to client with configuration parameters,
+ including committed network address.
+
+ DHCPNAK - Server to client indicating client's notion of network
+ address is incorrect (e.g., client has moved to new
+ subnet) or client's lease as expired
+
+ DHCPDECLINE - Client to server indicating network address is already
+ in use.
+
+ DHCPRELEASE - Client to server relinquishing network address and
+ cancelling remaining lease.
+
+ DHCPINFORM - Client to server, asking only for local configuration
+ parameters; client already has externally configured
+ network address.
+
+ Table 2: DHCP messages
+ Server Client Server
+ (not selected) (selected)
+
+ v v v
+ | | |
+ | Begins initialization |
+ | | |
+ | _____________/|\_____________ |
+ |/ DHCPDISCOVER | DHCPDISCOVER \|
+ | | |
+ Determines | Determines
+ configuration | configuration
+ | | |
+ |\ | ____________/|
+ | \_________ | /DHCPOFFER |
+ | DHCPOFFER\ |/ |
+ | \ | |
+ | Collects replies |
+ | \| |
+ | Selects configuration |
+ | | |
+ | _____________/|\_____________ |
+ |/ DHCPREQUEST | DHCPREQUEST \|
+ | | |
+ | | Commits configuration
+ | | |
+ | | _____________/|
+ | |/ DHCPACK |
+ | | |
+ | Initialization complete |
+ | | |
+ . . .
+ . . .
+ | | |
+ | Graceful shutdown |
+ | | |
+ | |\_____________ |
+ | | DHCPRELEASE \|
+ | | |
+ | | Discards lease
+ | | |
+ v v v
+ Figure 3: Timeline diagram of messages exchanged between DHCP
+ client and servers when allocating a new network address
+
+ 4. The servers receive the DHCPREQUEST broadcast from the client.
+ Those servers not selected by the DHCPREQUEST message use the
+ message as notification that the client has declined that server's
+ offer. The server selected in the DHCPREQUEST message commits the
+ binding for the client to persistent storage and responds with a
+ DHCPACK message containing the configuration parameters for the
+ requesting client. The combination of 'client identifier' or
+ 'chaddr' and assigned network address constitute a unique
+ identifier for the client's lease and are used by both the client
+ and server to identify a lease referred to in any DHCP messages.
+ Any configuration parameters in the DHCPACK message SHOULD NOT
+ conflict with those in the earlier DHCPOFFER message to which the
+ client is responding. The server SHOULD NOT check the offered
+ network address at this point. The 'yiaddr' field in the DHCPACK
+ messages is filled in with the selected network address.
+
+ If the selected server is unable to satisfy the DHCPREQUEST message
+ (e.g., the requested network address has been allocated), the
+ server SHOULD respond with a DHCPNAK message.
+
+ A server MAY choose to mark addresses offered to clients in
+ DHCPOFFER messages as unavailable. The server SHOULD mark an
+ address offered to a client in a DHCPOFFER message as available if
+ the server receives no DHCPREQUEST message from that client.
+
+ 5. The client receives the DHCPACK message with configuration
+ parameters. The client SHOULD perform a final check on the
+ parameters (e.g., ARP for allocated network address), and notes the
+ duration of the lease specified in the DHCPACK message. At this
+ point, the client is configured. If the client detects that the
+ address is already in use (e.g., through the use of ARP), the
+ client MUST send a DHCPDECLINE message to the server and restarts
+ the configuration process. The client SHOULD wait a minimum of ten
+ seconds before restarting the configuration process to avoid
+ excessive network traffic in case of looping.
+
+ If the client receives a DHCPNAK message, the client restarts the
+ configuration process.
+
+ The client times out and retransmits the DHCPREQUEST message if the
+ client receives neither a DHCPACK or a DHCPNAK message. The client
+ retransmits the DHCPREQUEST according to the retransmission
+ algorithm in section 4.1. The client should choose to retransmit
+ the DHCPREQUEST enough times to give adequate probability of
+ contacting the server without causing the client (and the user of
+ that client) to wait overly long before giving up; e.g., a client
+ retransmitting as described in section 4.1 might retransmit the
+ DHCPREQUEST message four times, for a total delay of 60 seconds,
+ before restarting the initialization procedure. If the client
+ receives neither a DHCPACK or a DHCPNAK message after employing the
+ retransmission algorithm, the client reverts to INIT state and
+ restarts the initialization process. The client SHOULD notify the
+ user that the initialization process has failed and is restarting.
+
+ 6. The client may choose to relinquish its lease on a network address
+ by sending a DHCPRELEASE message to the server. The client
+ identifies the lease to be released with its 'client identifier',
+ or 'chaddr' and network address in the DHCPRELEASE message. If the
+ client used a 'client identifier' when it obtained the lease, it
+ MUST use the same 'client identifier' in the DHCPRELEASE message.
+
+3.2 Client-server interaction - reusing a previously allocated network
+ address
+
+ If a client remembers and wishes to reuse a previously allocated
+ network address, a client may choose to omit some of the steps
+ described in the previous section. The timeline diagram in figure 4
+ shows the timing relationships in a typical client-server interaction
+ for a client reusing a previously allocated network address.
+
+ 1. The client broadcasts a DHCPREQUEST message on its local subnet.
+ The message includes the client's network address in the
+ 'requested IP address' option. As the client has not received its
+ network address, it MUST NOT fill in the 'ciaddr' field. BOOTP
+ relay agents pass the message on to DHCP servers not on the same
+ subnet. If the client used a 'client identifier' to obtain its
+ address, the client MUST use the same 'client identifier' in the
+ DHCPREQUEST message.
+
+ 2. Servers with knowledge of the client's configuration parameters
+ respond with a DHCPACK message to the client. Servers SHOULD NOT
+ check that the client's network address is already in use; the
+ client may respond to ICMP Echo Request messages at this point.
+
+ If the client's request is invalid (e.g., the client has moved to
+ a new subnet), servers SHOULD respond with a DHCPNAK message to
+ the client. Servers SHOULD NOT respond if their information is not
+ guaranteed to be accurate. For example, a server that identifies
+ a request for an expired binding that is owned by another server
+ SHOULD NOT respond with a DHCPNAK unless the servers are using an
+ explicit mechanism to maintain coherency among the servers.
+
+ Server Client Server
+
+ v v v
+ | | |
+ | Begins |
+ | initialization |
+ | | |
+ | /|\ |
+ | ___________/ | \___________ |
+ | /DHCPREQUEST | DHCPREQUEST\ |
+ |/ | \|
+ | | |
+ Locates | Locates
+ configuration | configuration
+ | | |
+ |\ | /|
+ | \ | ___________/ |
+ | \ | / DHCPACK |
+ | \_______ |/ |
+ | DHCPACK\ | |
+ | Initialization |
+ | complete |
+ | \| |
+ | | |
+ | (Subsequent |
+ | DHCPACKS |
+ | ignored) |
+ | | |
+ | | |
+ v v v
+
+ Figure 4: Timeline diagram of messages exchanged between DHCP
+ client and servers when reusing a previously allocated
+ network address
+
+
+ If 'giaddr' in the DHCPREQUEST message contains 0x0, the server sends
+ the DHCPNAK message directly to the client, as the client is on the
+ same subnet. Otherwise, the server send the DHCPNAK message to the IP
+ address of the BOOTP relay agent, as recorded in 'giaddr'. The
+ relay agent will, in turn, forward the message directly to the
+ client's hardware address, so that the DHCPNAK can be delivered even
+ if the client has moved to a new network.
+
+ 3. The client receives the DHCPACK message with configuration
+ parameters. The client performs a final check on the parameters
+ (as in section 3.1), and notes the duration of the lease specified
+ in the DHCPACK message. The specific lease is implicitly identified
+ by the 'client identifier' or 'chaddr' and the network address. At
+ this point, the client is configured.
+
+ If the client detects that the IP address in the DHCPACK message
+ is already in use, the client MUST send a DHCPDECLINE message to the
+ server and restarts the configuration process by requesting a
+ new network address. This action corresponds to the client
+ moving to the INIT state in the DHCP state diagram, which is
+ described in section 4.4.
+
+ If the client receives a DHCPNAK message, it cannot reuse its
+ remembered network address. It must instead request a new
+ address by restarting the configuration process, this time
+ using the (non-abbreviated) procedure described in section
+ 3.1. This action also corresponds to the client moving to
+ the INIT state in the DHCP state diagram.
+
+ The client times out and retransmits the DHCPREQUEST message if
+ the client receives neither a DHCPACK nor a DHCPNAK message. The
+ client retransmits the DHCPREQUEST according to the retransmission
+ algorithm in section 4.1. The client should choose to retransmit
+ the DHCPREQUEST enough times to give adequate probability of
+ contacting the server without causing the client (and the user of
+ that client) to wait overly long before giving up; e.g., a client
+ retransmitting as described in section 4.1 might retransmit the
+ DHCPREQUEST message four times, for a total delay of 60 seconds,
+ before restarting the initialization procedure. If the client
+ receives neither a DHCPACK or a DHCPNAK message after employing
+ the retransmission algorithm, the client MAY choose to use the
+ previously allocated network address and configuration parameters
+ for the remainder of the unexpired lease. This corresponds to
+ moving to BOUND state in the client state transition diagram shown
+ in figure 5.
+
+ 4. The client may choose to relinquish its lease on a network
+ address by sending a DHCPRELEASE message to the server. The
+ client identifies the lease to be released with its
+ 'client identifier', or 'chaddr' and network address in the
+ DHCPRELEASE message.
+
+ Note that in this case, where the client retains its network
+ address locally, the client will not normally relinquish its
+ lease during a graceful shutdown. Only in the case where the
+ client explicitly needs to relinquish its lease, e.g., the client
+ is about to be moved to a different subnet, will the client send
+ a DHCPRELEASE message.
+
+3.3 Interpretation and representation of time values
+
+ A client acquires a lease for a network address for a fixed period of
+ time (which may be infinite). Throughout the protocol, times are to
+ be represented in units of seconds. The time value of 0xffffffff is
+ reserved to represent "infinity".
+
+ As clients and servers may not have synchronized clocks, times are
+ represented in DHCP messages as relative times, to be interpreted
+ with respect to the client's local clock. Representing relative
+ times in units of seconds in an unsigned 32 bit word gives a range of
+ relative times from 0 to approximately 100 years, which is sufficient
+ for the relative times to be measured using DHCP.
+
+ The algorithm for lease duration interpretation given in the previous
+ paragraph assumes that client and server clocks are stable relative
+ to each other. If there is drift between the two clocks, the server
+ may consider the lease expired before the client does. To
+ compensate, the server may return a shorter lease duration to the
+ client than the server commits to its local database of client
+ information.
+
+3.4 Obtaining parameters with externally configured network address
+
+ If a client has obtained a network address through some other means
+ (e.g., manual configuration), it may use a DHCPINFORM request message
+ to obtain other local configuration parameters. Servers receiving a
+ DHCPINFORM message construct a DHCPACK message with any local
+ configuration parameters appropriate for the client without:
+ allocating a new address, checking for an existing binding, filling
+ in 'yiaddr' or including lease time parameters. The servers SHOULD
+ unicast the DHCPACK reply to the address given in the 'ciaddr' field
+ of the DHCPINFORM message.
+
+ The server SHOULD check the network address in a DHCPINFORM message
+ for consistency, but MUST NOT check for an existing lease. The
+ server forms a DHCPACK message containing the configuration
+ parameters for the requesting client and sends the DHCPACK message
+ directly to the client.
+
+3.5 Client parameters in DHCP
+
+ Not all clients require initialization of all parameters listed in
+ Appendix A. Two techniques are used to reduce the number of
+ parameters transmitted from the server to the client. First, most of
+ the parameters have defaults defined in the Host Requirements RFCs;
+ if the client receives no parameters from the server that override
+ the defaults, a client uses those default values. Second, in its
+ initial DHCPDISCOVER or DHCPREQUEST message, a client may provide the
+ server with a list of specific parameters the client is interested
+ in. If the client includes a list of parameters in a DHCPDISCOVER
+ message, it MUST include that list in any subsequent DHCPREQUEST
+ messages.
+
+ The client SHOULD include the 'maximum DHCP message size' option to
+ let the server know how large the server may make its DHCP messages.
+ The parameters returned to a client may still exceed the space
+ allocated to options in a DHCP message. In this case, two additional
+ options flags (which must appear in the 'options' field of the
+ message) indicate that the 'file' and 'sname' fields are to be used
+ for options.
+
+ The client can inform the server which configuration parameters the
+ client is interested in by including the 'parameter request list'
+ option. The data portion of this option explicitly lists the options
+ requested by tag number.
+
+ In addition, the client may suggest values for the network address
+ and lease time in the DHCPDISCOVER message. The client may include
+ the 'requested IP address' option to suggest that a particular IP
+ address be assigned, and may include the 'IP address lease time'
+ option to suggest the lease time it would like. Other options
+ representing "hints" at configuration parameters are allowed in a
+ DHCPDISCOVER or DHCPREQUEST message. However, additional options may
+ be ignored by servers, and multiple servers may, therefore, not
+ return identical values for some options. The 'requested IP address'
+ option is to be filled in only in a DHCPREQUEST message when the
+ client is verifying network parameters obtained previously. The
+ client fills in the 'ciaddr' field only when correctly configured
+ with an IP address in BOUND, RENEWING or REBINDING state.
+
+ If a server receives a DHCPREQUEST message with an invalid 'requested
+ IP address', the server SHOULD respond to the client with a DHCPNAK
+ message and may choose to report the problem to the system
+ administrator. The server may include an error message in the
+ 'message' option.
+
+3.6 Use of DHCP in clients with multiple interfaces
+
+ A client with multiple network interfaces must use DHCP through each
+ interface independently to obtain configuration information
+ parameters for those separate interfaces.
+
+3.7 When clients should use DHCP
+
+ A client SHOULD use DHCP to reacquire or verify its IP address and
+ network parameters whenever the local network parameters may have
+ changed; e.g., at system boot time or after a disconnection from the
+ local network, as the local network configuration may change without
+ the client's or user's knowledge.
+
+ If a client has knowledge of a previous network address and is unable
+ to contact a local DHCP server, the client may continue to use the
+ previous network address until the lease for that address expires.
+ If the lease expires before the client can contact a DHCP server, the
+ client must immediately discontinue use of the previous network
+ address and may inform local users of the problem.
+
+4. Specification of the DHCP client-server protocol
+
+ In this section, we assume that a DHCP server has a block of network
+ addresses from which it can satisfy requests for new addresses. Each
+ server also maintains a database of allocated addresses and leases in
+ local permanent storage.
+
+4.1 Constructing and sending DHCP messages
+
+ DHCP clients and servers both construct DHCP messages by filling in
+ fields in the fixed format section of the message and appending
+ tagged data items in the variable length option area. The options
+ area includes first a four-octet 'magic cookie' (which was described
+ in section 3), followed by the options. The last option must always
+ be the 'end' option.
+
+ DHCP uses UDP as its transport protocol. DHCP messages from a client
+ to a server are sent to the 'DHCP server' port (67), and DHCP
+ messages from a server to a client are sent to the 'DHCP client' port
+ (68). A server with multiple network address (e.g., a multi-homed
+ host) MAY use any of its network addresses in outgoing DHCP messages.
+
+ DHCP messages broadcast by a client prior to that client obtaining
+ its IP address must have the source address field in the IP header
+ set to 0.
+
+ If the 'giaddr' field in a DHCP message from a client is non-zero,
+ the server sends any return messages to the 'DHCP server' port on the
+ DHCP relaying agent whose address appears in 'giaddr'. If the
+ 'giaddr' field is zero and the 'ciaddr' field is nonzero, then the
+ server should unicast the packet to the address in 'ciaddr'. If
+ 'giaddr' is zero and 'ciaddr' is zero, and the broadcast bit is set,
+ then the server should broadcast the packet to 255.255.255.255. If
+ the broadcast bit is not set and 'giaddr' is zero and 'ciaddr' is
+ zero, then the server should unicast the packet to the client's
+ hardware address and 'yiaddr' address.
+
+ If the options in a DHCP message extend into the 'sname' and 'file'
+ fields, the 'option overload' option MUST appear in the 'options'
+ field, with value 1, 2 or 3, as specified in RFC 1533. If the
+ 'option overload' option is present in the 'options' field, the
+ options in the 'options' field MUST be terminated by an 'end' option,
+ and MAY contain one or more 'pad' options to fill the options field.
+ The options in the 'sname' and 'file' fields (if in use as indicated
+ by the 'options overload' option) MUST begin with the first octet of
+ the field, MUST be terminated by an 'end' option, and MUST be
+ followed by 'pad' options to fill the remainder of the field. Any
+ individual option in the 'options', 'sname' and 'file' fields MUST be
+ entirely contained in that field. The options in the 'options' field
+ MUST be interpreted first, so that any 'option overload' options may
+ be interpreted. The 'file' field MUST be interpreted next (if the
+ 'option overload' option indicates that the 'file' field contains
+ DHCP options), followed by the 'sname' field.
+
+ The values to be passed in an 'option' tag may be too long to fit in
+ the 255 octets available to a single option (e.g., a list of routers
+ in a 'router' option [21]). Options may appear only once, unless
+ otherwise specified in the options document. The client concatenates
+ the values of multiple instances of the same option into a single
+ parameter list for configuration.
+
+ DHCP clients are responsible for all message retransmission. The
+ client MUST adopt a retransmission strategy that incorporates a
+ randomized exponential backoff algorithm to determine the delay
+ between retransmissions. The delay between retransmissions SHOULD be
+ chosen to allow sufficient time for replies from the server to be
+ delivered based on the characteristics of the internetwork between
+ the client and the server. For example, in a 10Mb/sec Ethernet
+ internetwork, the delay before the first retransmission SHOULD be 4
+ seconds randomized by the value of a uniform random number chosen
+ from the range -1 to +1. Clients with clocks that provide resolution
+ granularity of less than one second may choose a non-integer
+ randomization value. The delay before the next retransmission SHOULD
+ be 8 seconds randomized by the value of a uniform number chosen from
+ the range -1 to +1. The retransmission delay SHOULD be doubled with
+ subsequent retransmissions up to a maximum of 64 seconds. The client
+ MAY provide an indication of retransmission attempts to the user as
+ an indication of the progress of the configuration process.
+
+ The 'xid' field is used by the client to match incoming DHCP messages
+ with pending requests. A DHCP client MUST choose 'xid's in such a
+ way as to minimize the chance of using an 'xid' identical to one used
+ by another client. For example, a client may choose a different,
+ random initial 'xid' each time the client is rebooted, and
+ subsequently use sequential 'xid's until the next reboot. Selecting
+ a new 'xid' for each retransmission is an implementation decision. A
+ client may choose to reuse the same 'xid' or select a new 'xid' for
+ each retransmitted message.
+
+ Normally, DHCP servers and BOOTP relay agents attempt to deliver
+ DHCPOFFER, DHCPACK and DHCPNAK messages directly to the client using
+ unicast delivery. The IP destination address (in the IP header) is
+ set to the DHCP 'yiaddr' address and the link-layer destination
+ address is set to the DHCP 'chaddr' address. Unfortunately, some
+ client implementations are unable to receive such unicast IP
+ datagrams until the implementation has been configured with a valid
+ IP address (leading to a deadlock in which the client's IP address
+ cannot be delivered until the client has been configured with an IP
+ address).
+
+ A client that cannot receive unicast IP datagrams until its protocol
+ software has been configured with an IP address SHOULD set the
+ BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
+ DHCPREQUEST messages that client sends. The BROADCAST bit will
+ provide a hint to the DHCP server and BOOTP relay agent to broadcast
+ any messages to the client on the client's subnet. A client that can
+ receive unicast IP datagrams before its protocol software has been
+ configured SHOULD clear the BROADCAST bit to 0. The BOOTP
+ clarifications document discusses the ramifications of the use of the
+ BROADCAST bit [21].
+
+ A server or relay agent sending or relaying a DHCP message directly
+ to a DHCP client (i.e., not to a relay agent specified in the
+ 'giaddr' field) SHOULD examine the BROADCAST bit in the 'flags'
+ field. If this bit is set to 1, the DHCP message SHOULD be sent as
+ an IP broadcast using an IP broadcast address (preferably
+ 255.255.255.255) as the IP destination address and the link-layer
+ broadcast address as the link-layer destination address. If the
+ BROADCAST bit is cleared to 0, the message SHOULD be sent as an IP
+ unicast to the IP address specified in the 'yiaddr' field and the
+ link-layer address specified in the 'chaddr' field. If unicasting is
+ not possible, the message MAY be sent as an IP broadcast using an IP
+ broadcast address (preferably 255.255.255.255) as the IP destination
+ address and the link-layer broadcast address as the link-layer
+ destination address.
+
+4.2 DHCP server administrative controls
+
+ DHCP servers are not required to respond to every DHCPDISCOVER and
+ DHCPREQUEST message they receive. For example, a network
+ administrator, to retain stringent control over the clients attached
+ to the network, may choose to configure DHCP servers to respond only
+ to clients that have been previously registered through some external
+ mechanism. The DHCP specification describes only the interactions
+ between clients and servers when the clients and servers choose to
+ interact; it is beyond the scope of the DHCP specification to
+ describe all of the administrative controls that system
+ administrators might want to use. Specific DHCP server
+ implementations may incorporate any controls or policies desired by a
+ network administrator.
+
+ In some environments, a DHCP server will have to consider the values
+ of the vendor and user class options included in DHCPDISCOVER or
+ DHCPREQUEST messages when determining the correct parameters for a
+ particular client. For example, an organization might have a
+ separate printer server for each type of end-user, requiring the DHCP
+ server to examine the 'user class identifier' to determine which
+ printer server address to return in a DHCPOFFER or DHCPACK message.
+
+ A DHCP server needs to use some unique identifier to associate a
+ client with its lease. The client MAY choose to explicitly provide
+ the identifier through the 'client identifier' option. If the client
+ supplies a 'client identifier', the client MUST use the same 'client
+ identifier' in all subsequent messages, and the server MUST use that
+ identifier to identify the client. If the client does not provide a
+ 'client identifier' option, the server MUST use the contents of the
+ 'chaddr' field to identify the client. It is crucial for DHCP clients
+ to use unique identifiers in the 'client identifier' option. Use of
+ 'chaddr' as the client's unique identifier may cause unexpected
+ results, as that identifier may be associated with a hardware
+ interface that could be moved to a new client. Some sites may choose
+ to use a manufacturer's serial number as the 'client identifier', to
+ avoid unexpected changes in a clients network address due to transfer
+ of hardware interfaces among computers. Sites may also choose to use
+ a DNS name as the 'client identifier', causing address leases to be
+ associated with the DNS name rather than a specific hardware box.
+
+ DHCP clients are free to use any strategy in selecting a DHCP server
+ among those from which the client receives a DHCPOFFER message. The
+ client implementation of DHCP SHOULD provide a mechanism for the user
+ to select directly the 'vendor class identifier' and 'user class
+ identifier' values.
+
+4.3 DHCP server behavior
+
+ A DHCP server processes incoming DHCP messages from a client based on
+ the current state of the binding for that client. A DHCP server can
+ receive the following messages from a client:
+
+ o DHCPDISCOVER
+
+ o DHCPREQUEST
+
+ o DHCPDECLINE
+
+ o DHCPRELEASE
+
+ o DHCPINFORM
+
+ Table 3 gives the use of the fields and options in a DHCP message by
+ a server. The remainder of this section describes the action of the
+ DHCP server for each possible incoming message.
+
+4.3.1 DHCPDISCOVER message
+
+ When a server receives a DHCPDISCOVER message from a client, the
+ server chooses a network address for the requesting client. If no
+ address is available, the server may choose to report the problem to
+ the system administrator. If an address is available, the new address
+ SHOULD be chosen as follows:
+
+ o The client's current address as recorded in the client's current
+ binding, ELSE
+
+ o The client's previous address as recorded in the client's (now
+ expired or released) binding, if that address is in the server's
+ pool of available addresses and not already allocated, ELSE
+
+ o The address requested in the 'Requested IP Address' option, if that
+ address is valid and not already allocated, ELSE
+
+ o A new address allocated from the server's pool of available
+ addresses; the address is selected based on the subnet from which
+ the message was received (if 'giaddr' is 0) or on the address of
+ the relay agent that forwarded the message ('giaddr' when not 0).
+
+ As described in section 4.2, a server MAY, for administrative
+ reasons, assign an address other than the one requested, or may
+ refuse to allocate an address to a particular client even though free
+ addresses are available.
+
+ While not required for correct operation of DHCP, the server SHOULD
+ not reuse the selected network address before the client responds to
+ the server's DHCPOFFER message. The server may choose to record the
+ address as offered to the client.
+
+ Field DHCPOFFER DHCPACK DHCPNAK
+ ----- --------- ------- -------
+ 'op' BOOTREPLY BOOTREPLY BOOTREPLY
+ 'htype' (From "Assigned Numbers" RFC)
+ 'hlen' (Hardware address length in octets)
+ 'hops' 0 0 0
+ 'xid' 'xid' from client 'xid' from client 'xid' from client
+ DHCPDISCOVER DHCPREQUEST DHCPREQUEST
+ message message message
+ 'secs' 0 0 0
+ 'ciaddr' 0 'ciaddr' from 0
+ DHCPREQUEST or 0
+ 'yiaddr' IP address offered IP address 0
+ to client assigned to client
+ 'siaddr' IP address of next IP address of next 0
+ bootstrap server bootstrap server
+ 'flags' 'flags' from 'flags' from 'flags' from
+ client DHCPDISCOVER client DHCPREQUEST client DHCPREQUEST
+ message message message
+ 'giaddr' 'giaddr' from 'giaddr' from 'giaddr' from
+ client DHCPDISCOVER client DHCPREQUEST client DHCPREQUEST
+ message message message
+ 'chaddr' 'chaddr' from 'chaddr' from 'chaddr' from
+ client DHCPDISCOVER client DHCPREQUEST client DHCPREQUEST
+ message message message
+ 'sname' Server host name Server host name (unused)
+ or options or options
+ 'file' Client boot file Client boot file (unused)
+ name or options name or options
+ 'options' options options
+
+ Option DHCPOFFER DHCPACK DHCPNAK
+ ------ --------- ------- -------
+ Requested IP address MUST NOT MUST NOT MUST NOT
+ IP address lease time MUST MUST (DHCPREQUEST) MUST NOT
+ MUST NOT (DHCPINFORM)
+ Use 'file'/'sname' fields MAY MAY MUST NOT
+ DHCP message type DHCPOFFER DHCPACK DHCPNAK
+ Parameter request list MUST NOT MUST NOT MUST NOT
+ Message SHOULD SHOULD SHOULD
+ Client identifier MUST NOT MUST NOT MAY
+ Vendor class identifier MAY MAY MAY
+ User class identifier MUST MUST MAY
+ Server identifier MUST MUST MUST
+ Maximum message size MUST NOT MUST NOT MUST NOT
+ All others MAY MAY MUST NOT
+
+ Table 3: Fields and options used by DHCP servers
+
+ The server must also choose an expiration time for the lease, as
+ follows:
+
+ o IF the client has not requested a specific lease in the
+ DHCPDISCOVER message and the client already has an assigned network
+ address, the server returns the lease expiration time previously
+ assigned to that address (note that the client must explicitly
+ request a specific lease to extend the expiration time on a
+ previously assigned address), ELSE
+
+ o IF the client has not requested a specific lease in the
+ DHCPDISCOVER message and the client does not have an assigned
+ network address, the server assigns a locally configured default
+ lease time, ELSE
+
+ o IF the client has requested a specific lease in the DHCPDISCOVER
+ message (regardless of whether the client has an assigned network
+ address), the server may choose either to return the requested
+ lease (if the lease is acceptable to local policy) or select
+ another lease.
+
+ Once the network address and lease have been determined, the server
+ constructs a DHCPOFFER message with the offered configuration
+ parameters. It is important for all DHCP servers to return the same
+ parameters (with the possible exception of a newly allocated network
+ address) to ensure predictable client behavior regardless of which
+ server the client selects. The configuration parameters MUST be
+ selected by applying the following rules in the order given below.
+ The network administrator is responsible for configuring multiple
+ DHCP servers to ensure uniform responses from those servers. The
+ server MUST return to the client:
+
+ o The client's network address, as determined by the rules given
+ earlier in this section,
+
+ o The expiration time for the client's lease, as determined by the
+ rules given earlier in this section,
+
+ o Parameters requested by the client, according to the following
+ rules:
+
+ -- IF the server has been explicitly configured with a default
+ value for the parameter, the server MUST include that value
+ in an appropriate option in the 'option' field, ELSE
+
+ -- IF the server recognizes the parameter as a parameter
+ defined in the Host Requirements Document, the server MUST
+ include the default value for that parameter as given in the
+ Host Requirements Document in an appropriate option in the
+ 'option' field, ELSE
+
+ -- The server MUST NOT return a value for that parameter,
+
+ The server MUST supply as many of the requested parameters as
+ possible and MUST omit any parameters it cannot provide. The
+ server MUST include each requested parameter only once unless
+ explicitly allowed in the DHCP Options and BOOTP Vendor
+ Extensions document.
+
+ o Any parameters from the existing binding that differ from the Host
+ Requirements Document defaults,
+
+ o Any parameters specific to this client (as identified by
+ the contents of 'chaddr' or 'client identifier' in the DHCPDISCOVER
+ or DHCPREQUEST message), e.g., as configured by the network
+ administrator,
+
+ o Any parameters specific to this client's class (as identified
+ by the contents of the 'vendor class identifier' or 'user class
+ identifier' options in the DHCPDISCOVER or DHCPREQUEST message),
+ e.g., as configured by the network administrator; the parameters
+ MUST be identified by an exact match between the client's vendor and
+ user class identifiers and the client's classes identified in the
+ server,
+
+ o Parameters with non-default values on the client's subnet.
+
+ The server MAY choose to return the 'vendor class identifier' and
+ MUST return the 'user class identifier' used to determine the
+ parameters in the DHCPOFFER message to assist the client in selecting
+ which DHCPOFFER to accept. The server inserts the 'xid' field from
+ the DHCPDISCOVER message into the 'xid' field of the DHCPOFFER
+ message and sends the DHCPOFFER message to the requesting client.
+
+4.3.2 DHCPREQUEST message
+
+ A DHCPREQUEST message may come from a client responding to a
+ DHCPOFFER message from a server, from a client verifying a previously
+ allocated IP address or from a client extending the lease on a
+ network address. If the DHCPREQUEST message contains a 'server
+ identifier' option, the message is in response to a DHCPOFFER
+ message. Otherwise, the message is a request to verify or extend an
+ existing lease. If the client uses a 'client identifier' in a
+ DHCPREQUEST message, it MUST use that same 'client identifier' in all
+ subsequent messages. If the client included a list of requested
+ parameters in a DHCPDISCOVER message, it MUST include that list in
+ all subsequent messages.
+
+ Any configuration parameters in the DHCPACK message SHOULD NOT
+ conflict with those in the earlier DHCPOFFER message to which the
+ client is responding. The client SHOULD use the parameters in the
+ DHCPACK message for configuration.
+
+ Clients send DHCPREQUEST messages as follows:
+
+ o DHCPREQUEST generated during SELECTING state:
+
+ Client inserts the address of the selected server in 'server
+ identifier', 'ciaddr' MUST be zero, 'requested IP address' MUST be
+ filled in with the yiaddr value from the chosen DHCPOFFER.
+
+ Note that the client may choose to collect several DHCPOFFER
+ messages and select the "best" offer. The client indicates its
+ selection by identifying the offering server in the DHCPREQUEST
+ message. If the client receives no acceptable offers, the client
+ may choose to try another DHCPDISCOVER message. Therefore, the
+ servers may not receive a specific DHCPREQUEST from which they can
+ decide whether or not the client has accepted the offer. Because
+ the servers have not committed any network address assignments on
+ the basis of a DHCPOFFER, servers are free to reuse offered network
+ addresses in response to subsequent requests. As an implementation
+ detail, servers SHOULD NOT reuse offered addresses and may use an
+ implementation-specific timeout mechanism to decide when to reuse
+ an offered address.
+
+ o DHCPREQUEST generated during INIT-REBOOT state:
+
+ 'server identifier' MUST NOT be filled in, 'requested IP address'
+ option MUST be filled in with client's notion of its previously
+ assigned address. ciaddr MUST be zero. The client is seeking to
+ verify a previously allocated, cached configuration. Server SHOULD
+ send a DHCPNAK message to the client if the 'requested IP address'
+ is incorrect, or is on the wrong network.
+
+ Determining whether a client in the INIT-REBOOT state is on the
+ correct network is done by examining the contents of 'giaddr', the
+ 'requested IP address' option, and a database lookup. If the DHCP
+ server detects that the client is on the wrong net (i.e., the
+ result of applying the local subnet mask or remote subnet mask (if
+ 'giaddr' is not zero) to 'requested IP address' option value
+ doesn't match reality), then the server SHOULD send a DHCPNAK
+ message to the client.
+
+ If the network is correct, then the DHCP server should check if the
+ client's notion of its IP address is correct. If not, then the
+ server SHOULD send a DHCPNAK message to the client. If the DHCP
+ server has no record of this client, then it MUST remain silent,
+ and MAY output a warning to the network administrator. This
+ behavior is necessary for peaceful coexistence of non-communicating
+ DHCP servers on the same wire.
+
+ If 'ciaddr' is not set in the DHCPREQUEST message, the server
+ SHOULD set the broadcast bit in the DHCPNAK message. DHCPNAK is
+ broadcast to ensure that clients that may have an incorrect notion
+ of subnet mask or have not yet configured a network address (in
+ INIT-REBOOT state) will receive the DHCPNAK.
+
+ If 'ciaddr' is set in the DHCPREQUEST message, then the client is
+ configured to use the address and can respond to ARP requests
+ messages, so the DHCPNAK should be unicast (since it may be on a
+ remote subnet). Typically, this case occurs when the client's
+ clock is much slower than the server's clock and the client
+ believes it still has a valid lease even though the lease has
+ actually expired.
+
+ If 'ciaddr' is not set in the DHCPREQUEST message, the server
+ SHOULD set the broadcast bit in the DHCPNAK message. DHCPNAK is
+ broadcast to ensure that clients that may have an incorrect notion
+ of subnet mask or have not yet configured a network address (in
+ INIT-REBOOT state) will receive the DHCPNAK.
+
+ If 'ciaddr' is set in the DHCPREQUEST message, then the client is
+ configured to use the address and can respond to ARP requests
+ messages, so the DHCPNAK should be unicast (since it may be on a
+ remote subnet). Typically, this case occurs when the client's
+ clock is much slower than the server's clock and the client
+ believes it still has a valid lease even though the lease has
+ actually expired.
+
+ o DHCPREQUEST generated during RENEWING state:
+
+ 'server identifier' MUST NOT be filled in, 'requested IP address'
+ option MUST NOT be filled in, 'ciaddr' MUST be filled in with
+ client's IP address. In this situation, the client is completely
+ configured, and is trying to extend its lease. This message will be
+ unicast, so no relay agents will be involved in its transmission.
+ Because 'giaddr' is therefore not filled in, the DHCP server will
+ trust the value in 'ciaddr', and use it when replying to the
+ client.
+
+ A client MAY choose to renew or extend its lease prior to T1. The
+ server may choose not to extend the lease (as a policy decision by
+ the network administrator), but should return a DHCPACK message
+ regardless.
+
+ o DHCPREQUEST generated during REBINDING state:
+
+ 'server identifier' MUST NOT be filled in, 'requested IP address'
+ option MUST NOT be filled in, 'ciaddr' MUST be filled in with
+ client's IP address. In this situation, the client is completely
+ configured, and is trying to extend its lease. This message MUST be
+ broadcast to the 0xffffffff IP broadcast address. The DHCP server
+ SHOULD check 'ciaddr' for correctness before replying to the
+ DHCPREQUEST.
+
+ The DHCPREQUEST from a REBINDING client is intended to accommodate
+ sites that have multiple DHCP servers and a mechanism for
+ maintaining consistency among leases managed by multiple servers.
+ A DHCP server MAY extend a client's lease only if it has local
+ administrative authority to do so.
+
+4.3.3 DHCPDECLINE message
+
+ If the server receives a DHCPDECLINE message, the client has
+ discovered through some other means that the suggested network
+ address is already in use. The server MUST mark the network
+ address as not available and SHOULD notify the local system
+ administrator of a possible configuration problem.
+
+4.3.4 DHCPRELEASE message
+
+ Upon receipt of a DHCPRELEASE message, the server marks the network
+ address as not allocated. The server SHOULD retain a record of the
+ client's initialization parameters for possible reuse in response
+ to subsequent requests from the client.
+
+4.3.5 DHCPINFORM message
+
+ The server responds to a DHCPINFORM message by sending a DHCPACK
+ message directly to the address given in the 'ciaddr' field of the
+ DHCPINFORM message. The server SHOULD NOT send a lease expiration
+ time to the client and SHOULD NOT fill in 'yiaddr'. The server
+ includes other parameters in the DHCPACK message as defined in
+ section 4.3.1.
+
+4.3.6 Client messages
+
+ Table 4 details the differences between messages from clients in
+ various states.
+
+ ---------------------------------------------------------------------
+ | |INIT-REBOOT |SELECTING |RENEWING |REBINDING |
+ ---------------------------------------------------------------------
+ |broad/unicast |broadcast |broadcast |unicast |broadcast |
+ |server-ip |MUST NOT |MUST |MUST NOT |MUST NOT |
+ |requested-ip |MUST |MUST |MUST NOT |MUST NOT |
+ |ciaddr |zero |zero |IP address |IP address|
+ ---------------------------------------------------------------------
+
+ Table 4: Client messages from different states
+
+4.4 DHCP client behavior
+
+ Figure 5 gives a state-transition diagram for a DHCP client. A
+ client can receive the following messages from a server:
+
+ o DHCPOFFER
+
+ o DHCPACK
+
+ o DHCPNAK
+
+ The DHCPINFORM message is not shown in figure 5. A client simply
+ sends the DHCPINFORM and waits for DHCPACK messages. Once the client
+ has selected its parameters, it has completed the configuration
+ process.
+
+ Table 5 gives the use of the fields and options in a DHCP message by
+ a client. The remainder of this section describes the action of the
+ DHCP client for each possible incoming message. The description in
+ the following section corresponds to the full configuration procedure
+ previously described in section 3.1, and the text in the subsequent
+ section corresponds to the abbreviated configuration procedure
+ described in section 3.2.
+
+ -------- -------
+| | +-------------------------->| |<-------------------+
+| INIT- | | +-------------------->| INIT | |
+| REBOOT |DHCPNAK/ +---------->| |<---+ |
+| |Restart| | ------- | |
+ -------- | DHCPNAK/ | | |
+ | Discard offer | -/Send DHCPDISCOVER |
+-/Send DHCPREQUEST | | |
+ | | | DHCPACK v | |
+ ----------- | (not accept.)/ ----------- | |
+| | | Send DHCPDECLINE | | |
+| REBOOTING | | | | SELECTING |<----+ |
+| | | / | | |DHCPOFFER/ |
+ ----------- | / ----------- | |Collect |
+ | | / | | | replies |
+DHCPACK/ | / +----------------+ +-------+ |
+Record lease, set| | v Select offer/ |
+timers T1, T2 ------------ send DHCPREQUEST | |
+ | +----->| | DHCPNAK, Lease expired/ |
+ | | | REQUESTING | Halt network |
+ DHCPOFFER/ | | | |
+ Discard ------------ | |
+ | | | | ----------- |
+ | +--------+ DHCPACK/ | | |
+ | Record lease, set -----| REBINDING | |
+ | timers T1, T2 / | | |
+ | | DHCPACK/ ----------- |
+ | v Record lease, set ^ |
+ +----------------> ------- /timers T1,T2 | |
+ +----->| |<---+ | |
+ | | BOUND |<---+ | |
+ DHCPOFFER, DHCPACK, | | | T2 expires/ DHCPNAK/
+ DHCPNAK/Discard ------- | Broadcast Halt network
+ | | | | DHCPREQUEST |
+ +-------+ | DHCPACK/ | |
+ T1 expires/ Record lease, set | |
+ Send DHCPREQUEST timers T1, T2 | |
+ to leasing server | | |
+ | ---------- | |
+ | | |------------+ |
+ +->| RENEWING | |
+ | |----------------------------+
+ ----------
+ Figure 5: State-transition diagram for DHCP clients
+
+4.4.1 Initialization and allocation of network address
+
+ The client begins in INIT state and forms a DHCPDISCOVER message.
+ The client SHOULD wait a random time between one and ten seconds to
+ desynchronize the use of DHCP at startup. The client sets 'ciaddr'
+ to 0x00000000. The client MAY request specific parameters by
+ including the 'parameter request list' option. The client MAY
+ suggest a network address and/or lease time by including the
+ 'requested IP address' and 'IP address lease time' options. The
+ client MUST include its hardware address in the 'chaddr' field, if
+ necessary for delivery of DHCP reply messages. The client MAY
+ include a different unique identifier in the 'client identifier'
+ option, as discussed in section 4.2. If the client included a list
+ of requested parameters in a DHCPDISCOVER message, it MUST include
+ that list in all subsequent messages.
+
+ The client generates and records a random transaction identifier and
+ inserts that identifier into the 'xid' field. The client records its
+ own local time for later use in computing the lease expiration. The
+ client then broadcasts the DHCPDISCOVER on the local hardware
+ broadcast address to the 0xffffffff IP broadcast address and 'DHCP
+ server' UDP port.
+
+ If the 'xid' of an arriving DHCPOFFER message does not match the
+ 'xid' of the most recent DHCPDISCOVER message, the DHCPOFFER message
+ must be silently discarded. Any arriving DHCPACK messages must be
+ silently discarded.
+
+ The client collects DHCPOFFER messages over a period of time, selects
+ one DHCPOFFER message from the (possibly many) incoming DHCPOFFER
+ messages (e.g., the first DHCPOFFER message or the DHCPOFFER message
+ from the previously used server) and extracts the server address from
+ the 'server identifier' option in the DHCPOFFER message. The time
+ over which the client collects messages and the mechanism used to
+ select one DHCPOFFER are implementation dependent.
+
+ Field DHCPDISCOVER DHCPREQUEST DHCPDECLINE,
+ DHCPINFORM DHCPRELEASE
+ ----- ------------ ----------- -----------
+ 'op' BOOTREQUEST BOOTREQUEST BOOTREQUEST
+ 'htype' (From "Assigned Numbers" RFC)
+ 'hlen' (Hardware address length in octets)
+ 'hops' 0 0 0
+ 'xid' selected by client 'xid' from server selected by
+ DHCPOFFER message client
+ 'secs' (opt.) (opt.) 0
+ 'flags' Set 'BROADCAST' Set 'BROADCAST' 0
+ flag if client flag if client
+ requires broadcast requires broadcast
+ reply reply
+ 'ciaddr' DHCPDISCOVER: 0 or client's client's network
+ 0 or client's network address address
+ netwrk address (BOUND/RENEW/REBIND) (DHCPRELEASE only)
+ (BOUND/RENEW/REBIND)
+ DHCPINFORM: client's
+ network address
+ 'yiaddr' 0 0 0
+ 'siaddr' 0 0 0
+ 'giaddr' 0 0 0
+ 'chaddr' client's hardware client's hardware client's hardware
+ address address address
+ 'sname' options, if options, if (unused)
+ indicated in indicated in
+ 'sname/file' 'sname/file'
+ option; otherwise option; otherwise
+ unused unused
+ 'file' options, if options, if (unused)
+ indicated in indicated in
+ 'sname/file' 'sname/file'
+ option; otherwise option; otherwise
+ unused unused
+ 'options' options options (unused)
+
+ Option DHCPDISCOVER DHCPREQUEST DHCPDECLINE,
+ DHCPINFORM DHCPRELEASE
+ ------ ------------ ----------- -----------
+ Requested IP address MAY MUST (in MUST
+ (DISCOVER) SELECTING or (DHCPDECLINE),
+ MUST NOT INIT-REBOOT) MUST NOT
+ (INFORM) MUST NOT (in (DHCPRELEASE)
+ BOUND or
+ RENEWING)
+ IP address lease time MAY MAY MUST NOT
+ (DISCOVER)
+ MUST NOT
+ (INFORM)
+ Use 'file'/'sname' fields MAY MAY MAY
+ DHCP message type DHCPDISCOVER/ DHCPREQUEST DHCPDECLINE/
+ DHCPINFORM DHCPRELEASE
+ Client identifier MAY MAY MAY
+ Vendor class identifier MAY MAY MUST NOT
+ User class identifier MAY MAY MUST NOT
+ Server identifier MUST NOT MUST (after MUST
+ SELECTING)
+ MUST NOT (after
+ INIT-REBOOT,
+ BOUND, RENEWING
+ or REBINDING)
+ Parameter request list MAY MAY MUST NOT
+ Maximum message size MAY MAY MUST NOT
+ Message SHOULD NOT SHOULD NOT SHOULD
+ Site-specific MAY MAY MUST NOT
+ All others MAY MAY MUST NOT
+
+ Table 5: Fields and options used by DHCP clients
+
+ If the parameters are acceptable, the client records the address of
+ the server that supplied the parameters from the 'server identifier'
+ field and sends that address in the 'server identifier' field of a
+ DHCPREQUEST broadcast message. Once the DHCPACK message from the
+ server arrives, the client is initialized and moves to BOUND state.
+ The DHCPREQUEST message contains the same 'xid' as the DHCPOFFER
+ message. The client records the lease expiration time as the sum of
+ the time at which the original request was sent and the duration of
+ the lease from the DHCPOFFER message. The client SHOULD perform a
+ check on the suggested address to ensure that the address is not
+ already in use. For example, if the client is on a network that
+ supports ARP, the client may issue an ARP request for the suggested
+ request. When broadcasting an ARP request for the suggested address,
+ the client must fill in its own hardware address as the sender's
+ hardware address, and 0 as the sender's IP address, to avoid
+ confusing ARP caches in other hosts on the same subnet. If the
+ network address appears to be in use, the client MUST send a
+ DHCPDECLINE message to the server. The client SHOULD broadcast an ARP
+ reply to announce the client's new IP address and clear any outdated
+ ARP cache entries in hosts on the client's subnet.
+
+4.4.2 Initialization with known network address
+
+ The client begins in INIT-REBOOT state and sends a DHCPREQUEST
+ message. The client may request specific configuration parameters by
+ including the 'parameter request list' option. The client generates
+ and records a random transaction identifier and inserts that
+ identifier into the 'xid' field. The client records its own local
+ time for later use in computing the lease expiration. The client
+ MUST NOT include a 'server identifier' in the DHCPREQUEST message.
+ The client then broadcasts the DHCPREQUEST on the local hardware
+ broadcast address to the 'DHCP server' UDP port.
+
+ Once a DHCPACK message with an 'xid' field matching that in the
+ client's DHCPREQUEST message arrives from any server, the client is
+ initialized and moves to BOUND state. The client records the lease
+ expiration time as the sum of the time at which the DHCPREQUEST
+ message was sent and the duration of the lease from the DHCPACK
+ message.
+
+4.4.3 Initialization with an externally assigned network address
+
+ The client sends a DHCPINFORM message. The client may request
+ specific configuration parameters by including the 'parameter request
+ list' option. The client generates and records a random transaction
+ identifier and inserts that identifier into the 'xid' field. The
+ client places its own network address in the 'ciaddr' field. The
+ client SHOULD NOT request lease time parameters.
+
+ The client then unicasts the DHCPINFORM to the DHCP server if it
+ knows the server's address, otherwise it broadcasts the message to
+ the limited (all 1s) broadcast address. DHCPINFORM messages MUST be
+ directed to the 'DHCP server' UDP port.
+
+ Once a DHCPACK message with an 'xid' field matching that in the
+ client's DHCPINFORM message arrives from any server, the client is
+ initialized.
+
+ If the client does not receive a DHCPACK within a reasonable period
+ of time (60 seconds or 4 tries if using timeout suggested in section
+ 4.1), then it SHOULD display a message informing the user of the
+ problem, and then SHOULD begin network processing using suitable
+ defaults as per Appendix A.
+
+4.4.4 Use of broadcast and unicast
+
+ The DHCP client broadcasts DHCPDISCOVER, DHCPREQUEST and DHCPINFORM
+ messages, unless the client knows the address of a DHCP server. The
+ client unicasts DHCPDECLINE and DHCPRELEASE messages to the server.
+ When the DHCP client knows the address of a DHCP server, in either
+ INIT or REBOOTING state, the client may use that address in the
+ DHCPDISCOVER or DHCPREQUEST rather than the IP broadcast address.
+ The client may also use unicast to send DHCPINFORM messages to a
+ known DHCP server. If the client receives no response to DHCP
+ messages sent to the IP address of a known DHCP server, the DHCP
+ client reverts to using the IP broadcast address.
+
+4.4.5 Reacquisition and expiration
+
+ The client maintains two times, T1 and T2, that specify the times at
+ which the client tries to extend its lease on its network address.
+ T1 is the time at which the client enters the RENEWING state and
+ attempts to contact the server that originally issued the client's
+ network address. T2 is the time at which the client enters the
+ REBINDING state and attempts to contact any server. T1 MUST be
+ earlier than T2, which, in turn, MUST be earlier than the time at
+ which the client's lease will expire.
+
+ To avoid the need for synchronized clocks, T1 and T2 are expressed in
+ options as relative times [2].
+
+ At time T1 the client moves to RENEWING state and sends (via unicast)
+ a DHCPREQUEST message to the server to extend its lease. The client
+ sets the 'ciaddr' field in the DHCPREQUEST to its current network
+ address. The client records the local time at which the DHCPREQUEST
+ message is sent for computation of the lease expiration time. The
+ client MUST NOT include a 'server identifier' in the DHCPREQUEST
+ message.
+
+ Any DHCPACK messages that arrive with an 'xid' that does not match
+ the 'xid' of the client's DHCPREQUEST message are silently discarded.
+ When the client receives a DHCPACK from the server, the client
+ computes the lease expiration time as the sum of the time at which
+ the client sent the DHCPREQUEST message and the duration of the lease
+ in the DHCPACK message. The client has successfully reacquired its
+ network address, returns to BOUND state and may continue network
+ processing.
+
+ If no DHCPACK arrives before time T2, the client moves to REBINDING
+ state and sends (via broadcast) a DHCPREQUEST message to extend its
+ lease. The client sets the 'ciaddr' field in the DHCPREQUEST to its
+ current network address. The client MUST NOT include a 'server
+ identifier' in the DHCPREQUEST message.
+
+ Times T1 and T2 are configurable by the server through options. T1
+ defaults to (0.5 * duration_of_lease). T2 defaults to (0.875 *
+ duration_of_lease). Times T1 and T2 SHOULD be chosen with some
+ random "fuzz" around a fixed value, to avoid synchronization of
+ client reacquisition.
+
+ A client MAY choose to renew or extend its lease prior to T1. The
+ server MAY choose to extend the client's lease according to policy
+ set by the network administrator. The server SHOULD return T1 and
+ T2, and their values SHOULD be adjusted from their original values to
+ take account of the time remaining on the lease.
+
+ In both RENEWING and REBINDING state, if the client receives no
+ response to its DHCPREQUEST message, the client SHOULD wait one-half
+ of the remaining time until T2 (in RENEWING state) and one-half of
+ the remaining lease time (in REBINDING state), down to a minimum of
+ 60 seconds, before retransmitting the DHCPREQUEST message.
+
+ If the lease expires before the client receives a DHCPACK, the client
+ moves to INIT state, MUST immediately stop any other network
+ processing and requests network initialization parameters as if the
+ client were uninitialized. If the client then receives a DHCPACK
+ allocating that client its previous network address, the client
+ SHOULD continue network processing. If the client is given a new
+ network address, it MUST NOT continue using the previous network
+ address and SHOULD notify the local users of the problem.
+
+4.4.6 DHCPRELEASE
+
+ If the client no longer requires use of its assigned network address
+ (e.g., the client is gracefully shut down), the client sends a
+ DHCPRELEASE message to the server. Note that the correct operation
+ of DHCP does not depend on the transmission of DHCPRELEASE messages.
+
+5. References
+
+ [1] Acetta, M., "Resource Location Protocol", RFC 887, CMU, December
+ 1983.
+
+ [2] Alexander, S., and R. Droms, "DHCP Options and BOOTP Vendor
+ Extensions", RFC 1533, Lachman Technology, Inc., Bucknell
+ University, October 1993.
+
+ [3] Braden, R., Editor, "Requirements for Internet Hosts --
+ Communication Layers", STD 3, RFC 1122, USC/Information Sciences
+ Institute, October 1989.
+
+ [4] Braden, R., Editor, "Requirements for Internet Hosts --
+ Application and Support, STD 3, RFC 1123, USC/Information
+ Sciences Institute, October 1989.
+
+ [5] Brownell, D, "Dynamic Reverse Address Resolution Protocol
+ (DRARP)", Work in Progress.
+
+ [6] Comer, D., and R. Droms, "Uniform Access to Internet Directory
+ Services", Proc. of ACM SIGCOMM '90 (Special issue of Computer
+ Communications Review), 20(4):50--59, 1990.
+
+ [7] Croft, B., and J. Gilmore, "Bootstrap Protocol (BOOTP)", RFC 951,
+ Stanford and SUN Microsystems, September 1985.
+
+ [8] Deering, S., "ICMP Router Discovery Messages", RFC 1256, Xerox
+ PARC, September 1991.
+
+ [9] Droms, D., "Interoperation between DHCP and BOOTP", RFC 1534,
+ Bucknell University, October 1993.
+
+ [10] Finlayson, R., Mann, T., Mogul, J., and M. Theimer, "A Reverse
+ Address Resolution Protocol", RFC 903, Stanford, June 1984.
+
+ [11] Gray C., and D. Cheriton, "Leases: An Efficient Fault-Tolerant
+ Mechanism for Distributed File Cache Consistency", In Proc. of
+ the Twelfth ACM Symposium on Operating Systems Design, 1989.
+
+ [12] Mockapetris, P., "Domain Names -- Concepts and Facilities", STD
+ 13, RFC 1034, USC/Information Sciences Institute, November 1987.
+
+ [13] Mockapetris, P., "Domain Names -- Implementation and
+ Specification", STD 13, RFC 1035, USC/Information Sciences
+ Institute, November 1987.
+
+ [14] Mogul J., and S. Deering, "Path MTU Discovery", RFC 1191,
+ November 1990.
+
+ [15] Morgan, R., "Dynamic IP Address Assignment for Ethernet Attached
+ Hosts", Work in Progress.
+
+ [16] Postel, J., "Internet Control Message Protocol", STD 5, RFC 792,
+ USC/Information Sciences Institute, September 1981.
+
+ [17] Reynolds, J., "BOOTP Vendor Information Extensions", RFC 1497,
+ USC/Information Sciences Institute, August 1993.
+
+ [18] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1340,
+ USC/Information Sciences Institute, July 1992.
+
+ [19] Jeffrey Schiller and Mark Rosenstein. A Protocol for the Dynamic
+ Assignment of IP Addresses for use on an Ethernet. (Available
+ from the Athena Project, MIT), 1989.
+
+ [20] Sollins, K., "The TFTP Protocol (Revision 2)", RFC 783, NIC,
+ June 1981.
+
+ [21] Wimer, W., "Clarifications and Extensions for the Bootstrap
+ Protocol", RFC 1542, Carnegie Mellon University, October 1993.
+
+6. Security Considerations
+
+ DHCP is built directly on UDP and IP which are as yet inherently
+ insecure. Furthermore, DHCP is generally intended to make
+ maintenance of remote and/or diskless hosts easier. While perhaps
+ not impossible, configuring such hosts with passwords or keys may be
+ difficult and inconvenient. Therefore, DHCP in its current form is
+ quite insecure.
+
+ Unauthorized DHCP servers may be easily set up. Such servers can
+ then send false and potentially disruptive information to clients
+ such as incorrect or duplicate IP addresses, incorrect routing
+ information (including spoof routers, etc.), incorrect domain
+ nameserver addresses (such as spoof nameservers), and so on.
+ Clearly, once this seed information is in place, an attacker can
+ further compromise affected systems.
+
+ Malicious DHCP clients could masquerade as legitimate clients and
+ retrieve information intended for those legitimate clients. Where
+ dynamic allocation of resources is used, a malicious client could
+ claim all resources for itself, thereby denying resources to
+ legitimate clients.
+
+7. Author's Address
+
+ Ralph Droms
+ Computer Science Department
+ 323 Dana Engineering
+ Bucknell University
+ Lewisburg, PA 17837
+
+ Phone: (717) 524-1145
+ EMail: droms@bucknell.edu
+
+ This document will expire on March 31, 1996.
+
+A. Host Configuration Parameters
+
+ IP-layer_parameters,_per_host:_
+
+ Be a router on/off HRC 3.1
+ Non-local source routing on/off HRC 3.3.5
+ Policy filters for
+ non-local source routing (list) HRC 3.3.5
+ Maximum reassembly size integer HRC 3.3.2
+ Default TTL integer HRC 3.2.1.7
+ PMTU aging timeout integer MTU 6.6
+ MTU plateau table (list) MTU 7
+ IP-layer_parameters,_per_interface:_
+ IP address (address) HRC 3.3.1.6
+ Subnet mask (address mask) HRC 3.3.1.6
+ MTU integer HRC 3.3.3
+ All-subnets-MTU on/off HRC 3.3.3
+ Broadcast address flavor 0x00000000/0xffffffff HRC 3.3.6
+ Perform mask discovery on/off HRC 3.2.2.9
+ Be a mask supplier on/off HRC 3.2.2.9
+ Perform router discovery on/off RD 5.1
+ Router solicitation address (address) RD 5.1
+ Default routers, list of:
+ router address (address) HRC 3.3.1.6
+ preference level integer HRC 3.3.1.6
+ Static routes, list of:
+ destination (host/subnet/net) HRC 3.3.1.2
+ destination mask (address mask) HRC 3.3.1.2
+ type-of-service integer HRC 3.3.1.2
+ first-hop router (address) HRC 3.3.1.2
+ ignore redirects on/off HRC 3.3.1.2
+ PMTU integer MTU 6.6
+ perform PMTU discovery on/off MTU 6.6
+
+ Link-layer_parameters,_per_interface:_
+ Trailers on/off HRC 2.3.1
+ ARP cache timeout integer HRC 2.3.2.1
+ Ethernet encapsulation (RFC 894/RFC 1042) HRC 2.3.3
+
+ TCP_parameters,_per_host:_
+ TTL integer HRC 4.2.2.19
+ Keep-alive interval integer HRC 4.2.3.6
+ Keep-alive data size 0/1 HRC 4.2.3.6
+
+Key:
+
+ MTU = Path MTU Discovery (RFC 1191, Proposed Standard)
+ RD = Router Discovery (RFC 1256, Proposed Standard)
+
+B. Changes to draft-ietf-dhc-dhcp-02.txt:
+
+* Changed 'host' to 'client' throughout when explicitly referencing a
+ DHCP client.
+
+* Section 3.1, numbered paragraph 5: changed "client performs" to
+ "client SHOULD perform"
+
+* Clarified text in section 3.1, numbered paragraph 6 and section 3.2,
+ numbered paragraph 4 describing use of DHCPRELEASE.
+
+* Clarified text in the second paragraph of section 2.2, describing
+ how the server probes a reused address before allocating it to a DHCP
+ client.
+
+* Changed and added text as suggested by Glenn Stump for separate
+ 'vendor class' and 'user class' options:
+
+ - Section 4.2, changed second paragraph to discuss vendor and user
+ class identifiers.
+
+ - Section 4.2, changed last sentence of third paragraph to include
+ both vendor and user class identifiers.
+
+ - Modified table 3 to include both vendor and user class identifiers.
+
+ - Section 4.3.1, changed 6th bulleted rule for selection of parameters
+ by server to include vendor and user class identifiers.
+
+ - Section 4.3.1, changed last paragraph to include vendor and user
+ class identifiers.
+
+ - Modified table 5 to include both vendor and uesr class identifiers.
--- /dev/null
+
+Network Working Group S. Alexander
+INTERNET DRAFT Lachman Technology, Inc.
+Obsoletes: draft-ietf-dhc-options-1533update-00.txt R. Droms
+ Bucknell University
+ September 1995
+ Expires March 1996
+
+
+ DHCP Options and BOOTP Vendor Extensions
+ <draft-ietf-dhc-options-1533update-01.txt>
+
+Status of this memo
+
+ This document is an Internet-Draft. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its areas,
+ and its working groups. Note that other groups may also distribute
+ working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as ``work in progress.''
+
+ To learn the current status of any Internet-Draft, please check the
+ ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
+ Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
+ munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
+ ftp.isi.edu (US West Coast).
+
+Abstract
+
+ The Dynamic Host Configuration Protocol (DHCP) [1] provides a
+ framework for passing configuration information to hosts on a TCP/IP
+ network. Configuration parameters and other control information are
+ carried in tagged data items that are stored in the 'options' field
+ of the DHCP message. The data items themselves are also called
+ "options."
+
+ This document specifies the current set of DHCP options. This
+ document will be periodically updated as new options are defined.
+ Each superseding document will include the entire current list of
+ valid options. The current list of valid options is also available
+ in ftp://ftp.isi.edu/in-notes/iana/assignments [22].
+
+ All of the vendor information extensions defined in RFC 1497 [2] may
+ be used as DHCP options. The definitions given in RFC 1497 are
+ included in this document, which supersedes RFC 1497. All of the
+ DHCP options defined in this document, except for those specific to
+ DHCP as defined in section 9, may be used as BOOTP vendor information
+ extensions.
+
+Table of Contents
+
+ 1. Introduction .............................................. 2
+ 2. BOOTP Extension/DHCP Option Field Format .................. 2
+ 3. RFC 1497 Vendor Extensions ................................ 3
+ 4. IP Layer Parameters per Host .............................. 10
+ 5. IP Layer Parameters per Interface ........................ 13
+ 6. Link Layer Parameters per Interface ....................... 16
+ 7. TCP Parameters ............................................ 17
+ 8. Application and Service Parameters ........................ 18
+ 9. DHCP Extensions ........................................... 26
+ 10. Extensions ................................................ 33
+ 11. Acknowledgements .......................................... 33
+ 12. References ................................................ 33
+ 13. Security Considerations ................................... 35
+ 14. Authors' Addresses ........................................ 35
+ A. Changes to draft-ietf-dhc-options-1533update-00.txt........ 36
+
+1. Introduction
+
+ This document specifies options for use with both the Dynamic Host
+ Configuration Protocol and the Bootstrap Protocol.
+
+ The full description of DHCP packet formats may be found in the DHCP
+ specification document [1], and the full description of BOOTP packet
+ formats may be found in the BOOTP specification document [3]. This
+ document defines the format of information in the last field of DHCP
+ packets ('options') and of BOOTP packets ('vend'). The remainder of
+ this section defines a generalized use of this area for giving
+ information useful to a wide class of machines, operating systems and
+ configurations. Sites with a single DHCP or BOOTP server that is
+ shared among heterogeneous clients may choose to define other, site-
+ specific formats for the use of the 'options' field.
+
+ Section 2 of this memo describes the formats of DHCP options and
+ BOOTP vendor extensions. Section 3 describes options defined in
+ previous documents for use with BOOTP (all may also be used with
+ DHCP). Sections 4-8 define new options intended for use with both
+ DHCP and BOOTP. Section 9 defines options used only in DHCP.
+
+ References further describing most of the options defined in sections
+ 2-6 can be found in section 12. The use of the options defined in
+ section 9 is described in the DHCP specification [1].
+
+ Information on registering new options is contained in section 10.
+
+2. BOOTP Extension/DHCP Option Field Format
+
+ DHCP options have the same format as the BOOTP 'vendor extensions'
+ defined in RFC 1497 [2]. Options may be fixed length or variable
+ length. All options begin with a tag octet, which uniquely
+ identifies the option. Fixed-length options without data consist of
+ only a tag octet. Only options 0 and 255 are fixed length. All
+ other options are variable-length with a length octet following the
+ tag octet. The value of the length octet does not include the two
+ octets specifying the tag and length. The length octet is followed
+ by "length" octets of data. Options containing NVT ASCII data SHOULD
+ NOT include a trailing NULL; however, the receiver of such options
+ MUST be prepared to delete trailing nulls if they exist. The
+ receiver MUST NOT require that a trailing null be included in the
+ data. In the case of some variable-length options the length field
+ is a constant but must still be specified.
+
+ Any options defined subsequent to this document should contain a
+ length octet even if the length is fixed or zero.
+
+ All multi-octet quantities are in network byte-order.
+
+ When used with BOOTP, the first four octets of the vendor information
+ field have been assigned to the "magic cookie" (as suggested in RFC
+ 951). This field identifies the mode in which the succeeding data is
+ to be interpreted. The value of the magic cookie is the 4 octet
+ dotted decimal 99.130.83.99 (or hexadecimal number 63.82.53.63) in
+ network byte order.
+
+ All of the "vendor extensions" defined in RFC 1497 are also DHCP
+ options.
+
+ Option codes 128 to 254 (decimal) are reserved for site-specific
+ options.
+
+ Except for the options in section 9, all options may be used with
+ either DHCP or BOOTP.
+
+ Many of these options have their default values specified in other
+ documents. In particular, RFC 1122 [4] specifies default values for
+ most IP and TCP configuration parameters.
+
+3. RFC 1497 Vendor Extensions
+
+ This section lists the vendor extensions as defined in RFC 1497.
+ They are defined here for completeness.
+
+3.1. Pad Option
+
+ The pad option can be used to cause subsequent fields to align on
+ word boundaries.
+
+ The code for the pad option is 0, and its length is 1 octet.
+
+ Code
+ +-----+
+ | 0 |
+ +-----+
+
+3.2. End Option
+
+ The end option marks the end of valid information in the vendor
+ field. Subsequent octets should be filled with pad options.
+
+ The code for the end option is 255, and its length is 1 octet.
+
+ Code
+ +-----+
+ | 255 |
+ +-----+
+
+3.3. Subnet Mask
+
+ The subnet mask option specifies the client's subnet mask as per RFC
+ 950 [5].
+
+ If both the subnet mask and the router option are specified in a DHCP
+ reply, the subnet mask option MUST be first.
+
+ The code for the subnet mask option is 1, and its length is 4 octets.
+
+ Code Len Subnet Mask
+ +-----+-----+-----+-----+-----+-----+
+ | 1 | 4 | m1 | m2 | m3 | m4 |
+ +-----+-----+-----+-----+-----+-----+
+
+3.4. Time Offset
+
+ The time offset field specifies the offset of the client's subnet in
+ seconds from Coordinated Universal Time (UTC). The offset is
+ expressed as a signed 32-bit integer.
+
+ The code for the time offset option is 2, and its length is 4 octets.
+
+ Code Len Time Offset
+ +-----+-----+-----+-----+-----+-----+
+ | 2 | 4 | n1 | n2 | n3 | n4 |
+ +-----+-----+-----+-----+-----+-----+
+
+3.5. Router Option
+
+ The router option specifies a list of IP addresses for routers on the
+ client's subnet. Routers SHOULD be listed in order of preference.
+
+ The code for the router option is 3. The minimum length for the
+ router option is 4 octets, and the length MUST always be a multiple
+ of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 3 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.6. Time Server Option
+
+ The time server option specifies a list of RFC 868 [6] time servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for the time server option is 4. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 4 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.7. Name Server Option
+
+ The name server option specifies a list of IEN 116 [7] name servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for the name server option is 5. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 5 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.8. Domain Name Server Option
+
+ The domain name server option specifies a list of Domain Name System
+ (STD 13, RFC 1035 [8]) name servers available to the client. Servers
+ SHOULD be listed in order of preference.
+
+ The code for the domain name server option is 6. The minimum length
+ for this option is 4 octets, and the length MUST always be a multiple
+ of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 6 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.9. Log Server Option
+
+ The log server option specifies a list of MIT-LCS UDP log servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for the log server option is 7. The minimum length for this
+ option is 4 octets, and the length MUST always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 7 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.10. Cookie Server Option
+
+ The cookie server option specifies a list of RFC 865 [9] cookie
+ servers available to the client. Servers SHOULD be listed in order
+ of preference.
+
+ The code for the log server option is 8. The minimum length for this
+ option is 4 octets, and the length MUST always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 8 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.11. LPR Server Option
+
+ The LPR server option specifies a list of RFC 1179 [10] line printer
+ servers available to the client. Servers SHOULD be listed in order
+ of preference.
+
+ The code for the LPR server option is 9. The minimum length for this
+ option is 4 octets, and the length MUST always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 9 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.12. Impress Server Option
+
+ The Impress server option specifies a list of Imagen Impress servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for the Impress server option is 10. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 10 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.13. Resource Location Server Option
+
+ This option specifies a list of RFC 887 [11] Resource Location
+ servers available to the client. Servers SHOULD be listed in order
+ of preference.
+
+ The code for this option is 11. The minimum length for this option
+ is 4 octets, and the length MUST always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 11 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.14. Host Name Option
+
+ This option specifies the name of the client. The name may or may
+ not be qualified with the local domain name (see section 3.17 for the
+ preferred way to retrieve the domain name). See RFC 1035 for
+ character set restrictions.
+
+ The code for this option is 12, and its minimum length is 1.
+
+ Code Len Host Name
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 12 | n | h1 | h2 | h3 | h4 | h5 | h6 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.15. Boot File Size Option
+
+ This option specifies the length in 512-octet blocks of the default
+ boot image for the client. The file length is specified as an
+ unsigned 16-bit integer.
+
+ The code for this option is 13, and its length is 2.
+
+ Code Len File Size
+ +-----+-----+-----+-----+
+ | 13 | 2 | l1 | l2 |
+ +-----+-----+-----+-----+
+
+3.16. Merit Dump File
+
+ This option specifies the path-name of a file to which the client's
+ core image should be dumped in the event the client crashes. The
+ path is formatted as a character string consisting of characters from
+ the NVT ASCII character set.
+
+ The code for this option is 14. Its minimum length is 1.
+
+ Code Len Dump File Pathname
+ +-----+-----+-----+-----+-----+-----+---
+ | 14 | n | n1 | n2 | n3 | n4 | ...
+ +-----+-----+-----+-----+-----+-----+---
+
+3.17. Domain Name
+
+ This option specifies the domain name that client should use when
+ resolving hostnames via the Domain Name System.
+
+ The code for this option is 15. Its minimum length is 1.
+
+ Code Len Domain Name
+ +-----+-----+-----+-----+-----+-----+--
+ | 15 | n | d1 | d2 | d3 | d4 | ...
+ +-----+-----+-----+-----+-----+-----+--
+
+3.18. Swap Server
+
+ This specifies the IP address of the client's swap server.
+
+ The code for this option is 16 and its length is 4.
+
+ Code Len Swap Server Address
+ +-----+-----+-----+-----+-----+-----+
+ | 16 | n | a1 | a2 | a3 | a4 |
+ +-----+-----+-----+-----+-----+-----+
+
+3.19. Root Path
+
+ This option specifies the path-name that contains the client's root
+ disk. The path is formatted as a character string consisting of
+ characters from the NVT ASCII character set.
+
+ The code for this option is 17. Its minimum length is 1.
+
+ Code Len Root Disk Pathname
+ +-----+-----+-----+-----+-----+-----+---
+ | 17 | n | n1 | n2 | n3 | n4 | ...
+ +-----+-----+-----+-----+-----+-----+---
+
+3.20. Extensions Path
+
+ A string to specify a file, retrievable via TFTP, which contains
+ information which can be interpreted in the same way as the 64-octet
+ vendor-extension field within the BOOTP response, with the following
+ exceptions:
+
+ - the length of the file is unconstrained;
+ - all references to Tag 18 (i.e., instances of the
+ BOOTP Extensions Path field) within the file are
+ ignored.
+
+ The code for this option is 18. Its minimum length is 1.
+
+ Code Len Extensions Pathname
+ +-----+-----+-----+-----+-----+-----+---
+ | 18 | n | n1 | n2 | n3 | n4 | ...
+ +-----+-----+-----+-----+-----+-----+---
+
+4. IP Layer Parameters per Host
+
+ This section details the options that affect the operation of the IP
+ layer on a per-host basis.
+
+4.1. IP Forwarding Enable/Disable Option
+
+ This option specifies whether the client should configure its IP
+ layer for packet forwarding. A value of 0 means disable IP
+ forwarding, and a value of 1 means enable IP forwarding.
+
+ The code for this option is 19, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 19 | 1 | 0/1 |
+ +-----+-----+-----+
+
+4.2. Non-Local Source Routing Enable/Disable Option
+
+ This option specifies whether the client should configure its IP
+ layer to allow forwarding of datagrams with non-local source routes
+ (see Section 3.3.5 of [4] for a discussion of this topic). A value
+ of 0 means disallow forwarding of such datagrams, and a value of 1
+ means allow forwarding.
+
+ The code for this option is 20, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 20 | 1 | 0/1 |
+ +-----+-----+-----+
+
+4.3. Policy Filter Option
+
+ This option specifies policy filters for non-local source routing.
+ The filters consist of a list of IP addresses and masks which specify
+ destination/mask pairs with which to filter incoming source routes.
+
+ Any source routed datagram whose next-hop address does not match one
+ of the filters should be discarded by the client.
+
+ See [4] for further information.
+
+ The code for this option is 21. The minimum length of this option is
+ 8, and the length MUST be a multiple of 8.
+
+ Code Len Address 1 Mask 1
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ | 21 | n | a1 | a2 | a3 | a4 | m1 | m2 | m3 | m4 |
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ Address 2 Mask 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+ | a1 | a2 | a3 | a4 | m1 | m2 | m3 | m4 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+
+4.4. Maximum Datagram Reassembly Size
+
+ This option specifies the maximum size datagram that the client
+ should be prepared to reassemble. The size is specified as a 16-bit
+ unsigned integer. The minimum value legal value is 576.
+
+ The code for this option is 22, and its length is 2.
+
+ Code Len Size
+ +-----+-----+-----+-----+
+ | 22 | 2 | s1 | s2 |
+ +-----+-----+-----+-----+
+
+4.5. Default IP Time-to-live
+
+ This option specifies the default time-to-live that the client should
+ use on outgoing datagrams. The TTL is specified as an octet with a
+ value between 1 and 255.
+
+ The code for this option is 23, and its length is 1.
+
+ Code Len TTL
+ +-----+-----+-----+
+ | 23 | 1 | ttl |
+ +-----+-----+-----+
+
+4.6. Path MTU Aging Timeout Option
+
+ This option specifies the timeout (in seconds) to use when aging Path
+ MTU values discovered by the mechanism defined in RFC 1191 [12]. The
+ timeout is specified as a 32-bit unsigned integer.
+
+ The code for this option is 24, and its length is 4.
+
+ Code Len Timeout
+ +-----+-----+-----+-----+-----+-----+
+ | 24 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+4.7. Path MTU Plateau Table Option
+
+ This option specifies a table of MTU sizes to use when performing
+ Path MTU Discovery as defined in RFC 1191. The table is formatted as
+ a list of 16-bit unsigned integers, ordered from smallest to largest.
+ The minimum MTU value cannot be smaller than 68.
+
+ The code for this option is 25. Its minimum length is 2, and the
+ length MUST be a multiple of 2.
+
+ Code Len Size 1 Size 2
+ +-----+-----+-----+-----+-----+-----+---
+ | 25 | n | s1 | s2 | s1 | s2 | ...
+ +-----+-----+-----+-----+-----+-----+---
+
+5. IP Layer Parameters per Interface
+
+ This section details the options that affect the operation of the IP
+ layer on a per-interface basis. It is expected that a client can
+ issue multiple requests, one per interface, in order to configure
+ interfaces with their specific parameters.
+
+5.1. Interface MTU Option
+
+ This option specifies the MTU to use on this interface. The MTU is
+ specified as a 16-bit unsigned integer. The minimum legal value for
+ the MTU is 68.
+
+ The code for this option is 26, and its length is 2.
+
+ Code Len MTU
+ +-----+-----+-----+-----+
+ | 26 | 2 | m1 | m2 |
+ +-----+-----+-----+-----+
+
+5.2. All Subnets are Local Option
+
+ This option specifies whether or not the client may assume that all
+ subnets of the IP network to which the client is connected use the
+ same MTU as the subnet of that network to which the client is
+ directly connected. A value of 1 indicates that all subnets share
+ the same MTU. A value of 0 means that the client should assume that
+ some subnets of the directly connected network may have smaller MTUs.
+
+ The code for this option is 27, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 27 | 1 | 0/1 |
+ +-----+-----+-----+
+
+5.3. Broadcast Address Option
+
+ This option specifies the broadcast address in use on the client's
+ subnet. Legal values for broadcast addresses are specified in
+ section 3.2.1.3 of [4].
+
+ The code for this option is 28, and its length is 4.
+
+ Code Len Broadcast Address
+ +-----+-----+-----+-----+-----+-----+
+ | 28 | 4 | b1 | b2 | b3 | b4 |
+ +-----+-----+-----+-----+-----+-----+
+
+5.4. Perform Mask Discovery Option
+
+ This option specifies whether or not the client should perform subnet
+ mask discovery using ICMP. A value of 0 indicates that the client
+ should not perform mask discovery. A value of 1 means that the
+ client should perform mask discovery.
+
+ The code for this option is 29, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 29 | 1 | 0/1 |
+ +-----+-----+-----+
+
+5.5. Mask Supplier Option
+
+ This option specifies whether or not the client should respond to
+ subnet mask requests using ICMP. A value of 0 indicates that the
+ client should not respond. A value of 1 means that the client should
+ respond.
+
+ The code for this option is 30, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 30 | 1 | 0/1 |
+ +-----+-----+-----+
+
+5.6. Perform Router Discovery Option
+
+ This option specifies whether or not the client should solicit
+ routers using the Router Discovery mechanism defined in RFC 1256
+ [13]. A value of 0 indicates that the client should not perform
+ router discovery. A value of 1 means that the client should perform
+ router discovery.
+
+ The code for this option is 31, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 31 | 1 | 0/1 |
+ +-----+-----+-----+
+
+5.7. Router Solicitation Address Option
+
+ This option specifies the address to which the client should transmit
+ router solicitation requests.
+
+ The code for this option is 32, and its length is 4.
+
+ Code Len Address
+ +-----+-----+-----+-----+-----+-----+
+ | 32 | 4 | a1 | a2 | a3 | a4 |
+ +-----+-----+-----+-----+-----+-----+
+
+5.8. Static Route Option
+
+ This option specifies a list of static routes that the client should
+ install in its routing cache. If multiple routes to the same
+ destination are specified, they are listed in descending order of
+ priority.
+
+ The routes consist of a list of IP address pairs. The first address
+ is the destination address, and the second address is the router for
+ the destination.
+
+ The default route (0.0.0.0) is an illegal destination for a static
+ route. See section 3.5 for information about the router option.
+
+ The code for this option is 33. The minimum length of this option is
+ 8, and the length MUST be a multiple of 8.
+
+ Code Len Destination 1 Router 1
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ | 33 | n | d1 | d2 | d3 | d4 | r1 | r2 | r3 | r4 |
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ Destination 2 Router 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+ | d1 | d2 | d3 | d4 | r1 | r2 | r3 | r4 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+
+6. Link Layer Parameters per Interface
+
+ This section lists the options that affect the operation of the data
+ link layer on a per-interface basis.
+
+6.1. Trailer Encapsulation Option
+
+ This option specifies whether or not the client should negotiate the
+ use of trailers (RFC 893 [14]) when using the ARP protocol. A value
+ of 0 indicates that the client should not attempt to use trailers. A
+ value of 1 means that the client should attempt to use trailers.
+
+ The code for this option is 34, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 34 | 1 | 0/1 |
+ +-----+-----+-----+
+
+6.2. ARP Cache Timeout Option
+
+ This option specifies the timeout in seconds for ARP cache entries.
+ The time is specified as a 32-bit unsigned integer.
+
+ The code for this option is 35, and its length is 4.
+
+ Code Len Time
+ +-----+-----+-----+-----+-----+-----+
+ | 35 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+6.3. Ethernet Encapsulation Option
+
+ This option specifies whether or not the client should use Ethernet
+ Version 2 (RFC 894 [15]) or IEEE 802.3 (RFC 1042 [16]) encapsulation
+ if the interface is an Ethernet. A value of 0 indicates that the
+ client should use RFC 894 encapsulation. A value of 1 means that the
+ client should use RFC 1042 encapsulation.
+
+ The code for this option is 36, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 36 | 1 | 0/1 |
+ +-----+-----+-----+
+
+7. TCP Parameters
+
+ This section lists the options that affect the operation of the TCP
+ layer on a per-interface basis.
+
+7.1. TCP Default TTL Option
+
+ This option specifies the default TTL that the client should use when
+ sending TCP segments. The value is represented as an 8-bit unsigned
+ integer. The minimum value is 1.
+
+ The code for this option is 37, and its length is 1.
+
+ Code Len TTL
+ +-----+-----+-----+
+ | 37 | 1 | n |
+ +-----+-----+-----+
+
+7.2. TCP Keepalive Interval Option
+
+ This option specifies the interval (in seconds) that the client TCP
+ should wait before sending a keepalive message on a TCP connection.
+ The time is specified as a 32-bit unsigned integer. A value of zero
+ indicates that the client should not generate keepalive messages on
+ connections unless specifically requested by an application.
+
+ The code for this option is 38, and its length is 4.
+
+ Code Len Time
+ +-----+-----+-----+-----+-----+-----+
+ | 38 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+7.3. TCP Keepalive Garbage Option
+
+ This option specifies the whether or not the client should send TCP
+ keepalive messages with a octet of garbage for compatibility with
+ older implementations. A value of 0 indicates that a garbage octet
+ should not be sent. A value of 1 indicates that a garbage octet
+ should be sent.
+
+ The code for this option is 39, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 39 | 1 | 0/1 |
+ +-----+-----+-----+
+
+8. Application and Service Parameters
+
+ This section details some miscellaneous options used to configure
+ miscellaneous applications and services.
+
+8.1. Network Information Service Domain Option
+
+ This option specifies the name of the client's NIS [17] domain. The
+ domain is formatted as a character string consisting of characters
+ from the NVT ASCII character set.
+
+ The code for this option is 40. Its minimum length is 1.
+
+ Code Len NIS Domain Name
+ +-----+-----+-----+-----+-----+-----+---
+ | 40 | n | n1 | n2 | n3 | n4 | ...
+ +-----+-----+-----+-----+-----+-----+---
+
+8.2. Network Information Servers Option
+
+ This option specifies a list of IP addresses indicating NIS servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for this option is 41. Its minimum length is 4, and the
+ length MUST be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 41 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.3. Network Time Protocol Servers Option
+
+ This option specifies a list of IP addresses indicating NTP [18]
+ servers available to the client. Servers SHOULD be listed in order
+ of preference.
+
+ The code for this option is 42. Its minimum length is 4, and the
+ length MUST be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 42 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.4. Vendor Specific Information
+
+ This option is used by clients and servers to exchange vendor-
+ specific information. The information is an opaque object of n
+ octets, presumably interpreted by vendor-specific code on the clients
+ and servers. The definition of this information is vendor specific.
+ The vendor is indicated in the vendor class identifier option.
+ Servers not equipped to interpret the vendor-specific information
+ sent by a client MUST ignore it (although it may be reported).
+ Clients which do not receive desired vendor-specific information
+ SHOULD make an attempt to operate without it, although they may do so
+ (and announce they are doing so) in a degraded mode.
+
+ If a vendor potentially encodes more than one item of information in
+ this option, then the vendor SHOULD encode the option using
+ "Encapsulated vendor-specific options" as described below:
+
+ The Encapsulated vendor-specific options field SHOULD be encoded as a
+ sequence of code/length/value fields of identical syntax to the DHCP
+ options field with the following exceptions:
+
+ 1) There SHOULD NOT be a "magic cookie" field in the encapsulated
+ vendor-specific extensions field.
+
+ 2) Codes other than 0 or 255 MAY be redefined by the vendor within
+ the encapsulated vendor-specific extensions field, but SHOULD
+ conform to the tag-length-value syntax defined in section 2.
+
+ 3) Code 255 (END), if present, signifies the end of the
+ encapsulated vendor extensions, not the end of the vendor
+ extensions field. If no code 255 is present, then the end of
+ the enclosing vendor-specific information field is taken as the
+ end of the encapsulated vendor-specific extensions field.
+
+ The code for this option is 43 and its minimum length is 1.
+
+ Code Len Vendor-specific information
+ +-----+-----+-----+-----+---
+ | 43 | n | i1 | i2 | ...
+ +-----+-----+-----+-----+---
+
+ When encapsulated vendor-specific extensions are used, the
+ information bytes 1-n have the following format:
+
+ Code Len Data item Code Len Data item Code
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ | T1 | n | d1 | d2 | ... | T2 | n | D1 | D2 | ... | ... |
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+
+8.5. NetBIOS over TCP/IP Name Server Option
+
+ The NetBIOS name server (NBNS) option specifies a list of RFC
+ 1001/1002 [19] [20] NBNS name servers listed in order of preference.
+
+ The code for this option is 44. The minimum length of the option is
+ 4 octets, and the length must always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+ | 44 | n | a1 | a2 | a3 | a4 | b1 | b2 | b3 | b4 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+
+8.6. NetBIOS over TCP/IP Datagram Distribution Server Option
+
+ The NetBIOS datagram distribution server (NBDD) option specifies a
+ list of RFC 1001/1002 NBDD servers listed in order of preference. The
+ code for this option is 45. The minimum length of the option is 4
+ octets, and the length must always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+ | 45 | n | a1 | a2 | a3 | a4 | b1 | b2 | b3 | b4 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+
+8.7. NetBIOS over TCP/IP Node Type Option
+
+ The NetBIOS node type option allows NetBIOS over TCP/IP clients which
+ are configurable to be configured as described in RFC 1001/1002. The
+ value is specified as a single octet which identifies the client type
+ as follows:
+
+ Value Node Type
+ ----- ---------
+ 0x1 B-node
+ 0x2 P-node
+ 0x4 M-node
+ 0x8 H-node
+
+ In the above chart, the notation '0x' indicates a number in base-16
+ (hexadecimal).
+
+ The code for this option is 46. The length of this option is always
+ 1.
+
+ Code Len Node Type
+ +-----+-----+-----------+
+ | 46 | 1 | see above |
+ +-----+-----+-----------+
+
+8.8. NetBIOS over TCP/IP Scope Option
+
+ The NetBIOS scope option specifies the NetBIOS over TCP/IP scope
+ parameter for the client as specified in RFC 1001/1002. See [19],
+ [20], and [8] for character-set restrictions.
+
+ The code for this option is 47. The minimum length of this option is
+ 1.
+
+ Code Len NetBIOS Scope
+ +-----+-----+-----+-----+-----+-----+----
+ | 47 | n | s1 | s2 | s3 | s4 | ...
+ +-----+-----+-----+-----+-----+-----+----
+
+8.9. X Window System Font Server Option
+
+ This option specifies a list of X Window System [21] Font servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for this option is 48. The minimum length of this option is
+ 4 octets, and the length MUST be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+ | 48 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+
+8.10. X Window System Display Manager Option
+
+ This option specifies a list of IP addresses of systems that are
+ running the X Window System Display Manager and are available to the
+ client.
+
+ Addresses SHOULD be listed in order of preference.
+
+ The code for the this option is 49. The minimum length of this option
+ is 4, and the length MUST be a multiple of 4.
+
+ Code Len Address 1 Address 2
+
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+ | 49 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+
+8.11. Network Information Service+ Domain Option
+
+This option specifies the name of the client's NIS+ [17] domain. The
+domain is formatted as a character string consisting of characters
+from the NVT ASCII character set.
+
+The code for this option is 64. Its minimum length is 1.
+
+ Code Len NIS Client Domain Name
+ +-----+-----+-----+-----+-----+-----+---
+ | 64 | n | n1 | n2 | n3 | n4 | ...
+ +-----+-----+-----+-----+-----+-----+---
+
+8.12. Network Information Service+ Servers Option
+
+ This option specifies a list of IP addresses indicating NIS+ servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for this option is 65. Its minimum length is 4, and the
+ length MUST be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 65 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.13. Mobile IP Home Agent option
+
+ This option specifies a list of IP addresses indicating mobile IP
+ home agents available to the client. Agents SHOULD be listed in
+ order of preference.
+
+ The code for this option is 68. Its minimum length is 0 (indicating
+ no home agents are available) and the length MUST be a multiple of 4.
+ It is expected that the usual length will be four octets, containing
+ a single home agent's address.
+
+ Code Len Home Agent Addresses (zero or more)
+ +-----+-----+-----+-----+-----+-----+--
+ | 68 | n | a1 | a2 | a3 | a4 | ...
+ +-----+-----+-----+-----+-----+-----+--
+
+8.14. Simple Mail Transport Protocol (SMTP) Server Option
+
+ The SMTP server option specifies a list of SMTP servers available to
+ the client. Servers SHOULD be listed in order of preference.
+
+ The code for the SMTP server option is 69. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 69 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.15. Post Office Protocol (POP3) Server Option
+
+ The POP3 server option specifies a list of POP3 available to the
+ client. Servers SHOULD be listed in order of preference.
+
+ The code for the POP3 server option is 70. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 70 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.16. Network News Transport Protocol (NNTP) Server Option
+
+ The NNTP server option specifies a list of NNTP available to the
+ client. Servers SHOULD be listed in order of preference.
+
+ The code for the NNTP server option is 71. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 71 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.17. Default World Wide Web (WWW) Server Option
+
+ The WWW server option specifies a list of WWW available to the
+ client. Servers SHOULD be listed in order of preference.
+
+ The code for the WWW server option is 72. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 72 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.18. Default Finger Server Option
+
+ The Finger server option specifies a list of Finger available to the
+ client. Servers SHOULD be listed in order of preference.
+
+ The code for the Finger server option is 73. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 73 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.19. Default Internet Relay Chat (IRC) Server Option
+
+ The IRC server option specifies a list of IRC available to the
+ client. Servers SHOULD be listed in order of preference.
+
+ The code for the IRC server option is 74. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 74 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.20. StreetTalk Server Option
+
+ The StreetTalk server option specifies a list of StreetTalk servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for the StreetTalk server option is 75. The minimum length
+ for this option is 4 octets, and the length MUST always be a multiple
+ of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 75 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.21. StreetTalk Directory Assistance (STDA) Server Option
+
+ The StreetTalk Directory Assistance (STDA) server option specifies a
+ list of STDA servers available to the client. Servers SHOULD be
+ listed in order of preference.
+
+ The code for the StreetTalk Directory Assistance server option is 76.
+ The minimum length for this option is 4 octets, and the length MUST
+ always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 76 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+9. DHCP Extensions
+
+ This section details the options that are specific to DHCP.
+
+9.1. Requested IP Address
+
+ This option is used in a client request (DHCPDISCOVER) to allow the
+ client to request that a particular IP address be assigned.
+
+ The code for this option is 50, and its length is 4.
+
+ Code Len Address
+ +-----+-----+-----+-----+-----+-----+
+ | 50 | 4 | a1 | a2 | a3 | a4 |
+ +-----+-----+-----+-----+-----+-----+
+
+9.2. IP Address Lease Time
+
+ This option is used in a client request (DHCPDISCOVER or DHCPREQUEST)
+ to allow the client to request a lease time for the IP address. In a
+ server reply (DHCPOFFER), a DHCP server uses this option to specify
+ the lease time it is willing to offer.
+
+ The time is in units of seconds, and is specified as a 32-bit
+ unsigned integer.
+
+ The code for this option is 51, and its length is 4.
+
+ Code Len Lease Time
+ +-----+-----+-----+-----+-----+-----+
+ | 51 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+9.3. Option Overload
+
+ This option is used to indicate that the DHCP 'sname' or 'file'
+ fields are being overloaded by using them to carry DHCP options. A
+ DHCP server inserts this option if the returned parameters will
+ exceed the usual space allotted for options.
+
+ If this option is present, the client interprets the specified
+ additional fields after it concludes interpretation of the standard
+ option fields.
+
+ The code for this option is 52, and its length is 1. Legal values
+ for this option are:
+
+ Value Meaning
+ ----- --------
+ 1 the 'file' field is used to hold options
+ 2 the 'sname' field is used to hold options
+ 3 both fields are used to hold options
+
+ Code Len Value
+ +-----+-----+-----+
+ | 52 | 1 |1/2/3|
+ +-----+-----+-----+
+
+9.4 TFTP server name
+
+This option is used to identify a TFTP server when the 'sname'
+field in the DHCP header has been used for DHCP options.
+
+The code for this option is 66, and its minimum length is 1.
+
+ Code Len TFTP server
+ +-----+-----+-----+-----+-----+---
+ | 66 | n | c1 | c2 | c3 | ...
+ +-----+-----+-----+-----+-----+---
+
+9.5 Bootfile name
+
+This option is used to identify a bootfile when the 'file' field in the
+DHCP header has been used for DHCP options.
+
+The code for this option is 67, and its minimum length is 1.
+
+ Code Len Bootfile name
+ +-----+-----+-----+-----+-----+---
+ | 67 | n | c1 | c2 | c3 | ...
+ +-----+-----+-----+-----+-----+---
+
+9.6. DHCP Message Type
+
+ This option is used to convey the type of the DHCP message. The code
+ for this option is 53, and its length is 1. Legal values for this
+ option are:
+
+ Value Message Type
+ ----- ------------
+ 1 DHCPDISCOVER
+ 2 DHCPOFFER
+ 3 DHCPREQUEST
+ 4 DHCPDECLINE
+ 5 DHCPACK
+ 6 DHCPNAK
+ 7 DHCPRELEASE
+ 8 DHCPINFORM
+
+ Code Len Type
+ +-----+-----+-----+
+ | 53 | 1 | 1-9 |
+ +-----+-----+-----+
+
+9.7. Server Identifier
+
+ This option is used in DHCPOFFER and DHCPREQUEST messages, and may
+ optionally be included in the DHCPACK and DHCPNAK messages. DHCP
+ servers include this option in the DHCPOFFER in order to allow the
+ client to distinguish between lease offers. DHCP clients indicate
+ which of several lease offers is being accepted by including this
+ option in a DHCPREQUEST message.
+
+ The identifier is the IP address of the selected server.
+
+ The code for this option is 54, and its length is 4.
+
+ Code Len Address
+ +-----+-----+-----+-----+-----+-----+
+ | 54 | 4 | a1 | a2 | a3 | a4 |
+ +-----+-----+-----+-----+-----+-----+
+
+9.8. Parameter Request List
+
+ This option is used by a DHCP client to request values for specified
+ configuration parameters. The list of requested parameters is
+ specified as n octets, where each octet is a valid DHCP option code
+ as defined in this document.
+
+ The client MAY list the options in order of preference. The DHCP
+ server is not required to return the options in the requested order,
+ but MUST try to insert the requested options in the order requested
+ by the client.
+
+ The code for this option is 55. Its minimum length is 1.
+
+ Code Len Option Codes
+ +-----+-----+-----+-----+---
+ | 55 | n | c1 | c2 | ...
+ +-----+-----+-----+-----+---
+
+9.9. Message
+
+ This option is used by a DHCP server to provide an error message to a
+ DHCP client in a DHCPNAK message in the event of a failure. A client
+ may use this option in a DHCPDECLINE message to indicate the why the
+ client declined the offered parameters. The message consists of n
+ octets of NVT ASCII text, which the client may display on an
+ available output device.
+
+ The code for this option is 56 and its minimum length is 1.
+
+ Code Len Text
+ +-----+-----+-----+-----+---
+ | 56 | n | c1 | c2 | ...
+ +-----+-----+-----+-----+---
+
+9.10. Maximum DHCP Message Size
+
+ This option specifies the maximum length DHCP message that it is
+ willing to accept. The length is specified as an unsigned 16-bit
+ integer. A client may use the maximum DHCP message size option in
+ DHCPDISCOVER or DHCPREQUEST messages, but should not use the option
+ in DHCPDECLINE messages.
+
+ The code for this option is 57, and its length is 2. The minimum
+ legal value is 576 octets.
+
+ Code Len Length
+ +-----+-----+-----+-----+
+ | 57 | 2 | l1 | l2 |
+ +-----+-----+-----+-----+
+
+9.11. Renewal (T1) Time Value
+
+ This option specifies the time interval from address assignment until
+ the client transitions to the RENEWING state.
+
+ The value is in units of seconds, and is specified as a 32-bit
+ unsigned integer.
+
+ The code for this option is 58, and its length is 4.
+
+ Code Len T1 Interval
+ +-----+-----+-----+-----+-----+-----+
+ | 58 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+9.12. Rebinding (T2) Time Value
+
+ This option specifies the time interval from address assignment until
+ the client transitions to the REBINDING state.
+
+ The value is in units of seconds, and is specified as a 32-bit
+ unsigned integer.
+
+ The code for this option is 59, and its length is 4.
+
+ Code Len T2 Interval
+ +-----+-----+-----+-----+-----+-----+
+ | 59 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+9.13. Vendor class identifier
+
+ This option is used by DHCP clients to optionally identify the vendor
+ type and configuration of a DHCP client. The information is a string
+ of n octets, interpreted by servers. Vendors may choose to define
+ specific vendor class identifiers to convey particular configuration
+ or other identification information about a client. For example, the
+ identifier may encode the client's hardware configuration. Servers
+ not equipped to interpret the class-specific information sent by a
+ client MUST ignore it (although it may be reported). Servers that
+ respond SHOULD only use option 43 to return the vendor-specific
+ information to the client.
+
+ The code for this option is 60, and its minimum length is 1.
+
+ Code Len Vendor class Identifier
+ +-----+-----+-----+-----+---
+ | 60 | n | i1 | i2 | ...
+ +-----+-----+-----+-----+---
+
+9.14. Client-identifier
+
+ This option is used by DHCP clients to specify their unique
+ identifier. DHCP servers use this value to index their database of
+ address bindings. This value is expected to be unique for all
+ clients in an administrative domain.
+
+ Identifiers SHOULD be treated as opaque objects by DHCP servers.
+
+ The client identifier MAY consist of type-value pairs similar to the
+ 'htype'/'chaddr' fields defined in [3]. For instance, it MAY consist
+ of a hardware type and hardware address. In this case the type field
+ SHOULD be one of the ARP hardware types defined in STD2 [22]. A
+ hardware type of 0 (zero) should be used when the value field
+ contains an identifier other than a hardware address (e.g. a fully
+ qualified domain name).
+
+ The code for this option is 61, and its minimum length is 2.
+
+ Code Len Type Client-Identifier
+ +-----+-----+-----+-----+-----+---
+ | 61 | n | t1 | i1 | i2 | ...
+ +-----+-----+-----+-----+-----+---
+
+9.15. User Class Information
+
+ This option is used by a DHCP client to optionally identify the type
+ or category of user or applications it represents. The information
+ contained in this option is an NVT ASCII text object that represents
+ the user class of which the client is a member.
+
+ DHCP administrators may define specific user class identifiers to
+ convey information about a client's software configuration or about
+ its user's preferences. For example, an identifier may specify that
+ a particular DHCP client is a member of the class "accounting
+ auditors", which have special service needs such as a particular
+ database server.
+
+ Servers not equipped to interpret any of user classes specified by a
+ client MUST ignore it (although it may be reported). Otherwise,
+ servers SHOULD respond with the set of options corresponding to the
+ user class specified by the client. Further, if the server responds,
+ it MUST return this option to the client.
+
+ Clients which do not receive information for the user class requested
+ SHOULD make an attempt to operate without it, although they may do so
+ (and may announce they are doing so) in a degraded mode.
+ The code for this option is 77. The minimum length for this option
+ is two.
+
+ Code Len text1
+ +-----+-----+-----+-----+-----
+ | 77 | N | c1 | c2 | ...
+ +-----+-----+-----+-----+-----
+
+
+10. Extensions
+
+ Additional generic data fields may be registered by contacting:
+
+ Internet Assigned Numbers Authority (IANA)
+ USC/Information Sciences Institute
+ 4676 Admiralty Way
+ Marina del Rey, California 90292-6695
+
+ or by email as: iana@isi.edu
+
+ Implementation specific use of undefined generic types (those in the
+ range 61-127) may conflict with other implementations, and
+ registration is required.
+
+11. Acknowledgements
+
+ The authors would like to thank Philip Almquist for his feedback on
+ this document. The comments of the DHCP Working Group are also
+ gratefully acknowledged. In particular, Mike Carney and Jon Dreyer
+ from SunSelect suggested the current format of the Vendor-specific
+ Information option.
+
+ RFC 1497 is based on earlier work by Philip Prindeville, with help
+ from Drew Perkins, Bill Croft, and Steve Deering.
+
+12. References
+
+ [1] Droms, R., "Dynamic Host Configuration Protocol", RFC 1531,
+ Bucknell University, October 1993.
+
+ [2] Reynolds, J., "BOOTP Vendor Information Extensions", RFC 1497,
+ USC/Information Sciences Institute, August 1993.
+
+ [3] Croft, W., and J. Gilmore, "Bootstrap Protocol", RFC 951,
+ Stanford University and Sun Microsystems, September 1985.
+
+ [4] Braden, R., Editor, "Requirements for Internet Hosts -
+ Communication Layers", STD 3, RFC 1122, USC/Information Sciences
+ Institute, October 1989.
+
+ [5] Mogul, J., and J. Postel, "Internet Standard Subnetting
+ Procedure", STD 5, RFC 950, USC/Information Sciences Institute,
+ August 1985.
+
+ [6] Postel, J., and K. Harrenstien, "Time Protocol", STD 26, RFC
+ 868, USC/Information Sciences Institute, SRI, May 1983.
+
+ [7] Postel, J., "Name Server", IEN 116, USC/Information Sciences
+ Institute, August 1979.
+
+ [8] Mockapetris, P., "Domain Names - Implementation and
+ Specification", STD 13, RFC 1035, USC/Information Sciences
+ Institute, November 1987.
+
+ [9] Postel, J., "Quote of the Day Protocol", STD 23, RFC 865,
+ USC/Information Sciences Institute, May 1983.
+
+ [10] McLaughlin, L., "Line Printer Daemon Protocol", RFC 1179, The
+ Wollongong Group, August 1990.
+
+ [11] Accetta, M., "Resource Location Protocol", RFC 887, CMU,
+ December 1983.
+
+ [12] Mogul, J. and S. Deering, "Path MTU Discovery", RFC 1191,
+ DECWRL, Stanford University, November 1990.
+
+ [13] Deering, S., "ICMP Router Discovery Messages", RFC 1256,
+ Xerox PARC, September 1991.
+
+ [14] Leffler, S. and M. Karels, "Trailer Encapsulations", RFC 893,
+ U. C. Berkeley, April 1984.
+
+ [15] Hornig, C., "Standard for the Transmission of IP Datagrams over
+ Ethernet Networks", RFC 894, Symbolics, April 1984.
+
+ [16] Postel, J. and J. Reynolds, "Standard for the Transmission of
+ IP Datagrams Over IEEE 802 Networks", RFC 1042, USC/Information
+ Sciences Institute, February 1988.
+
+ [17] Sun Microsystems, "System and Network Administration", March
+ 1990.
+
+ [18] Mills, D., "Internet Time Synchronization: The Network Time
+ Protocol", RFC 1305, UDEL, March 1992.
+
+ [19] NetBIOS Working Group, "Protocol Standard for a NetBIOS Service
+ on a TCP/UDP transport: Concepts and Methods", STD 19, RFC 1001,
+ March 1987.
+
+ [20] NetBIOS Working Group, "Protocol Standard for a NetBIOS Service
+ on a TCP/UDP transport: Detailed Specifications", STD 19, RFC
+ 1002, March 1987.
+
+ [21] Scheifler, R., "FYI On the X Window System", FYI 6, RFC 1198,
+ MIT Laboratory for Computer Science, January 1991.
+
+ [22] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1700,
+ USC/Information Sciences Institute, July 1992.
+
+13. Security Considerations
+
+ Security issues are not discussed in this memo.
+
+14. Authors' Addresses
+
+ Steve Alexander
+ Lachman Technology, Inc.
+ 1901 North Naper Boulevard
+ Naperville, IL 60563-8895
+
+ Phone: (708) 505-9555 x256
+ EMail: stevea@lachman.com
+
+
+ Ralph Droms
+ Computer Science Department
+ 323 Dana Engineering
+ Bucknell University
+ Lewisburg, PA 17837
+
+ Phone: (717) 524-1145
+ EMail: droms@bucknell.edu
+
+A. Changes to draft-ietf-dhc-options-1533update-00.txt:
+
+* Section 8.4 - changed to indicate vendor-specific information is
+ interpreted based on vendor class identifier.
+
+* Section 9.13 - changed "Class-identifier" to "Vendor class
+ identifier"
+
+* Added section 9.15 describing "User class identifier"
--- /dev/null
+
+
+
+
+
+
+DNSIND Working Group Susan Thomson (Bellcore)
+INTERNET-DRAFT Yakov Rekhter (IBM)
+<draft-ietf-dnsind-dynDNS-00.txt> Jim Bound (DEC)
+ January 31, 1995
+
+
+ Extending the Domain Name System (DNS) to Perform Dynamic Updates
+
+
+Status of this Memo
+
+ This document is an Internet Draft. Internet Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its Areas,
+ and its Working Groups. Note that other groups may also distribute
+ working documents as Internet Drafts.
+
+ Internet Drafts are draft documents valid for a maximum of six
+ months. Internet Drafts may be updated, replaced, or obsoleted by
+ other documents at any time. It is not appropriate to use Internet
+ Drafts as reference material or to cite them other than as a "working
+ draft" or "work in progress."
+
+ To learn the current status of any Internet Draft. please check the
+ 1id-abstracts.txt listing contained in the Internet Drafts Shadow
+ Directories on ds.internic.net, nic.nordu.net, ftp.nisc.sri.com or
+ munnari.oz.au.
+
+
+Abstract
+
+ The Domain Name System currently only supports queries on a
+ statically configured database. This document describes extensions to
+ the Domain Name System to enable name servers to accept requests to
+ update the database dynamically. Extensions include support for
+ adding and deleting a set of names and associated resource records
+ within a zone atomically and the definition of a new resource record
+ that enables update requests to be serialized.
+
+
+
+
+
+
+
+
+
+
+
+Expires July 31, 1995 [Page 1]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+1. INTRODUCTION
+
+
+ The Domain Name System currently only supports queries on a stati-
+ cally configured database. This document describes extensions to the
+ Domain Name System to enable name servers to accept requests to
+ update the database dynamically.
+
+ Section 2 provides an overview of the update function. Section 3
+ describes the update message format and Sections 4 and 5 describe
+ name server and resolver behavior when processing dynamic updates in
+ more detail. Examples of usage are described in Section 6. A new
+ resource record useful for serializing update requests is defined in
+ Section 7 and security considerations are discussed in Section 8.
+
+
+
+2. OVERVIEW
+
+ A domain name identifies a node within the domain name space tree
+ structure. Each node has a set of Resource Records (RRs).
+
+ The extensions to the DNS protocol enable name servers to accept
+ requests to update the names space and RRs associated with nodes in
+ the name space dynamically. An update request is an atomic transac-
+ tion consisting of a set of operations on names and RRs in a zone.
+ The operations may be one of four types:
+
+ 1. Add new name and associated with it a set of records to zone
+ (ADDNEW)
+
+ This operation is only successful if the name of the records
+ does not already exist in the zone. The effect of the operation
+ is to create a new node in the name space and add records to
+ this node.
+
+ 2. Add records associated with an existing name to zone (ADDEXIST)
+
+ This operation is only successful if the name the records are
+ associated with exists in the zone. The effect of the operation
+ is to update records that belong to an existing node in the name
+ space.
+
+ 3. Add name and associated with it a set of records to zone,
+ whether name exists or not (ADD)
+
+
+
+Expires July 31, 1995 [Page 2]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ If the name already exists, then the semantics of this operation
+ is the same as ADDEXIST. If the name doesn't exist, then the
+ semantics of this operation is the same as ADDNEW.
+
+ 4. Delete records from zone (DELETE)
+
+ This operation is only successful if the specified records
+ exist. However, it is possible to specify that all resource
+ records associated with a name, class and type must be deleted
+ without explicitly deleting each and every one of them. This is
+ done using a wildcard data field in the resource record.
+
+
+ The update protocol allows several operations to be performed on sets
+ of records with different owner names and record types, provided all
+ names are contained within a single zone. The effect of an update
+ transaction is to perform all of the operations in the transaction,
+ if all can be performed successfully, or none at all. If the zone
+ serial number in the SOA RR is not explicitly updated in an update
+ request, a side-effect of a successful update transaction may be to
+ update the zone serial number. A successful update is applied syn-
+ chronously to the database by the primary name server for the zone,
+ and the updates are transferred to secondary name servers asynchro-
+ nously.
+
+ Some of the operations depend on comparing an existing record with a
+ record specified in an update. Two records are considered to be the
+ same if their name, class, type, data length and value are the same.
+ The time-to-live field is specifically excluded from comparison. The
+ effect of wildcard names and data fields are discussed in Section 3.
+
+ The message format used to implement an atomic transaction has a
+ similar structure to that of a query, but the contents of some of the
+ fields differ. An entity that initiates an update indicates in an
+ update message the update operations to be performed along with the
+ records to be updated. A name server responds to an update request
+ by (a) indicating that the update has been successfully applied to
+ the database at the primary name server, (b) indicating that the name
+ server is not authoritative for the records specified, or (c) indi-
+ cating an error.
+
+ An update may be carried in a UDP datagram or a TCP connection.
+
+
+
+
+
+
+Expires July 31, 1995 [Page 3]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+3. UPDATE MESSAGE FORMAT
+
+
+ The message format has the following structure: the message header,
+ which is similar to that of the query, and the message body, which
+ consists of four sections, one per operation type. The four sections
+ are in the order listed: the delete section, the add new record sec-
+ tion, the add existing record section and the plain add secion. Each
+ section contains the records that need to have the associated opera-
+ tion applied.
+
+
+
+3.1. Header Section
+
+
+
+
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ID |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | DELCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ANCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | AECOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ACOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+
+
+ The differences between the query header and the update header are in
+ the values that certain fields can assume, and in the semantics of
+ certain fields.
+
+ There is a new operation code (value to be defined) to specify an
+ update request in the Opcode field.
+
+
+ UPDATE TBD
+
+
+
+
+Expires July 31, 1995 [Page 4]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ This Opcode distinguishes the update header from the query header.
+ This document specifies the semantics of the fields in the update
+ header only.
+
+ Besides a new operation code, there are also new return codes. The
+ four count fields have different semantics: they contain the number
+ of records in the DELETE section, the number of records in the ADDNEW
+ section, the number of records in the ADDEXIST section and the number
+ of records in the ADD section, respectively.
+
+ The other fields remain the same, except that they apply to update
+ requests rather than queries. Note the AA bit is set in a response if
+ and only if a server is authoritative for ALL nodes specified in the
+ request. Also, the TC bit is not applicable to updates.
+
+ The fields are set as follows in update requests and responses:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires July 31, 1995 [Page 5]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ ID A 16 bit identifier assigned by the entity that
+ generates any kind of request. This identifier is
+ copied in the corresponding reply and can be used by the
+ requestor to match up replies to outstanding requests.
+
+ QR A one bit field that specifies whether this message is a
+ request (0), or a response (1).
+
+ OPCODE A four bit field that specifies the kind of request in
+ this message. This value is set by the originator of a
+ request and copied into the response. In addition to
+ the values defined in RFC1034, this document defines the
+ following value:
+
+ TBD an update request (UPDATE)
+
+
+ AA Authoritative Answer - this bit is valid in responses,
+ and specifies that the responding name server is an
+ authority for all domain names in the message body.
+
+ TC Bit is set to zero in an update request and copied into
+ the response. The TC bit is ignored on receipt of a
+ request or response.
+
+
+ RD Recursion Desired - this bit may be set in a request and
+ is copied into the response. If RD is set, it directs
+ the name server to pursue the request recursively.
+ Recursive update support is optional.
+
+ RA Recursion Available - this be is set or cleared in a
+ response, and denotes whether recursive update support is
+ available in the name server.
+
+ Z Reserved for future use. Must be zero in all requests
+ and responses.
+
+ RCODE Response code - this 4 bit field is set as part of
+ responses. The values and semantics of update responses
+ are as follows:
+
+ 0 No error condition
+
+ 1 Format error - The name server was
+
+
+
+Expires July 31, 1995 [Page 6]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ unable to interpret the request.
+
+ 2 Server failure - The name server was
+ unable to process this request due to a
+ problem with the name server.
+
+ 3 Name Error - Meaningful only for
+ responses from an authoritative name
+ server, this code signifies that one or
+ more of the domain names referenced in
+ the update request does not exist.
+
+ 4 Not Implemented - The name server does
+ not support the specified operation.
+
+ 5 Refused - The name server refuses to
+ perform the specified operation for
+ policy reasons.
+
+ 6 Alias Error - This code indicates that the
+ domain name specified in an update is an
+ alias.
+
+ 7 Name Exists Error - This code indicates
+ the name already exists. This return code
+ is only meaningful from a server
+ in response to an ADDNEW operation.
+
+ 8 Record Not Exist Error - This code
+ indicates that the resource record does
+ not exist.
+ This return code is only meaningful from a
+ server in response to a DELETE operation.
+
+ 9 Too many Zones Error - This code
+ indicates that the records to be
+ updated exist in more than one zone.
+
+ 10 SERIAL RR Error - This code
+ indicates that an operation on the
+ SERIAL record is in error.
+
+ 11 Permission Denied - This code indicates
+ that the client has insufficient authority
+ to perform the update.
+
+
+
+Expires July 31, 1995 [Page 7]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ DELCOUNT an unsigned 16 bit integer specifying the number of
+ resource records in the DELETE section. Always zero in a
+ response.
+
+ ANCOUNT an unsigned 16 bit integer specifying the number of
+ resource records in the ADDNEW section. Always zero
+ in a response.
+
+ AECOUNT an unsigned 16 bit integer specifying the number of
+ resource records in the ADDEXIST section.
+ Always zero in a response.
+
+ ACOUNT an unsigned 16 bit integer specifying the number of
+ resource records in the ADD section.
+ Always zero in a response.
+
+
+
+3.2. Testing for Resource Record Equality
+
+
+ The update operations require that records be compared. In particu-
+ lar, the DELETE operation requires that the records to be deleted
+ must exist. It has already been stated that records are tested for
+ equality by comparing their name, class, type, data length and data
+ values. The time-to-live value is excluded from the comparison.
+
+ The comparison of character strings in names and in data fields is
+ case-insensitive. For two names to match, they must match label by
+ label. A non-wildcard label never matches the '*' label, i.e. names
+ must exist explicitly in a zone to be matched by a record specified
+ in an update; the use of a wildcard name in a zone does not imply
+ existence for updates.
+
+ In a DELETE operation, it is sometimes convenient to specify that all
+ records associated with a certain name that are of a given class and
+ type be deleted without specifying all existing records explicitly. A
+ record with a data field containing the '*' character and a data
+ length field of one is defined to match data in any other record.
+
+ DISCUSSION: I believe the '*' data value does not match existing
+ legal data values, expect for the NULL record, which is experimental
+ and not supported by BIND.
+
+
+
+
+
+Expires July 31, 1995 [Page 8]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+4. NAME SERVER BEHAVIOR
+
+
+ From a client's perspective, any authoritative server can process an
+ update request. Non-authoritative name servers forward the request to
+ an authoritative name server if recursive service is specified or
+ indicate to the client that the server is not authoritative for the
+ records to be updated.
+
+ From a server's perspective, only the primary authoritative name
+ server actually performs the update request. A secondary name server
+ is responsible for forwarding the request to the primary name server
+ for the zone. As mentioned above, a non-authoritative name server is
+ also responsible for forwarding the update request to the primary, if
+ recursive service is desired by the client and it is available.
+ Unlike a secondary, however, a non-authoritative name server will
+ need to determine the name servers authoritative for the domain names
+ to be updated by asking other names servers for referrals if the
+ information is not cached locally. A secondary name server will have
+ this information preconfigured. Note that the forwarding of an update
+ message is done synchronously on an update request, whether it is
+ performed by a secondary name server or a non-authoritative server
+ that provides recursive service. That is, a name server will wait
+ for a response to a forwarded update request before returning the
+ response to the client.
+
+
+
+4.1. Maintaining Internal Consistency
+
+
+ Zone consistency between primary and secondaries is achieved through
+ asynchronous zone transfer. Either full zone transfer as currently
+ defined can be used, or incremental zone transfer when it becomes
+ available[IXFR]. The proposed Notify mechanism[NOTIFY] may also be
+ used to cause zone transfers to happen earlier than would otherwise
+ be determined by the zone refresh time.
+
+
+
+4.2. Algorithm
+
+
+ On receiving an update request, the server's behavior will depend on
+ whether recursive service is requested and available. If recursive
+
+
+
+Expires July 31, 1995 [Page 9]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ service is requested and available, the server determines the set of
+ authoritative name servers for the nodes specified in the transac-
+ tion. The server sends the update to the set of name servers, waits
+ for the response, and returns the response to the resolver.
+
+ If recursive service is not requested or is not available, then the
+ name server checks to see whether the update is in a zone for which
+ it is authoritative. If so, the server attempts to perform the update
+ if the name server is primary for the zone. If the name server is
+ secondary for the zone, the server forwards the update to the pri-
+ mary name server, waits for the response and returns the response to
+ the resolver. Otherwise, if the name server is not authoritative for
+ the zone to be updated, an error is returned.
+
+ The algorithm for name server behavior is explained in more detail
+ below (adapted from [RFC1034]):
+
+ 1. Indicate in the response whether update recursion is available
+ or not. If recursive service is available and requested, then
+ the server uses the local resolver or a copy of its algorithm
+ (Section 4) to perform the update operation. Otherwise, go to
+ step 2.
+
+ 2 Determine the names (RRNAMEs) associated with all records to be
+ updated in the transaction. For each RRNAME, search the avail-
+ able zones for the zone which is the nearest to RRNAME.
+
+ a) If no zone is found, return a non-authoritative response
+ indicating no error. Exit.
+
+ b) If more than one zone is found, return a response indicat-
+ ing that the update request is not restricted to a single
+ zone. Exit.
+
+ Otherwise, go to step 3.
+
+ 3. If this is a secondary name server for the zone, forward the
+ request to the primary and wait for the response. Send the
+ response to the resolver. Exit. (A secondary may do further
+ checking of the update request before sending to the primary for
+ processing, if desired.) Otherwise, go to step 4.
+
+ 4. Start the transaction
+
+ 5. For each RRNAME in the update request, start matching down,
+
+
+
+Expires July 31, 1995 [Page 10]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ label by label, in the zone (found in step 2). For each label,
+ test for the following cases:
+
+ a) If the whole RRNAME is matched, we have found the node to
+ be updated.
+
+ If the record at the node is a CNAME, and RRTYPE does not
+ match CNAME, abort the transaction and return an authorita-
+ tive response indicating an alias error.
+
+ If the operation is ADDNEW, abort the transaction and
+ return an authoritative response indicating that the name
+ already exists.
+
+ If the operation is ADDEXIST or ADD, check if the specified
+ record already exists. If so, ignore.
+
+ If the operation is DELETE, check if the specified record
+ exists in the zone. If not, abort the transaction and
+ return an authoritative response indicating that the record
+ does not exist.
+
+ Otherwise, perform the update operation tentatively.
+
+ b) If we have a referral, abort the transaction. Return a
+ non-authoritative response indicating no error. Exit.
+
+ c) If at some label, a match is impossible (i.e. the label
+ does not exist), and the operation is ADDEXIST or DELETE,
+ abort the transaction and return an authoritative response
+ indicating that the name does not exist.
+
+ Otherwise, perform the update operation tentatively.
+
+ 6 Commit the transaction. If the zone serial number has not been
+ explicitly updated as part of the transaction, the zone serial
+ number may or may not be incremented at this time. Indicate in
+ the response that the server is authoritative and return a suc-
+ cessful response. Exit.
+
+ At the start of a transaction, the zone must be locked to prevent
+ concurrent interleaving of concurrent update requests. The zone is
+ unlocked at the end of a (successful or unsuccessful) transaction.
+ Aborting a transaction requires that any changes made so far must be
+ rolled back. Committing a transaction means that the changes are
+
+
+
+Expires July 31, 1995 [Page 11]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ applied to the zone and are visible to subsequent queries to the pri-
+ mary. (It is an implementation matter whether the master file is
+ updated at this time or later. The point is that the changes are made
+ persistent, e.g. in a log on stable storage, and are added to the
+ cached copy of the zone.) If the zone serial number is not explicitly
+ updated in a request, a primary name server may update the zone
+ serial number when committing each transaction, or periodically,
+ after some number of transactions or time has passed, depending on
+ policy. The effect of incrementing the serial number periodically
+ rather than on each transaction means that a secondary may not detect
+ that a zone has been updated as quickly as it otherwise would do. On
+ the other hand, updating the serial number periodically makes it pos-
+ sible to slow incrementing of the serial number in situations where
+ many updates occur close together in time.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires July 31, 1995 [Page 12]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+5. RESOLVER BEHAVIOR
+
+
+ A resolver provides the application interface to name servers. A
+ resolver must enable applications to perform both standard queries
+ and updates.
+
+ A stub resolver performs no resolution function itself, but must
+ either be configured with a list of name servers that provide recur-
+ sive service, i.e. name servers that can perform requests on the
+ resolver's behalf, or be configured with the names of authoritative
+ servers of zones that this resolver is known to be responsible for
+ updating.
+
+ A full-service resolver traverses the domain name space itself, pos-
+ sibly querying several name servers to find the name servers authori-
+ tative for the zone to be updated. A full-service resolver performs
+ an update operation as follows (adapted from [RFC1034]):
+
+ 1. If a resolver has direct access to a name server's authoritative
+ data, determine the names (RRNAMEs) associated with all records
+ to be updated in the transaction. For each RRNAME, search the
+ available zones for the zone which is authoritative for RRNAME.
+
+ a) If more than one zone is found, return a response indicat-
+ ing that the update request is not restricted to a single
+ zone. Exit.
+
+ b) If a single authoritative zone is found, perform the update
+ transaction in the relevant zone as outlined in Section
+ 4.2. Exit.
+
+ 2. If the zone is non-local, find the best servers to ask for any
+ or all RRNAMEs. If the resolver finds that the RRNAMEs cannot be
+ in the same zone, it returns a response indicating that the
+ update is not constrained to a single zone and exits.
+
+ 3. Send a query to one of the servers for any RRNAME, RRCLASS and
+ RRTYPE to be updated in the zone.
+
+ 4. Analyze the response:
+
+ a) If the response is authoritative, go to step 5
+
+ b) If the response contains better delegation information,
+
+
+
+Expires July 31, 1995 [Page 13]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ cache the delegation information and go to step 2.
+
+ c) If the response shows a server failure or other bizarre
+ contents, delete the server from the list of servers and go
+ back to step 3.
+
+ 5. Send an update to an authoritative name server.
+
+ 6. Analyze the response:
+
+ a) If the response shows a server failure or other bizarre
+ contents, delete the server from the list of servers and go
+ back to step 5.
+
+ b) Otherwise, return the response to the client.
+
+ The data structures used to represent the state of a query in pro-
+ gress in the resolver are the same as that specified in RFC1034,
+ except that the list that represents the resolver's best guess about
+ which name servers to ask may include additional information per-
+ tinent to updates, e.g. which in a set of authoritative name servers
+ accept update requests for a given zone (some name servers may refuse
+ to accept update requests) and the relative performance of the name
+ servers (primary may provide better performance than secondaries).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires July 31, 1995 [Page 14]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+6. EXAMPLES
+
+ A wide range of update functions can be achieved using a combination
+ of the four update operations. To illustrate this, we use a simple
+ zone consisting of the following records:
+
+
+ xyz.com. SOA ns.xyz.com sysadm.xyz.com
+ ( ... )
+ NS ns.xyz.com.
+
+ ns.xyz.com. A 128.96.33.22
+
+ foo.xyz.com. A 128.96.33.33
+ A 128.96.34.34
+
+
+ For example, one of the A records belonging to foo.xyz.com can be
+ modified by first deleting it and adding the new.
+
+
+ DELETE foo.xyz.com A 128.96.33.33
+
+ ADD foo.xyz.com A 128.96.44.44
+
+
+ Both ADD or ADDEXIST would work in the above example to add the
+ replacement record.
+
+ The canonical name of a host can be changed from "foo" to "bar" and
+ the old name "foo" made an alias, by sending an update transaction
+ consisting of the following three operations:
+
+
+ DELETE foo.xyz.com A 128.96.33.33
+ foo.xyz.com A 128.96.34.34
+
+ ADDEXIST foo.xyz.com CNAME bar.xyz.com
+
+ ADDNEW bar.xyz.com A 128.61.44.33
+
+
+
+ Alternatively, the A records belonging to "foo" need not be individu-
+ ally deleted. The wildcard data field can be used to delete all
+
+
+
+Expires July 31, 1995 [Page 15]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ records associated with "foo" as follows:
+
+
+ DELETE foo.xyz.com A *
+
+
+ Also, both of the above add operations could be replaced by ADD.
+ However, the existence checks would not then be applied.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires July 31, 1995 [Page 16]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+7. SERIAL RESOURCE RECORD
+
+
+ A new resource record is defined that can be used to serialize update
+ requests. Serialization is needed if updates can be concurrent or the
+ update is dependent on the database being in a certain state. In
+ particular, serialisation may be necessary to protect against dupli-
+ cate messages. Duplicate messages arise when the transport protocol
+ used does not guarantee otherwise, or when resolvers retransmit mes-
+ sages because the transport protocol is unreliable. Also, malicious
+ clients may deliberately replay old update requests.
+
+ In general, to serialize requests, a token needs to be associated
+ with the set of records to be updated. This token must be set to a
+ different value on each update. The SERIAL resource record is defined
+ to hold this token and to indicate the set of records associated with
+ the token. The SERIAL record has the same name, class, and TTL
+ values as the records to be protected. The name may contain the wild-
+ card label in which case the SERIAL record covers all records in the
+ zone (of the type specified in the data field), and can be used to
+ serialize updates at the granularity of a zone. The data field of
+ the record contains the type of the records protected and the token
+ itself. The type may be any valid record type, or it may contain type
+ ANY which means that the token covers all records associated with the
+ name specified. The token is a 64-bit number (the exact definition of
+ which is to be discussed below).
+
+ The data field of the record is as follows:
+
+
+
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | RR type covered |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | |
+ | token |
+ | |
+ | |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+
+
+ To update the SERIAL record, a client MUST delete the current record
+ explicitly and then add the new record with the new token value. The
+
+
+
+Expires July 31, 1995 [Page 17]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ SERIAL record is the only record where the use of the wildcard data
+ field when deleting records is invalid. This restriction ensures
+ that the update of the token is itself serialized, by making sure
+ that the change from the current token value to the new token value
+ is done in a mutually exclusive manner.
+
+ For example, given a zone containing a SERIAL RR as follows:
+
+
+ xyz.com. SOA ns.xyz.com sysadm.xyz.com
+ ( ... )
+ NS ns.xyz.com.
+
+ ns.xyz.com. A 128.96.33.22
+
+ foo.xyz.com. SERIAL A 2157449756503
+ A 128.96.33.33
+ A 128.96.34.34
+
+
+ Updates to the A records would be serialized by using the following
+ operations:
+
+
+ DELETE foo.xyz.com SERIAL A 2157449756503
+ foo.xyz.com A *
+
+ ADD foo.xyz.com SERIAL A 7575470909833451
+ foo.xyz.com A 128.96.44.44
+ foo.xyz.com A 128.96.55.55
+
+
+ FOR DISCUSSION: One approach would be to define the token as a random
+ number. However, update serialization is only as good as the random
+ numbers generated. If clients cannot be trusted to generate unique
+ random numbers or it is too expensive to do so, an alternative
+ approach is to define the token as a sequence number. This approach
+ is cheap to implement, but does require that the name server inter-
+ pret the value of the data field of the SERIAL RR added to determine
+ that it is appropriately set. Another approach is to have the server
+ responsible for generating the next token (in any way it liked). This
+ also requires the server to interpret the data field of the SERIAL
+ RR.
+
+
+
+
+
+Expires July 31, 1995 [Page 18]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+8. SECURITY CONSIDERATIONS
+
+
+ DNS updates must be able to be made secure. The security mechanism
+ must provide data origin authentication, data integrity and protec-
+ tion against replay. Data confidentiality is not required.
+
+ The signature records defined in [DNSSEC] can be used to ensure that
+ each set of records of a particular name, type and class are updated
+ by an entity that has the appropriate authority. The signature
+ record is updated along with the associated records in an update
+ transaction. The SIG RR must sign all records associated with a name,
+ class and type, not only those updated in the request. The "time
+ signed" timestamp in the SIG record may be used to protect against
+ replay if it is defined that, when updated, it must have a value
+ greater than the current value and be set to a time not too far in
+ the future.
+
+ Note that a signature record only covers records of a particular
+ name, class and type. Thus, while the integrity of each set of
+ records of the same name, class and type updated in a transaction can
+ be assured, the integrity of a set of updates records with different
+ names or types is not. To ensure integrity of the entire message, a
+ network layer security protocol should be used if available. Alterna-
+ tively, a SIG RR signing the entire message can be placed at the end
+ of the last section of a message as explained in [DNSSEC]. If SIG
+ records are not used to authenticate individual updates, the SERIAL
+ record will need to be used to ensure against replay.
+
+ Note that a SIG RR is not only used to authenticate an update
+ request, but is stored along with the authenticated data in DNS to
+ authenticate subsequent queries for the data.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires July 31, 1995 [Page 19]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+9. OPEN ISSUES
+
+
+
+ 1. Should non-recursive updates perform referrals when an update is
+ sent to a non-authoritative server?
+
+
+ This is a bit less clean for updates than for queries, since
+ multiple nodes can be specified in an atomic transaction. (A
+ referral need only be to one of the nodes specified - any one
+ will do.
+
+ On the other hand, using queries to locate authoritative servers
+ before sending an update is likely to be less efficient than
+ using updates only. However, caching of queries should alleviate
+ this.
+
+ The usefulness of having updates perform referrals is not clear:
+
+ a) While updates need to be reliable and hence might be car-
+ ried using TCP, the recommended approach to get referrals
+ is UDP.
+
+ b) As a practical matter, it cannot be required that all name
+ servers in DNS support dynamic updates. Thus, queries will
+ always have to be used as the fallback mechanism for locat-
+ ing the authoritative name servers for a dynamic zone.
+
+ This document as it stands does not specify referrals.
+
+
+
+10. ACKNOWLEDGEMENTS
+
+
+ We would like to thank the DNSIND working group for their valuable
+ input, in particular, Donald Eastlake.
+
+
+
+11. REFERENCES
+
+
+
+
+
+
+Expires July 31, 1995 [Page 20]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+ [RFC1034]
+ P. Mockapetris, "Domain Names - Concepts and Facilities", RFC
+ 1034, USC/Information Sciences Institute, November 1987.
+
+ [RFC1035]
+ P. Mockapetris, "Domain Names - Implementation and Specifica-
+ tion", RFC 1035, USC/Information Sciences Institute, November
+ 1987.
+
+ [DNSSEC]
+ Donald E. Eastlake and Charles W. Kaufman, "Domain Name System
+ Protocol Security Extensions", Internet Draft, March 1994,
+ <draft-ietf-dnssec-secext-03.txt>.
+
+ [IXFR]M. Ohta, "Incremental Zone Transfer", Internet Draft, November
+ 1994.
+
+ [NOTIFY]
+ P. Vixie, "Notify: a mechanism for prompt notification of
+ authority zone changes", Internet Draft, November 1994, <draft-
+ ietf-dnsind-notify-00.txt>.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires July 31, 1995 [Page 21]
+
+
+
+
+
+\fINTERNET-DRAFT Dynamic DNS Updates January 1995
+
+
+Authors' Addresses
+
+
+ Susan Thomson
+ Bellcore
+ 445 South Street
+ Morristown, NJ 07960
+ Phone: (201) 829-4514
+ email: set@thumper.bellcore.com
+
+ Yakov Rekhter
+ T.J. Watson Research Center IBM Corporation
+ P.O. Box 740, H3-D40,
+ Yorktown Heights, NY 10598
+ Phone: (914) 784-7361
+ email: yakov@watson.ibm.com
+
+ Jim Bound
+ Digital Equipment Corporation
+ 110 Spitbrook Road ZK3-3/U14
+ Nashua, NH 03062-2698
+ Phone: (603) 881-0400
+ email: bound@zk3.dec.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires July 31, 1995 [Page 22]
+
+
--- /dev/null
+
+This Internet-Draft was deleted. For more information, send a message to
+
+ Internet-Drafts@cnri.reston.va.us
+
--- /dev/null
+
+
+
+
+
+
+Network Working Group S. Alexander
+Request for Comments: 1533 Lachman Technology, Inc.
+Obsoletes: 1497, 1395, 1084, 1048 R. Droms
+Category: Standards Track Bucknell University
+ October 1993
+
+
+ DHCP Options and BOOTP Vendor Extensions
+
+Status of this Memo
+
+ This RFC specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" for the standardization state and status
+ of this protocol. Distribution of this memo is unlimited.
+
+Abstract
+
+ The Dynamic Host Configuration Protocol (DHCP) [1] provides a
+ framework for passing configuration information to hosts on a TCP/IP
+ network. Configuration parameters and other control information are
+ carried in tagged data items that are stored in the "options" field
+ of the DHCP message. The data items themselves are also called
+ "options."
+
+ This document specifies the current set of DHCP options. This
+ document will be periodically updated as new options are defined.
+ Each superseding document will include the entire current list of
+ valid options.
+
+ All of the vendor information extensions defined in RFC 1497 [2] may
+ be used as DHCP options. The definitions given in RFC 1497 are
+ included in this document, which supersedes RFC 1497. All of the
+ DHCP options defined in this document, except for those specific to
+ DHCP as defined in section 9, may be used as BOOTP vendor information
+ extensions.
+
+Table of Contents
+
+ 1. Introduction .............................................. 2
+ 2. BOOTP Extension/DHCP Option Field Format .................. 2
+ 3. RFC 1497 Vendor Extensions ................................ 3
+ 4. IP Layer Parameters per Host .............................. 10
+ 5. IP Layer Parameters per Interface ........................ 13
+ 6. Link Layer Parameters per Interface ....................... 16
+ 7. TCP Parameters ............................................ 17
+ 8. Application and Service Parameters ........................ 18
+
+
+
+Alexander & Droms [Page 1]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+ 9. DHCP Extensions ........................................... 23
+ 10. Extensions ................................................ 27
+ 11. Acknowledgements .......................................... 28
+ 12. References ................................................ 28
+ 13. Security Considerations ................................... 19
+ 14. Authors' Addresses ........................................ 30
+
+1. Introduction
+
+ This document specifies options for use with both the Dynamic Host
+ Configuration Protocol and the Bootstrap Protocol.
+
+ The full description of DHCP packet formats may be found in the DHCP
+ specification document [1], and the full description of BOOTP packet
+ formats may be found in the BOOTP specification document [3]. This
+ document defines the format of information in the last field of DHCP
+ packets ('options') and of BOOTP packets ('vend'). The remainder of
+ this section defines a generalized use of this area for giving
+ information useful to a wide class of machines, operating systems and
+ configurations. Sites with a single DHCP or BOOTP server that is
+ shared among heterogeneous clients may choose to define other, site-
+ specific formats for the use of the 'options' field.
+
+ Section 2 of this memo describes the formats of DHCP options and
+ BOOTP vendor extensions. Section 3 describes options defined in
+ previous documents for use with BOOTP (all may also be used with
+ DHCP). Sections 4-8 define new options intended for use with both
+ DHCP and BOOTP. Section 9 defines options used only in DHCP.
+
+ References further describing most of the options defined in sections
+ 2-6 can be found in section 12. The use of the options defined in
+ section 9 is described in the DHCP specification [1].
+
+ Information on registering new options is contained in section 10.
+
+2. BOOTP Extension/DHCP Option Field Format
+
+ DHCP options have the same format as the BOOTP "vendor extensions"
+ defined in RFC 1497 [2]. Options may be fixed length or variable
+ length. All options begin with a tag octet, which uniquely
+ identifies the option. Fixed-length options without data consist of
+ only a tag octet. Only options 0 and 255 are fixed length. All
+ other options are variable-length with a length octet following the
+ tag octet. The value of the length octet does not include the two
+ octets specifying the tag and length. The length octet is followed
+ by "length" octets of data. In the case of some variable-length
+ options the length field is a constant but must still be specified.
+
+
+
+
+Alexander & Droms [Page 2]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+ Any options defined subsequent to this document should contain a
+ length octet even if the length is fixed or zero.
+
+ All multi-octet quantities are in network byte-order.
+
+ When used with BOOTP, the first four octets of the vendor information
+ field have been assigned to the "magic cookie" (as suggested in RFC
+ 951). This field identifies the mode in which the succeeding data is
+ to be interpreted. The value of the magic cookie is the 4 octet
+ dotted decimal 99.130.83.99 (or hexadecimal number 63.82.53.63) in
+ network byte order.
+
+ All of the "vendor extensions" defined in RFC 1497 are also DHCP
+ options.
+
+ Option codes 128 to 254 (decimal) are reserved for site-specific
+ options.
+
+ Except for the options in section 9, all options may be used with
+ either DHCP or BOOTP.
+
+ Many of these options have their default values specified in other
+ documents. In particular, RFC 1122 [4] specifies default values for
+ most IP and TCP configuration parameters.
+
+3. RFC 1497 Vendor Extensions
+
+ This section lists the vendor extensions as defined in RFC 1497.
+ They are defined here for completeness.
+
+3.1. Pad Option
+
+ The pad option can be used to cause subsequent fields to align on
+ word boundaries.
+
+ The code for the pad option is 0, and its length is 1 octet.
+
+ Code
+ +-----+
+ | 0 |
+ +-----+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 3]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+3.2. End Option
+
+ The end option marks the end of valid information in the vendor
+ field. Subsequent octets should be filled with pad options.
+
+ The code for the end option is 255, and its length is 1 octet.
+
+ Code
+ +-----+
+ | 255 |
+ +-----+
+
+3.3. Subnet Mask
+
+ The subnet mask option specifies the client's subnet mask as per RFC
+ 950 [5].
+
+ If both the subnet mask and the router option are specified in a DHCP
+ reply, the subnet mask option MUST be first.
+
+ The code for the subnet mask option is 1, and its length is 4 octets.
+
+ Code Len Subnet Mask
+ +-----+-----+-----+-----+-----+-----+
+ | 1 | 4 | m1 | m2 | m3 | m4 |
+ +-----+-----+-----+-----+-----+-----+
+
+3.4. Time Offset
+
+ The time offset field specifies the offset of the client's subnet in
+ seconds from Coordinated Universal Time (UTC). The offset is
+ expressed as a signed 32-bit integer.
+
+ The code for the time offset option is 2, and its length is 4 octets.
+
+ Code Len Time Offset
+ +-----+-----+-----+-----+-----+-----+
+ | 2 | 4 | n1 | n2 | n3 | n4 |
+ +-----+-----+-----+-----+-----+-----+
+
+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 4]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+3.5. Router Option
+
+ The router option specifies a list of IP addresses for routers on the
+ client's subnet. Routers SHOULD be listed in order of preference.
+
+ The code for the router option is 3. The minimum length for the
+ router option is 4 octets, and the length MUST always be a multiple
+ of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 3 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.6. Time Server Option
+
+ The time server option specifies a list of RFC 868 [6] time servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for the time server option is 4. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 4 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.7. Name Server Option
+
+ The name server option specifies a list of IEN 116 [7] name servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for the name server option is 5. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 5 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 5]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+3.8. Domain Name Server Option
+
+ The domain name server option specifies a list of Domain Name System
+ (STD 13, RFC 1035 [8]) name servers available to the client. Servers
+ SHOULD be listed in order of preference.
+
+ The code for the domain name server option is 6. The minimum length
+ for this option is 4 octets, and the length MUST always be a multiple
+ of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 6 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.9. Log Server Option
+
+ The log server option specifies a list of MIT-LCS UDP log servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for the log server option is 7. The minimum length for this
+ option is 4 octets, and the length MUST always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 7 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.10. Cookie Server Option
+
+ The cookie server option specifies a list of RFC 865 [9] cookie
+ servers available to the client. Servers SHOULD be listed in order
+ of preference.
+
+ The code for the log server option is 8. The minimum length for this
+ option is 4 octets, and the length MUST always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 8 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 6]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+3.11. LPR Server Option
+
+ The LPR server option specifies a list of RFC 1179 [10] line printer
+ servers available to the client. Servers SHOULD be listed in order
+ of preference.
+
+ The code for the LPR server option is 9. The minimum length for this
+ option is 4 octets, and the length MUST always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 9 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.12. Impress Server Option
+
+ The Impress server option specifies a list of Imagen Impress servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for the Impress server option is 10. The minimum length for
+ this option is 4 octets, and the length MUST always be a multiple of
+ 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 10 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.13. Resource Location Server Option
+
+ This option specifies a list of RFC 887 [11] Resource Location
+ servers available to the client. Servers SHOULD be listed in order
+ of preference.
+
+ The code for this option is 11. The minimum length for this option
+ is 4 octets, and the length MUST always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 11 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 7]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+3.14. Host Name Option
+
+ This option specifies the name of the client. The name may or may
+ not be qualified with the local domain name (see section 3.17 for the
+ preferred way to retrieve the domain name). See RFC 1035 for
+ character set restrictions.
+
+ The code for this option is 12, and its minimum length is 1.
+
+ Code Len Host Name
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 12 | n | h1 | h2 | h3 | h4 | h5 | h6 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+3.15. Boot File Size Option
+
+ This option specifies the length in 512-octet blocks of the default
+ boot image for the client. The file length is specified as an
+ unsigned 16-bit integer.
+
+ The code for this option is 13, and its length is 2.
+
+ Code Len File Size
+ +-----+-----+-----+-----+
+ | 13 | 2 | l1 | l2 |
+ +-----+-----+-----+-----+
+
+3.16. Merit Dump File
+
+ This option specifies the path-name of a file to which the client's
+ core image should be dumped in the event the client crashes. The
+ path is formatted as a character string consisting of characters from
+ the NVT ASCII character set.
+
+ The code for this option is 14. Its minimum length is 1.
+
+ Code Len Dump File Pathname
+ +-----+-----+-----+-----+-----+-----+---
+ | 14 | n | n1 | n2 | n3 | n4 | ...
+ +-----+-----+-----+-----+-----+-----+---
+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 8]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+3.17. Domain Name
+
+ This option specifies the domain name that client should use when
+ resolving hostnames via the Domain Name System.
+
+ The code for this option is 15. Its minimum length is 1.
+
+ Code Len Domain Name
+ +-----+-----+-----+-----+-----+-----+--
+ | 15 | n | d1 | d2 | d3 | d4 | ...
+ +-----+-----+-----+-----+-----+-----+--
+
+3.18. Swap Server
+
+ This specifies the IP address of the client's swap server.
+
+ The code for this option is 16 and its length is 4.
+
+ Code Len Swap Server Address
+ +-----+-----+-----+-----+-----+-----+
+ | 16 | n | a1 | a2 | a3 | a4 |
+ +-----+-----+-----+-----+-----+-----+
+
+3.19. Root Path
+
+ This option specifies the path-name that contains the client's root
+ disk. The path is formatted as a character string consisting of
+ characters from the NVT ASCII character set.
+
+ The code for this option is 17. Its minimum length is 1.
+
+ Code Len Root Disk Pathname
+ +-----+-----+-----+-----+-----+-----+---
+ | 17 | n | n1 | n2 | n3 | n4 | ...
+ +-----+-----+-----+-----+-----+-----+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 9]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+3.20. Extensions Path
+
+ A string to specify a file, retrievable via TFTP, which contains
+ information which can be interpreted in the same way as the 64-octet
+ vendor-extension field within the BOOTP response, with the following
+ exceptions:
+
+ - the length of the file is unconstrained;
+ - all references to Tag 18 (i.e., instances of the
+ BOOTP Extensions Path field) within the file are
+ ignored.
+
+ The code for this option is 18. Its minimum length is 1.
+
+ Code Len Extensions Pathname
+ +-----+-----+-----+-----+-----+-----+---
+ | 18 | n | n1 | n2 | n3 | n4 | ...
+ +-----+-----+-----+-----+-----+-----+---
+
+4. IP Layer Parameters per Host
+
+ This section details the options that affect the operation of the IP
+ layer on a per-host basis.
+
+4.1. IP Forwarding Enable/Disable Option
+
+ This option specifies whether the client should configure its IP
+ layer for packet forwarding. A value of 0 means disable IP
+ forwarding, and a value of 1 means enable IP forwarding.
+
+ The code for this option is 19, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 19 | 1 | 0/1 |
+ +-----+-----+-----+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 10]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+4.2. Non-Local Source Routing Enable/Disable Option
+
+ This option specifies whether the client should configure its IP
+ layer to allow forwarding of datagrams with non-local source routes
+ (see Section 3.3.5 of [4] for a discussion of this topic). A value
+ of 0 means disallow forwarding of such datagrams, and a value of 1
+ means allow forwarding.
+
+ The code for this option is 20, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 20 | 1 | 0/1 |
+ +-----+-----+-----+
+
+4.3. Policy Filter Option
+
+ This option specifies policy filters for non-local source routing.
+ The filters consist of a list of IP addresses and masks which specify
+ destination/mask pairs with which to filter incoming source routes.
+
+ Any source routed datagram whose next-hop address does not match one
+ of the filters should be discarded by the client.
+
+ See [4] for further information.
+
+ The code for this option is 21. The minimum length of this option is
+ 8, and the length MUST be a multiple of 8.
+
+ Code Len Address 1 Mask 1
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ | 21 | n | a1 | a2 | a3 | a4 | m1 | m2 | m3 | m4 |
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ Address 2 Mask 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+ | a1 | a2 | a3 | a4 | m1 | m2 | m3 | m4 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 11]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+4.4. Maximum Datagram Reassembly Size
+
+ This option specifies the maximum size datagram that the client
+ should be prepared to reassemble. The size is specified as a 16-bit
+ unsigned integer. The minimum value legal value is 576.
+
+ The code for this option is 22, and its length is 2.
+
+ Code Len Size
+ +-----+-----+-----+-----+
+ | 22 | 2 | s1 | s2 |
+ +-----+-----+-----+-----+
+
+4.5. Default IP Time-to-live
+
+ This option specifies the default time-to-live that the client should
+ use on outgoing datagrams. The TTL is specified as an octet with a
+ value between 1 and 255.
+
+ The code for this option is 23, and its length is 1.
+
+ Code Len TTL
+ +-----+-----+-----+
+ | 23 | 1 | ttl |
+ +-----+-----+-----+
+
+4.6. Path MTU Aging Timeout Option
+
+ This option specifies the timeout (in seconds) to use when aging Path
+ MTU values discovered by the mechanism defined in RFC 1191 [12]. The
+ timeout is specified as a 32-bit unsigned integer.
+
+ The code for this option is 24, and its length is 4.
+
+ Code Len Timeout
+ +-----+-----+-----+-----+-----+-----+
+ | 24 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 12]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+4.7. Path MTU Plateau Table Option
+
+ This option specifies a table of MTU sizes to use when performing
+ Path MTU Discovery as defined in RFC 1191. The table is formatted as
+ a list of 16-bit unsigned integers, ordered from smallest to largest.
+ The minimum MTU value cannot be smaller than 68.
+
+ The code for this option is 25. Its minimum length is 2, and the
+ length MUST be a multiple of 2.
+
+ Code Len Size 1 Size 2
+ +-----+-----+-----+-----+-----+-----+---
+ | 25 | n | s1 | s2 | s1 | s2 | ...
+ +-----+-----+-----+-----+-----+-----+---
+
+5. IP Layer Parameters per Interface
+
+ This section details the options that affect the operation of the IP
+ layer on a per-interface basis. It is expected that a client can
+ issue multiple requests, one per interface, in order to configure
+ interfaces with their specific parameters.
+
+5.1. Interface MTU Option
+
+ This option specifies the MTU to use on this interface. The MTU is
+ specified as a 16-bit unsigned integer. The minimum legal value for
+ the MTU is 68.
+
+ The code for this option is 26, and its length is 2.
+
+ Code Len MTU
+ +-----+-----+-----+-----+
+ | 26 | 2 | m1 | m2 |
+ +-----+-----+-----+-----+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 13]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+5.2. All Subnets are Local Option
+
+ This option specifies whether or not the client may assume that all
+ subnets of the IP network to which the client is connected use the
+ same MTU as the subnet of that network to which the client is
+ directly connected. A value of 1 indicates that all subnets share
+ the same MTU. A value of 0 means that the client should assume that
+ some subnets of the directly connected network may have smaller MTUs.
+
+ The code for this option is 27, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 27 | 1 | 0/1 |
+ +-----+-----+-----+
+
+5.3. Broadcast Address Option
+
+ This option specifies the broadcast address in use on the client's
+ subnet. Legal values for broadcast addresses are specified in
+ section 3.2.1.3 of [4].
+
+ The code for this option is 28, and its length is 4.
+
+ Code Len Broadcast Address
+ +-----+-----+-----+-----+-----+-----+
+ | 28 | 4 | b1 | b2 | b3 | b4 |
+ +-----+-----+-----+-----+-----+-----+
+
+5.4. Perform Mask Discovery Option
+
+ This option specifies whether or not the client should perform subnet
+ mask discovery using ICMP. A value of 0 indicates that the client
+ should not perform mask discovery. A value of 1 means that the
+ client should perform mask discovery.
+
+ The code for this option is 29, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 29 | 1 | 0/1 |
+ +-----+-----+-----+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 14]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+5.5. Mask Supplier Option
+
+ This option specifies whether or not the client should respond to
+ subnet mask requests using ICMP. A value of 0 indicates that the
+ client should not respond. A value of 1 means that the client should
+ respond.
+
+ The code for this option is 30, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 30 | 1 | 0/1 |
+ +-----+-----+-----+
+
+5.6. Perform Router Discovery Option
+
+ This option specifies whether or not the client should solicit
+ routers using the Router Discovery mechanism defined in RFC 1256
+ [13]. A value of 0 indicates that the client should not perform
+ router discovery. A value of 1 means that the client should perform
+ router discovery.
+
+ The code for this option is 31, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 31 | 1 | 0/1 |
+ +-----+-----+-----+
+
+5.7. Router Solicitation Address Option
+
+ This option specifies the address to which the client should transmit
+ router solicitation requests.
+
+ The code for this option is 32, and its length is 4.
+
+ Code Len Address
+ +-----+-----+-----+-----+-----+-----+
+ | 32 | 4 | a1 | a2 | a3 | a4 |
+ +-----+-----+-----+-----+-----+-----+
+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 15]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+5.8. Static Route Option
+
+ This option specifies a list of static routes that the client should
+ install in its routing cache. If multiple routes to the same
+ destination are specified, they are listed in descending order of
+ priority.
+
+ The routes consist of a list of IP address pairs. The first address
+ is the destination address, and the second address is the router for
+ the destination.
+
+ The default route (0.0.0.0) is an illegal destination for a static
+ route. See section 3.5 for information about the router option.
+
+ The code for this option is 33. The minimum length of this option is
+ 8, and the length MUST be a multiple of 8.
+
+ Code Len Destination 1 Router 1
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ | 33 | n | d1 | d2 | d3 | d4 | r1 | r2 | r3 | r4 |
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ Destination 2 Router 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+ | d1 | d2 | d3 | d4 | r1 | r2 | r3 | r4 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+
+6. Link Layer Parameters per Interface
+
+ This section lists the options that affect the operation of the data
+ link layer on a per-interface basis.
+
+6.1. Trailer Encapsulation Option
+
+ This option specifies whether or not the client should negotiate the
+ use of trailers (RFC 893 [14]) when using the ARP protocol. A value
+ of 0 indicates that the client should not attempt to use trailers. A
+ value of 1 means that the client should attempt to use trailers.
+
+ The code for this option is 34, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 34 | 1 | 0/1 |
+ +-----+-----+-----+
+
+
+
+
+
+
+
+Alexander & Droms [Page 16]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+6.2. ARP Cache Timeout Option
+
+ This option specifies the timeout in seconds for ARP cache entries.
+ The time is specified as a 32-bit unsigned integer.
+
+ The code for this option is 35, and its length is 4.
+
+ Code Len Time
+ +-----+-----+-----+-----+-----+-----+
+ | 35 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+6.3. Ethernet Encapsulation Option
+
+ This option specifies whether or not the client should use Ethernet
+ Version 2 (RFC 894 [15]) or IEEE 802.3 (RFC 1042 [16]) encapsulation
+ if the interface is an Ethernet. A value of 0 indicates that the
+ client should use RFC 894 encapsulation. A value of 1 means that the
+ client should use RFC 1042 encapsulation.
+
+ The code for this option is 36, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 36 | 1 | 0/1 |
+ +-----+-----+-----+
+
+7. TCP Parameters
+
+ This section lists the options that affect the operation of the TCP
+ layer on a per-interface basis.
+
+7.1. TCP Default TTL Option
+
+ This option specifies the default TTL that the client should use when
+ sending TCP segments. The value is represented as an 8-bit unsigned
+ integer. The minimum value is 1.
+
+ The code for this option is 37, and its length is 1.
+
+ Code Len TTL
+ +-----+-----+-----+
+ | 37 | 1 | n |
+ +-----+-----+-----+
+
+
+
+
+
+
+
+Alexander & Droms [Page 17]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+7.2. TCP Keepalive Interval Option
+
+ This option specifies the interval (in seconds) that the client TCP
+ should wait before sending a keepalive message on a TCP connection.
+ The time is specified as a 32-bit unsigned integer. A value of zero
+ indicates that the client should not generate keepalive messages on
+ connections unless specifically requested by an application.
+
+ The code for this option is 38, and its length is 4.
+
+ Code Len Time
+ +-----+-----+-----+-----+-----+-----+
+ | 38 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+7.3. TCP Keepalive Garbage Option
+
+ This option specifies the whether or not the client should send TCP
+ keepalive messages with a octet of garbage for compatibility with
+ older implementations. A value of 0 indicates that a garbage octet
+ should not be sent. A value of 1 indicates that a garbage octet
+ should be sent.
+
+ The code for this option is 39, and its length is 1.
+
+ Code Len Value
+ +-----+-----+-----+
+ | 39 | 1 | 0/1 |
+ +-----+-----+-----+
+
+8. Application and Service Parameters
+
+ This section details some miscellaneous options used to configure
+ miscellaneous applications and services.
+
+8.1. Network Information Service Domain Option
+
+ This option specifies the name of the client's NIS [17] domain. The
+ domain is formatted as a character string consisting of characters
+ from the NVT ASCII character set.
+
+ The code for this option is 40. Its minimum length is 1.
+
+ Code Len NIS Domain Name
+ +-----+-----+-----+-----+-----+-----+---
+ | 40 | n | n1 | n2 | n3 | n4 | ...
+ +-----+-----+-----+-----+-----+-----+---
+
+
+
+
+Alexander & Droms [Page 18]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+8.2. Network Information Servers Option
+
+ This option specifies a list of IP addresses indicating NIS servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for this option is 41. Its minimum length is 4, and the
+ length MUST be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 41 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.3. Network Time Protocol Servers Option
+
+ This option specifies a list of IP addresses indicating NTP [18]
+ servers available to the client. Servers SHOULD be listed in order
+ of preference.
+
+ The code for this option is 42. Its minimum length is 4, and the
+ length MUST be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 42 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+
+8.4. Vendor Specific Information
+
+ This option is used by clients and servers to exchange vendor-
+ specific information. The information is an opaque object of n
+ octets, presumably interpreted by vendor-specific code on the clients
+ and servers. The definition of this information is vendor specific.
+ The vendor is indicated in the class-identifier option. Servers not
+ equipped to interpret the vendor-specific information sent by a
+ client MUST ignore it (although it may be reported). Clients which
+ do not receive desired vendor-specific information SHOULD make an
+ attempt to operate without it, although they may do so (and announce
+ they are doing so) in a degraded mode.
+
+ If a vendor potentially encodes more than one item of information in
+ this option, then the vendor SHOULD encode the option using
+ "Encapsulated vendor-specific options" as described below:
+
+ The Encapsulated vendor-specific options field SHOULD be encoded as a
+ sequence of code/length/value fields of identical syntax to the DHCP
+ options field with the following exceptions:
+
+
+
+Alexander & Droms [Page 19]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+ 1) There SHOULD NOT be a "magic cookie" field in the encapsulated
+ vendor-specific extensions field.
+
+ 2) Codes other than 0 or 255 MAY be redefined by the vendor within
+ the encapsulated vendor-specific extensions field, but SHOULD
+ conform to the tag-length-value syntax defined in section 2.
+
+ 3) Code 255 (END), if present, signifies the end of the
+ encapsulated vendor extensions, not the end of the vendor
+ extensions field. If no code 255 is present, then the end of
+ the enclosing vendor-specific information field is taken as the
+ end of the encapsulated vendor-specific extensions field.
+
+ The code for this option is 43 and its minimum length is 1.
+
+ Code Len Vendor-specific information
+ +-----+-----+-----+-----+---
+ | 43 | n | i1 | i2 | ...
+ +-----+-----+-----+-----+---
+
+ When encapsulated vendor-specific extensions are used, the
+ information bytes 1-n have the following format:
+
+ Code Len Data item Code Len Data item Code
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ | T1 | n | d1 | d2 | ... | T2 | n | D1 | D2 | ... | ... |
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+
+8.5. NetBIOS over TCP/IP Name Server Option
+
+ The NetBIOS name server (NBNS) option specifies a list of RFC
+ 1001/1002 [19] [20] NBNS name servers listed in order of preference.
+
+ The code for this option is 44. The minimum length of the option is
+ 4 octets, and the length must always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+ | 44 | n | a1 | a2 | a3 | a4 | b1 | b2 | b3 | b4 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 20]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+8.6. NetBIOS over TCP/IP Datagram Distribution Server Option
+
+ The NetBIOS datagram distribution server (NBDD) option specifies a
+ list of RFC 1001/1002 NBDD servers listed in order of preference. The
+ code for this option is 45. The minimum length of the option is 4
+ octets, and the length must always be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+ | 45 | n | a1 | a2 | a3 | a4 | b1 | b2 | b3 | b4 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
+
+8.7. NetBIOS over TCP/IP Node Type Option
+
+ The NetBIOS node type option allows NetBIOS over TCP/IP clients which
+ are configurable to be configured as described in RFC 1001/1002. The
+ value is specified as a single octet which identifies the client type
+ as follows:
+
+ Value Node Type
+ ----- ---------
+ 0x1 B-node
+ 0x2 P-node
+ 0x4 M-node
+ 0x8 H-node
+
+ In the above chart, the notation '0x' indicates a number in base-16
+ (hexadecimal).
+
+ The code for this option is 46. The length of this option is always
+ 1.
+
+ Code Len Node Type
+ +-----+-----+-----------+
+ | 46 | 1 | see above |
+ +-----+-----+-----------+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 21]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+8.8. NetBIOS over TCP/IP Scope Option
+
+ The NetBIOS scope option specifies the NetBIOS over TCP/IP scope
+ parameter for the client as specified in RFC 1001/1002. See [19],
+ [20], and [8] for character-set restrictions.
+
+ The code for this option is 47. The minimum length of this option is
+ 1.
+
+ Code Len NetBIOS Scope
+ +-----+-----+-----+-----+-----+-----+----
+ | 47 | n | s1 | s2 | s3 | s4 | ...
+ +-----+-----+-----+-----+-----+-----+----
+
+8.9. X Window System Font Server Option
+
+ This option specifies a list of X Window System [21] Font servers
+ available to the client. Servers SHOULD be listed in order of
+ preference.
+
+ The code for this option is 48. The minimum length of this option is
+ 4 octets, and the length MUST be a multiple of 4.
+
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+ | 48 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+
+8.10. X Window System Display Manager Option
+
+ This option specifies a list of IP addresses of systems that are
+ running the X Window System Display Manager and are available to the
+ client.
+
+ Addresses SHOULD be listed in order of preference.
+
+ The code for the this option is 49. The minimum length of this option
+ is 4, and the length MUST be a multiple of 4.
+
+ Code Len Address 1 Address 2
+
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+ | 49 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+---
+
+
+
+
+
+
+
+Alexander & Droms [Page 22]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+9. DHCP Extensions
+
+ This section details the options that are specific to DHCP.
+
+9.1. Requested IP Address
+
+ This option is used in a client request (DHCPDISCOVER) to allow the
+ client to request that a particular IP address be assigned.
+
+ The code for this option is 50, and its length is 4.
+
+ Code Len Address
+ +-----+-----+-----+-----+-----+-----+
+ | 50 | 4 | a1 | a2 | a3 | a4 |
+ +-----+-----+-----+-----+-----+-----+
+
+9.2. IP Address Lease Time
+
+ This option is used in a client request (DHCPDISCOVER or DHCPREQUEST)
+ to allow the client to request a lease time for the IP address. In a
+ server reply (DHCPOFFER), a DHCP server uses this option to specify
+ the lease time it is willing to offer.
+
+ The time is in units of seconds, and is specified as a 32-bit
+ unsigned integer.
+
+ The code for this option is 51, and its length is 4.
+
+ Code Len Lease Time
+ +-----+-----+-----+-----+-----+-----+
+ | 51 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+9.3. Option Overload
+
+ This option is used to indicate that the DHCP "sname" or "file"
+ fields are being overloaded by using them to carry DHCP options. A
+ DHCP server inserts this option if the returned parameters will
+ exceed the usual space allotted for options.
+
+ If this option is present, the client interprets the specified
+ additional fields after it concludes interpretation of the standard
+ option fields.
+
+ The code for this option is 52, and its length is 1. Legal values
+ for this option are:
+
+
+
+
+
+Alexander & Droms [Page 23]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+ Value Meaning
+ ----- --------
+ 1 the "file" field is used to hold options
+ 2 the "sname" field is used to hold options
+ 3 both fields are used to hold options
+
+ Code Len Value
+ +-----+-----+-----+
+ | 52 | 1 |1/2/3|
+ +-----+-----+-----+
+
+9.4. DHCP Message Type
+
+ This option is used to convey the type of the DHCP message. The code
+ for this option is 53, and its length is 1. Legal values for this
+ option are:
+
+ Value Message Type
+ ----- ------------
+ 1 DHCPDISCOVER
+ 2 DHCPOFFER
+ 3 DHCPREQUEST
+ 4 DHCPDECLINE
+ 5 DHCPACK
+ 6 DHCPNAK
+ 7 DHCPRELEASE
+
+ Code Len Type
+ +-----+-----+-----+
+ | 53 | 1 | 1-7 |
+ +-----+-----+-----+
+
+9.5. Server Identifier
+
+ This option is used in DHCPOFFER and DHCPREQUEST messages, and may
+ optionally be included in the DHCPACK and DHCPNAK messages. DHCP
+ servers include this option in the DHCPOFFER in order to allow the
+ client to distinguish between lease offers. DHCP clients indicate
+ which of several lease offers is being accepted by including this
+ option in a DHCPREQUEST message.
+
+ The identifier is the IP address of the selected server.
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 24]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+ The code for this option is 54, and its length is 4.
+
+ Code Len Address
+ +-----+-----+-----+-----+-----+-----+
+ | 54 | 4 | a1 | a2 | a3 | a4 |
+ +-----+-----+-----+-----+-----+-----+
+
+9.6. Parameter Request List
+
+ This option is used by a DHCP client to request values for specified
+ configuration parameters. The list of requested parameters is
+ specified as n octets, where each octet is a valid DHCP option code
+ as defined in this document.
+
+ The client MAY list the options in order of preference. The DHCP
+ server is not required to return the options in the requested order,
+ but MUST try to insert the requested options in the order requested
+ by the client.
+
+ The code for this option is 55. Its minimum length is 1.
+
+ Code Len Option Codes
+ +-----+-----+-----+-----+---
+ | 55 | n | c1 | c2 | ...
+ +-----+-----+-----+-----+---
+
+9.7. Message
+
+ This option is used by a DHCP server to provide an error message to a
+ DHCP client in a DHCPNAK message in the event of a failure. A client
+ may use this option in a DHCPDECLINE message to indicate the why the
+ client declined the offered parameters. The message consists of n
+ octets of NVT ASCII text, which the client may display on an
+ available output device.
+
+ The code for this option is 56 and its minimum length is 1.
+
+ Code Len Text
+ +-----+-----+-----+-----+---
+ | 56 | n | c1 | c2 | ...
+ +-----+-----+-----+-----+---
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 25]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+9.8. Maximum DHCP Message Size
+
+ This option specifies the maximum length DHCP message that it is
+ willing to accept. The length is specified as an unsigned 16-bit
+ integer. A client may use the maximum DHCP message size option in
+ DHCPDISCOVER or DHCPREQUEST messages, but should not use the option
+ in DHCPDECLINE messages.
+
+ The code for this option is 57, and its length is 2. The minimum
+ legal value is 576 octets.
+
+ Code Len Length
+ +-----+-----+-----+-----+
+ | 57 | 2 | l1 | l2 |
+ +-----+-----+-----+-----+
+
+9.9. Renewal (T1) Time Value
+
+ This option specifies the time interval from address assignment until
+ the client transitions to the RENEWING state.
+
+ The value is in units of seconds, and is specified as a 32-bit
+ unsigned integer.
+
+ The code for this option is 58, and its length is 4.
+
+ Code Len T1 Interval
+ +-----+-----+-----+-----+-----+-----+
+ | 58 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+9.10. Rebinding (T2) Time Value
+
+ This option specifies the time interval from address assignment until
+ the client transitions to the REBINDING state.
+
+ The value is in units of seconds, and is specified as a 32-bit
+ unsigned integer.
+
+ The code for this option is 59, and its length is 4.
+
+ Code Len T2 Interval
+ +-----+-----+-----+-----+-----+-----+
+ | 59 | 4 | t1 | t2 | t3 | t4 |
+ +-----+-----+-----+-----+-----+-----+
+
+
+
+
+
+
+Alexander & Droms [Page 26]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+9.11. Class-identifier
+
+ This option is used by DHCP clients to optionally identify the type
+ and configuration of a DHCP client. The information is a string of n
+ octets, interpreted by servers. Vendors and sites may choose to
+ define specific class identifiers to convey particular configuration
+ or other identification information about a client. For example, the
+ identifier may encode the client's hardware configuration. Servers
+ not equipped to interpret the class-specific information sent by a
+ client MUST ignore it (although it may be reported).
+
+ The code for this option is 60, and its minimum length is 1.
+
+ Code Len Class-Identifier
+ +-----+-----+-----+-----+---
+ | 60 | n | i1 | i2 | ...
+ +-----+-----+-----+-----+---
+
+9.12. Client-identifier
+
+ This option is used by DHCP clients to specify their unique
+ identifier. DHCP servers use this value to index their database of
+ address bindings. This value is expected to be unique for all
+ clients in an administrative domain.
+
+ Identifiers consist of a type-value pair, similar to the
+
+ It is expected that this field will typically contain a hardware type
+ and hardware address, but this is not required. Current legal values
+ for hardware types are defined in [22].
+
+ The code for this option is 61, and its minimum length is 2.
+
+ Code Len Type Client-Identifier
+ +-----+-----+-----+-----+-----+---
+ | 61 | n | t1 | i1 | i2 | ...
+ +-----+-----+-----+-----+-----+---
+
+10. Extensions
+
+ Additional generic data fields may be registered by contacting:
+
+ Internet Assigned Numbers Authority (IANA)
+ USC/Information Sciences Institute
+ 4676 Admiralty Way
+ Marina del Rey, California 90292-6695
+
+ or by email as: iana@isi.edu
+
+
+
+Alexander & Droms [Page 27]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+ Implementation specific use of undefined generic types (those in the
+ range 61-127) may conflict with other implementations, and
+ registration is required.
+
+11. Acknowledgements
+
+ The authors would like to thank Philip Almquist for his feedback on
+ this document. The comments of the DHCP Working Group are also
+ gratefully acknowledged. In particular, Mike Carney and Jon Dreyer
+ from SunSelect suggested the current format of the Vendor-specific
+ Information option.
+
+ RFC 1497 is based on earlier work by Philip Prindeville, with help
+ from Drew Perkins, Bill Croft, and Steve Deering.
+
+12. References
+
+ [1] Droms, R., "Dynamic Host Configuration Protocol", RFC 1531,
+ Bucknell University, October 1993.
+
+ [2] Reynolds, J., "BOOTP Vendor Information Extensions", RFC 1497,
+ USC/Information Sciences Institute, August 1993.
+
+ [3] Croft, W., and J. Gilmore, "Bootstrap Protocol", RFC 951,
+ Stanford University and Sun Microsystems, September 1985.
+
+ [4] Braden, R., Editor, "Requirements for Internet Hosts -
+ Communication Layers", STD 3, RFC 1122, USC/Information Sciences
+ Institute, October 1989.
+
+ [5] Mogul, J., and J. Postel, "Internet Standard Subnetting
+ Procedure", STD 5, RFC 950, USC/Information Sciences Institute,
+ August 1985.
+
+ [6] Postel, J., and K. Harrenstien, "Time Protocol", STD 26, RFC
+ 868, USC/Information Sciences Institute, SRI, May 1983.
+
+ [7] Postel, J., "Name Server", IEN 116, USC/Information Sciences
+ Institute, August 1979.
+
+ [8] Mockapetris, P., "Domain Names - Implementation and
+ Specification", STD 13, RFC 1035, USC/Information Sciences
+ Institute, November 1987.
+
+ [9] Postel, J., "Quote of the Day Protocol", STD 23, RFC 865,
+ USC/Information Sciences Institute, May 1983.
+
+
+
+
+
+Alexander & Droms [Page 28]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+ [10] McLaughlin, L., "Line Printer Daemon Protocol", RFC 1179, The
+ Wollongong Group, August 1990.
+
+ [11] Accetta, M., "Resource Location Protocol", RFC 887, CMU,
+ December 1983.
+
+ [12] Mogul, J. and S. Deering, "Path MTU Discovery", RFC 1191,
+ DECWRL, Stanford University, November 1990.
+
+ [13] Deering, S., "ICMP Router Discovery Messages", RFC 1256,
+ Xerox PARC, September 1991.
+
+ [14] Leffler, S. and M. Karels, "Trailer Encapsulations", RFC 893,
+ U. C. Berkeley, April 1984.
+
+ [15] Hornig, C., "Standard for the Transmission of IP Datagrams over
+ Ethernet Networks", RFC 894, Symbolics, April 1984.
+
+ [16] Postel, J. and J. Reynolds, "Standard for the Transmission of
+ IP Datagrams Over IEEE 802 Networks", RFC 1042, USC/Information
+ Sciences Institute, February 1988.
+
+ [17] Sun Microsystems, "System and Network Administration", March
+ 1990.
+
+ [18] Mills, D., "Internet Time Synchronization: The Network Time
+ Protocol", RFC 1305, UDEL, March 1992.
+
+ [19] NetBIOS Working Group, "Protocol Standard for a NetBIOS Service
+ on a TCP/UDP transport: Concepts and Methods", STD 19, RFC 1001,
+ March 1987.
+
+ [20] NetBIOS Working Group, "Protocol Standard for a NetBIOS Service
+ on a TCP/UDP transport: Detailed Specifications", STD 19, RFC
+ 1002, March 1987.
+
+ [21] Scheifler, R., "FYI On the X Window System", FYI 6, RFC 1198,
+ MIT Laboratory for Computer Science, January 1991.
+
+ [22] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1340,
+ USC/Information Sciences Institute, July 1992.
+
+13. Security Considerations
+
+ Security issues are not discussed in this memo.
+
+
+
+
+
+
+Alexander & Droms [Page 29]
+\f
+RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993
+
+
+14. Authors' Addresses
+
+ Steve Alexander
+ Lachman Technology, Inc.
+ 1901 North Naper Boulevard
+ Naperville, IL 60563-8895
+
+ Phone: (708) 505-9555 x256
+ EMail: stevea@lachman.com
+
+
+ Ralph Droms
+ Computer Science Department
+ 323 Dana Engineering
+ Bucknell University
+ Lewisburg, PA 17837
+
+ Phone: (717) 524-1145
+ EMail: droms@bucknell.edu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Alexander & Droms [Page 30]
+\f
\ No newline at end of file
--- /dev/null
+/* errwarn.c
+
+ Errors and warnings... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 RadioMail Corporation. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+#include <syslog.h>
+#include <errno.h>
+
+static void do_percentm PROTO ((char *obuf, char *ibuf));
+
+static char mbuf [1024];
+static char fbuf [1024];
+
+/* Log an error message, then exit... */
+
+int error (ANSI_DECL(char *) fmt, VA_DOTDOTDOT)
+ KandR (char *fmt;)
+ va_dcl
+{
+ va_list list;
+ extern int logged_in;
+
+ do_percentm (fbuf, fmt);
+
+ VA_start (list, fmt);
+ vsnprintf (mbuf, sizeof mbuf, fbuf, list);
+ va_end (list);
+#ifndef DEBUG
+ syslog (LOG_ERR, mbuf);
+#else
+ write (1, mbuf, strlen (mbuf));
+ write (1, "\n", 1);
+#endif
+
+ cleanup ();
+ exit (1);
+}
+
+/* Log a warning message... */
+
+int warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+ KandR (char *fmt;)
+ va_dcl
+{
+ va_list list;
+
+ do_percentm (fbuf, fmt);
+
+ VA_start (list, fmt);
+ vsnprintf (mbuf, sizeof mbuf, fbuf, list);
+ va_end (list);
+#ifndef DEBUG
+ syslog (LOG_ERR, mbuf);
+#else
+ write (1, mbuf, strlen (mbuf));
+ write (1, "\n", 1);
+#endif
+ return 0;
+}
+
+/* Log a note... */
+
+int note (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+ KandR (char *fmt;)
+ va_dcl
+{
+ va_list list;
+
+ do_percentm (fbuf, fmt);
+
+ VA_start (list, fmt);
+ vsnprintf (mbuf, sizeof mbuf, fbuf, list);
+ va_end (list);
+#ifndef DEBUG
+ syslog (LOG_INFO, mbuf);
+#else
+ write (1, mbuf, strlen (mbuf));
+ write (1, "\n", 1);
+#endif
+ return 0;
+}
+
+/* Log a debug message... */
+
+int debug (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+ KandR (char *fmt;)
+ va_dcl
+{
+ va_list list;
+
+ do_percentm (fbuf, fmt);
+
+ VA_start (list, fmt);
+ vsnprintf (mbuf, sizeof mbuf, fbuf, list);
+ va_end (list);
+#ifndef DEBUG
+ syslog (LOG_DEBUG, mbuf);
+#else
+ write (1, mbuf, strlen (mbuf));
+ write (1, "\n", 1);
+#endif
+ return 0;
+}
+
+/* Find %m in the input string and substitute an error message string. */
+
+static void do_percentm (obuf, ibuf)
+ char *obuf;
+ char *ibuf;
+{
+ char *s = ibuf;
+ char *p = obuf;
+ int infmt = 0;
+
+ while (*s)
+ {
+ if (infmt)
+ {
+ if (*s == 'm')
+ {
+ strcpy (p - 1, strerror (errno));
+ p += strlen (p);
+ ++s;
+ }
+ else
+ *p++ = *s++;
+ infmt = 0;
+ }
+ else
+ {
+ if (*s == '%')
+ infmt = 1;
+ *p++ = *s++;
+ }
+ }
+ *p = 0;
+}
+
+
+int parse_warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+ KandR (char *fmt;)
+ va_dcl
+{
+ extern int tline, tlpos;
+ va_list list;
+
+ do_percentm (mbuf, fmt);
+ snprintf (fbuf, sizeof fbuf, "dhcpd.conf line %d char %d: %s",
+ tline, tlpos, mbuf);
+
+ VA_start (list, fmt);
+ vsnprintf (mbuf, sizeof mbuf, fbuf, list);
+ va_end (list);
+#ifndef DEBUG
+ syslog (LOG_ERROR, mbuf);
+#else
+ write (1, mbuf, strlen (mbuf));
+ write (1, "\n", 1);
+#endif
+ return 0;
+}
--- /dev/null
+/* hash.c
+
+ Routines for manipulating hash tables... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+struct hash_table *new_hash ()
+{
+ struct hash_table *rv = new_hash_table (DEFAULT_HASH_SIZE, "new_hash");
+ if (!rv)
+ return rv;
+ memset (&rv -> buckets, 0,
+ DEFAULT_HASH_SIZE * sizeof (struct hash_bucket *));
+ return rv;
+}
+
+static INLINE do_hash (name, len, size)
+ char *name;
+ int len;
+ int size;
+{
+ register int accum = 0;
+ register unsigned char *s = (unsigned char *)name;
+ int i = len;
+ if (i) {
+ while (i--) {
+ /* Add the character in... */
+ accum += *s++;
+ /* Add carry back in... */
+ while (accum > 255) {
+ accum = (accum & 255) + (accum >> 8);
+ }
+ }
+ } else {
+ while (*s) {
+ /* Add the character in... */
+ accum += *s++;
+ /* Add carry back in... */
+ while (accum > 255) {
+ accum = (accum & 255) + (accum >> 8);
+ }
+ }
+ }
+ return accum % size;
+}
+
+void add_hash (table, name, len, pointer)
+ struct hash_table *table;
+ int len;
+ char *name;
+ unsigned char *pointer;
+{
+ int hashno = do_hash (name, len, table -> hash_count);
+ struct hash_bucket *bp = new_hash_bucket ("add_hash");
+ if (!bp) {
+ warn ("Can't add %s to hash table.", name);
+ return;
+ }
+ bp -> name = name;
+ bp -> value = pointer;
+ bp -> next = table -> buckets [hashno];
+ table -> buckets [hashno] = bp;
+}
+
+void delete_hash_entry (table, name, len)
+ struct hash_table *table;
+ int len;
+ char *name;
+{
+ int hashno = do_hash (name, len, table -> hash_count);
+ struct hash_bucket *bp, *pbp = (struct hash_bucket *)0;
+
+ /* Go through the list looking for an entry that matches;
+ if we find it, delete it. */
+ for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
+ if ((!bp -> len && !strcmp (bp -> name, name)) ||
+ (bp -> len == len &&
+ !memcmp (bp -> name, name, len))) {
+ if (pbp) {
+ pbp -> next = bp -> next;
+ } else {
+ table -> buckets [hashno] = bp -> next;
+ }
+ free_hash_bucket (bp, "delete_hash_entry");
+ break;
+ }
+ }
+}
+
+unsigned char *hash_lookup (table, name, len)
+ struct hash_table *table;
+ char *name;
+ int len;
+{
+ int hashno = do_hash (name, len, table -> hash_count);
+ struct hash_bucket *bp;
+
+ if (len) {
+ for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
+ if (len == bp -> len
+ && !memcmp (bp -> name, name, len))
+ return bp -> value;
+ } else {
+ for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
+ if (!strcmp (bp -> name, name))
+ return bp -> value;
+ }
+ return (unsigned char *)0;
+}
+
--- /dev/null
+/* hash.h
+
+ Definitions for hashing... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#define DEFAULT_HASH_SIZE 97
+
+struct hash_bucket {
+ struct hash_bucket *next;
+ char *name;
+ int len;
+ unsigned char *value;
+};
+
+struct hash_table {
+ int hash_count;
+ struct hash_bucket *buckets [DEFAULT_HASH_SIZE];
+};
+
--- /dev/null
+/* cdefs.h
+
+ Standard C definitions... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#if defined (__GNUC__) || defined (__STDC__)
+#define PROTO(x) x
+#define KandR(x)
+#define ANSI_DECL(x) x
+#define INLINE inline
+#else
+#define PROTO(x) ()
+#define KandR(x) x
+#define ANSI_DECL(x)
+#define INLINE
+#endif
--- /dev/null
+/* bsdos.h
+
+ System dependencies for BSD/os... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <paths.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <limits.h>
+
+#include <netdb.h>
+extern int h_errno;
+
+#include <net/if.h>
+
+/* Time stuff... */
+#include <sys/time.h>
+#define TIME struct timeval
+#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
+#define TIME_DIFF_US(high, low) \
+ (((high) -> tv_sec - (low) -> tv_sec) * 1000000 \
+ + ((high) -> tv_usec - (low) -> tv_usec))
+#define SET_TIME(x, y) (((x) -> tv_sec = ((y) / 1000000)), \
+ ((x) -> tv_usec = ((y) % 1000000)))
+#define DELAY() usleep (2000)
+#define DELAY_ONE_SECOND() usleep (1000000)
+
+/* Login stuff... */
+#include <utmp.h>
+#include <sys/syslimits.h>
+#define _PATH_LOGIN "/usr/bin/login"
+#define SETLOGIN(x) setlogin (x)
+#define SETUID(x) setuid (x)
+#define SETGID(x) (setgroups (0, &x), setgid (x))
+#define USER_MAX UT_NAMESIZE
+
+/* Varargs stuff... */
+#include <stdarg.h>
+#define VA_DOTDOTDOT ...
+#define va_dcl
+#define VA_start(list, last) va_start (list, last)
+
+#define _PATH_MPOOL_PID "/var/run/mpoold.pid"
+
+#define EOL '\n'
+#define VOIDPTR void *
+
+/* Time stuff... */
+#include <sys/time.h>
+#define TIME struct timeval
+#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
+#define TIME_DIFF(high, low) \
+ (((high) -> tv_sec == (low) -> tv_sec) \
+ ? ((high) -> tv_usec > (low) -> tv_usec \
+ ? 1 : (((high) -> tv_usec == (low) -> tv_usec) ? 0 : -1)) \
+ : (high) -> tv_sec - (low) -> tv_sec)
+#define SET_TIME(x, y) (((x) -> tv_sec = ((y))), ((x) -> tv_usec = 0))
+#define ADD_TIME(d, s1, s2) { \
+ (d) -> tv_usec = (s1) -> tv_usec + (s2) -> tv_usec; \
+ if ((d) -> tv_usec > 1000000 || (d) -> tv_usec < -1000000) { \
+ (d) -> tv_sec = (d) -> tv_usec / 1000000; \
+ (d) -> tv_usec %= 1000000; \
+ } else \
+ (d) -> tv_sec = 0; \
+ (d) -> tv_sec += (s1) -> tv_sec + (s2) -> tv_sec; \
+ }
+#define SET_MAX_TIME(x) (((x) -> tv_sec = INT_MAX), \
+ ((x) -> tv_usec = 999999))
--- /dev/null
+/* netbsd.h
+
+ System dependencies for NetBSD... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <paths.h>
+#include <errno.h>
+#include <unistd.h>
+#include <setjmp.h>
+#include <limits.h>
+
+#include <sys/wait.h>
+#include <signal.h>
+
+#include <netdb.h>
+extern int h_errno;
+
+#include <net/if.h>
+
+/* Varargs stuff... */
+#include <stdarg.h>
+#define VA_DOTDOTDOT ...
+#define va_dcl
+#define VA_start(list, last) va_start (list, last)
+
+#define _PATH_DHCPD_PID "/var/run/dhcpd.pid"
+
+#define EOL '\n'
+#define VOIDPTR void *
+
+/* Time stuff... */
+#include <sys/time.h>
+#define TIME time_t
+#define GET_TIME(x) time ((x))
+#define TIME_DIFF(high, low) (*(high) - *(low))
+#define SET_TIME(x, y) (*(x) = (y))
+#define ADD_TIME(d, s1, s2) (*(d) = *(s1) + *(s2))
+#define SET_MAX_TIME(x) (*(x) = INT_MAX)
--- /dev/null
+/* sunos4.h
+
+ System dependencies for SunOS 4 (tested on 4.1.4)... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <limits.h>
+
+#include <netdb.h>
+extern int h_errno;
+
+#include <net/if.h>
+
+/* Varargs stuff... */
+#include <varargs.h>
+#define VA_DOTDOTDOT va_alist
+#define VA_start(list, last) va_start (list)
+
+#define vsnprintf(buf, size, fmt, list) vsprintf (buf, fmt, list)
+
+#define EOL '\n'
+#define VOIDPTR void *
+
+/* Time stuff... */
+#include <sys/time.h>
+#define TIME struct timeval
+#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
+#define TIME_DIFF(high, low) \
+ (((high) -> tv_sec == (low) -> tv_sec) \
+ ? ((high) -> tv_usec > (low) -> tv_usec \
+ ? 1 : (((high) -> tv_usec == (low) -> tv_usec) ? 0 : -1)) \
+ : (high) -> tv_sec - (low) -> tv_sec)
+#define SET_TIME(x, y) (((x) -> tv_sec = ((y))), ((x) -> tv_usec = 0))
+#define ADD_TIME(d, s1, s2) { \
+ (d) -> tv_usec = (s1) -> tv_usec + (s2) -> tv_usec; \
+ if ((d) -> tv_usec > 1000000 || (d) -> tv_usec < -1000000) { \
+ (d) -> tv_sec = (d) -> tv_usec / 1000000; \
+ (d) -> tv_usec %= 1000000; \
+ } else \
+ (d) -> tv_sec = 0; \
+ (d) -> tv_sec += (s1) -> tv_sec + (s2) -> tv_sec; \
+ }
+#define SET_MAX_TIME(x) (((x) -> tv_sec = INT_MAX), \
+ ((x) -> tv_usec = 999999))
--- /dev/null
+/* dhcp.h
+
+ Protocol structures... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#define DHCP_UDP_OVERHEAD (14 + /* Ethernet header */ \
+ 20 + /* IP header */ \
+ 8) /* UDP header */
+#define DHCP_SNAME_LEN 64
+#define DHCP_FILE_LEN 128
+#define DHCP_FIXED_LEN (236 + DHCP_UDP_OVERHEAD) /* Everything but
+ options. */
+#define DHCP_MTU_MAX 1500
+#define DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
+
+struct dhcp_packet {
+ u_int8_t op; /* Message opcode/type */
+ u_int8_t htype; /* Hardware addr type (see net/if_types.h) */
+ u_int8_t hlen; /* Hardware addr length */
+ u_int8_t hops; /* Number of relay agent hops from client */
+ u_int32_t xid; /* Transaction ID */
+ u_int16_t secs; /* Seconds since client started looking */
+ u_int16_t flags; /* Flag bits */
+ struct in_addr ciaddr; /* Client IP address (if already in use) */
+ struct in_addr yiaddr; /* Client IP address */
+ struct in_addr siaddr; /* IP address of next server to talk to */
+ struct in_addr giaddr; /* DHCP relay agent IP address */
+ char chaddr [16]; /* Client hardware address */
+ char sname [64]; /* Server name */
+ char file [128]; /* Boot filename */
+ char options [DHCP_OPTION_LEN]; /* Optional parameters
+ (actual length dependent on MTU). */
+};
+
+/* BOOTP (rfc951) message types */
+#define BOOTREQUEST 1
+#define BOOTREPLY 2
+
+/* Possible values for flags field... */
+#define BOOTP_BROADCAST 32768L
+
+/* Magic cookie validating dhcp options field (and bootp vendor
+ extensions field). */
+#define DHCP_OPTIONS_COOKIE "\143\202\123\143"
+
+/* DHCP Option codes: */
+
+#define DHO_PAD 0
+#define DHO_SUBNET_MASK 1
+#define DHO_TIME_OFFSET 2
+#define DHO_ROUTERS 3
+#define DHO_TIME_SERVERS 4
+#define DHO_NAME_SERVERS 5
+#define DHO_DOMAIN_NAME_SERVERS 6
+#define DHO_LOG_SERVERS 7
+#define DHO_COOKIE_SERVERS 8
+#define DHO_LPR_SERVERS 9
+#define DHO_IMPRESS_SERVERS 10
+#define DHO_RESOURCE_LOCATION_SERVERS 11
+#define DHO_HOST_NAME 12
+#define DHO_BOOT_SIZE 13
+#define DHO_MERIT_DUMP 14
+#define DHO_DOMAIN_NAME 15
+#define DHO_SWAP_SERVER 16
+#define DHO_ROOT_PATH 17
+#define DHO_EXTENSIONS_PATH 18
+#define DHO_IP_FORWARDING 19
+#define DHO_NON_LOCAL_SOURCE_ROUTING 20
+#define DHO_POLICY_FILTER 21
+#define DHO_MAX_DGRAM_REASSEMBLY 22
+#define DHO_DEFAULT_IP_TTL 23
+#define DHO_PATH_MTU_AGING_TIMEOUT 24
+#define DHO_PATH_MTU_PLATEAU_TABLE 25
+#define DHO_INTERFACE_MTU 26
+#define DHO_ALL_SUBNETS_LOCAL 27
+#define DHO_BROADCAST_ADDRESS 28
+#define DHO_PERFORM_MASK_DISCOVERY 29
+#define DHO_MASK_SUPPLIER 30
+#define DHO_ROUTER_DISCOVERY 31
+#define DHO_ROUTER_SOLICITATION_ADDRESS 32
+#define DHO_STATIC_ROUTES 33
+#define DHO_TRAILER_ENCAPSULATION 34
+#define DHO_ARP_CACHE_TIMEOUT 35
+#define DHO_IEEE802_3_ENCAPSULATION 36
+#define DHO_DEFAULT_TCP_TTL 37
+#define DHO_TCP_KEEPALIVE_INTERVAL 38
+#define DHO_TCP_KEEPALIVE_GARBAGE 39
+#define DHO_NIS_DOMAIN 40
+#define DHO_NIS_SERVERS 41
+#define DHO_NTP_SERVERS 42
+#define DHO_VENDOR_ENCAPSULATED_OPTIONS 43
+#define DHO_NETBIOS_NAME_SERVERS 44
+#define DHO_NETBIOS_DD_SERVER 45
+#define DHO_NETBIOS_NODE_TYPE 46
+#define DHO_NETBIOS_SCOPE 47
+#define DHO_FONT_SERVERS 48
+#define DHO_X_DISPLAY_MANAGER 49
+#define DHO_DHCP_REQUESTED_ADDRESS 50
+#define DHO_DHCP_LEASE_TIME 51
+#define DHO_DHCP_OPTION_OVERLOAD 52
+#define DHO_DHCP_MESSAGE_TYPE 53
+#define DHO_DHCP_SERVER_IDENTIFIER 54
+#define DHO_DHCP_PARAMETER_REQUEST_LIST 55
+#define DHO_DHCP_MESSAGE 56
+#define DHO_DHCP_MAX_MESSAGE_SIZE 57
+#define DHO_DHCP_RENEWAL_TIME 58
+#define DHO_DHCP_REBINDING_TIME 59
+#define DHO_DHCP_CLASS_IDENTIFIER 60
+#define DHO_DHCP_CLIENT_IDENTIFIER 61
+#define DHO_END 255
+
+/* DHCP message types. */
+#define DHCPDISCOVER 1
+#define DHCPOFFER 2
+#define DHCPREQUEST 3
+#define DHCPDECLINE 4
+#define DHCPACK 5
+#define DHCPNAK 6
+#define DHCPRELEASE 7
--- /dev/null
+/* dhcpd.h
+
+ Definitions for dhcpd... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#include <sys/types.h>
+#include <syslog.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include "dhcp.h"
+#include "cdefs.h"
+#include "osdep.h"
+#include "tree.h"
+#include "hash.h"
+
+/* A dhcp packet and the pointers to its option values. */
+struct packet {
+ struct dhcp_packet *raw;
+ int packet_length;
+ int packet_type;
+ int options_valid;
+ struct sockaddr_in client;
+ int client_len;
+ int client_sock;
+ struct {
+ int len;
+ unsigned char *data;
+ } options [256];
+};
+
+struct hardware {
+ u_int8_t htype;
+ u_int8_t hlen;
+ u_int8_t haddr [16];
+};
+
+/* A dhcp host declaration structure. */
+struct host_decl {
+ struct host_decl *n_name, *n_haddr, *n_cid;
+ char *name;
+ struct hardware *interfaces;
+ int interface_count;
+ char *filename;
+ char *server_name;
+ struct tree_cache *fixed_addr;
+ struct tree_cache *options [256];
+};
+
+/* A dhcp lease declaration structure. */
+struct lease {
+ struct lease *next;
+ struct lease *prev;
+ struct in_addr ip_addr;
+ TIME starts, ends, timestamp;
+ unsigned char *uid;
+ int uid_len;
+ struct host_decl *host;
+ struct subnet *contain;
+ struct hardware hardware_addr;
+ int state;
+};
+
+struct subnet {
+ struct in_addr net;
+ struct in_addr netmask;
+ struct lease *leases;
+ struct lease *insertion_point;
+};
+
+/* Bitmask of dhcp option codes. */
+typedef unsigned char option_mask [16];
+
+/* DHCP Option mask manipulation macros... */
+#define OPTION_ZERO(mask) (memset (mask, 0, 16))
+#define OPTION_SET(mask, bit) (mask [bit >> 8] |= (1 << (bit & 7)))
+#define OPTION_CLR(mask, bit) (mask [bit >> 8] &= ~(1 << (bit & 7)))
+#define OPTION_ISSET(mask, bit) (mask [bit >> 8] & (1 << (bit & 7)))
+#define OPTION_ISCLR(mask, bit) (!OPTION_ISSET (mask, bit))
+
+/* An option occupies its length plus two header bytes (code and
+ length) for every 255 bytes that must be stored. */
+#define OPTION_SPACE(x) ((x) + 2 * ((x) / 255 + 1))
+
+/* Default path to dhcpd config file. */
+#ifndef _PATH_DHCPD_CONF
+#ifdef DEBUG
+#define _PATH_DHCPD_CONF "dhcpd.conf"
+#else
+#define _PATH_DHCPD_CONF "/etc/dhcpd.conf"
+#endif
+#endif
+
+/* Subnet macros... */
+#define SUBNET(addr, mask) ((addr).s_addr & (netmask).s_addr)
+#define IP_ADDR(net, host) ((net).s_addr | i)
+#define HOST_ADDR(addr, mask) ((addr).s_addr & ~(netmask).s_addr)
+#define MAX_TIME 0x7fffffff
+#define MIN_TIME 0
+
+/* External definitions... */
+
+/* options.c */
+
+void parse_options PROTO ((struct packet *));
+void parse_option_buffer PROTO ((struct packet *, unsigned char *, int));
+void cons_options PROTO ((struct packet *, struct dhcp_packet *,
+ struct host_decl *, int));
+char *pretty_print_option PROTO ((unsigned char, unsigned char *, int));
+
+/* errwarn.c */
+int error PROTO ((char *, ...));
+int warn PROTO ((char *, ...));
+int note PROTO ((char *, ...));
+int debug PROTO ((char *, ...));
+int parse_warn PROTO ((char *, ...));
+
+/* dhcpd.c */
+TIME cur_time;
+extern u_int32_t *server_addrlist;
+extern int server_addrcount;
+extern u_int16_t server_port;
+int main PROTO ((int, char **, char **));
+void cleanup PROTO ((void));
+void do_packet PROTO ((unsigned char *, int, struct sockaddr_in *, int, int));
+u_int32_t pick_interface PROTO ((struct packet *));
+
+
+/* conflex.c */
+int next_token PROTO ((char **, FILE *));
+int peek_token PROTO ((char **, FILE *));
+
+/* confpars.c */
+void readconf PROTO ((void));
+void parse_statement PROTO ((FILE *));
+void skip_to_semi PROTO ((FILE *));
+struct host_decl *parse_host_statement PROTO ((FILE *, jmp_buf *));
+char *parse_host_name PROTO ((FILE *, jmp_buf *));
+void parse_host_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
+void parse_hardware_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
+struct hardware parse_hardware_addr PROTO ((FILE *, jmp_buf *));
+void parse_filename_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
+void parse_fixed_addr_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
+void parse_option_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
+TIME parse_timestamp PROTO ((FILE *, jmp_buf *));
+TIME parse_date PROTO ((FILE *, jmp_buf *));
+struct lease *parse_lease_statement PROTO ((FILE *, jmp_buf *));
+void parse_address_range PROTO ((FILE *, jmp_buf *));
+unsigned char *parse_numeric_aggregate PROTO ((FILE *, jmp_buf *,
+ unsigned char *, int *,
+ int, int, int));
+void convert_num PROTO ((unsigned char *, char *, int, int));
+
+/* tree.c */
+pair cons PROTO ((caddr_t, pair));
+struct tree_cache *tree_cache PROTO ((struct tree *));
+struct tree *tree_host_lookup PROTO ((char *));
+struct dns_host_entry *enter_dns_host PROTO ((char *));
+struct tree *tree_const PROTO ((unsigned char *, int));
+struct tree *tree_concat PROTO ((struct tree *, struct tree *));
+struct tree *tree_limit PROTO ((struct tree *, int));
+int tree_evaluate PROTO ((struct tree_cache *));
+
+/* dhcp.c */
+void dhcp PROTO ((struct packet *));
+
+/* bootp.c */
+void bootp PROTO ((struct packet *));
+
+/* memory.c */
+void enter_host PROTO ((struct host_decl *));
+struct host_decl *find_host_by_name PROTO ((char *name));
+struct host_decl *find_host_by_addr PROTO ((int, unsigned char *, int));
+extern struct subnet *find_subnet (struct in_addr);
+void enter_subnet (struct subnet *);
+void enter_lease PROTO ((struct lease *));
+void supersede_lease PROTO ((struct lease *, struct lease *));
+struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
+struct lease *find_lease_by_ip_addr PROTO ((struct in_addr));
+struct lease *find_next_expiring_lease PROTO ((void));
+
+/* alloc.c */
+VOIDPTR dmalloc PROTO ((int, char *));
+void dfree PROTO ((VOIDPTR, char *));
+struct packet *new_packet PROTO ((char *));
+struct dhcp_packet *new_dhcp_packet PROTO ((char *));
+struct tree *new_tree PROTO ((char *));
+struct tree_cache *new_tree_cache PROTO ((char *));
+struct hash_table *new_hash_table PROTO ((int, char *));
+struct hash_bucket *new_hash_bucket PROTO ((char *));
+struct lease *new_lease PROTO ((char *));
+struct lease *new_leases (int, char *);
+struct subnet *new_subnet PROTO ((char *));
+void free_subnet PROTO ((struct subnet *, char *));
+void free_lease PROTO ((struct lease *, char *));
+void free_hash_bucket PROTO ((struct hash_bucket *, char *));
+void free_hash_table PROTO ((struct hash_table *, char *));
+void free_tree_cache PROTO ((struct tree_cache *, char *));
+void free_packet PROTO ((struct packet *, char *));
+void free_dhcp_packet PROTO ((struct dhcp_packet *, char *));
+void free_tree PROTO ((struct tree *, char *));
+
+/* print.c */
+char *print_hw_addr PROTO ((int, int, unsigned char *));
+
+/* socket.c */
+u_int32_t *get_interface_list PROTO ((int *));
+void listen_on PROTO ((u_int16_t, u_int32_t));
+void dispatch PROTO ((void));
+
+/* hash.c */
+struct hash_table *new_hash PROTO ((void));
+void add_hash PROTO ((struct hash_table *, char *, int, unsigned char *));
+void delete_hash_entry PROTO ((struct hash_table *, char *, int));
+unsigned char *hash_lookup PROTO ((struct hash_table *, char *, int));
+
+/* tables.c */
+extern struct option dhcp_options [256];
+extern unsigned char dhcp_option_default_priority_list [];
+extern int sizeof_dhcp_option_default_priority_list;
+extern struct hash_table universe_hash;
+extern struct universe dhcp_universe;
+void initialize_universes PROTO ((void));
+
--- /dev/null
+/* dhctoken.h
+
+ Tokens for config file lexer and parser. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#define SEMI ';'
+#define DOT '.'
+#define COLON ':'
+#define COMMA ','
+#define SLASH '/'
+
+#define FIRST_TOKEN HOST
+#define HOST 256
+#define HARDWARE 257
+#define FILENAME 258
+#define FIXED_ADDR 259
+#define OPTION 260
+#define ETHERNET 261
+#define STRING 262
+#define NUMBER 263
+#define NUMBER_OR_ATOM 264
+#define ATOM 265
+#define TIMESTAMP 266
+#define STARTS 267
+#define ENDS 268
+#define UID 269
+#define CLASS 270
+#define LEASE 271
+#define RANGE 272
+#define LAST_TOKEN RANGE
+
+#define is_identifier(x) ((x) >= FIRST_TOKEN && \
+ (x) <= FIRST_TOKEN && \
+ (x) != STRING && \
+ (x) != NUMBER)
--- /dev/null
+/* hash.h
+
+ Definitions for hashing... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#define DEFAULT_HASH_SIZE 97
+
+struct hash_bucket {
+ struct hash_bucket *next;
+ char *name;
+ int len;
+ unsigned char *value;
+};
+
+struct hash_table {
+ int hash_count;
+ struct hash_bucket *buckets [DEFAULT_HASH_SIZE];
+};
+
--- /dev/null
+/* osdep.h
+
+ Operating system dependencies... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#ifdef sun
+#include "cf/sunos4.h"
+#endif
+
+#ifdef bsdi
+#include "cf/bsdos.h"
+#endif
+
+#ifdef __NetBSD__
+#include "cf/netbsd.h"
+#endif
+
--- /dev/null
+/* tree.h
+
+ Definitions for address trees... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+/* A pair of pointers, suitable for making a linked list. */
+typedef struct _pair {
+ caddr_t car;
+ struct _pair *cdr;
+} *pair;
+
+/* Tree node types... */
+#define TREE_CONCAT 1
+#define TREE_HOST_LOOKUP 2
+#define TREE_CONST 3
+#define TREE_LIMIT 4
+
+/* Tree structure for deferred evaluation of changing values. */
+struct tree {
+ int op;
+ union {
+ struct concat {
+ struct tree *left;
+ struct tree *right;
+ } concat;
+ struct host_lookup {
+ struct dns_host_entry *host;
+ } host_lookup;
+ struct const_val {
+ unsigned char *data;
+ int len;
+ } const_val;
+ struct limit {
+ struct tree *tree;
+ int limit;
+ } limit;
+ } data;
+};
+
+/* DNS host entry structure... */
+struct dns_host_entry {
+ char *hostname;
+ unsigned char *data;
+ int data_len;
+ int buf_len;
+ TIME timeout;
+};
+
+struct tree_cache {
+ unsigned char *value;
+ int len;
+ int buf_size;
+ TIME timeout;
+ struct tree *tree;
+};
+
+struct universe {
+ char *name;
+ struct hash_table *hash;
+ struct option *options [256];
+};
+
+struct option {
+ char *name;
+ char *format;
+ struct universe *universe;
+ unsigned char code;
+};
--- /dev/null
+/* memory.c
+
+ Memory-resident database... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+static struct host_decl *hosts;
+static struct hash_table *subnet_hash;
+static struct hash_table *lease_uid_hash;
+static struct hash_table *lease_ip_addr_hash;
+static struct hash_table *lease_hw_addr_hash;
+static struct lease *dangling_leases;
+
+void enter_host (hd)
+ struct host_decl *hd;
+{
+ hd -> n_name = hosts;
+ hd -> n_haddr = hosts;
+ hd -> n_cid = hosts;
+
+ hosts = hd;
+}
+
+struct host_decl *find_host_by_name (name)
+ char *name;
+{
+ struct host_decl *foo;
+
+ for (foo = hosts; foo; foo = foo -> n_name)
+ if (!strcmp (name, foo -> name))
+ return foo;
+ return (struct host_decl *)0;
+}
+
+struct host_decl *find_host_by_addr (htype, haddr, hlen)
+ int htype;
+ unsigned char *haddr;
+ int hlen;
+{
+ struct host_decl *foo;
+ int i;
+
+ for (foo = hosts; foo; foo = foo -> n_haddr)
+ for (i = 0; i < foo -> interface_count; i++)
+ if (foo -> interfaces [i].htype == htype &&
+ foo -> interfaces [i].hlen == hlen &&
+ !memcmp (foo -> interfaces [i].haddr, haddr, hlen))
+ return foo;
+ return (struct host_decl *)0;
+}
+
+void new_address_range (low, high, netmask)
+ struct in_addr low, high, netmask;
+{
+ struct lease *address_range, *lp, *plp;
+ struct subnet *subnet;
+ struct in_addr net;
+ int i, max;
+ char lowbuf [16], highbuf [16], netbuf [16];
+
+ /* Initialize the hash table if it hasn't been done yet. */
+ if (!subnet_hash)
+ subnet_hash = new_hash ();
+ if (!lease_uid_hash)
+ lease_uid_hash = new_hash ();
+ if (!lease_ip_addr_hash)
+ lease_ip_addr_hash = new_hash ();
+ if (!lease_hw_addr_hash)
+ lease_hw_addr_hash = new_hash ();
+
+ /* Make sure that high and low addresses are in same subnet. */
+ net.s_addr = SUBNET (low, netmask);
+ if (net.s_addr != SUBNET (high, netmask)) {
+ strcpy (lowbuf, inet_ntoa (low));
+ strcpy (highbuf, inet_ntoa (high));
+ strcpy (netbuf, inet_ntoa (netmask));
+ error ("Address range %s to %s, netmask %s spans %s!",
+ lowbuf, highbuf, netbuf, "multiple subnets");
+ }
+
+ /* See if this subnet is already known - if not, make a new one. */
+ subnet = find_subnet (net);
+ if (!subnet) {
+ subnet = new_subnet ("new_address_range");
+ if (!subnet)
+ error ("No memory for new subnet");
+ subnet -> net = net;
+ subnet -> netmask = netmask;
+ subnet -> leases = (struct lease *)0;
+ enter_subnet (subnet);
+ }
+
+ /* Get the high and low host addresses... */
+ max = HOST_ADDR (high, netmask);
+ i = HOST_ADDR (low, netmask);
+
+ /* Allow range to be specified high-to-low as well as low-to-high. */
+ if (i > max) {
+ max = i;
+ i = HOST_ADDR (high, netmask);
+ }
+
+ /* Get a lease structure for each address in the range. */
+ address_range = new_leases (max - i + 1, "new_address_range");
+ if (!address_range) {
+ strcpy (lowbuf, inet_ntoa (low));
+ strcpy (highbuf, inet_ntoa (high));
+ error ("No memory for address range %s-%s.", lowbuf, highbuf);
+ }
+ memset (address_range, 0, (sizeof *address_range) * (max - i + 1));
+
+ /* Fill out the lease structures with some minimal information. */
+ for (; i <= max; i++) {
+ address_range [i].ip_addr.s_addr = IP_ADDR (subnet -> net, i);
+ address_range [i].starts =
+ address_range [i].timestamp = MIN_TIME;
+ address_range [i].ends = MIN_TIME;
+ address_range [i].contain = subnet;
+
+ /* Link this entry into the list. */
+ address_range [i].next = subnet -> leases;
+ address_range [i].prev = (struct lease *)0;
+ subnet -> leases = &address_range [i];
+ address_range [i].next -> prev = subnet -> leases;
+ add_hash (lease_ip_addr_hash,
+ (char *)&address_range [i].ip_addr,
+ sizeof address_range [i].ip_addr,
+ (unsigned char *)&address_range [i]);
+ }
+
+ /* Find out if any dangling leases are in range... */
+ plp = (struct lease *)0;
+ for (lp = dangling_leases; lp; lp = lp -> next) {
+ struct in_addr lnet;
+ int lhost;
+
+ lnet.s_addr = SUBNET (lp -> ip_addr, subnet -> netmask);
+ lhost = HOST_ADDR (lp -> ip_addr, subnet -> netmask);
+
+ /* If it's in range, fill in the real lease structure with
+ the dangling lease's values, and remove the lease from
+ the list of dangling leases. */
+ if (lnet.s_addr == subnet -> net.s_addr &&
+ lhost >= i && lhost <= max) {
+ if (plp) {
+ plp -> next = lp -> next;
+ } else {
+ dangling_leases = lp -> next;
+ }
+ lp -> next = (struct lease *)0;
+ supersede_lease (&address_range [lhost - i], lp);
+ free_lease (lp, "new_address_range");
+ } else
+ plp = lp;
+ }
+}
+
+struct subnet *find_subnet (subnet)
+ struct in_addr subnet;
+{
+ struct subnet *rv;
+
+ return (struct subnet *)hash_lookup (subnet_hash,
+ (char *)&subnet, sizeof subnet);
+}
+
+/* Enter a new subnet into the subnet hash. */
+
+void enter_subnet (subnet)
+ struct subnet *subnet;
+{
+ add_hash (subnet_hash, (char *)&subnet -> net,
+ sizeof subnet -> net, (unsigned char *)subnet);
+}
+
+/* Enter a lease into the system. This is called by the parser each
+ time it reads in a new lease. If the subnet for that lease has
+ already been read in (usually the case), just update that lease;
+ otherwise, allocate temporary storage for the lease and keep it around
+ until we're done reading in the config file. */
+
+void enter_lease (lease)
+ struct lease *lease;
+{
+ struct lease *comp = find_lease_by_ip_addr (lease -> ip_addr);
+
+ /* If we don't have a place for this lease yet, save it for
+ later. */
+ if (!comp) {
+ comp = new_lease ("enter_lease");
+ if (!comp) {
+ error ("No memory for lease %s\n",
+ inet_ntoa (lease -> ip_addr));
+ }
+ *comp = *lease;
+ lease -> next = dangling_leases;
+ lease -> prev = (struct lease *)0;
+ dangling_leases = lease;
+ } else {
+ supersede_lease (comp, lease);
+ }
+}
+
+/* Replace the data in an existing lease with the data in a new lease;
+ adjust hash tables to suit, and insertion sort the lease into the
+ list of leases by expiry time so that we can always find the oldest
+ lease. */
+
+void supersede_lease (comp, lease)
+ struct lease *comp, *lease;
+{
+ int enter_uid = 0;
+ int enter_hwaddr = 0;
+ struct subnet *parent;
+ struct lease *lp;
+
+ /* If the existing lease hasn't expired and has a different
+ unique identifier or, if it doesn't have a unique
+ identifier, a different hardware address, then the two
+ leases are in conflict. */
+ if (comp -> ends > cur_time &&
+ ((comp -> uid &&
+ (comp -> uid_len != lease -> uid_len ||
+ memcmp (comp -> uid, lease -> uid, comp -> uid_len))) ||
+ (!comp -> uid &&
+ ((comp -> hardware_addr.htype !=
+ lease -> hardware_addr.htype) ||
+ (comp -> hardware_addr.hlen !=
+ lease -> hardware_addr.hlen) ||
+ memcmp (comp -> hardware_addr.haddr,
+ lease -> hardware_addr.haddr,
+ comp -> hardware_addr.hlen))))) {
+ warn ("Lease conflict at %s",
+ inet_ntoa (comp -> ip_addr));
+ } else {
+ /* If there's a Unique ID, dissociate it from the hash
+ table if necessary, and always free it. */
+ if (comp -> uid) {
+ if (comp -> uid_len != lease -> uid_len ||
+ memcmp (comp -> uid, lease -> uid,
+ comp -> uid_len)) {
+ delete_hash_entry (lease_uid_hash,
+ comp -> uid,
+ comp -> uid_len);
+ enter_uid = 1;
+ }
+ free (comp -> uid);
+ }
+ if (comp -> hardware_addr.htype &&
+ (comp -> hardware_addr.hlen !=
+ lease -> hardware_addr.hlen) ||
+ (comp -> hardware_addr.htype !=
+ lease -> hardware_addr.htype) ||
+ memcmp (comp -> hardware_addr.haddr,
+ lease -> hardware_addr.haddr,
+ comp -> hardware_addr.hlen)) {
+ delete_hash_entry (lease_hw_addr_hash,
+ comp -> hardware_addr.haddr,
+ comp -> hardware_addr.hlen);
+ enter_hwaddr = 1;
+ }
+
+ /* Copy the data files, but not the linkages. */
+ comp -> starts = lease -> starts;
+ comp -> ends = lease -> ends;
+ comp -> timestamp = lease -> timestamp;
+ comp -> uid = lease -> uid;
+ comp -> uid_len = lease -> uid_len;
+ comp -> host = lease -> host;
+ comp -> hardware_addr = lease -> hardware_addr;
+ comp -> state = lease -> state;
+
+ /* Record the lease in the uid hash if necessary. */
+ if (enter_uid && lease -> uid) {
+ add_hash (lease_uid_hash, lease -> uid,
+ lease -> uid_len, (unsigned char *)lease);
+ }
+
+ /* Record it in the hardware address hash if necessary. */
+ if (enter_hwaddr && lease -> hardware_addr.htype) {
+ add_hash (lease_hw_addr_hash,
+ lease -> hardware_addr.haddr,
+ lease -> hardware_addr.hlen,
+ (unsigned char *)lease);
+ }
+
+ /* Remove the lease from its current place in the list. */
+ if (comp -> prev) {
+ comp -> prev -> next = comp -> next;
+ } else {
+ comp -> contain -> leases = comp -> next;
+ }
+ if (comp -> next) {
+ comp -> next -> prev = comp -> prev;
+ }
+
+ /* Find the last insertion point... */
+ if (comp == comp -> contain -> insertion_point ||
+ !comp -> contain -> insertion_point) {
+ lp = comp -> contain -> leases;
+ } else {
+ lp = comp -> contain -> insertion_point;
+ }
+
+ if (!lp) {
+ /* Nothing on the list yet? Just make comp the
+ head of the list. */
+ comp -> contain -> leases = comp;
+ } else if (lp -> ends <= comp -> ends) {
+ /* Skip down the list until we run out of list
+ or find a place for comp. */
+ while (lp -> next && lp -> ends < comp -> ends) {
+ lp = lp -> next;
+ }
+ if (lp -> ends < comp -> ends) {
+ /* If we ran out of list, put comp
+ at the end. */
+ lp -> next = comp;
+ comp -> prev = lp;
+ comp -> next = (struct lease *)0;
+ } else {
+ /* If we didn't, put it between lp and
+ the previous item on the list. */
+ comp -> prev = lp -> prev;
+ comp -> prev -> next = comp;
+ comp -> next = lp;
+ lp -> prev = comp;
+ }
+ } else {
+ /* Skip ip the list until we run out of list
+ or find a place for comp. */
+ while (lp -> prev && lp -> ends > comp -> ends) {
+ lp = lp -> prev;
+ }
+ if (lp -> ends > comp -> ends) {
+ /* If we ran out of list, put comp
+ at the beginning. */
+ lp -> prev = comp;
+ comp -> next = lp;
+ comp -> prev = (struct lease *)0;
+ comp -> contain -> leases = comp;
+ } else {
+ /* If we didn't, put it between lp and
+ the next item on the list. */
+ comp -> next = lp -> next;
+ comp -> next -> prev = comp;
+ comp -> prev = lp;
+ lp -> next = comp;
+ }
+ }
+ comp -> contain -> insertion_point = comp;
+ }
+}
--- /dev/null
+/* options.c
+
+ DHCP options parsing and reassembly. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#define DHCP_OPTION_DATA
+#include "dhcpd.h"
+
+/* Parse all available options out of the specified packet. */
+
+void parse_options (packet)
+ struct packet *packet;
+{
+ /* Initially, zero all option pointers. */
+ memset (packet -> options, 0, sizeof (packet -> options));
+
+ /* If we don't see the magic cookie, there's nothing to parse. */
+ if (memcmp (packet -> raw -> options, DHCP_OPTIONS_COOKIE, 4)) {
+ packet -> options_valid = 0;
+ return;
+ }
+
+ /* Go through the options field, up to the end of the packet
+ or the End field. */
+ parse_option_buffer (packet, &packet -> raw -> options [4],
+ packet -> packet_length - DHCP_FIXED_LEN);
+ /* If we parsed a DHCP Option Overload option, parse more
+ options out of the buffer(s) containing them. */
+ if (packet -> options_valid
+ && packet -> options [DHO_DHCP_OPTION_OVERLOAD].data) {
+ if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 1)
+ parse_option_buffer (packet,
+ packet -> raw -> file,
+ sizeof packet -> raw -> file);
+ if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 2)
+ parse_option_buffer (packet,
+ packet -> raw -> sname,
+ sizeof packet -> raw -> sname);
+ }
+}
+
+/* Parse options out of the specified buffer, storing addresses of option
+ values in packet -> options and setting packet -> options_valid if no
+ errors are encountered. */
+
+void parse_option_buffer (packet, buffer, length)
+ struct packet *packet;
+ unsigned char *buffer;
+ int length;
+{
+ unsigned char *s, *t;
+ unsigned char *end = buffer + length;
+ int len;
+ int code;
+
+ for (s = buffer; *s != DHO_END && s < end; ) {
+ code = s [0];
+ /* Pad options don't have a length - just skip them. */
+ if (code == DHO_PAD) {
+ ++s;
+ continue;
+ }
+ /* All other fields (except end, see above) have a
+ one-byte length. */
+ len = s [1];
+ /* If the length is outrageous, the options are bad. */
+ if (s + len + 2 > end) {
+ warn ("Option %s length %d overflows input buffer.",
+ dhcp_options [code].name,
+ len);
+ packet -> options_valid = 0;
+ return;
+ }
+ /* If we haven't seen this option before, just make
+ space for it and copy it there. */
+ if (!packet -> options [code].data) {
+ if (!(t = (unsigned char *)malloc (len + 1)))
+ error ("Can't allocate storage for option %s.",
+ dhcp_options [code].name);
+ /* Copy and NUL-terminate the option (in case it's an
+ ASCII string. */
+ memcpy (t, &s [2], len);
+ t [len] = 0;
+ packet -> options [code].len = len;
+ packet -> options [code].data = t;
+ } else {
+ /* If it's a repeat, concatenate it to whatever
+ we last saw. This is really only required
+ for clients, but what the heck... */
+ t = (unsigned char *)
+ malloc (len + packet -> options [code].len);
+ if (!t)
+ error ("Can't expand storage for option %s.",
+ dhcp_options [code].name);
+ memcpy (t, packet -> options [code].data,
+ packet -> options [code].len);
+ memcpy (t + packet -> options [code].len,
+ &s [2], len);
+ packet -> options [code].len += len;
+ t [packet -> options [code].len] = 0;
+ free (packet -> options [code].data);
+ packet -> options [code].data = t;
+ }
+ s += len + 2;
+ }
+ packet -> options_valid = 1;
+}
+
+/* Cons up options based on client-supplied desired option list (if any)
+ and selected server option list. */
+
+void cons_options (inpacket, outpacket, hp, overload)
+ struct packet *inpacket;
+ struct dhcp_packet *outpacket;
+ struct host_decl *hp;
+ int overload; /* Overload flags that may be set. */
+{
+ option_mask options_have; /* Options we can send. */
+ option_mask options_want; /* Options client wants. */
+ option_mask options_done; /* Options we've already encoded. */
+ option_mask temp; /* Working option mask. */
+ unsigned char *priority_list;
+ int priority_len;
+ unsigned char *buffer = inpacket -> raw -> options;
+ int buflen, bufix;
+ int reserved = 3; /* Reserved space for overload. */
+ unsigned char *overload_ptr = (unsigned char *)0;
+ int stored_length [256];
+ int missed = 0;
+ int missed_code;
+ int missed_length;
+ int result;
+ int i;
+
+ /* If there's no place to overload with options, don't save space
+ for an overload option. */
+ if (!overload)
+ reserved = 0;
+
+ /* Zero out the stored-lengths array. */
+ memset (stored_length, 0, sizeof stored_length);
+
+ /* If the client has provided a maximum DHCP message size,
+ use that. Otherwise, we use the default MTU size (576 bytes). */
+ /* XXX Maybe it would be safe to assume that we can send a packet
+ to the client that's as big as the one it sent us, even if it
+ didn't specify a large MTU. */
+ if (inpacket -> options [DHO_DHCP_MAX_MESSAGE_SIZE].data)
+ buflen = (getUShort (inpacket -> options
+ [DHO_DHCP_MAX_MESSAGE_SIZE].data)
+ - DHCP_FIXED_LEN);
+ else
+ buflen = 576 - DHCP_FIXED_LEN;
+
+ /* If the client has provided a list of options that it wishes
+ returned, use it to prioritize. */
+ if (inpacket -> options [DHO_DHCP_PARAMETER_REQUEST_LIST].data) {
+ priority_list =
+ inpacket -> options
+ [DHO_DHCP_PARAMETER_REQUEST_LIST].data;
+ priority_len =
+ inpacket -> options
+ [DHO_DHCP_PARAMETER_REQUEST_LIST].len;
+ } else {
+ /* Otherwise, prioritize based on the default priority list. */
+ priority_list = dhcp_option_default_priority_list;
+ priority_len = sizeof_dhcp_option_default_priority_list;
+ }
+
+ /* Make a bitmask of all the options the client wants. */
+ OPTION_ZERO (options_want);
+ for (i = 0; i < priority_len; i++)
+ OPTION_SET (options_want, priority_list [i]);
+
+ /* Make a bitmask of all the options we have available. */
+ OPTION_ZERO (options_have);
+ for (i = 0; i < 256; i++)
+ if (hp -> options [i])
+ OPTION_SET (options_have, i);
+
+ again:
+ /* Try copying out options that fit easily. */
+ for (i = 0; i < priority_len; i++) {
+ /* Code for next option to try to store. */
+ int code = priority_list [i];
+
+ /* Number of bytes left to store (some may already
+ have been stored by a previous pass). */
+ int length;
+
+ /* If no data is available for this option, skip it. */
+ if (!hp -> options [code])
+ continue;
+
+ /* Don't look at options that have already been stored. */
+ if (OPTION_ISSET (options_done, code))
+ continue;
+
+ /* Find the value of the option... */
+ if (!tree_evaluate (hp -> options [code]))
+ continue;
+
+ /* We should now have a constant length for the option. */
+ length = (hp -> options [code] -> len - stored_length [code]);
+
+ /* If there's no space for this option, skip it. */
+ if ((bufix + OPTION_SPACE (length) + reserved) > buflen) {
+ /* If this is the first missed option, remember it. */
+ if (++missed == 1) {
+ missed_code = code;
+ missed_length = length;
+ }
+ continue;
+ }
+
+ /* Otherwise, store the option. */
+ result = store_option (outpacket, code,
+ buffer + bufix,
+ buflen - bufix - reserved,
+ stored_length);
+ bufix += result;
+
+ /* The following test should always succeed because of
+ preconditioning above. */
+ if (stored_length [code] == hp -> options [code] -> len)
+ OPTION_SET (options_done, code);
+ else {
+ warn ("%s: Only stored %d out of %d bytes.",
+ dhcp_options [code].name,
+ stored_length [code],
+ hp -> options [code] -> len);
+ if (++missed == 1) {
+ missed_code = code;
+ missed_length = hp -> options [code] -> len
+ - stored_length [code];
+ }
+ }
+ }
+
+ /* If we didn't miss any options, we're done. */
+ /* XXX Maybe we want to try to encode options the client didn't
+ request but that we have available? */
+ if (!missed)
+ return;
+
+ /* If we did miss one or more options, they must not have fit.
+ It's possible, though, that there's only one option left to
+ store, and that it would fit if we weren't reserving space
+ for the overload option. In that case, we want to avoid
+ overloading. */
+ if (reserved && missed == 1
+ && (bufix + OPTION_SPACE (missed_length) <= buflen)) {
+ result = store_option (outpacket, missed_code,
+ buffer + bufix, buflen - bufix,
+ stored_length);
+ bufix += result;
+ /* This test should always fail -- we'll send bad
+ data if it doesn't. */
+ if (stored_length [missed_code]
+ == hp -> options [missed_code] -> len) {
+ OPTION_SET (options_done, missed_code);
+ } else {
+ warn ("%s (last): Only stored %d out of %d bytes.",
+ dhcp_options [missed_code].name,
+ stored_length [missed_code],
+ hp -> options [missed_code] -> len);
+ }
+ return;
+ }
+
+ /* We've crammed in all the options that completely fit in
+ the current buffer, but maybe we can fit part of the next
+ option into the current buffer and part into the next. */
+ if (bufix + OPTION_SPACE (missed_length) + reserved
+ < buflen + (overload & 1 ? 128 : 0) + (overload & 2 ? 64 : 0)) {
+ result = store_option (outpacket, missed_code,
+ buffer + bufix,
+ buflen - bufix - reserved,
+ stored_length);
+ bufix += result;
+
+ /* This test should never fail. */
+ if (stored_length [missed_code]
+ == hp -> options [missed_code] -> len) {
+ OPTION_SET (options_done, missed_code);
+ warn ("%s: Unexpected completed store.",
+ dhcp_options [missed_code].name);
+ }
+ }
+
+ /* Okay, nothing else is going to fit in the current buffer
+ except possibly the override option. Store that. */
+ if (reserved) {
+ buffer [bufix++] = DHO_DHCP_OPTION_OVERLOAD;
+ buffer [bufix++] = 1;
+ overload_ptr = buffer + bufix;
+ buffer [bufix++] = 0;
+ /* If there's space, store an End option code. */
+ if (bufix < buflen)
+ buffer [bufix++] = DHO_END;
+ /* If there's still space, pad it. */
+ while (bufix < buflen)
+ buffer [bufix++] = DHO_PAD;
+ }
+
+ /* If we've fallen through to here, we still have options to
+ store, and may be able to overload options into the file
+ and server name fields of the DHCP packet. */
+
+ /* We should have stored an overload option by now if we're
+ going to need it, so if this test fails, there's a programming
+ error somewhere above. */
+ if (overload && !overload_ptr) {
+ warn ("Need to overload, but didn't store overload option!");
+ return;
+ }
+
+ /* Can we use the file buffer? */
+ if (overload & 1) {
+ buffer = inpacket -> raw -> file;
+ buflen = sizeof inpacket -> raw -> file;
+ bufix = 0;
+ overload &= ~1;
+ goto again;
+ }
+ /* Can we use the sname buffer? */
+ if (overload & 2) {
+ buffer = inpacket -> raw -> sname;
+ buflen = sizeof inpacket -> raw -> sname;
+ bufix = 0;
+ overload &= ~2;
+ goto again;
+ }
+
+ warn ("Insufficient packet space for all options.");
+}
+
+/* Copy the option data specified by code from the packet structure's
+ option array into an option buffer specified by buf and buflen,
+ updating stored_length[code] to reflect the amount of code's option
+ data that has been stored so far. Return 1 if all the option data
+ has been stored. */
+
+int store_option (packet, code, buffer, buflen, stored_length)
+ struct packet *packet;
+ unsigned char code;
+ unsigned char *buffer;
+ int buflen;
+ int *stored_length;
+{
+ int length = packet -> options [code].len - stored_length [code];
+ int bufix = 0;
+ int rv = 1;
+ if (length > buflen) {
+ rv = 0;
+ length = buflen;
+ }
+
+ /* If the option's length is more than 255, we must store it
+ in multiple hunks. Store 255-byte hunks first. */
+ /* XXX Might a client lose its cookies if options aren't
+ chunked out so that each chunk is aligned to the size
+ of the data being represented? */
+ while (length) {
+ unsigned char incr = length > 255 ? 255 : length;
+ buffer [bufix] = code;
+ buffer [bufix + 1] = incr;
+ memcpy (buffer + bufix + 2, (packet -> options [code].data
+ + stored_length [code]), incr);
+ length -= incr;
+ stored_length [code] += incr;
+ bufix += 2 + incr;
+ }
+ return rv;
+}
+
+/* Format the specified option so that a human can easily read it. */
+
+char *pretty_print_option (code, data, len)
+ unsigned char code;
+ unsigned char *data;
+ int len;
+{
+ static char optbuf [32768]; /* XXX */
+ int hunksize = 0;
+ int numhunk = -1;
+ int numelem = 0;
+ char fmtbuf [32];
+ int i, j;
+ char *op = optbuf;
+ unsigned char *dp = data;
+ struct in_addr foo;
+
+ /* Figure out the size of the data. */
+ for (i = 0; dhcp_options [code].format [i]; i++) {
+ if (!numhunk) {
+ warn ("%s: Excess information in format string: %s\n",
+ dhcp_options [code].name,
+ &(dhcp_options [code].format [i]));
+ break;
+ }
+ numelem++;
+ fmtbuf [i] = dhcp_options [code].format [i];
+ switch (dhcp_options [code].format [i]) {
+ case 'A':
+ --numelem;
+ fmtbuf [i] = 0;
+ numhunk = 0;
+ break;
+ case 't':
+ fmtbuf [i] = 't';
+ fmtbuf [i + 1] = 0;
+ numhunk = -2;
+ break;
+ case 'I':
+ case 'l':
+ case 'L':
+ hunksize += 4;
+ break;
+ case 's':
+ case 'S':
+ hunksize += 2;
+ break;
+ case 'b':
+ case 'B':
+ case 'f':
+ hunksize++;
+ break;
+ case 'e':
+ break;
+ default:
+ warn ("%s: garbage in format string: %s\n",
+ dhcp_options [code].name,
+ &(dhcp_options [code].format [i]));
+ break;
+ }
+ }
+
+ /* Check for too few bytes... */
+ if (hunksize > len) {
+ warn ("%s: expecting at least %d bytes; got %d",
+ dhcp_options [code].name,
+ hunksize, len);
+ return "<error>";
+ }
+ /* Check for too many bytes... */
+ if (numhunk == -1 && hunksize < len)
+ warn ("%s: %d extra bytes",
+ dhcp_options [code].name,
+ len - hunksize);
+
+ /* If this is an array, compute its size. */
+ if (!numhunk)
+ numhunk = len / hunksize;
+ /* See if we got an exact number of hunks. */
+ if (numhunk > 0 && numhunk * hunksize < len)
+ warn ("%s: %d extra bytes at end of array\n",
+ dhcp_options [code].name,
+ len - numhunk * hunksize);
+
+ /* A one-hunk array prints the same as a single hunk. */
+ if (numhunk < 0)
+ numhunk = 1;
+
+printf ("numhunk = %d numelem = %d\n", numhunk, numelem);
+ /* Cycle through the array (or hunk) printing the data. */
+ for (i = 0; i < numhunk; i++) {
+ for (j = 0; j < numelem; j++) {
+ switch (fmtbuf [j]) {
+ case 't':
+ strcpy (op, dp);
+ break;
+ case 'I':
+ foo.s_addr = htonl (getULong (dp));
+ strcpy (op, inet_ntoa (foo));
+ dp += 4;
+ break;
+ case 'l':
+ sprintf (op, "%ld", getLong (dp));
+ dp += 4;
+ break;
+ case 'L':
+ sprintf (op, "%ld", getULong (dp));
+ dp += 4;
+ break;
+ case 's':
+ sprintf (op, "%d", getShort (dp));
+ dp += 2;
+ break;
+ case 'S':
+ sprintf (op, "%d", getUShort (dp));
+ dp += 2;
+ break;
+ case 'b':
+ sprintf (op, "%d", *(char *)dp++);
+ break;
+ case 'B':
+ sprintf (op, "%d", *dp++);
+ break;
+ case 'f':
+ strcpy (op, *dp++ ? "true" : "false");
+ break;
+ default:
+ warn ("Unexpected format code %c", fmtbuf [j]);
+ }
+ op += strlen (op);
+ *op++ = ' ';
+ }
+ }
+ *--op = 0;
+ return optbuf;
+}
+
+
+
--- /dev/null
+/* osdep.h
+
+ Operating system dependencies... */
+
+/*
+ * Copyright (c) 1995 RadioMail Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation 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 RADIOMAIL CORPORATION 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
+ * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises, and is based on an earlier
+ * design by Paul Vixie.
+ */
+
+#ifdef sun
+#include "cf/sunos4.h"
+#endif
+
+#ifdef bsdi
+#include "cf/bsdos.h"
+#endif
+
+#ifdef __NetBSD__
+#include "cf/netbsd.h"
+#endif
+
--- /dev/null
+/* print.c
+
+ Turn data structures into printable text. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+char *print_hw_addr (htype, hlen, data)
+ int htype;
+ int hlen;
+ unsigned char *data;
+{
+ static char habuf [49];
+ char *s;
+ int i;
+
+ s = habuf;
+ for (i = 0; i < hlen; i++) {
+ sprintf (s, "%x", data [i]);
+ s += strlen (s);
+ *s++ = ':';
+ }
+ *--s = 0;
+ return habuf;
+}
+
--- /dev/null
+/* bootp.c
+
+ BOOTP Protocol support. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+void bootp (packet)
+ struct packet *packet;
+{
+ int result;
+ struct host_decl *hp = find_host_by_addr (packet -> raw -> htype,
+ packet -> raw -> chaddr,
+ packet -> raw -> hlen);
+ struct dhcp_packet *reply;
+ struct sockaddr_in to;
+
+ /* If the packet is from a host we don't know, drop it on
+ the floor. XXX */
+ if (!hp) {
+ note ("Can't find record for BOOTP host %s",
+ print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr));
+ return;
+ }
+ /* If we don't have a fixed address for it, drop it on the floor.
+ XXX */
+ if (!hp -> fixed_addr || !tree_evaluate (hp -> fixed_addr)) {
+ note ("No fixed address for BOOTP host %s (%s)",
+ print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr),
+ hp -> name);
+ return;
+ }
+ reply = new_dhcp_packet ("bootp");
+ if (!reply) {
+ free_dhcp_packet (packet -> raw, "bootp");
+ free_packet (packet, "bootp");
+ return;
+ }
+ /* Take the fields that we care about... */
+ reply -> op = BOOTREPLY;
+ reply -> htype = packet -> raw -> htype;
+ reply -> hlen = packet -> raw -> hlen;
+ memcpy (reply -> chaddr, packet -> raw -> chaddr, reply -> hlen);
+ memset (&reply -> chaddr [reply -> hlen], 0,
+ (sizeof reply -> chaddr) - reply -> hlen);
+ reply -> hops = packet -> raw -> hops;
+ reply -> xid = packet -> raw -> xid;
+ reply -> secs = packet -> raw -> secs;
+ reply -> flags = 0;
+ reply -> ciaddr = packet -> raw -> ciaddr;
+ if (!tree_evaluate (hp -> fixed_addr))
+ warn ("tree_evaluate failed.");
+ debug ("fixed_addr: %x %d %d %d %d %x",
+ *(int *)(hp -> fixed_addr -> value), hp -> fixed_addr -> len,
+ hp -> fixed_addr -> buf_size, hp -> fixed_addr -> timeout,
+ hp -> fixed_addr -> tree);
+ memcpy (&reply -> yiaddr, hp -> fixed_addr -> value,
+ sizeof reply -> yiaddr);
+ reply -> siaddr.s_addr = pick_interface (packet);
+ reply -> giaddr = packet -> raw -> giaddr;
+ if (hp -> server_name) {
+ strncpy (reply -> sname, hp -> server_name,
+ (sizeof reply -> sname) - 1);
+ reply -> sname [(sizeof reply -> sname) - 1] = 0;
+ }
+ if (hp -> filename) {
+ strncpy (reply -> file, hp -> filename,
+ (sizeof reply -> file) - 1);
+ reply -> file [(sizeof reply -> file) - 1] = 0;
+ }
+ reply -> options [0] = 0;
+ /* XXX gateways? */
+ to.sin_port = server_port;
+
+#if 0
+ if (packet -> raw -> flags & BOOTP_BROADCAST)
+#endif
+ to.sin_addr.s_addr = INADDR_BROADCAST;
+#if 0
+ else
+ to.sin_addr.s_addr = INADDR_ANY;
+#endif
+
+ memset (reply -> options, 0, sizeof (reply -> options));
+ /* If we got the magic cookie, send it back. */
+ if (packet -> options_valid)
+ memcpy (reply -> options, packet -> raw -> options, 4);
+ to.sin_port = packet -> client.sin_port;
+ to.sin_family = AF_INET;
+ to.sin_len = sizeof to;
+ memset (to.sin_zero, 0, sizeof to.sin_zero);
+
+ note ("Sending bootp reply to %s, port %d",
+ inet_ntoa (to.sin_addr), htons (to.sin_port));
+
+ errno = 0;
+ result = sendto (packet -> client_sock, reply,
+ ((char *)(&reply -> options) - (char *)reply) + 64,
+ 0, (struct sockaddr *)&to, sizeof to);
+ if (result < 0)
+ warn ("sendto: %m");
+}
--- /dev/null
+/* confpars.c
+
+ Parser for dhcpd config file... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+#include "dhctoken.h"
+
+static TIME parsed_time;
+
+/* conf-file :== statements
+ declarations :== <nil> | declaration | declarations declaration */
+
+void readconf (void)
+{
+ FILE *cfile;
+ char *val;
+ int token;
+
+ /* Set up the initial dhcp option universe. */
+ initialize_universes ();
+
+ if ((cfile = fopen (_PATH_DHCPD_CONF, "r")) == NULL)
+ error ("Can't open %s: %m", _PATH_DHCPD_CONF);
+ do {
+ token = peek_token (&val, cfile);
+ if (token == EOF)
+ break;
+ parse_statement (cfile);
+ } while (1);
+}
+
+/* statement :== host_statement */
+
+void parse_statement (cfile)
+ FILE *cfile;
+{
+ char *val;
+ jmp_buf bc;
+
+ switch (next_token (&val, cfile)) {
+ case HOST:
+ if (!setjmp (bc)) {
+ struct host_decl *hd =
+ parse_host_statement (cfile, &bc);
+ if (hd) {
+ enter_host (hd);
+ }
+ }
+ break;
+ case LEASE:
+ if (!setjmp (bc)) {
+ struct lease *lease =
+ parse_lease_statement (cfile, &bc);
+ enter_lease (lease);
+ }
+ break;
+ case TIMESTAMP:
+ if (!setjmp (bc)) {
+ parsed_time = parse_timestamp (cfile, &bc);
+ }
+ break;
+ case RANGE:
+ if (!setjmp (bc)) {
+ parse_address_range (cfile, &bc);
+ }
+ break;
+ default:
+ parse_warn ("expecting a declaration.");
+ skip_to_semi (cfile);
+ break;
+ }
+}
+
+void skip_to_semi (cfile)
+ FILE *cfile;
+{
+ int token;
+ char *val;
+
+ do {
+ token = next_token (&val, cfile);
+ } while (token != SEMI && token != EOF);
+}
+
+/* host_statement :== HOST hostname declarations SEMI
+ host_declarations :== <nil> | host_declaration
+ | host_declarations host_declaration */
+
+struct host_decl *parse_host_statement (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ char *val;
+ int token;
+ struct host_decl tmp, *perm;
+
+ memset (&tmp, 0, sizeof tmp);
+ tmp.name = parse_host_name (cfile, bc);
+ do {
+ token = peek_token (&val, cfile);
+ if (token == SEMI) {
+ token = next_token (&val, cfile);
+ break;
+ }
+ parse_host_decl (cfile, bc, &tmp);
+ } while (1);
+ perm = (struct host_decl *)malloc (sizeof (struct host_decl));
+ if (!perm)
+ error ("can't allocate host decl struct for %s.", tmp.name);
+ *perm = tmp;
+ return perm;
+}
+
+/* host_name :== identifier | host_name DOT identifier */
+
+char *parse_host_name (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ char *val;
+ int token;
+ int len = 0;
+ char *s;
+ char *t;
+ pair c = (pair)0;
+
+ /* Read a dotted hostname... */
+ do {
+ /* Read a token, which should be an identifier. */
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting an identified in hostname");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ /* Store this identifier... */
+ if (!(s = (char *)malloc (strlen (val) + 1)))
+ error ("can't allocate temp space for hostname.");
+ strcpy (s, val);
+ c = cons ((caddr_t)s, c);
+ len += strlen (s) + 1;
+ /* Look for a dot; if it's there, keep going, otherwise
+ we're done. */
+ token = peek_token (&val, cfile);
+ if (token == DOT)
+ token = next_token (&val, cfile);
+ } while (token == DOT);
+
+ /* Assemble the hostname together into a string. */
+ if (!(s = (char *)malloc (len)))
+ error ("can't allocate space for hostname.");
+ t = s + len;
+ *--t = 0;
+ while (c) {
+ pair cdr = c -> cdr;
+ int l = strlen ((char *)(c -> car));
+ t -= l;
+ memcpy (t, (char *)(c -> car), l);
+ /* Free up temp space. */
+ free (c -> car);
+ free (c);
+ c = cdr;
+ if (t != s)
+ *--t = '.';
+ }
+ return s;
+}
+
+/* host_declaration :== hardware_declaration | filename_declaration
+ | fixed_addr_declaration | option_declaration */
+
+void parse_host_decl (cfile, bc, decl)
+ FILE *cfile;
+ jmp_buf *bc;
+ struct host_decl *decl;
+{
+ char *val;
+ int token;
+
+ token = next_token (&val, cfile);
+ switch (token) {
+ case HARDWARE:
+ parse_hardware_decl (cfile, bc, decl);
+ break;
+ case FILENAME:
+ parse_filename_decl (cfile, bc, decl);
+ break;
+ case FIXED_ADDR:
+ parse_fixed_addr_decl (cfile, bc, decl);
+ break;
+ case OPTION:
+ parse_option_decl (cfile, bc, decl);
+ break;
+ default:
+ parse_warn ("expecting a dhcp option declaration.");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ break;
+ }
+}
+
+/* hardware_decl :== HARDWARE ETHERNET NUMBER COLON NUMBER COLON NUMBER COLON
+ NUMBER COLON NUMBER COLON NUMBER */
+
+void parse_hardware_decl (cfile, bc, decl)
+ FILE *cfile;
+ jmp_buf *bc;
+ struct host_decl *decl;
+{
+ char *val;
+ int token;
+ struct hardware hw;
+
+ hw = parse_hardware_addr (cfile, bc);
+
+ /* Find space for the new interface... */
+ if (decl -> interfaces) {
+ decl -> interfaces =
+ (struct hardware *)realloc (decl -> interfaces,
+ ++decl -> interface_count *
+ sizeof (struct hardware));
+ } else {
+ decl -> interfaces =
+ (struct hardware *)malloc (sizeof (struct hardware));
+ decl -> interface_count = 1;
+ }
+ if (!decl -> interfaces)
+ error ("no memory for hardware interface info.");
+
+ /* Copy out the information... */
+ decl -> interfaces [decl -> interface_count - 1].htype = hw.htype;
+ decl -> interfaces [decl -> interface_count - 1].hlen = hw.hlen;
+ memcpy (decl -> interfaces [decl -> interface_count - 1].haddr,
+ &hw.haddr, hw.hlen);
+}
+
+struct hardware parse_hardware_addr (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ char *val;
+ int token;
+ int hlen;
+ struct hardware rv;
+
+ token = next_token (&val, cfile);
+ switch (token) {
+ case ETHERNET:
+ rv.htype = ARPHRD_ETHER;
+ hlen = 6;
+ parse_numeric_aggregate (cfile, bc,
+ (unsigned char *)&rv.haddr, &hlen,
+ COLON, 16, 8);
+ rv.hlen = hlen;
+ break;
+ default:
+ parse_warn ("expecting a network hardware type");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ return rv;
+}
+
+/* filename_decl :== FILENAME STRING */
+
+void parse_filename_decl (cfile, bc, decl)
+ FILE *cfile;
+ jmp_buf *bc;
+ struct host_decl *decl;
+{
+ char *val;
+ int token;
+ char *s;
+
+ token = next_token (&val, cfile);
+ if (token != STRING) {
+ parse_warn ("filename must be a string");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ s = (char *)malloc (strlen (val));
+ if (!s)
+ error ("no memory for filename.");
+ strcpy (s, val);
+ decl -> filename = s;
+}
+
+/* ip_addr_or_hostname :== ip_address | hostname
+ ip_address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
+
+ Parse an ip address or a hostname. If uniform is zero, put in
+ a TREE_LIMIT node to catch hostnames that evaluate to more than
+ one IP address. */
+
+struct tree *parse_ip_addr_or_hostname (cfile, bc, uniform)
+ FILE *cfile;
+ jmp_buf *bc;
+ int uniform;
+{
+ char *val;
+ int token;
+ unsigned char addr [4];
+ int len = sizeof addr;
+ char *name;
+ struct tree *rv;
+
+ token = peek_token (&val, cfile);
+ if (is_identifier (token)) {
+ name = parse_host_name (cfile, bc);
+ rv = tree_host_lookup (name);
+ if (!uniform)
+ rv = tree_limit (rv, 4);
+ } else if (token == NUMBER) {
+ parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
+ rv = tree_const (addr, len);
+ } else {
+ parse_warn ("%s (%d): expecting IP address or hostname",
+ val, token);
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ return rv;
+}
+
+
+/* fixed_addr_declaration :== FIXED_ADDR ip_addr_or_hostname */
+
+void parse_fixed_addr_decl (cfile, bc, decl)
+ FILE *cfile;
+ jmp_buf *bc;
+ struct host_decl *decl;
+{
+ decl -> fixed_addr =
+ tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
+}
+
+/* option_declaration :== OPTION identifier DOT identifier <syntax> |
+ OPTION identifier <syntax>
+
+ Option syntax is handled specially through format strings, so it
+ would be painful to come up with BNF for it. However, it always
+ starts as above. */
+
+void parse_option_decl (cfile, bc, decl)
+ FILE *cfile;
+ jmp_buf *bc;
+ struct host_decl *decl;
+{
+ char *val;
+ int token;
+ unsigned char buf [4];
+ char *vendor;
+ char *fmt;
+ struct universe *universe;
+ struct option *option;
+ struct tree *tree = (struct tree *)0;
+
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting identifier after option keyword.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ vendor = dmalloc (strlen (val) + 1, "parse_option_decl");
+ strcpy (vendor, val);
+ token = peek_token (&val, cfile);
+ if (token == DOT) {
+ /* Go ahead and take the DOT token... */
+ token = next_token (&val, cfile);
+
+ /* The next token should be an identifier... */
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting identifier after '.'");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Look up the option name hash table for the specified
+ vendor. */
+ universe = (struct universe *)hash_lookup (&universe_hash,
+ vendor, 0);
+ /* If it's not there, we can't parse the rest of the
+ statement. */
+ if (!universe) {
+ parse_warn ("no vendor named %s.", vendor);
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ } else {
+ /* Use the default hash table, which contains all the
+ standard dhcp option names. */
+ val = vendor;
+ universe = &dhcp_universe;
+ }
+
+ /* Look up the actual option info... */
+ option = (struct option *)hash_lookup (universe -> hash, val, 0);
+
+ /* If we didn't get an option structure, it's an undefined option. */
+ if (!option) {
+ if (val == vendor)
+ parse_warn ("no option named %s", val);
+ else
+ parse_warn ("no option named %s for vendor %s",
+ val, vendor);
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Free the initial identifier token. */
+ free (vendor);
+
+ /* Parse the option data... */
+ do {
+ /* Set a flag if this is an array of a simple type (i.e.,
+ not an array of pairs of IP addresses, or something
+ like that. */
+ int uniform = option -> format [1] == 'A';
+
+ for (fmt = option -> format; *fmt; fmt++) {
+ if (*fmt == 'A')
+ break;
+ switch (*fmt) {
+ case 't': /* Text string... */
+ token = next_token (&val, cfile);
+ if (token != STRING
+ && !is_identifier (token)) {
+ parse_warn ("expecting string.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tree = tree_concat (tree,
+ tree_const (val,
+ strlen (val)));
+ break;
+
+ case 'I': /* IP address or hostname. */
+ tree = tree_concat (tree,
+ parse_ip_addr_or_hostname
+ (cfile, bc, uniform));
+ break;
+
+ case 'L': /* Unsigned 32-bit integer... */
+ case 'l': /* Signed 32-bit integer... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ need_number:
+ parse_warn ("expecting number.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ convert_num (buf, val, 0, 32);
+ tree = tree_concat (tree, tree_const (buf, 4));
+ break;
+ case 's': /* Signed 16-bit integer. */
+ case 'S': /* Unsigned 16-bit integer. */
+ token = next_token (&val, cfile);
+ if (token != NUMBER)
+ goto need_number;
+ convert_num (buf, val, 0, 16);
+ tree = tree_concat (tree, tree_const (buf, 2));
+ break;
+ case 'b': /* Signed 8-bit integer. */
+ case 'B': /* Unsigned 8-bit integer. */
+ token = next_token (&val, cfile);
+ if (token != NUMBER)
+ goto need_number;
+ convert_num (buf, val, 0, 8);
+ tree = tree_concat (tree, tree_const (buf, 1));
+ break;
+ case 'f': /* Boolean flag. */
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ parse_warn ("expecting identifier.");
+ bad_flag:
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ if (!strcasecmp (val, "true")
+ || !strcasecmp (val, "on"))
+ buf [0] = 1;
+ else if (!strcasecmp (val, "false")
+ || !strcasecmp (val, "off"))
+ buf [0] = 0;
+ else {
+ parse_warn ("expecting boolean.");
+ goto bad_flag;
+ }
+ tree = tree_concat (tree, tree_const (buf, 1));
+ break;
+ default:
+ warn ("Bad format %c in parse_option_decl.",
+ *fmt);
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ }
+ if (*fmt == 'A') {
+ token = peek_token (&val, cfile);
+ if (token == COMMA) {
+ token = next_token (&val, cfile);
+ continue;
+ }
+ break;
+ }
+ } while (*fmt == 'A');
+
+ if (decl -> options [option -> code]) {
+ parse_warn ("duplicate option code %d (%s).",
+ option -> code, option -> name);
+ }
+ decl -> options [option -> code] = tree_cache (tree);
+}
+
+/* timestamp :== TIMESTAMP date
+
+ Timestamps are actually not used in dhcpd.conf, which is a static file,
+ but rather in the database file and the journal file. */
+
+TIME parse_timestamp (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ return parse_date (cfile, bc);
+}
+
+/* lease_decl :== LEASE ip_address lease_modifiers
+ lease_modifiers :== <nil>
+ | lease_modifier
+ | lease_modifier lease_modifiers
+ lease_modifier :== STARTS date
+ | ENDS date
+ | UID hex_numbers
+ | HOST identifier
+ | CLASS identifier
+ | TIMESTAMP number */
+
+struct lease *parse_lease_statement (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ char *val;
+ int token;
+ unsigned char addr [4];
+ int len = sizeof addr;
+ char *name;
+ unsigned char *uid;
+ int seenmask = 0;
+ int seenbit;
+ char tbuf [32];
+ char ubuf [1024];
+ static struct lease lease;
+
+ /* Get the address for which the lease has been issued. */
+ parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
+ memcpy (&lease.ip_addr, addr, len);
+
+ do {
+ token = next_token (&val, cfile);
+ if (token == SEMI)
+ break;
+ strncpy (val, tbuf, sizeof tbuf);
+ tbuf [(sizeof tbuf) - 1] = 0;
+
+ /* Parse any of the times associated with the lease. */
+ if (token == STARTS || token == ENDS || token == TIMESTAMP) {
+ TIME t;
+ t = parse_date (cfile, bc);
+ switch (token) {
+ case STARTS:
+ seenbit = 1;
+ lease.starts = t;
+ break;
+
+ case ENDS:
+ seenbit = 2;
+ lease.ends = t;
+ break;
+
+ case TIMESTAMP:
+ seenbit = 4;
+ lease.timestamp = t;
+ break;
+ }
+ } else {
+ switch (token) {
+ /* Colon-seperated hexadecimal octets... */
+ case UID:
+ seenbit = 8;
+ lease.uid_len = 0;
+ parse_numeric_aggregate (cfile, bc, ubuf,
+ &lease.uid_len,
+ ':', 16, 8);
+ lease.uid = (unsigned char *)
+ malloc (lease.uid_len);
+ if (!lease.uid) {
+ error ("No memory for lease uid");
+ }
+ memcpy (lease.uid, ubuf, lease.uid_len);
+ break;
+
+ case HOST:
+ seenbit = 16;
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ lease.host =
+ find_host_by_name (val);
+ if (!lease.host)
+ parse_warn ("lease host ``%s'' is %s",
+ lease.host,
+ "no longer known.");
+ break;
+
+ case CLASS:
+ seenbit = 32;
+ token = next_token (&val, cfile);
+ if (!is_identifier (token)) {
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ /* for now, we aren't using this. */
+ break;
+
+ case HARDWARE:
+ seenbit = 64;
+ lease.hardware_addr
+ = parse_hardware_addr (cfile, bc);
+ break;
+
+ default:
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ }
+ if (seenmask & seenbit) {
+ parse_warn ("Too many %s declarations in lease %s\n",
+ tbuf, inet_ntoa (lease.ip_addr));
+ } else
+ seenmask |= seenbit;
+ } while (1);
+ return &lease;
+}
+
+/* address_range :== RANGE ip_address ip_address ip_address */
+
+void parse_address_range (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ struct in_addr low, high, mask;
+ unsigned char addr [4];
+ int len = sizeof addr;
+
+ /* Get the bottom address in the range... */
+ parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
+ memcpy (&low, addr, len);
+
+ /* Get the top address in the range... */
+ parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
+ memcpy (&high, addr, len);
+
+ /* Get the netmask of the subnet containing the range... */
+ parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
+ memcpy (&mask, addr, len);
+
+ /* Create the new address range... */
+ new_address_range (low, high, mask);
+}
+
+/* date :== NUMBER NUMBER/NUMBER/NUMBER NUMBER:NUMBER:NUMBER
+
+ Dates are always in GMT; first number is day of week; next is
+ year/month/day; next is hours:minutes:seconds on a 24-hour
+ clock. */
+
+TIME parse_date (cfile, bc)
+ FILE *cfile;
+ jmp_buf *bc;
+{
+ TIME t;
+ struct tm tm;
+ char *val;
+ int token;
+
+ /* Day of week... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric day of week expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_wday = atoi (token);
+
+ /* Year... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric year expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_year = atoi (token);
+ if (tm.tm_year > 1900)
+ tm.tm_year -= 1900;
+
+ /* Slash seperating year from month... */
+ token = next_token (&val, cfile);
+ if (token != SLASH) {
+ parse_warn ("expected slash seperating year from month.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Month... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric month expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_mon = atoi (token);
+
+ /* Slash seperating month from day... */
+ token = next_token (&val, cfile);
+ if (token != SLASH) {
+ parse_warn ("expected slash seperating month from day.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Month... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric day of month expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_mday = atoi (token);
+
+ /* Hour... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric hour expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_hour = atoi (token);
+
+ /* Colon seperating hour from minute... */
+ token = next_token (&val, cfile);
+ if (token != COLON) {
+ parse_warn ("expected colon seperating hour from minute.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Minute... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric minute expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_min = atoi (token);
+
+ /* Colon seperating minute from second... */
+ token = next_token (&val, cfile);
+ if (token != COLON) {
+ parse_warn ("expected colon seperating hour from minute.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+
+ /* Minute... */
+ token = next_token (&val, cfile);
+ if (token != NUMBER) {
+ parse_warn ("numeric minute expected.");
+ if (token != SEMI)
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ tm.tm_sec = atoi (token);
+
+ tm.tm_zone = "GMT";
+ tm.tm_isdst = 0;
+ tm.tm_gmtoff = 0;
+
+ /* XXX */ /* We assume that mktime does not use tm_yday. */
+ tm.tm_yday = 0;
+
+ return mktime (&tm);
+}
+
+/* No BNF for numeric aggregates - that's defined by the caller. What
+ this function does is to parse a sequence of numbers seperated by
+ the token specified in seperator. If max is zero, any number of
+ numbers will be parsed; otherwise, exactly max numbers are
+ expected. Base and size tell us how to internalize the numbers
+ once they've been tokenized. */
+
+unsigned char *parse_numeric_aggregate (cfile, bc, buf,
+ max, seperator, base, size)
+ FILE *cfile;
+ jmp_buf *bc;
+ unsigned char *buf;
+ int *max;
+ int seperator;
+ int base;
+ int size;
+{
+ char *val;
+ int token;
+ unsigned char *bufp = buf, *s, *t;
+ int count = 0;
+ pair c = (pair)0;
+
+ if (!bufp && *max) {
+ bufp = (unsigned char *)malloc (*max * size / 8);
+ if (!bufp)
+ error ("can't allocate space for numeric aggregate");
+ } else
+ s = bufp;
+
+ do {
+ if (count) {
+ token = peek_token (&val, cfile);
+ if (token != seperator) {
+ if (!*max)
+ break;
+ parse_warn ("too few numbers.");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ token = next_token (&val, cfile);
+ }
+ token = next_token (&val, cfile);
+ /* Allow NUMBER_OR_ATOM if base is 16. */
+ if (token != NUMBER &&
+ (base != 16 || token != NUMBER_OR_ATOM)) {
+ parse_warn ("expecting numeric value.");
+ skip_to_semi (cfile);
+ longjmp (*bc, 1);
+ }
+ /* If we can, convert the number now; otherwise, build
+ a linked list of all the numbers. */
+ if (s) {
+ convert_num (s, val, base, size);
+ s += size / 8;
+ } else {
+ t = (char *)malloc (strlen (val) + 1);
+ if (!t)
+ error ("no temp space for number.");
+ strcpy (t, val);
+ c = cons (t, c);
+ }
+ } while (++count != *max);
+
+ /* If we had to cons up a list, convert it now. */
+ if (c) {
+ bufp = (unsigned char *)malloc (count * size / 8);
+ if (!bufp)
+ error ("can't allocate space for numeric aggregate.");
+ s = bufp;
+ *max = count;
+ }
+ while (c) {
+ pair cdr = c -> cdr;
+ convert_num (s, (char *)(c -> car), base, size);
+ s += size / 8;
+ /* Free up temp space. */
+ free (c -> car);
+ free (c);
+ c = cdr;
+ }
+ return bufp;
+}
+
+void convert_num (buf, str, base, size)
+ unsigned char *buf;
+ char *str;
+ int base;
+ int size;
+{
+ char *ptr = str;
+ int negative = 0;
+ u_int32_t val = 0;
+ int tval;
+ int max;
+
+ if (*ptr == '-') {
+ negative = 1;
+ ++ptr;
+ }
+
+ /* If base wasn't specified, figure it out from the data. */
+ if (!base) {
+ if (ptr [0] == '0') {
+ if (ptr [1] == 'x') {
+ base = 16;
+ ptr += 2;
+ } else if (isascii (ptr [1]) && isdigit (ptr [1])) {
+ base = 8;
+ ptr += 1;
+ } else {
+ base = 10;
+ }
+ } else {
+ base = 10;
+ }
+ }
+
+ do {
+ tval = *ptr++;
+ /* XXX assumes ASCII... */
+ if (tval >= 'a')
+ tval = tval - 'a' + 10;
+ else if (tval >= 'A')
+ tval = tval - 'A' + 10;
+ else if (tval >= '0')
+ tval -= '0';
+ else {
+ warn ("Bogus number: %s.", str);
+ break;
+ }
+ if (tval >= base) {
+ warn ("Bogus number: %s: digit %d not in base %d\n",
+ str, tval, base);
+ break;
+ }
+ val = val * base + tval;
+ } while (*ptr);
+
+ if (negative)
+ max = (1 << (size - 1));
+ else
+ max = (1 << size) - 1;
+ if (val > max) {
+ switch (base) {
+ case 8:
+ warn ("value %s%lo exceeds max (%d) for precision.",
+ negative ? "-" : "", val, max);
+ break;
+ case 16:
+ warn ("value %s%lx exceeds max (%d) for precision.",
+ negative ? "-" : "", val, max);
+ break;
+ default:
+ warn ("value %s%ld exceeds max (%d) for precision.",
+ negative ? "-" : "", val, max);
+ break;
+ }
+ }
+
+ if (negative) {
+ switch (size) {
+ case 8:
+ *buf = -(unsigned long)val;
+ break;
+ case 16:
+ putShort (buf, -(unsigned long)val);
+ break;
+ case 32:
+ putLong (buf, -(unsigned long)val);
+ break;
+ default:
+ warn ("Unexpected integer size: %d\n");
+ break;
+ }
+ } else {
+ switch (size) {
+ case 8:
+ *buf = (u_int8_t)val;
+ break;
+ case 16:
+ putUShort (buf, (u_int16_t)val);
+ break;
+ case 32:
+ putULong (buf, val);
+ break;
+ default:
+ warn ("Unexpected integer size: %d\n");
+ break;
+ }
+ }
+}
--- /dev/null
+/* db.c
+
+ IP Address Allocation database... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+/*
+ The IP Address Allocation Database tracks addresses that have been
+ allocated from the free pool as specified in dhcpd.conf. The
+ database is maintained in two parts to maintain integrity: the
+ journal file and the data file.
+
+ Both files are free-form flat files similar to dhcpd.conf, but with
+ a more limited syntax - all that can be specified are leases and
+ who they belong to.
+
+ When dhcpd starts up, it reads the entire data file into memory.
+ It then reads the journal file into memory and makes corrections to
+ the data based on journal entries.
+
+ While dhcpd is running, it periodically records the current time,
+ forks (if possible) and dumps the recorded time and its internal
+ database of temporarily assigned addresses into a temporary file.
+ It then removes any existing backup file, renames the existing file
+ with the backup filename, and then renames the new temporary file
+ with the real data file name. The link syscall is not present on
+ most systems, so a synchronous ``rename'' that guarantees that
+ exactly one file will be the master database may not be possible.
+ Therefore the recovery routine needs to know what to do if it finds
+ a backup and a temporary file, but no database file.
+
+ Whenever a client requests that an address be allocated to it, or
+ requests a lease renewal, and the server is able to satisfy the
+ request, it writes a record into the journal file indicating what
+ has been requested and waits for that information to reach the
+ disk. Once the file's dirty buffers have been flushed, the server
+ responds to the request, and logs another record in the journal
+ indicating that it has done so.
+
+ Entries in the journal file are logged along with the time at which
+ the logging occurred. When the server forks to dump the database,
+ it records the current time before forking. The copy of the server
+ that writes out the database records the time read prior to forking
+ in the new data file. The copy of the server that continues to
+ serve DHCP requests ensures that any journal entries subsequent to
+ the fork have time stamps that are greater than the time read
+ before forking. When recovering from a crash, the server discards
+ any entries in the journal which have time stamps earlier than the
+ time stamp on the data file.
+
+ When recovering from a crash, dhcpd may find a journal entry for a
+ request, but no entry indicating that it was satisfied. There is
+ no automatic way to recover from this, since the server may have
+ sent out a response, so in this case the server must notify
+ sysadmin of the problem and leave it to them to solve it.
+
+ In addition to the actual data files, we also keep a running log of
+ ``interesting'' events, which we mail to the dhcp-admin alias every
+ morning at 7:00 AM. This log can be tailed by paranoid sysadmins
+ or in times of network trouble. */
+
+/* Initialize the internal database, perform crash recovery as needed. */
+
+void dbinit ()
+{
+ FILE *dbfile;
+
+ /* We are assuming that on entry, there is no other dhcpd
+ running on this machine. If there were, there would be the
+ potential for serious database corruption. The main code
+ currently assures that there is only one server running by
+ listening on the bootps port with INADDR_ANY. Unices that
+ I'm familiar with will only allow one process to do this,
+ even if the SO_REUSEADDR option is set. 'twouldn't surprise
+ me terribly, though, if this didn't work for some other
+ operating system. Beware. XXX */
+
+ /* Look for a file under the official database name.
+ Failing that, look for a file under the backup name.
+ If we find neither, we assume that the database is empty. */
+
+ if ((dbfile = fopen (_PATH_DHCP_DB, "r")) != NULL
+ (dbfile = fopen (_PATH_DHCP_DB_BACKUP, "r") != NULL)) {
+
+ /* Read in the data file, making a list of assigned
+ addresses that have been removed from dhcpd.conf. */
+
+ }
+
+ /* Open the journal file and read through any entries which
+ are out of date. */
+
+ /* Now read entries that postdate the last database sync,
+ keeping track of incomplete entries (when we're done, there
+ should never be more than one such entry. */
+
+ /* Now expire any leases that have lapsed since we last ran. */
+
+ /* ...and we're done... */
+}
--- /dev/null
+/* dhcp.c
+
+ DHCP Protocol support. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+void dhcp (packet)
+ struct packet *packet;
+{
+}
--- /dev/null
+/* dhcpd.c
+
+ DHCP Server Daemon. */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+static void usage PROTO ((void));
+
+TIME cur_time;
+
+u_int32_t *server_addrlist;
+int server_addrcount;
+u_int16_t server_port;
+
+int main (argc, argv, envp)
+ int argc;
+ char **argv, **envp;
+{
+ struct in_addr addr;
+ int port = 0;
+ int i;
+ struct sockaddr_in name;
+ u_int32_t *addrlist = (u_int32_t *)0;
+ int addrcount = 0;
+ struct tree *addrtree = (struct tree *)0;
+ struct servent *ent;
+ int sock;
+ int pid;
+ int result;
+ int flag;
+
+ openlog ("dhcpd", LOG_NDELAY, LOG_DAEMON);
+#ifndef DEBUG
+ setlogmask (LOG_UPTO (LOG_INFO));
+
+ /* Become a daemon... */
+ if ((pid = fork ()) < 0)
+ error ("Can't fork daemon: %m");
+ else if (pid)
+ exit (0);
+ /* Become session leader and get pid... */
+ pid = setsid ();
+#endif
+ for (i = 1; i < argc; i++) {
+ if (!strcmp (argv [i], "-p")) {
+ if (++i == argc)
+ usage ();
+ server_port = htons (atoi (argv [i]));
+ debug ("binding to user-specified port %d\n",
+ ntohs (server_port));
+#if 0
+ } else if (!strcmp (argv [i], "-a")) {
+ if (++i == argc)
+ usage ();
+ if (inet_aton (argv [i], &addr)) {
+ addrtree =
+ tree_concat (addrtree,
+ tree_const
+ ((unsigned char *)&addr,
+ sizeof addr));
+ } else {
+ addrtree = tree_concat (addrtree,
+ tree_host_lookup
+ (argv [i]));
+ }
+#endif
+ } else
+ usage ();
+ }
+
+ /* Default to the DHCP/BOOTP port. */
+ if (!server_port)
+ {
+ ent = getservbyname ("dhcp", "udp");
+ if (!ent)
+ server_port = htons (67);
+ else
+ server_port = ent -> s_port;
+ endservent ();
+ }
+
+ /* Get the current time... */
+ GET_TIME (&cur_time);
+
+ /* Read the dhcpd.conf file... */
+ readconf ();
+
+#if 0
+ /* If addresses were specified on the command line, resolve them;
+ otherwise, just get a list of the addresses that are configured
+ on this host and listen on all of them. */
+ if (addrtree) {
+ tree_evaluate ((unsigned char **)&addrlist,
+ &addrcount, addrtree);
+ addrcount /= 4;
+ if (!addrcount)
+ error ("Server addresses resolve to nothing.");
+ } else {
+/* addrlist = get_interface_list (&addrcount); */
+#endif
+ addr.s_addr = 0;
+ addrlist = (u_int32_t *)&(addr.s_addr);
+ addrcount = 1;
+#if 0
+ }
+#endif
+
+ server_addrlist = get_interface_list (&server_addrcount);
+
+ /* Listen on the specified (or default) port on each specified
+ (or default) IP address. */
+ for (i = 0; i < addrcount; i++) {
+ listen_on (server_port, addrlist [i]);
+ }
+
+ /* Write a pid file. */
+ if ((i = open (_PATH_DHCPD_PID, O_WRONLY | O_CREAT)) >= 0) {
+ char obuf [20];
+ sprintf (obuf, "%d\n", getpid ());
+ write (i, obuf, strlen (obuf));
+ close (i);
+ }
+
+ /* Receive packets and dispatch them... */
+ dispatch ();
+}
+
+/* Print usage message. */
+
+static void usage ()
+{
+ error ("Usage: dhcpd [-p <port>] [-a <ip-addr>]");
+}
+
+void cleanup ()
+{
+}
+
+void do_packet (packbuf, len, from, fromlen, sock)
+ unsigned char *packbuf;
+ int len;
+ struct sockaddr_in *from;
+ int fromlen;
+ int sock;
+{
+ struct packet *tp;
+ struct dhcp_packet *tdp;
+
+ if (!(tp = new_packet ("do_packet")))
+ return;
+ if (!(tdp = new_dhcp_packet ("do_packet"))) {
+ free_packet (tp, "do_packet");
+ return;
+ }
+ memcpy (tdp, packbuf, len);
+ memset (tp, 0, sizeof *tp);
+ tp -> raw = tdp;
+ tp -> packet_length = len;
+ tp -> client = *from;
+ tp -> client_len = fromlen;
+ tp -> client_sock = sock;
+ parse_options (tp);
+ if (tp -> options_valid &&
+ tp -> options [DHO_DHCP_MESSAGE_TYPE].data)
+ dhcp (tp);
+ else
+ bootp (tp);
+}
+
+dump_packet (tp)
+ struct packet *tp;
+{
+ struct dhcp_packet *tdp = tp -> raw;
+
+ debug ("op = %d htype = %d hlen = %d hops = %d",
+ tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops);
+ debug ("xid = %x secs = %d flags = %x",
+ tdp -> xid, tdp -> secs, tdp -> flags);
+ debug ("ciaddr = %s yiaddr = %s",
+ inet_ntoa (tdp -> ciaddr), inet_ntoa (tdp -> yiaddr));
+ debug ("siaddr = %s giaddr = %s",
+ inet_ntoa (tdp -> siaddr), inet_ntoa (tdp -> giaddr));
+ debug ("chaddr = %02.2x:%02.2x:%02.2x:%02.2x:%02.2x:%02.2x",
+ ((unsigned char *)(tdp -> chaddr)) [0],
+ ((unsigned char *)(tdp -> chaddr)) [1],
+ ((unsigned char *)(tdp -> chaddr)) [2],
+ ((unsigned char *)(tdp -> chaddr)) [3],
+ ((unsigned char *)(tdp -> chaddr)) [4],
+ ((unsigned char *)(tdp -> chaddr)) [5]);
+ if (tp -> options_valid) {
+ int i;
+
+ for (i = 0; i < 256; i++) {
+ if (tp -> options [i].data)
+ printf (" %s = %s\n",
+ dhcp_options [i].name,
+ pretty_print_option
+ (i, tp -> options [i].data,
+ tp -> options [i].len));
+ }
+ }
+}
+
+/* Based on the contents of packet, figure out which interface address
+ to use from server_addrlist. Currently just picks the first
+ interface. */
+
+u_int32_t pick_interface (packet)
+ struct packet *packet;
+{
+ if (server_addrlist)
+ return server_addrlist [0];
+ return 0;
+}
--- /dev/null
+host minuet
+ hardware ethernet 08:00:2b:35:0c:18
+ filename "/tftpboot/netbsd.minuet"
+ fixed-address minuet.fugue.com;
+
+host allegro
+ hardware ethernet 08:00:2b:1c:07:b6
+ filename "/tftpboot/netbsd.allegro"
+ fixed-address allegro.fugue.com;
+
+host fantasia
+ hardware ethernet 8:0:7:26:c0:a5
+ fixed-address fantasia.fugue.com
+ option routers prelude.fugue.com
+ option name-servers toccata.fugue.com, passacaglia.fugue.com
+ option domain-name "fugue.com";
+
--- /dev/null
+/* socket.c
+
+ BSD socket interface code... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+#include <sys/ioctl.h>
+
+/* List of sockets we're accepting packets on... */
+struct socklist {
+ struct socklist *next;
+ struct sockaddr_in addr;
+ int sock;
+} *sockets;
+
+/* Return the list of IP addresses associated with each network interface. */
+
+u_int32_t *get_interface_list (count)
+ int *count;
+{
+ u_int32_t *intbuf = (u_int32_t *)0;
+ static char buf [8192];
+ struct ifconf ic;
+ int i;
+ int sock;
+ int ifcount = 0;
+ int ifix = 0;
+
+ /* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
+ if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ error ("Can't create addrlist socket");
+
+ /* Get the interface configuration information... */
+ ic.ifc_len = sizeof buf;
+ ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
+ i = ioctl(sock, SIOCGIFCONF, &ic);
+ close (sock);
+ if (i < 0)
+ error ("ioctl: SIOCGIFCONF: %m");
+
+ again:
+ /* Cycle through the list of interfaces looking for IP addresses.
+ Go through twice; once to count the number if addresses, and a
+ second time to copy them into an array of addresses. */
+ for (i = 0; i < ic.ifc_len;) {
+ struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
+ i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
+ if (ifp -> ifr_addr.sa_family == AF_INET) {
+ struct sockaddr_in *foo =
+ (struct sockaddr_in *)(&ifp -> ifr_addr);
+ /* We don't want the loopback interface. */
+ if (foo -> sin_addr.s_addr == INADDR_LOOPBACK)
+ continue;
+ if (intbuf)
+ intbuf [ifix++] = foo -> sin_addr.s_addr;
+ else
+ ++ifcount;
+ }
+ }
+ /* If we haven't already filled our array, allocate it and go
+ again. */
+ if (!intbuf) {
+ intbuf = (u_int32_t *)dmalloc ((ifcount + 1)
+ * sizeof (u_int32_t),
+ "get_interface_list");
+ if (!intbuf)
+ return intbuf;
+ goto again;
+ }
+ *count = ifcount;
+ return intbuf;
+}
+
+void listen_on (port, address)
+ u_int16_t port;
+ u_int32_t address;
+{
+ struct sockaddr_in name;
+ int sock;
+ struct socklist *tmp;
+ int flag;
+
+ name.sin_family = AF_INET;
+ name.sin_port = port;
+ name.sin_addr.s_addr = address;
+ memset (name.sin_zero, 0, sizeof (name.sin_zero));
+
+ /* List addresses on which we're listening. */
+ note ("Receiving on %s, port %d",
+ inet_ntoa (name.sin_addr), htons (name.sin_port));
+ if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ error ("Can't create dhcp socket: %m");
+
+ flag = 1;
+ if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
+ &flag, sizeof flag) < 0)
+ error ("Can't set SO_REUSEADDR option on dhcp socket: %m");
+
+ if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
+ &flag, sizeof flag) < 0)
+ error ("Can't set SO_BROADCAST option on dhcp socket: %m");
+
+ if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
+ error ("Can't bind to dhcp address: %m");
+
+ tmp = (struct socklist *)dmalloc (sizeof (struct socklist),
+ "listen_on");
+ if (!tmp)
+ error ("Can't allocate memory for socket list.");
+ tmp -> addr = name;
+ tmp -> sock = sock;
+ tmp -> next = sockets;
+ sockets = tmp;
+}
+
+unsigned char packbuf [65536]; /* Should cover the gnarliest MTU... */
+
+void dispatch ()
+{
+ struct sockaddr_in from;
+ int fromlen = sizeof from;
+ fd_set r, w, x;
+ struct socklist *l;
+ int max = 0;
+ int count;
+ int result;
+
+ FD_ZERO (&r);
+ FD_ZERO (&w);
+ FD_ZERO (&x);
+
+ do {
+ /* Set up the read mask. */
+ for (l = sockets; l; l = l -> next) {
+ FD_SET (l -> sock, &r);
+ FD_SET (l -> sock, &x);
+ if (l -> sock > max)
+ max = l -> sock;
+ }
+
+ /* Wait for a packet or a timeout... XXX */
+ count = select (max + 1, &r, &w, &x, (struct timeval *)0);
+
+ /* Not likely to be transitory... */
+ if (count < 0)
+ error ("select: %m");
+
+ for (l = sockets; l; l = l -> next) {
+ if (!FD_ISSET (l -> sock, &r))
+ continue;
+ if ((result =
+ recvfrom (l -> sock, packbuf, sizeof packbuf, 0,
+ (struct sockaddr *)&from, &fromlen))
+ < 0) {
+ warn ("recvfrom failed on %s: %m",
+ inet_ntoa (l -> addr.sin_addr));
+ sleep (5);
+ continue;
+ }
+ note ("request from %s, port %d",
+ inet_ntoa (from.sin_addr),
+ htons (from.sin_port));
+ do_packet (packbuf, result, &from, fromlen, l -> sock);
+ }
+ } while (1);
+}
+
--- /dev/null
+/* tables.c
+
+ Tables of information... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+/* DHCP Option names, formats and codes, from RFC1533.
+
+ Format codes:
+
+ e - end of data
+ I - IP address
+ l - 32-bit signed integer
+ L - 32-bit unsigned integer
+ s - 16-bit signed integer
+ S - 16-bit unsigned integer
+ b - 8-bit signed integer
+ B - 8-bit unsigned integer
+ t - ASCII text
+ f - flag (true or false)
+ A - array of whatever precedes (e.g., IA means array of IP addresses)
+*/
+
+struct universe dhcp_universe;
+struct option dhcp_options [256] = {
+ "pad", "", &dhcp_universe, 0,
+ "subnet-mask", "I", &dhcp_universe, 1,
+ "time-offset", "l", &dhcp_universe, 2,
+ "routers", "IA", &dhcp_universe, 3,
+ "time-servers", "IA", &dhcp_universe, 4,
+ "name-servers", "IA", &dhcp_universe, 5,
+ "domain-name-servers", "IA", &dhcp_universe, 6,
+ "log-servers", "IA", &dhcp_universe, 7,
+ "cookie-servers", "IA", &dhcp_universe, 8,
+ "lpr-servers", "IA", &dhcp_universe, 9,
+ "impress-servers", "IA", &dhcp_universe, 10,
+ "resource-location-servers", "IA", &dhcp_universe, 11,
+ "host-name", "t", &dhcp_universe, 12,
+ "boot-size", "S", &dhcp_universe, 13,
+ "merit-dump", "t", &dhcp_universe, 14,
+ "domain-name", "t", &dhcp_universe, 15,
+ "swap-server", "I", &dhcp_universe, 16,
+ "root-path", "t", &dhcp_universe, 17,
+ "extensions-path", "t", &dhcp_universe, 18,
+ "ip-forwarding", "f", &dhcp_universe, 19,
+ "non-local-source-routing", "f", &dhcp_universe, 20,
+ "policy-filter", "IIA", &dhcp_universe, 21,
+ "max-dgram-reassembly", "S", &dhcp_universe, 22,
+ "default-ip-ttl", "B", &dhcp_universe, 23,
+ "path-mtu-aging-timeout", "L", &dhcp_universe, 24,
+ "path-mtu-plateau-table", "SA", &dhcp_universe, 25,
+ "interface-mtu", "S", &dhcp_universe, 26,
+ "all-subnets-local", "f", &dhcp_universe, 27,
+ "broadcast-address", "I", &dhcp_universe, 28,
+ "perform-mask-discovery", "f", &dhcp_universe, 29,
+ "mask-supplier", "f", &dhcp_universe, 30,
+ "router-discovery", "f", &dhcp_universe, 31,
+ "router-solicitation-address", "I", &dhcp_universe, 32,
+ "static-routes", "IIA", &dhcp_universe, 33,
+ "trailer-encapsulation", "f", &dhcp_universe, 34,
+ "arp-cache-timeout", "L", &dhcp_universe, 35,
+ "ieee802.3-encapsulation", "f", &dhcp_universe, 36,
+ "default-tcp-ttl", "B", &dhcp_universe, 37,
+ "tcp-keepalive-interval", "L", &dhcp_universe, 38,
+ "tcp-keepalive-garbage", "f", &dhcp_universe, 39,
+ "nis-domain", "t", &dhcp_universe, 40,
+ "nis-servers", "IA", &dhcp_universe, 41,
+ "ntp-servers", "IA", &dhcp_universe, 42,
+ "vendor-encapsulated-options", "t", &dhcp_universe, 43,
+ "netbios-name-servers", "IA", &dhcp_universe, 44,
+ "netbios-dd-server", "IA", &dhcp_universe, 45,
+ "netbios-node-type", "B", &dhcp_universe, 46,
+ "netbios-scope", "t", &dhcp_universe, 47,
+ "font-servers", "IA", &dhcp_universe, 48,
+ "x-display-manager", "IA", &dhcp_universe, 49,
+ "dhcp-requested-address", "I", &dhcp_universe, 50,
+ "dhcp-lease-time", "L", &dhcp_universe, 51,
+ "dhcp-option-overload", "B", &dhcp_universe, 52,
+ "dhcp-message-type", "B", &dhcp_universe, 53,
+ "dhcp-server-identifier", "I", &dhcp_universe, 54,
+ "dhcp-parameter-request-list", "BA", &dhcp_universe, 55,
+ "dhcp-message", "t", &dhcp_universe, 56,
+ "dhcp-max-message-size", "S", &dhcp_universe, 57,
+ "dhcp-renewal-time", "L", &dhcp_universe, 58,
+ "dhcp-rebinding-time", "L", &dhcp_universe, 59,
+ "dhcp-class-identifier", "t", &dhcp_universe, 60,
+ "dhcp-client-identifier", "t", &dhcp_universe, 61,
+ "option-62", "", &dhcp_universe, 62,
+ "option-63", "", &dhcp_universe, 63,
+ "option-64", "", &dhcp_universe, 64,
+ "option-65", "", &dhcp_universe, 65,
+ "option-66", "", &dhcp_universe, 66,
+ "option-67", "", &dhcp_universe, 67,
+ "option-68", "", &dhcp_universe, 68,
+ "option-69", "", &dhcp_universe, 69,
+ "option-70", "", &dhcp_universe, 70,
+ "option-71", "", &dhcp_universe, 71,
+ "option-72", "", &dhcp_universe, 72,
+ "option-73", "", &dhcp_universe, 73,
+ "option-74", "", &dhcp_universe, 74,
+ "option-75", "", &dhcp_universe, 75,
+ "option-76", "", &dhcp_universe, 76,
+ "option-77", "", &dhcp_universe, 77,
+ "option-78", "", &dhcp_universe, 78,
+ "option-79", "", &dhcp_universe, 79,
+ "option-80", "", &dhcp_universe, 80,
+ "option-81", "", &dhcp_universe, 81,
+ "option-82", "", &dhcp_universe, 82,
+ "option-83", "", &dhcp_universe, 83,
+ "option-84", "", &dhcp_universe, 84,
+ "option-85", "", &dhcp_universe, 85,
+ "option-86", "", &dhcp_universe, 86,
+ "option-87", "", &dhcp_universe, 87,
+ "option-88", "", &dhcp_universe, 88,
+ "option-89", "", &dhcp_universe, 89,
+ "option-90", "", &dhcp_universe, 90,
+ "option-91", "", &dhcp_universe, 91,
+ "option-92", "", &dhcp_universe, 92,
+ "option-93", "", &dhcp_universe, 93,
+ "option-94", "", &dhcp_universe, 94,
+ "option-95", "", &dhcp_universe, 95,
+ "option-96", "", &dhcp_universe, 96,
+ "option-97", "", &dhcp_universe, 97,
+ "option-98", "", &dhcp_universe, 98,
+ "option-99", "", &dhcp_universe, 99,
+ "option-100", "", &dhcp_universe, 100,
+ "option-101", "", &dhcp_universe, 101,
+ "option-102", "", &dhcp_universe, 102,
+ "option-103", "", &dhcp_universe, 103,
+ "option-104", "", &dhcp_universe, 104,
+ "option-105", "", &dhcp_universe, 105,
+ "option-106", "", &dhcp_universe, 106,
+ "option-107", "", &dhcp_universe, 107,
+ "option-108", "", &dhcp_universe, 108,
+ "option-109", "", &dhcp_universe, 109,
+ "option-110", "", &dhcp_universe, 110,
+ "option-111", "", &dhcp_universe, 111,
+ "option-112", "", &dhcp_universe, 112,
+ "option-113", "", &dhcp_universe, 113,
+ "option-114", "", &dhcp_universe, 114,
+ "option-115", "", &dhcp_universe, 115,
+ "option-116", "", &dhcp_universe, 116,
+ "option-117", "", &dhcp_universe, 117,
+ "option-118", "", &dhcp_universe, 118,
+ "option-119", "", &dhcp_universe, 119,
+ "option-120", "", &dhcp_universe, 120,
+ "option-121", "", &dhcp_universe, 121,
+ "option-122", "", &dhcp_universe, 122,
+ "option-123", "", &dhcp_universe, 123,
+ "option-124", "", &dhcp_universe, 124,
+ "option-125", "", &dhcp_universe, 125,
+ "option-126", "", &dhcp_universe, 126,
+ "option-127", "", &dhcp_universe, 127,
+ "option-128", "", &dhcp_universe, 128,
+ "option-129", "", &dhcp_universe, 129,
+ "option-130", "", &dhcp_universe, 130,
+ "option-131", "", &dhcp_universe, 131,
+ "option-132", "", &dhcp_universe, 132,
+ "option-133", "", &dhcp_universe, 133,
+ "option-134", "", &dhcp_universe, 134,
+ "option-135", "", &dhcp_universe, 135,
+ "option-136", "", &dhcp_universe, 136,
+ "option-137", "", &dhcp_universe, 137,
+ "option-138", "", &dhcp_universe, 138,
+ "option-139", "", &dhcp_universe, 139,
+ "option-140", "", &dhcp_universe, 140,
+ "option-141", "", &dhcp_universe, 141,
+ "option-142", "", &dhcp_universe, 142,
+ "option-143", "", &dhcp_universe, 143,
+ "option-144", "", &dhcp_universe, 144,
+ "option-145", "", &dhcp_universe, 145,
+ "option-146", "", &dhcp_universe, 146,
+ "option-147", "", &dhcp_universe, 147,
+ "option-148", "", &dhcp_universe, 148,
+ "option-149", "", &dhcp_universe, 149,
+ "option-150", "", &dhcp_universe, 150,
+ "option-151", "", &dhcp_universe, 151,
+ "option-152", "", &dhcp_universe, 152,
+ "option-153", "", &dhcp_universe, 153,
+ "option-154", "", &dhcp_universe, 154,
+ "option-155", "", &dhcp_universe, 155,
+ "option-156", "", &dhcp_universe, 156,
+ "option-157", "", &dhcp_universe, 157,
+ "option-158", "", &dhcp_universe, 158,
+ "option-159", "", &dhcp_universe, 159,
+ "option-160", "", &dhcp_universe, 160,
+ "option-161", "", &dhcp_universe, 161,
+ "option-162", "", &dhcp_universe, 162,
+ "option-163", "", &dhcp_universe, 163,
+ "option-164", "", &dhcp_universe, 164,
+ "option-165", "", &dhcp_universe, 165,
+ "option-166", "", &dhcp_universe, 166,
+ "option-167", "", &dhcp_universe, 167,
+ "option-168", "", &dhcp_universe, 168,
+ "option-169", "", &dhcp_universe, 169,
+ "option-170", "", &dhcp_universe, 170,
+ "option-171", "", &dhcp_universe, 171,
+ "option-172", "", &dhcp_universe, 172,
+ "option-173", "", &dhcp_universe, 173,
+ "option-174", "", &dhcp_universe, 174,
+ "option-175", "", &dhcp_universe, 175,
+ "option-176", "", &dhcp_universe, 176,
+ "option-177", "", &dhcp_universe, 177,
+ "option-178", "", &dhcp_universe, 178,
+ "option-179", "", &dhcp_universe, 179,
+ "option-180", "", &dhcp_universe, 180,
+ "option-181", "", &dhcp_universe, 181,
+ "option-182", "", &dhcp_universe, 182,
+ "option-183", "", &dhcp_universe, 183,
+ "option-184", "", &dhcp_universe, 184,
+ "option-185", "", &dhcp_universe, 185,
+ "option-186", "", &dhcp_universe, 186,
+ "option-187", "", &dhcp_universe, 187,
+ "option-188", "", &dhcp_universe, 188,
+ "option-189", "", &dhcp_universe, 189,
+ "option-190", "", &dhcp_universe, 190,
+ "option-191", "", &dhcp_universe, 191,
+ "option-192", "", &dhcp_universe, 192,
+ "option-193", "", &dhcp_universe, 193,
+ "option-194", "", &dhcp_universe, 194,
+ "option-195", "", &dhcp_universe, 195,
+ "option-196", "", &dhcp_universe, 196,
+ "option-197", "", &dhcp_universe, 197,
+ "option-198", "", &dhcp_universe, 198,
+ "option-199", "", &dhcp_universe, 199,
+ "option-200", "", &dhcp_universe, 200,
+ "option-201", "", &dhcp_universe, 201,
+ "option-202", "", &dhcp_universe, 202,
+ "option-203", "", &dhcp_universe, 203,
+ "option-204", "", &dhcp_universe, 204,
+ "option-205", "", &dhcp_universe, 205,
+ "option-206", "", &dhcp_universe, 206,
+ "option-207", "", &dhcp_universe, 207,
+ "option-208", "", &dhcp_universe, 208,
+ "option-209", "", &dhcp_universe, 209,
+ "option-210", "", &dhcp_universe, 210,
+ "option-211", "", &dhcp_universe, 211,
+ "option-212", "", &dhcp_universe, 212,
+ "option-213", "", &dhcp_universe, 213,
+ "option-214", "", &dhcp_universe, 214,
+ "option-215", "", &dhcp_universe, 215,
+ "option-216", "", &dhcp_universe, 216,
+ "option-217", "", &dhcp_universe, 217,
+ "option-218", "", &dhcp_universe, 218,
+ "option-219", "", &dhcp_universe, 219,
+ "option-220", "", &dhcp_universe, 220,
+ "option-221", "", &dhcp_universe, 221,
+ "option-222", "", &dhcp_universe, 222,
+ "option-223", "", &dhcp_universe, 223,
+ "option-224", "", &dhcp_universe, 224,
+ "option-225", "", &dhcp_universe, 225,
+ "option-226", "", &dhcp_universe, 226,
+ "option-227", "", &dhcp_universe, 227,
+ "option-228", "", &dhcp_universe, 228,
+ "option-229", "", &dhcp_universe, 229,
+ "option-230", "", &dhcp_universe, 230,
+ "option-231", "", &dhcp_universe, 231,
+ "option-232", "", &dhcp_universe, 232,
+ "option-233", "", &dhcp_universe, 233,
+ "option-234", "", &dhcp_universe, 234,
+ "option-235", "", &dhcp_universe, 235,
+ "option-236", "", &dhcp_universe, 236,
+ "option-237", "", &dhcp_universe, 237,
+ "option-238", "", &dhcp_universe, 238,
+ "option-239", "", &dhcp_universe, 239,
+ "option-240", "", &dhcp_universe, 240,
+ "option-241", "", &dhcp_universe, 241,
+ "option-242", "", &dhcp_universe, 242,
+ "option-243", "", &dhcp_universe, 243,
+ "option-244", "", &dhcp_universe, 244,
+ "option-245", "", &dhcp_universe, 245,
+ "option-246", "", &dhcp_universe, 246,
+ "option-247", "", &dhcp_universe, 247,
+ "option-248", "", &dhcp_universe, 248,
+ "option-249", "", &dhcp_universe, 249,
+ "option-250", "", &dhcp_universe, 250,
+ "option-251", "", &dhcp_universe, 251,
+ "option-252", "", &dhcp_universe, 252,
+ "option-253", "", &dhcp_universe, 253,
+ "option-254", "", &dhcp_universe, 254,
+ "option-end", "e", &dhcp_universe, 255,
+};
+
+/* Default dhcp option priority list (this is ad hoc and should not be
+ mistaken for a carefully crafted and optimized list). */
+unsigned char dhcp_option_default_priority_list [] = {
+ DHO_SUBNET_MASK,
+ DHO_TIME_OFFSET,
+ DHO_ROUTERS,
+ DHO_TIME_SERVERS,
+ DHO_NAME_SERVERS,
+ DHO_DOMAIN_NAME_SERVERS,
+ DHO_LOG_SERVERS,
+ DHO_COOKIE_SERVERS,
+ DHO_LPR_SERVERS,
+ DHO_IMPRESS_SERVERS,
+ DHO_RESOURCE_LOCATION_SERVERS,
+ DHO_HOST_NAME,
+ DHO_BOOT_SIZE,
+ DHO_MERIT_DUMP,
+ DHO_DOMAIN_NAME,
+ DHO_SWAP_SERVER,
+ DHO_ROOT_PATH,
+ DHO_EXTENSIONS_PATH,
+ DHO_IP_FORWARDING,
+ DHO_NON_LOCAL_SOURCE_ROUTING,
+ DHO_POLICY_FILTER,
+ DHO_MAX_DGRAM_REASSEMBLY,
+ DHO_DEFAULT_IP_TTL,
+ DHO_PATH_MTU_AGING_TIMEOUT,
+ DHO_PATH_MTU_PLATEAU_TABLE,
+ DHO_INTERFACE_MTU,
+ DHO_ALL_SUBNETS_LOCAL,
+ DHO_BROADCAST_ADDRESS,
+ DHO_PERFORM_MASK_DISCOVERY,
+ DHO_MASK_SUPPLIER,
+ DHO_ROUTER_DISCOVERY,
+ DHO_ROUTER_SOLICITATION_ADDRESS,
+ DHO_STATIC_ROUTES,
+ DHO_TRAILER_ENCAPSULATION,
+ DHO_ARP_CACHE_TIMEOUT,
+ DHO_IEEE802_3_ENCAPSULATION,
+ DHO_DEFAULT_TCP_TTL,
+ DHO_TCP_KEEPALIVE_INTERVAL,
+ DHO_TCP_KEEPALIVE_GARBAGE,
+ DHO_NIS_DOMAIN,
+ DHO_NIS_SERVERS,
+ DHO_NTP_SERVERS,
+ DHO_VENDOR_ENCAPSULATED_OPTIONS,
+ DHO_NETBIOS_NAME_SERVERS,
+ DHO_NETBIOS_DD_SERVER,
+ DHO_NETBIOS_NODE_TYPE,
+ DHO_NETBIOS_SCOPE,
+ DHO_FONT_SERVERS,
+ DHO_X_DISPLAY_MANAGER,
+ DHO_DHCP_REQUESTED_ADDRESS,
+ DHO_DHCP_LEASE_TIME,
+ DHO_DHCP_OPTION_OVERLOAD,
+ DHO_DHCP_MESSAGE_TYPE,
+ DHO_DHCP_SERVER_IDENTIFIER,
+ DHO_DHCP_PARAMETER_REQUEST_LIST,
+ DHO_DHCP_MESSAGE,
+ DHO_DHCP_MAX_MESSAGE_SIZE,
+ DHO_DHCP_RENEWAL_TIME,
+ DHO_DHCP_REBINDING_TIME,
+ DHO_DHCP_CLASS_IDENTIFIER,
+ DHO_DHCP_CLIENT_IDENTIFIER,
+};
+
+int sizeof_dhcp_option_default_priority_list =
+ sizeof dhcp_option_default_priority_list;
+
+
+struct hash_table universe_hash;
+
+void initialize_universes()
+{
+ int i;
+
+ dhcp_universe.name = "dhcp";
+ dhcp_universe.hash = new_hash ();
+ if (!dhcp_universe.hash)
+ error ("Can't allocate dhcp option hash table.");
+ for (i = 0; i < 256; i++) {
+ dhcp_universe.options [i] = &dhcp_options [i];
+ add_hash (dhcp_universe.hash, dhcp_options [i].name, 0,
+ (unsigned char *)&dhcp_options [i]);
+ }
+ universe_hash.hash_count = DEFAULT_HASH_SIZE;
+ add_hash (&universe_hash, dhcp_universe.name, 0,
+ (unsigned char *)&dhcp_universe);
+}
--- /dev/null
+/* tree.c
+
+ Routines for manipulating parse trees... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+static TIME tree_evaluate_recurse PROTO ((int *, unsigned char **, int *,
+ struct tree *));
+static TIME do_host_lookup PROTO ((int *, unsigned char **, int *,
+ struct dns_host_entry *));
+static void do_data_copy PROTO ((int *, unsigned char **, int *,
+ unsigned char *, int));
+
+pair cons (car, cdr)
+ caddr_t car;
+ pair cdr;
+{
+ pair foo = (pair)dmalloc (sizeof *foo, "cons");
+ if (!foo)
+ error ("no memory for cons.");
+ foo -> car = car;
+ foo -> cdr = cdr;
+ return foo;
+}
+
+struct tree_cache *tree_cache (tree)
+ struct tree *tree;
+{
+ struct tree_cache *tc;
+
+ tc = new_tree_cache ("tree_cache");
+ if (!tc)
+ return 0;
+ tc -> value = (char *)0;
+ tc -> len = tc -> buf_size = 0;
+ tc -> timeout = 0;
+ tc -> tree = tree;
+ return tc;
+}
+
+struct tree *tree_host_lookup (name)
+ char *name;
+{
+ struct tree *nt;
+ nt = new_tree ("tree_host_lookup");
+ if (!nt)
+ error ("No memory for host lookup tree node.");
+ nt -> op = TREE_HOST_LOOKUP;
+ nt -> data.host_lookup.host = enter_dns_host (name);
+ return nt;
+}
+
+struct dns_host_entry *enter_dns_host (name)
+ char *name;
+{
+ struct dns_host_entry *dh;
+
+ if (!(dh = (struct dns_host_entry *)dmalloc
+ (sizeof (struct dns_host_entry), "enter_dns_host"))
+ || !(dh -> hostname = dmalloc (strlen (name) + 1,
+ "enter_dns_host")))
+ error ("Can't allocate space for new host.");
+ strcpy (dh -> hostname, name);
+ dh -> data = (unsigned char *)0;
+ dh -> data_len = 0;
+ dh -> timeout = 0;
+ return dh;
+}
+
+struct tree *tree_const (data, len)
+ unsigned char *data;
+ int len;
+{
+ struct tree *nt;
+ if (!(nt = new_tree ("tree_const"))
+ || !(nt -> data.const_val.data =
+ (unsigned char *)dmalloc (len, "tree_const")))
+ error ("No memory for constant data tree node.");
+ nt -> op = TREE_CONST;
+ memcpy (nt -> data.const_val.data, data, len);
+ nt -> data.const_val.len = len;
+ return nt;
+}
+
+struct tree *tree_concat (left, right)
+ struct tree *left, *right;
+{
+ struct tree *nt;
+
+ /* If we're concatenating a null tree to a non-null tree, just
+ return the non-null tree; if both trees are null, return
+ a null tree. */
+ if (!left)
+ return right;
+ if (!right)
+ return left;
+
+ /* If both trees are constant, combine them. */
+ if (left -> op = TREE_CONST && right -> op == TREE_CONST) {
+ unsigned char *buf = dmalloc (left -> data.const_val.len
+ + right -> data.const_val.len,
+ "tree_concat");
+ if (!buf)
+ error ("No memory to concatenate constants.");
+ memcpy (buf, left -> data.const_val.data,
+ left -> data.const_val.len);
+ memcpy (buf + left -> data.const_val.len,
+ right -> data.const_val.data,
+ right -> data.const_val.len);
+ dfree (left -> data.const_val.data, "tree_concat");
+ dfree (right -> data.const_val.data, "tree_concat");
+ left -> data.const_val.data = buf;
+ left -> data.const_val.len += right -> data.const_val.len;
+ free_tree (right, "tree_concat");
+ return left;
+ }
+
+ /* Otherwise, allocate a new node to concatenate the two. */
+ if (!(nt = new_tree ("tree_concat")))
+ error ("No memory for data tree concatenation node.");
+ nt -> op = TREE_CONCAT;
+ nt -> data.concat.left = left;
+ nt -> data.concat.right = right;
+ return nt;
+}
+
+struct tree *tree_limit (tree, limit)
+ struct tree *tree;
+ int limit;
+{
+ struct tree *rv;
+
+ /* If the tree we're limiting is constant, limit it now. */
+ if (tree -> op == TREE_CONST) {
+ if (tree -> data.const_val.len > limit)
+ tree -> data.const_val.len = limit;
+ return tree;
+ }
+
+ /* Otherwise, put in a node which enforces the limit on evaluation. */
+ rv = new_tree ("tree_limit");
+ if (!rv)
+ return (struct tree *)0;
+ rv -> op = TREE_LIMIT;
+ rv -> data.limit.tree = tree;
+ rv -> data.limit.limit = limit;
+ return rv;
+}
+
+int tree_evaluate (tree_cache)
+ struct tree_cache *tree_cache;
+{
+ unsigned char *bp = tree_cache -> value;
+ int bc = tree_cache -> buf_size;
+ int bufix = 0;
+
+ /* If there's no tree associated with this cache, it evaluates
+ to a constant and that was detected at startup. */
+ if (!tree_cache -> tree)
+ return 1;
+
+ /* Try to evaluate the tree without allocating more memory... */
+ tree_cache -> timeout = tree_evaluate_recurse (&bufix, &bp, &bc,
+ tree_cache -> tree);
+
+ /* No additional allocation needed? */
+ if (bufix <= bc) {
+ tree_cache -> len = bufix;
+ return 1;
+ }
+
+ /* If we can't allocate more memory, return with what we
+ have (maybe nothing). */
+ if (!(bp = (unsigned char *)dmalloc (bufix, "tree_evaluate")))
+ return 0;
+
+ /* Record the change in conditions... */
+ bc = bufix;
+ bufix = 0;
+
+ /* Note that the size of the result shouldn't change on the
+ second call to tree_evaluate_recurse, since we haven't
+ changed the ``current'' time. */
+ tree_evaluate_recurse (&bufix, &bp, &bc, tree_cache -> tree);
+
+ /* Free the old buffer if needed, then store the new buffer
+ location and size and return. */
+ if (tree_cache -> value)
+ dfree (tree_cache -> value, "tree_evaluate");
+ tree_cache -> value = bp;
+ tree_cache -> len = bufix;
+ tree_cache -> buf_size = bc;
+ return 1;
+}
+
+static TIME tree_evaluate_recurse (bufix, bufp, bufcount, tree)
+ int *bufix;
+ unsigned char **bufp;
+ int *bufcount;
+ struct tree *tree;
+{
+ int limit;
+ TIME t1, t2;
+
+ switch (tree -> op) {
+ case TREE_CONCAT:
+ t1 = tree_evaluate_recurse (bufix, bufp, bufcount,
+ tree -> data.concat.left);
+ t2 = tree_evaluate_recurse (bufix, bufp, bufcount,
+ tree -> data.concat.right);
+ if (t1 > t2)
+ return t2;
+ return t1;
+
+ case TREE_HOST_LOOKUP:
+ return do_host_lookup (bufix, bufp, bufcount,
+ tree -> data.host_lookup.host);
+
+ case TREE_CONST:
+ do_data_copy (bufix, bufp, bufcount,
+ tree -> data.const_val.data,
+ tree -> data.const_val.len);
+ t1 = MAX_TIME;
+ return t1;
+
+ case TREE_LIMIT:
+ limit = *bufix + tree -> data.limit.limit;
+ t1 = tree_evaluate_recurse (bufix, bufp, bufcount,
+ tree -> data.limit.tree);
+ *bufix = limit;
+ return t1;
+
+ default:
+ warn ("Bad node id in tree: %d.");
+ t1 = MAX_TIME;
+ return t1;
+ }
+}
+
+static TIME do_host_lookup (bufix, bufp, bufcount, dns)
+ int *bufix;
+ unsigned char **bufp;
+ int *bufcount;
+ struct dns_host_entry *dns;
+{
+ struct hostent *h;
+ int i;
+ int new_len;
+
+ debug ("time: now = %d dns = %d %d diff = %d",
+ cur_time, dns -> timeout, cur_time - dns -> timeout);
+
+ /* If the record hasn't timed out, just copy the data and return. */
+ if (cur_time <= dns -> timeout) {
+ debug ("easy copy: %x %d %x",
+ dns -> data, dns -> data_len, *(int *)(dns -> data));
+ do_data_copy (bufix, bufp, bufcount,
+ dns -> data, dns -> data_len);
+ return dns -> timeout;
+ }
+ debug ("Looking up %s", dns -> hostname);
+
+ /* Otherwise, look it up... */
+ h = gethostbyname (dns -> hostname);
+ if (!h) {
+ switch (h_errno) {
+ case HOST_NOT_FOUND:
+ warn ("%s: host unknown.", dns -> hostname);
+ break;
+ case TRY_AGAIN:
+ warn ("%s: temporary name server failure",
+ dns -> hostname);
+ break;
+ case NO_RECOVERY:
+ warn ("%s: name server failed", dns -> hostname);
+ break;
+ case NO_DATA:
+ warn ("%s: no A record associated with address",
+ dns -> hostname);
+ }
+
+ /* Okay to try again after a minute. */
+ return cur_time + 60;
+ }
+
+ debug ("Lookup succeeded; first address is %x",
+ h -> h_addr_list [0]);
+
+ /* Count the number of addresses we got... */
+ for (i = 0; h -> h_addr_list [i]; i++)
+ ;
+
+ /* Do we need to allocate more memory? */
+ new_len = i * h -> h_length;
+ if (dns -> buf_len < i) {
+ unsigned char *buf =
+ (unsigned char *)dmalloc (new_len, "do_host_lookup");
+ /* If we didn't get more memory, use what we have. */
+ if (!buf) {
+ new_len = dns -> buf_len;
+ if (!dns -> buf_len) {
+ dns -> timeout = cur_time + 60;
+ return dns -> timeout;
+ }
+ } else {
+ dfree (dns -> data, "do_host_lookup");
+ dns -> data = buf;
+ dns -> buf_len = new_len;
+ }
+ }
+
+ /* Addresses are conveniently stored one to the buffer, so we
+ have to copy them out one at a time... :'( */
+ for (i = 0; i < new_len / h -> h_length; i++)
+ memcpy (dns -> data + h -> h_length * i,
+ h -> h_addr_list [i], h -> h_length);
+ debug ("dns -> data: %x h -> h_addr_list [0]: %x",
+ *(int *)(dns -> data), h -> h_addr_list [0]);
+ dns -> data_len = new_len;
+
+ /* Set the timeout for an hour from now.
+ XXX This should really use the time on the DNS reply. */
+ dns -> timeout = cur_time + 3600;
+
+ debug ("hard copy: %x %d %x",
+ dns -> data, dns -> data_len, *(int *)(dns -> data));
+ do_data_copy (bufix, bufp, bufcount, dns -> data, dns -> data_len);
+ return dns -> timeout;
+}
+
+static void do_data_copy (bufix, bufp, bufcount, data, len)
+ int *bufix;
+ unsigned char **bufp;
+ int *bufcount;
+ unsigned char *data;
+ int len;
+{
+ int space = *bufcount - *bufix;
+
+ /* If there's more space than we need, use only what we need. */
+ if (space > len)
+ space = len;
+
+ /* Copy as much data as will fit, then increment the buffer index
+ by the amount we actually had to copy, which could be more. */
+ if (space > 0)
+ memcpy (*bufp + *bufix, data, space);
+ *bufix += len;
+}
--- /dev/null
+/* tree.h
+
+ Definitions for address trees... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+/* A pair of pointers, suitable for making a linked list. */
+typedef struct _pair {
+ caddr_t car;
+ struct _pair *cdr;
+} *pair;
+
+/* Tree node types... */
+#define TREE_CONCAT 1
+#define TREE_HOST_LOOKUP 2
+#define TREE_CONST 3
+#define TREE_LIMIT 4
+
+/* Tree structure for deferred evaluation of changing values. */
+struct tree {
+ int op;
+ union {
+ struct concat {
+ struct tree *left;
+ struct tree *right;
+ } concat;
+ struct host_lookup {
+ struct dns_host_entry *host;
+ } host_lookup;
+ struct const_val {
+ unsigned char *data;
+ int len;
+ } const_val;
+ struct limit {
+ struct tree *tree;
+ int limit;
+ } limit;
+ } data;
+};
+
+/* DNS host entry structure... */
+struct dns_host_entry {
+ char *hostname;
+ unsigned char *data;
+ int data_len;
+ int buf_len;
+ TIME timeout;
+};
+
+struct tree_cache {
+ unsigned char *value;
+ int len;
+ int buf_size;
+ TIME timeout;
+ struct tree *tree;
+};
+
+struct universe {
+ char *name;
+ struct hash_table *hash;
+ struct option *options [256];
+};
+
+struct option {
+ char *name;
+ char *format;
+ struct universe *universe;
+ unsigned char code;
+};