]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
moved to common/
authorTed Lemon <source@isc.org>
Sat, 22 Feb 1997 12:55:05 +0000 (12:55 +0000)
committerTed Lemon <source@isc.org>
Sat, 22 Feb 1997 12:55:05 +0000 (12:55 +0000)
16 files changed:
alloc.c [deleted file]
bpf.c [deleted file]
dispatch.c [deleted file]
errwarn.c [deleted file]
hash.c [deleted file]
inet.c [deleted file]
memory.c [deleted file]
nit.c [deleted file]
options.c [deleted file]
packet.c [deleted file]
parse.c [deleted file]
print.c [deleted file]
raw.c [deleted file]
socket.c [deleted file]
tables.c [deleted file]
tree.c [deleted file]

diff --git a/alloc.c b/alloc.c
deleted file mode 100644 (file)
index dcf4672..0000000
--- a/alloc.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/* alloc.c
-
-   Memory allocation... */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: alloc.c,v 1.9 1996/08/28 01:19:42 mellon Exp $ Copyright (c) 1995, 1996 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.", name);
-       memset (foo, 0, size);
-       return foo;
-}
-
-void dfree (ptr, name)
-       VOIDPTR ptr;
-       char *name;
-{
-       if (!ptr) {
-               warn ("dfree %s: free on null pointer.", name);
-               return;
-       }
-       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;
-}
-
-struct class *new_class (name)
-       char *name;
-{
-       struct class *rval = dmalloc (sizeof (struct class), name);
-       return rval;
-}
-
-struct shared_network *new_shared_network (name)
-       char *name;
-{
-       struct shared_network *rval =
-               dmalloc (sizeof (struct shared_network), name);
-       return rval;
-}
-
-struct group *new_group (name)
-       char *name;
-{
-       struct group *rval =
-               dmalloc (sizeof (struct group), name);
-       return rval;
-}
-
-void free_group (ptr, name)
-       struct group *ptr;
-       char *name;
-{
-       dfree ((VOIDPTR)ptr, name);
-}
-
-void free_shared_network (ptr, name)
-       struct shared_network *ptr;
-       char *name;
-{
-       dfree ((VOIDPTR)ptr, name);
-}
-
-void free_class (ptr, name)
-       struct class *ptr;
-       char *name;
-{
-       dfree ((VOIDPTR)ptr, name);
-}
-
-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);
-}
diff --git a/bpf.c b/bpf.c
deleted file mode 100644 (file)
index 8584f00..0000000
--- a/bpf.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/* bpf.c
-
-   BPF socket interface code, originally contributed by Archie Cobbs. */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: bpf.c,v 1.16 1997/02/19 10:49:20 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include <net/bpf.h>
-#ifdef NEED_OSF_PFILT_HACKS
-#include <net/pfilt.h>
-#endif
-#include <netinet/in_systm.h>
-#include "includes/netinet/ip.h"
-#include "includes/netinet/udp.h"
-#include "includes/netinet/if_ether.h"
-
-/* Reinitializes the specified interface after an address change.   This
-   is not required for packet-filter APIs. */
-
-#ifdef USE_BPF_SEND
-void if_reinitialize_send (info)
-       struct interface_info *info;
-{
-}
-#endif
-
-#ifdef USE_BPF_RECEIVE
-void if_reinitialize_receive (info)
-       struct interface_info *info;
-{
-}
-#endif
-
-/* Called by get_interface_list for each interface that's discovered.
-   Opens a packet filter for each interface and adds it to the select
-   mask. */
-
-int if_register_bpf (info)
-       struct interface_info *info;
-{
-       int sock;
-       char filename[50];
-       int b;
-
-       /* Open a BPF device */
-       for (b = 0; 1; b++) {
-#ifndef NO_SNPRINTF
-               snprintf(filename, sizeof(filename), BPF_FORMAT, b);
-#else
-               sprintf(filename, BPF_FORMAT, b);
-#endif
-               sock = open (filename, O_RDWR, 0);
-               if (sock < 0) {
-                       if (errno == EBUSY) {
-                               continue;
-                       } else {
-                               error ("Can't find free bpf: %m");
-                       }
-               } else {
-                       break;
-               }
-       }
-
-       /* Set the BPF device to point at this interface. */
-       if (ioctl (sock, BIOCSETIF, info -> ifp) < 0)
-               error ("Can't attach interface %s to bpf device %s: %m",
-                      info -> name, filename);
-
-       return sock;
-}
-#endif /* USE_BPF_SEND || USE_BPF_RECEIVE */
-
-#ifdef USE_BPF_SEND
-void if_register_send (info)
-       struct interface_info *info;
-{
-       /* If we're using the bpf API for sending and receiving,
-          we don't need to register this interface twice. */
-#ifndef USE_BPF_RECEIVE
-       info -> wfdesc = if_register_bpf (info, interface);
-#else
-       info -> wfdesc = info -> rfdesc;
-#endif
-       note ("Sending on   BPF/%s/%s/%s",
-             info -> name,
-             print_hw_addr (info -> hw_address.htype,
-                            info -> hw_address.hlen,
-                            info -> hw_address.haddr),
-             (info -> shared_network ?
-              info -> shared_network -> name : "unattached"));
-}
-#endif /* USE_BPF_SEND */
-
-#ifdef USE_BPF_RECEIVE
-/* Packet filter program...
-   XXX Changes to the filter program may require changes to the constant
-   offsets used in if_register_send to patch the BPF program! XXX */
-
-struct bpf_insn filter [] = {
-       /* Make sure this is an IP packet... */
-       BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
-       BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
-
-       /* Make sure it's a UDP packet... */
-       BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 23),
-       BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
-
-       /* Make sure this isn't a fragment... */
-       BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
-       BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
-
-       /* Get the IP header length... */
-       BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 14),
-
-       /* Make sure it's to the right port... */
-       BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
-       BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),             /* patch */
-
-       /* If we passed all the tests, ask for the whole packet. */
-       BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
-
-       /* Otherwise, drop it. */
-       BPF_STMT(BPF_RET+BPF_K, 0),
-};
-
-void if_register_receive (info)
-       struct interface_info *info;
-{
-       int flag = 1;
-       struct bpf_version v;
-       u_int32_t addr;
-       struct bpf_program p;
-       u_int32_t bits;
-
-       /* Open a BPF device and hang it on this interface... */
-       info -> rfdesc = if_register_bpf (info);
-
-       /* Make sure the BPF version is in range... */
-       if (ioctl (info -> rfdesc, BIOCVERSION, &v) < 0)
-               error ("Can't get BPF version: %m");
-
-       if (v.bv_major != BPF_MAJOR_VERSION ||
-           v.bv_minor < BPF_MINOR_VERSION)
-               error ("Kernel BPF version out of range - recompile dhcpd!");
-
-       /* Set immediate mode so that reads return as soon as a packet
-          comes in, rather than waiting for the input buffer to fill with
-          packets. */
-       if (ioctl (info -> rfdesc, BIOCIMMEDIATE, &flag) < 0)
-               error ("Can't set immediate mode on bpf device: %m");
-
-#ifdef NEED_OSF_PFILT_HACKS
-       /* Allow the copyall flag to be set... */
-       if (ioctl(info -> rfdesc, EIOCALLOWCOPYALL, &flag) < 0)
-               error ("Can't set ALLOWCOPYALL: %m");
-
-       /* Clear all the packet filter mode bits first... */
-       bits = 0;
-       if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
-               error ("Can't clear pfilt bits: %m");
-
-       /* Set the ENBATCH, ENCOPYALL, ENBPFHDR bits... */
-       bits = ENBATCH | ENCOPYALL | ENBPFHDR;
-       if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
-               error ("Can't set ENBATCH|ENCOPYALL|ENBPFHDR: %m");
-#endif
-       /* Get the required BPF buffer length from the kernel. */
-       if (ioctl (info -> rfdesc, BIOCGBLEN, &info -> rbuf_max) < 0)
-               error ("Can't get bpf buffer length: %m");
-       info -> rbuf = malloc (info -> rbuf_max);
-       if (!info -> rbuf)
-               error ("Can't allocate %d bytes for bpf input buffer.");
-       info -> rbuf_offset = 0;
-       info -> rbuf_len = 0;
-
-       /* Set up the bpf filter program structure. */
-       p.bf_len = sizeof filter / sizeof (struct bpf_insn);
-       p.bf_insns = filter;
-
-        /* Patch the server port into the BPF  program...
-          XXX changes to filter program may require changes
-          to the insn number(s) used below! XXX */
-       filter [8].k = ntohs (local_port);
-
-       if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0)
-               error ("Can't install packet filter program: %m");
-       note ("Listening on BPF/%s/%s/%s",
-             info -> name,
-             print_hw_addr (info -> hw_address.htype,
-                            info -> hw_address.hlen,
-                            info -> hw_address.haddr),
-             (info -> shared_network ?
-              info -> shared_network -> name : "unattached"));
-}
-#endif /* USE_BPF_RECEIVE */
-
-#ifdef USE_BPF_SEND
-size_t send_packet (interface, packet, raw, len, from, to, hto)
-       struct interface_info *interface;
-       struct packet *packet;
-       struct dhcp_packet *raw;
-       size_t len;
-       struct in_addr from;
-       struct sockaddr_in *to;
-       struct hardware *hto;
-{
-       int bufp = 0;
-       unsigned char buf [256];
-       struct iovec iov [2];
-
-       /* Assemble the headers... */
-       assemble_hw_header (interface, buf, &bufp, hto);
-       assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
-                               to -> sin_addr.s_addr, to -> sin_port,
-                               (unsigned char *)raw, len);
-
-       /* Fire it off */
-       iov [0].iov_base = (char *)buf;
-       iov [0].iov_len = bufp;
-       iov [1].iov_base = (char *)raw;
-       iov [1].iov_len = len;
-
-       return writev(interface -> wfdesc, iov, 2);
-}
-#endif /* USE_BPF_SEND */
-
-#ifdef USE_BPF_RECEIVE
-size_t receive_packet (interface, buf, len, from, hfrom)
-       struct interface_info *interface;
-       unsigned char *buf;
-       size_t len;
-       struct sockaddr_in *from;
-       struct hardware *hfrom;
-{
-       int length = 0;
-       int offset = 0;
-       struct bpf_hdr hdr;
-
-       /* All this complexity is because BPF doesn't guarantee
-          that only one packet will be returned at a time.   We're
-          getting what we deserve, though - this is a terrible abuse
-          of the BPF interface.   Sigh. */
-
-       /* Process packets until we get one we can return or until we've
-          done a read and gotten nothing we can return... */
-
-       do {
-               /* If the buffer is empty, fill it. */
-               if (interface -> rbuf_offset == interface -> rbuf_len) {
-                       length = read (interface -> rfdesc,
-                                      interface -> rbuf,
-                                      interface -> rbuf_max);
-                       if (length <= 0)
-                               return length;
-                       interface -> rbuf_offset = 0;
-                       interface -> rbuf_len = length;
-               }
-
-               /* If there isn't room for a whole bpf header, something went
-                  wrong, but we'll ignore it and hope it goes away... XXX */
-               if (interface -> rbuf_len -
-                   interface -> rbuf_offset < sizeof hdr) {
-                       interface -> rbuf_offset = interface -> rbuf_len;
-                       continue;
-               }
-
-               /* Copy out a bpf header... */
-               memcpy (&hdr, &interface -> rbuf [interface -> rbuf_offset],
-                       sizeof hdr);
-
-               /* If the bpf header plus data doesn't fit in what's left
-                  of the buffer, stick head in sand yet again... */
-               if (interface -> rbuf_offset +
-                   hdr.bh_hdrlen + hdr.bh_caplen > interface -> rbuf_len) {
-                       interface -> rbuf_offset = interface -> rbuf_len;
-                       continue;
-               }
-
-               /* If the captured data wasn't the whole packet, or if
-                  the packet won't fit in the input buffer, all we
-                  can do is drop it. */
-               if (hdr.bh_caplen != hdr.bh_datalen) {
-                       interface -> rbuf_offset +=
-                               hdr.bh_hdrlen = hdr.bh_caplen;
-                       continue;
-               }
-
-               /* Skip over the BPF header... */
-               interface -> rbuf_offset += hdr.bh_hdrlen;
-
-               /* Decode the physical header... */
-               offset = decode_hw_header (interface,
-                                          interface -> rbuf,
-                                          interface -> rbuf_offset,
-                                          hfrom);
-
-               /* If a physical layer checksum failed (dunno of any
-                  physical layer that supports this, but WTH), skip this
-                  packet. */
-               if (offset < 0) {
-                       interface -> rbuf_offset += hdr.bh_caplen;
-                       continue;
-               }
-               interface -> rbuf_offset += offset;
-               hdr.bh_caplen -= offset;
-
-               /* Decode the IP and UDP headers... */
-               offset = decode_udp_ip_header (interface,
-                                              interface -> rbuf,
-                                              interface -> rbuf_offset,
-                                              from,
-                                              (unsigned char *)0,
-                                              hdr.bh_caplen);
-
-               /* If the IP or UDP checksum was bad, skip the packet... */
-               if (offset < 0) {
-                       interface -> rbuf_offset += hdr.bh_caplen;
-                       continue;
-               }
-               interface -> rbuf_offset += offset;
-               hdr.bh_caplen -= offset;
-
-               /* If there's not enough room to stash the packet data,
-                  we have to skip it (this shouldn't happen in real
-                  life, though). */
-               if (hdr.bh_caplen > len) {
-                       interface -> rbuf_offset += hdr.bh_caplen;
-                       continue;
-               }
-
-               /* Copy out the data in the packet... */
-               memcpy (buf, interface -> rbuf + interface -> rbuf_offset,
-                       hdr.bh_caplen);
-               interface -> rbuf_offset += hdr.bh_caplen;
-               return hdr.bh_caplen;
-       } while (!length);
-       return 0;
-}
-#endif
-
-#if defined (USE_BPF_SEND)
-void if_enable (interface)
-       struct interface_info *interface;
-{
-       struct ifreq ifr;
-       int sock;
-
-       if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
-               error ("Can't create addrlist socket");
-
-       /* Bring the interface down and then up again to clear
-        * all its routes. */
-       strncpy(ifr.ifr_name, interface -> name, IFNAMSIZ);
-       if (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0)
-               error ("SIOCGIFFLAGS %s: %m", interface -> name);
-
-       ifr.ifr_flags |= (IFF_UP|IFF_RUNNING);
-       if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
-               error ("SIOCSIFFLAGS %s: %m", interface -> name);
-}
-#endif
diff --git a/dispatch.c b/dispatch.c
deleted file mode 100644 (file)
index 5f60275..0000000
+++ /dev/null
@@ -1,719 +0,0 @@
-/* dispatch.c
-
-   Network input dispatcher... */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: dispatch.c,v 1.33 1997/02/22 12:26:41 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include <sys/ioctl.h>
-
-struct interface_info *interfaces, *dummy_interfaces;
-struct timeout *timeouts;
-static struct timeout *free_timeouts;
-static int interfaces_invalidated;
-
-static void got_one PROTO ((struct interface_info *, int));
-
-/* Use the SIOCGIFCONF ioctl to get a list of all the attached interfaces.
-   For each interface that's of type INET and not the loopback interface,
-   register that interface with the network I/O software, figure out what
-   subnet it's on, and add it to the list of interfaces. */
-
-void discover_interfaces (state)
-       int state;
-{
-       struct interface_info *tmp;
-       struct interface_info *last;
-       char buf [8192];
-       struct ifconf ic;
-       struct ifreq ifr;
-       int i;
-       int sock;
-       int address_count = 0;
-       struct subnet *subnet;
-       struct shared_network *share;
-       struct sockaddr_in foo;
-       int ir;
-#ifdef ALIAS_NAMES_PERMUTED
-       char *s;
-#endif
-#ifdef USE_FALLBACK
-       static struct shared_network fallback_network;
-#endif
-
-       /* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
-       if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
-               error ("Can't create addrlist socket");
-
-       /* Get the interface configuration information... */
-       ic.ifc_len = sizeof buf;
-       ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
-       i = ioctl(sock, SIOCGIFCONF, &ic);
-
-       if (i < 0)
-               error ("ioctl: SIOCGIFCONF: %m");
-
-       /* If we already have a list of interfaces, and we're running as
-          a DHCP server, the interfaces were requested. */
-       if (interfaces &&
-           (state == DISCOVER_SERVER || state == DISCOVER_RELAY))
-               ir = 0;
-       else
-               ir = INTERFACE_REQUESTED;
-
-       /* 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);
-#ifdef HAVE_SA_LEN
-               i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
-#else
-               i += sizeof *ifp;
-#endif
-
-#ifdef ALIAS_NAMES_PERMUTED
-               if ((s = strrchr (ifp -> ifr_name, ':'))) {
-                       *s = 0;
-               }
-#endif
-
-
-               /* See if this is the sort of interface we want to
-                  deal with. */
-               strcpy (ifr.ifr_name, ifp -> ifr_name);
-               if (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0)
-                       error ("Can't get interface flags for %s: %m",
-                              ifr.ifr_name);
-
-               /* Skip loopback, point-to-point and down interfaces,
-                  except don't skip down interfaces if we're trying to
-                  get a list of configurable interfaces. */
-               if ((ifr.ifr_flags & IFF_LOOPBACK) ||
-                   (ifr.ifr_flags & IFF_POINTOPOINT) ||
-                   (!(ifr.ifr_flags & IFF_UP) &&
-                    state != DISCOVER_UNCONFIGURED))
-                       continue;
-               
-               /* See if we've seen an interface that matches this one. */
-               for (tmp = interfaces; tmp; tmp = tmp -> next)
-                       if (!strcmp (tmp -> name, ifp -> ifr_name))
-                               break;
-
-               /* If there isn't already an interface by this name,
-                  allocate one. */
-               if (!tmp) {
-                       tmp = ((struct interface_info *)
-                              dmalloc (sizeof *tmp, "get_interface_list"));
-                       if (!tmp)
-                               error ("Insufficient memory to %s %s",
-                                      "record interface", ifp -> ifr_name);
-                       strcpy (tmp -> name, ifp -> ifr_name);
-                       tmp -> next = interfaces;
-                       tmp -> flags = ir;
-                       interfaces = tmp;
-               }
-
-               /* If we have the capability, extract link information
-                  and record it in a linked list. */
-#ifdef AF_LINK
-               if (ifp -> ifr_addr.sa_family == AF_LINK) {
-                       struct sockaddr_dl *foo = ((struct sockaddr_dl *)
-                                                  (&ifp -> ifr_addr));
-                       tmp -> hw_address.hlen = foo -> sdl_alen;
-                       tmp -> hw_address.htype = HTYPE_ETHER; /* XXX */
-                       memcpy (tmp -> hw_address.haddr,
-                               LLADDR (foo), foo -> sdl_alen);
-               } else
-#endif /* AF_LINK */
-
-               if (ifp -> ifr_addr.sa_family == AF_INET) {
-                       struct iaddr addr;
-
-#if defined (SIOCGIFHWADDR) && !defined (AF_LINK)
-                       struct ifreq ifr;
-                       struct sockaddr sa;
-                       int b, sk;
-                       
-                       /* Read the hardware address from this interface. */
-                       ifr = *ifp;
-                       if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
-                               error ("Can't get hardware address for %s: %m",
-                                      ifr.ifr_name);
-
-                       sa = *(struct sockaddr *)&ifr.ifr_hwaddr;
-                                       
-                       switch (sa.sa_family) {
-                             case ARPHRD_LOOPBACK:
-                               /* ignore loopback interface */
-                               break;
-
-                             case ARPHRD_ETHER:
-                               tmp -> hw_address.hlen = 6;
-                               tmp -> hw_address.htype = ARPHRD_ETHER;
-                               memcpy (tmp -> hw_address.haddr,
-                                       sa.sa_data, 6);
-                               break;
-
-                             case ARPHRD_METRICOM:
-                               tmp -> hw_address.hlen = 6;
-                               tmp -> hw_address.htype = ARPHRD_METRICOM;
-                               memcpy (tmp -> hw_address.haddr,
-                                       sa.sa_data, 6);
-                               break;
-
-                             default:
-                               error ("%s: unknown hardware address type %d",
-                                      ifr.ifr_name, sa.sa_family);
-                       }
-#endif /* defined (SIOCGIFHWADDR) && !defined (AF_LINK) */
-
-                       /* Get a pointer to the address... */
-                       memcpy (&foo, &ifp -> ifr_addr,
-                               sizeof ifp -> ifr_addr);
-
-                       /* We don't want the loopback interface. */
-                       if (foo.sin_addr.s_addr == htonl (INADDR_LOOPBACK))
-                               continue;
-
-
-                       /* If this is the first real IP address we've
-                          found, keep a pointer to ifreq structure in
-                          which we found it. */
-                       if (!tmp -> ifp) {
-                               struct ifreq *tif;
-#ifdef HAVE_SA_LEN
-                               int len = ((sizeof ifp -> ifr_name) +
-                                          ifp -> ifr_addr.sa_len);
-#else
-                               int len = sizeof *ifp;
-#endif
-                               tif = (struct ifreq *)malloc (len);
-                               if (!tif)
-                                       error ("no space to remember ifp.");
-                               memcpy (tif, ifp, len);
-                               tmp -> ifp = ifp;
-                               tmp -> primary_address = foo.sin_addr;
-                       }
-
-                       /* Grab the address... */
-                       addr.len = 4;
-                       memcpy (addr.iabuf, &foo.sin_addr.s_addr,
-                               addr.len);
-
-                       /* If there's a registered subnet for this address,
-                          connect it together... */
-                       if ((subnet = find_subnet (addr))) {
-                               /* If this interface has multiple aliases
-                                  on the same subnet, ignore all but the
-                                  first we encounter. */
-                               if (!subnet -> interface) {
-                                       subnet -> interface = tmp;
-                                       subnet -> interface_address = addr;
-                               } else if (subnet -> interface != tmp) {
-                                       warn ("Multiple %s %s: %s %s", 
-                                             "interfaces match the",
-                                             "same subnet",
-                                             subnet -> interface -> name,
-                                             tmp -> name);
-                               }
-                               share = subnet -> shared_network;
-                               if (tmp -> shared_network &&
-                                   tmp -> shared_network != share) {
-                                       warn ("Interface %s matches %s",
-                                             tmp -> name,
-                                             "multiple shared networks");
-                               } else {
-                                       tmp -> shared_network = share;
-                               }
-
-                               if (!share -> interface) {
-                                       share -> interface = tmp;
-                               } else if (share -> interface != tmp) {
-                                       warn ("Multiple %s %s: %s %s", 
-                                             "interfaces match the",
-                                             "same shared network",
-                                             share -> interface -> name,
-                                             tmp -> name);
-                               }
-                       }
-               }
-       }
-
-       /* If we're just trying to get a list of interfaces that we might
-          be able to configure, we can quit now. */
-       if (state == DISCOVER_UNCONFIGURED)
-               return;
-
-       /* Weed out the interfaces that did not have IP addresses. */
-       last = (struct interface_info *)0;
-       for (tmp = interfaces; tmp; tmp = tmp -> next) {
-               if (!tmp -> ifp || !(tmp -> flags & INTERFACE_REQUESTED)) {
-                       if ((tmp -> flags & INTERFACE_REQUESTED) != ir)
-                               error ("%s: not found", tmp -> name);
-                       if (!last)
-                               interfaces = interfaces -> next;
-                       else
-                               last -> next = tmp -> next;
-
-                       /* Remember the interface in case we need to know
-                          about it later. */
-                       tmp -> next = dummy_interfaces;
-                       dummy_interfaces = tmp;
-                       continue;
-               }
-               last = tmp;
-
-               memcpy (&foo, &tmp -> ifp -> ifr_addr,
-                       sizeof tmp -> ifp -> ifr_addr);
-
-               /* We must have a subnet declaration for each interface. */
-               if (!tmp -> shared_network && (state == DISCOVER_SERVER))
-                       error ("No subnet declaration for %s (%s).",
-                              tmp -> name, inet_ntoa (foo.sin_addr));
-
-               /* Find subnets that don't have valid interface
-                  addresses... */
-               for (subnet = (tmp -> shared_network
-                              ? tmp -> shared_network -> subnets
-                              : (struct subnet *)0);
-                    subnet; subnet = subnet -> next_sibling) {
-                       if (!subnet -> interface_address.len) {
-                               /* Set the interface address for this subnet
-                                  to the first address we found. */
-                               subnet -> interface_address.len = 4;
-                               memcpy (subnet -> interface_address.iabuf,
-                                       &foo.sin_addr.s_addr, 4);
-                       }
-               }
-
-               /* Register the interface... */
-               if_register_receive (tmp);
-               if_register_send (tmp);
-       }
-
-       close (sock);
-
-#ifdef USE_FALLBACK
-       strcpy (fallback_interface.name, "fallback");   
-       fallback_interface.shared_network = &fallback_network;
-       fallback_network.name = "fallback-net";
-       if_register_fallback (&fallback_interface);
-#endif
-}
-
-void reinitialize_interfaces ()
-{
-       struct interface_info *ip;
-
-       for (ip = interfaces; ip; ip = ip -> next) {
-               if_reinitialize_receive (ip);
-               if_reinitialize_send (ip);
-       }
-
-#ifdef USE_FALLBACK
-       if_reinitialize_fallback (&fallback_interface);
-#endif
-
-       interfaces_invalidated = 1;
-}
-
-#ifdef USE_POLL
-/* Wait for packets to come in using poll().  Anyway, when a packet
-   comes in, call receive_packet to receive the packet and possibly
-   strip hardware addressing information from it, and then call
-   do_packet to try to do something with it. 
-
-   As you can see by comparing this with the code that uses select(),
-   below, this is gratuitously complex.  Quelle surprise, eh?  This is
-   SysV we're talking about, after all, and even in the 90's, it
-   wouldn't do for SysV to make networking *easy*, would it?  Rant,
-   rant... */
-
-void dispatch (parse)
-       int parse;
-{
-       struct interface_info *l;
-       int nfds = 0;
-       struct pollfd *fds;
-       int count;
-       int i;
-       int to_msec;
-
-       nfds = 0;
-       for (l = interfaces; l; l = l -> next) {
-               ++nfds;
-       }
-#ifdef USE_FALLBACK
-       ++nfds;
-#endif
-       fds = (struct pollfd *)malloc ((nfds) * sizeof (struct pollfd));
-       if (!fds)
-               error ("Can't allocate poll structures.");
-
-       do {
-               /* Call any expired timeouts, and then if there's
-                  still a timeout registered, time out the select
-                  call then. */
-             another:
-               if (timeouts) {
-                       struct timeout *t;
-                       if (timeouts -> when <= cur_time) {
-                               t = timeouts;
-                               timeouts = timeouts -> next;
-                               (*(t -> func)) (t -> interface);
-                               t -> next = free_timeouts;
-                               free_timeouts = t;
-                               goto another;
-                       }
-                       /* Figure timeout in milliseconds, and check for
-                          potential overflow.   We assume that integers
-                          are 32 bits, which is harmless if they're 64
-                          bits - we'll just get extra timeouts in that
-                          case.    Lease times would have to be quite
-                          long in order for a 32-bit integer to overflow,
-                          anyway. */
-                       to_msec = timeouts -> when - cur_time;
-                       if (to_msec > 2147483)
-                               to_msec = 2147483;
-                       to_msec *= 1000;
-               } else
-                       to_msec = -1;
-
-               /* Set up the descriptors to be polled. */
-               i = 0;
-               for (l = interfaces; l; l = l -> next) {
-                       fds [i].fd = l -> rfdesc;
-                       fds [i].events = POLLIN;
-                       fds [i].revents = 0;
-                       ++i;
-               }
-
-#ifdef USE_FALLBACK
-               fds [i].fd = fallback_interface.wfdesc;
-               fds [i].events = POLLIN;
-               fds [i].revents = 0;
-               ++i;
-#endif
-
-               /* Wait for a packet or a timeout... XXX */
-               count = poll (fds, nfds, to_msec);
-
-               /* Get the current time... */
-               GET_TIME (&cur_time);
-
-               /* Not likely to be transitory... */
-               if (count < 0)
-                       error ("poll: %m");
-
-               i = 0;
-               for (l = interfaces; l; l = l -> next) {
-                       if ((fds [i].revents & POLLIN)) {
-                               fds [i].revents = 0;
-                               got_one (l, parse);
-                               if (interfaces_invalidated)
-                                       break;
-                       }
-                       ++i;
-               }
-#ifdef USE_FALLBACK
-               if ((fds [i].revents & POLLIN) && !interfaces_invalidated)
-                       fallback_discard (&fallback_interface);
-#endif
-               interfaces_invalidated = 0;
-       } while (1);
-}
-#else
-/* Wait for packets to come in using select().   When one does, call
-   receive_packet to receive the packet and possibly strip hardware
-   addressing information from it, and then call do_packet to try to
-   do something with it. */
-
-void dispatch (parse)
-       int parse;
-{
-       fd_set r, w, x;
-       struct interface_info *l;
-       int max = 0;
-       int count;
-       struct timeval tv, *tvp;
-
-       FD_ZERO (&w);
-       FD_ZERO (&x);
-
-       do {
-               /* Call any expired timeouts, and then if there's
-                  still a timeout registered, time out the select
-                  call then. */
-             another:
-               if (timeouts) {
-                       struct timeout *t;
-                       if (timeouts -> when <= cur_time) {
-                               t = timeouts;
-                               timeouts = timeouts -> next;
-                               (*(t -> func)) (t -> interface);
-                               t -> next = free_timeouts;
-                               free_timeouts = t;
-                               goto another;
-                       }
-                       tv.tv_sec = timeouts -> when - cur_time;
-                       tv.tv_usec = 0;
-                       tvp = &tv;
-               } else
-                       tvp = (struct timeval *)0;
-
-               /* Set up the read mask. */
-               FD_ZERO (&r);
-
-               for (l = interfaces; l; l = l -> next) {
-                       FD_SET (l -> rfdesc, &r);
-                       FD_SET (l -> rfdesc, &x);
-                       if (l -> rfdesc > max)
-                               max = l -> rfdesc;
-               }
-#ifdef USE_FALLBACK
-               FD_SET (fallback_interface.wfdesc, &r);
-               if (fallback_interface.wfdesc > max)
-                               max = fallback_interface.wfdesc;
-#endif
-
-               /* Wait for a packet or a timeout... XXX */
-               count = select (max + 1, &r, &w, &x, tvp);
-
-               /* Get the current time... */
-               GET_TIME (&cur_time);
-
-               /* Not likely to be transitory... */
-               if (count < 0)
-                       error ("select: %m");
-
-               for (l = interfaces; l; l = l -> next) {
-                       if (!FD_ISSET (l -> rfdesc, &r))
-                               continue;
-                       got_one (l, parse);
-                       if (interfaces_invalidated)
-                               break;
-               }
-#ifdef USE_FALLBACK
-               if (FD_ISSET (fallback_interface.wfdesc, &r) &&
-                   !interfaces_invalidated)
-                       fallback_discard (&fallback_interface);
-#endif
-               interfaces_invalidated = 1;
-       } while (1);
-}
-#endif /* USE_POLL */
-
-static void got_one (l, parse)
-       struct interface_info *l;
-       int parse;
-{
-       struct sockaddr_in from;
-       struct hardware hfrom;
-       struct iaddr ifrom;
-       int result;
-       static unsigned char packbuf [4095]; /* Packet input buffer.
-                                               Must be as large as largest
-                                               possible MTU. */
-
-       if ((result = receive_packet (l, packbuf, sizeof packbuf,
-                                     &from, &hfrom)) < 0) {
-               warn ("receive_packet failed on %s: %m", l -> name);
-               return;
-       }
-       if (result == 0)
-               return;
-
-       if (parse) {
-               ifrom.len = 4;
-               memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len);
-       
-               do_packet (l, packbuf, result,
-                          from.sin_port, ifrom, &hfrom);
-       } else
-               relay (l, (struct dhcp_packet *)packbuf, result);
-}
-
-void do_packet (interface, packbuf, len, from_port, from, hfrom)
-       struct interface_info *interface;
-       unsigned char *packbuf;
-       int len;
-       unsigned short from_port;
-       struct iaddr from;
-       struct hardware *hfrom;
-{
-       struct packet tp;
-       struct dhcp_packet tdp;
-
-       memcpy (&tdp, packbuf, len);
-       memset (&tp, 0, sizeof tp);
-       tp.raw = &tdp;
-       tp.packet_length = len;
-       tp.client_port = from_port;
-       tp.client_addr = from;
-       tp.interface = interface;
-       tp.haddr = hfrom;
-       
-       parse_options (&tp);
-       if (tp.options_valid &&
-           tp.options [DHO_DHCP_MESSAGE_TYPE].data)
-               tp.packet_type =
-                       tp.options [DHO_DHCP_MESSAGE_TYPE].data [0];
-       if (tp.packet_type)
-               dhcp (&tp);
-       else if (tdp.op == BOOTREQUEST)
-               bootp (&tp);
-}
-
-int locate_network (packet)
-       struct packet *packet;
-{
-       struct iaddr ia;
-
-       /* If this came through a gateway, find the corresponding subnet... */
-       if (packet -> raw -> giaddr.s_addr) {
-               struct subnet *subnet;
-               ia.len = 4;
-               memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
-               subnet = find_subnet (ia);
-               if (subnet)
-                       packet -> shared_network = subnet -> shared_network;
-               else
-                       packet -> shared_network = (struct shared_network *)0;
-       } else {
-               packet -> shared_network =
-                       packet -> interface -> shared_network;
-       }
-       if (packet -> shared_network)
-               return 1;
-       return 0;
-}
-
-void add_timeout (when, where, what)
-       TIME when;
-       void (*where) (struct interface_info *);
-       struct interface_info *what;
-{
-       struct timeout *t, *q;
-
-       /* See if this timeout supersedes an existing timeout. */
-       t = (struct timeout *)0;
-       for (q = timeouts; q; q = q -> next) {
-               if (q -> func == where && q -> interface == what) {
-                       if (t)
-                               t -> next = q -> next;
-                       else
-                               timeouts = q -> next;
-                       break;
-               }
-               t = q;
-       }
-
-       /* If we didn't supersede a timeout, allocate a timeout
-          structure now. */
-       if (!q) {
-               if (free_timeouts) {
-                       q = free_timeouts;
-                       free_timeouts = q -> next;
-                       q -> func = where;
-                       q -> interface = what;
-               } else {
-                       q = (struct timeout *)malloc (sizeof (struct timeout));
-                       if (!q)
-                               error ("Can't allocate timeout structure!");
-                       q -> func = where;
-                       q -> interface = what;
-               }
-       }
-
-       q -> when = when;
-
-       /* Now sort this timeout into the timeout list. */
-
-       /* Beginning of list? */
-       if (!timeouts || timeouts -> when > q -> when) {
-               q -> next = timeouts;
-               timeouts = q;
-               return;
-       }
-
-       /* Middle of list? */
-       for (t = timeouts; t -> next; t = t -> next) {
-               if (t -> next -> when > q -> when) {
-                       q -> next = t -> next;
-                       t -> next = q;
-                       return;
-               }
-       }
-
-       /* End of list. */
-       t -> next = q;
-       q -> next = (struct timeout *)0;
-}
-
-void cancel_timeout (where, what)
-       void (*where) (struct interface_info *);
-       struct interface_info *what;
-{
-       struct timeout *t, *q;
-
-       /* Look for this timeout on the list, and unlink it if we find it. */
-       t = (struct timeout *)0;
-       for (q = timeouts; q; q = q -> next) {
-               if (q -> func == where && q -> interface == what) {
-                       if (t)
-                               t -> next = q -> next;
-                       else
-                               timeouts = q -> next;
-                       break;
-               }
-               t = q;
-       }
-
-       /* If we found the timeout, put it on the free list. */
-       if (q) {
-               q -> next = free_timeouts;
-               free_timeouts = q;
-       }
-}
diff --git a/errwarn.c b/errwarn.c
deleted file mode 100644 (file)
index 34e0d81..0000000
--- a/errwarn.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/* errwarn.c
-
-   Errors and warnings... */
-
-/*
- * Copyright (c) 1996 The Internet Software Consortium.
- * All Rights Reserved.
- * 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, 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 RADIOMAIL CORPORATION, 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 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.   Further modifications have
- * been made for the Internet Software Consortium under a contract
- * with Vixie Laboratories.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: errwarn.c,v 1.14 1997/02/22 12:26:12 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include <errno.h>
-
-static void do_percentm PROTO ((char *obuf, char *ibuf));
-
-static char mbuf [1024];
-static char fbuf [1024];
-
-int warnings_occurred;
-
-/* Log an error message, then exit... */
-
-void 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_priority | LOG_ERR, mbuf);
-#endif
-
-  /* Also log it to stderr? */
-  if (log_perror) {
-         write (2, mbuf, strlen (mbuf));
-         write (2, "\n", 1);
-  }
-
-  syslog (LOG_CRIT, "exiting.");
-  if (log_perror) {
-       fprintf (stderr, "exiting.\n");
-       fflush (stderr);
-  }
-  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_priority | LOG_ERR, mbuf);
-#endif
-
-  if (log_perror) {
-         write (2, mbuf, strlen (mbuf));
-         write (2, "\n", 1);
-  }
-
-  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_priority | LOG_INFO, mbuf);
-#endif
-
-  if (log_perror) {
-         write (2, mbuf, strlen (mbuf));
-         write (2, "\n", 1);
-  }
-
-  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_priority | LOG_DEBUG, mbuf);
-#endif
-
-  if (log_perror) {
-         write (2, mbuf, strlen (mbuf));
-         write (2, "\n", 1);
-  }
-
-  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
-{
-       va_list list;
-       static char spaces [] = "                                                                                ";
-       
-       do_percentm (mbuf, fmt);
-#ifndef NO_SNPRINTF
-       snprintf (fbuf, sizeof fbuf, "%s line %d: %s",
-                 tlname, lexline, mbuf);
-#else
-       sprintf (fbuf, "%s line %d: %s",
-                tlname, lexline, mbuf);
-#endif
-       
-       VA_start (list, fmt);
-       vsnprintf (mbuf, sizeof mbuf, fbuf, list);
-       va_end (list);
-
-#ifndef DEBUG
-       syslog (log_priority | LOG_ERR, mbuf);
-       syslog (log_priority | LOG_ERR, token_line);
-       if (lexline < 81)
-               syslog (log_priority | LOG_ERR,
-                       "%s^", &spaces [sizeof spaces - lexchar]);
-#endif
-
-       if (log_perror) {
-               write (2, mbuf, strlen (mbuf));
-               write (2, "\n", 1);
-               write (2, token_line, strlen (token_line));
-               write (2, "\n", 1);
-               write (2, spaces, lexchar - 1);
-               write (2, "^\n", 2);
-       }
-
-       warnings_occurred = 1;
-
-       return 0;
-}
-
-#ifdef NO_STRERROR
-char *strerror (err)
-       int err;
-{
-       extern char *sys_errlist [];
-       extern int sys_nerr;
-       static char errbuf [128];
-
-       if (err < 0 || err >= sys_nerr) {
-               sprintf (errbuf, "Error %d", err);
-               return errbuf;
-       }
-       return sys_errlist [err];
-}
-#endif /* NO_STRERROR */
diff --git a/hash.c b/hash.c
deleted file mode 100644 (file)
index e8e9375..0000000
--- a/hash.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/* hash.c
-
-   Routines for manipulating hash tables... */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: hash.c,v 1.9 1996/09/09 07:04:45 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-static INLINE int do_hash PROTO ((char *, int, int));
-
-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], 0,
-               DEFAULT_HASH_SIZE * sizeof (struct hash_bucket *));
-       return rv;
-}
-
-static INLINE int 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;
-       struct hash_bucket *bp;
-
-       if (!table)
-               return;
-
-       hashno = do_hash (name, len, table -> hash_count);
-       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];
-       bp -> len = len;
-       table -> buckets [hashno] = bp;
-}
-
-void delete_hash_entry (table, name, len)
-       struct hash_table *table;
-       int len;
-       char *name;
-{
-       int hashno;
-       struct hash_bucket *bp, *pbp = (struct hash_bucket *)0;
-
-       if (!table)
-               return;
-
-       hashno = do_hash (name, len, table -> hash_count);
-
-       /* 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;
-               }
-               pbp = bp;       /* jwg, 9/6/96 - nice catch! */
-       }
-}
-
-unsigned char *hash_lookup (table, name, len)
-       struct hash_table *table;
-       char *name;
-       int len;
-{
-       int hashno;
-       struct hash_bucket *bp;
-
-       if (!table)
-               return (unsigned char *)0;
-       hashno = do_hash (name, len, table -> hash_count);
-
-       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;
-}
-
diff --git a/inet.c b/inet.c
deleted file mode 100644 (file)
index 000d971..0000000
--- a/inet.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/* inet.c
-
-   Subroutines to manipulate internet addresses in a safely portable
-   way... */
-
-/*
- * Copyright (c) 1996 The Internet Software Consortium.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * 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"
-
-/* Return just the network number of an internet address... */
-
-struct iaddr subnet_number (addr, mask)
-       struct iaddr addr;
-       struct iaddr mask;
-{
-       int i;
-       struct iaddr rv;
-
-       rv.len = 0;
-
-       /* Both addresses must have the same length... */
-       if (addr.len != mask.len)
-               return rv;
-
-       rv.len = addr.len;
-       for (i = 0; i < rv.len; i++)
-               rv.iabuf [i] = addr.iabuf [i] & mask.iabuf [i];
-       return rv;
-}
-
-/* Combine a network number and a integer to produce an internet address.
-   This won't work for subnets with more than 32 bits of host address, but
-   maybe this isn't a problem. */
-
-struct iaddr ip_addr (subnet, mask, host_address)
-       struct iaddr subnet;
-       struct iaddr mask;
-       u_int32_t host_address;
-{
-       int i, j, k;
-       u_int32_t swaddr;
-       struct iaddr rv;
-       unsigned char habuf [sizeof swaddr];
-
-       swaddr = htonl (host_address);
-       memcpy (habuf, &swaddr, sizeof swaddr);
-
-       /* Combine the subnet address and the host address.   If
-          the host address is bigger than can fit in the subnet,
-          return a zero-length iaddr structure. */
-       rv = subnet;
-       j = rv.len - sizeof habuf;
-       for (i = sizeof habuf - 1; i >= 0; i--) {
-               if (mask.iabuf [i + j]) {
-                       if (habuf [i] > (mask.iabuf [i + j] ^ 0xFF)) {
-                               rv.len = 0;
-                               return rv;
-                       }
-                       for (k = i - 1; k >= 0; k--) {
-                               if (habuf [k]) {
-                                       rv.len = 0;
-                                       return rv;
-                               }
-                       }
-                       rv.iabuf [i + j] |= habuf [i];
-                       break;
-               } else
-                       rv.iabuf [i + j] = habuf [i];
-       }
-               
-       return rv;
-}
-
-u_int32_t host_addr (addr, mask)
-       struct iaddr addr;
-       struct iaddr mask;
-{
-       int i;
-       u_int32_t swaddr;
-       struct iaddr rv;
-
-       rv.len = 0;
-
-       /* Mask out the network bits... */
-       rv.len = addr.len;
-       for (i = 0; i < rv.len; i++)
-               rv.iabuf [i] = addr.iabuf [i] & ~mask.iabuf [i];
-
-       /* Copy out up to 32 bits... */
-       memcpy (&swaddr, &rv.iabuf [rv.len - sizeof swaddr], sizeof swaddr);
-
-       /* Swap it and return it. */
-       return ntohl (swaddr);
-}
-
-int addr_eq (addr1, addr2)
-       struct iaddr addr1, addr2;
-{
-       if (addr1.len != addr2.len)
-               return 0;
-       return memcmp (addr1.iabuf, addr2.iabuf, addr1.len) == 0;
-}
-
-char *piaddr (addr)
-       struct iaddr addr;
-{
-       static char pbuf [4 * 16];
-       char *s = pbuf;
-       int i;
-
-       if (addr.len == 0) {
-               strcpy (s, "<null address>");
-       }
-       for (i = 0; i < addr.len; i++) {
-               sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]);
-               s += strlen (s);
-       }
-       return pbuf;
-}
diff --git a/memory.c b/memory.c
deleted file mode 100644 (file)
index 437c913..0000000
--- a/memory.c
+++ /dev/null
@@ -1,873 +0,0 @@
-/* memory.c
-
-   Memory-resident database... */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: memory.c,v 1.23 1996/12/31 02:02:54 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-static struct subnet *subnets;
-static struct shared_network *shared_networks;
-static struct hash_table *host_hw_addr_hash;
-static struct hash_table *host_uid_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;
-
-static struct hash_table *vendor_class_hash;
-static struct hash_table *user_class_hash;
-
-void enter_host (hd)
-       struct host_decl *hd;
-{
-       struct host_decl *hp = (struct host_decl *)0;
-       struct host_decl *np = (struct host_decl *)0;
-
-       hd -> n_ipaddr = (struct host_decl *)0;
-
-       if (hd -> interface.hlen) {
-               if (!host_hw_addr_hash)
-                       host_hw_addr_hash = new_hash ();
-               else
-                       hp = (struct host_decl *)
-                               hash_lookup (host_hw_addr_hash,
-                                            hd -> interface.haddr,
-                                            hd -> interface.hlen);
-
-               /* If there isn't already a host decl matching this
-                  address, add it to the hash table. */
-               if (!hp)
-                       add_hash (host_hw_addr_hash,
-                                 hd -> interface.haddr, hd -> interface.hlen,
-                                 (unsigned char *)hd);
-       }
-
-       /* If there was already a host declaration for this hardware
-          address, add this one to the end of the list. */
-
-       if (hp) {
-               for (np = hp; np -> n_ipaddr; np = np -> n_ipaddr)
-                       ;
-               np -> n_ipaddr = hd;
-       }
-
-       if (hd -> group -> options [DHO_DHCP_CLIENT_IDENTIFIER]) {
-               if (!tree_evaluate (hd -> group -> options
-                                   [DHO_DHCP_CLIENT_IDENTIFIER]))
-                       return;
-                       
-               /* If there's no uid hash, make one; otherwise, see if
-                  there's already an entry in the hash for this host. */
-               if (!host_uid_hash) {
-                       host_uid_hash = new_hash ();
-                       hp = (struct host_decl *)0;
-               } else
-                       hp = (struct host_decl *) hash_lookup
-                               (host_uid_hash,
-                                hd -> group -> options
-                                [DHO_DHCP_CLIENT_IDENTIFIER] -> value,
-                                hd -> group -> options
-                                [DHO_DHCP_CLIENT_IDENTIFIER] -> len);
-
-               /* If there's already a host declaration for this
-                  client identifier, add this one to the end of the
-                  list.  Otherwise, add it to the hash table. */
-               if (hp) {
-                       /* Don't link it in twice... */
-                       if (!np) {
-                               for (np = hp; np -> n_ipaddr;
-                                    np = np -> n_ipaddr)
-                                       ;
-                               np -> n_ipaddr = hd;
-                       }
-               } else {
-                       add_hash (host_uid_hash,
-                                 hd -> group -> options
-                                 [DHO_DHCP_CLIENT_IDENTIFIER] -> value,
-                                 hd -> group -> options
-                                 [DHO_DHCP_CLIENT_IDENTIFIER] -> len,
-                                 (unsigned char *)hd);
-               }
-       }
-}
-
-struct host_decl *find_hosts_by_haddr (htype, haddr, hlen)
-       int htype;
-       unsigned char *haddr;
-       int hlen;
-{
-       struct host_decl *foo;
-
-       foo = (struct host_decl *)hash_lookup (host_hw_addr_hash,
-                                              haddr, hlen);
-       return foo;
-}
-
-struct host_decl *find_hosts_by_uid (data, len)
-       unsigned char *data;
-       int len;
-{
-       struct host_decl *foo;
-
-       foo = (struct host_decl *)hash_lookup (host_uid_hash, data, len);
-       return foo;
-}
-
-/* More than one host_decl can be returned by find_hosts_by_haddr or
-   find_hosts_by_uid, and each host_decl can have multiple addresses.
-   Loop through the list of hosts, and then for each host, through the
-   list of addresses, looking for an address that's in the same shared
-   network as the one specified.    Store the matching address through
-   the addr pointer, update the host pointer to point at the host_decl
-   that matched, and return the subnet that matched. */
-
-struct subnet *find_host_for_network (host, addr, share)
-       struct host_decl **host;
-       struct iaddr *addr;
-       struct shared_network *share;
-{
-       int i;
-       struct subnet *subnet;
-       struct iaddr ip_address;
-       struct host_decl *hp;
-
-       for (hp = *host; hp; hp = hp -> n_ipaddr) {
-               if (!hp -> fixed_addr || !tree_evaluate (hp -> fixed_addr))
-                       continue;
-               for (i = 0; i < hp -> fixed_addr -> len; i += 4) {
-                       ip_address.len = 4;
-                       memcpy (ip_address.iabuf,
-                               hp -> fixed_addr -> value + i, 4);
-                       subnet = find_grouped_subnet (share, ip_address);
-                       if (subnet) {
-                               *addr = ip_address;
-                               *host = hp;
-                               return subnet;
-                       }
-               }
-       }
-       return (struct subnet *)0;
-}
-
-void new_address_range (low, high, subnet, dynamic)
-       struct iaddr low, high;
-       struct subnet *subnet;
-       int dynamic;
-{
-       struct lease *address_range, *lp, *plp;
-       struct iaddr net;
-       int min, max, i;
-       char lowbuf [16], highbuf [16], netbuf [16];
-       struct shared_network *share = subnet -> shared_network;
-       struct hostent *h;
-       struct in_addr ia;
-
-       /* All subnets should have attached shared network structures. */
-       if (!share) {
-               strcpy (netbuf, piaddr (subnet -> net));
-               error ("No shared network for network %s (%s)",
-                      netbuf, piaddr (subnet -> netmask));
-       }
-
-       /* Initialize the hash table if it hasn't been done yet. */
-       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 = subnet_number (low, subnet -> netmask);
-       if (!addr_eq (net, subnet_number (high, subnet -> netmask))) {
-               strcpy (lowbuf, piaddr (low));
-               strcpy (highbuf, piaddr (high));
-               strcpy (netbuf, piaddr (subnet -> netmask));
-               error ("Address range %s to %s, netmask %s spans %s!",
-                      lowbuf, highbuf, netbuf, "multiple subnets");
-       }
-
-       /* Get the high and low host addresses... */
-       max = host_addr (high, subnet -> netmask);
-       min = host_addr (low, subnet -> netmask);
-
-       /* Allow range to be specified high-to-low as well as low-to-high. */
-       if (min > max) {
-               max = min;
-               min = host_addr (high, subnet -> netmask);
-       }
-
-       /* Get a lease structure for each address in the range. */
-       address_range = new_leases (max - min + 1, "new_address_range");
-       if (!address_range) {
-               strcpy (lowbuf, piaddr (low));
-               strcpy (highbuf, piaddr (high));
-               error ("No memory for address range %s-%s.", lowbuf, highbuf);
-       }
-       memset (address_range, 0, (sizeof *address_range) * (max - min + 1));
-
-       /* Fill in the last lease if it hasn't been already... */
-       if (!share -> last_lease) {
-               share -> last_lease = &address_range [0];
-       }
-
-       /* Fill out the lease structures with some minimal information. */
-       for (i = 0; i < max - min + 1; i++) {
-               address_range [i].ip_addr =
-                       ip_addr (subnet -> net, subnet -> netmask, i + min);
-               address_range [i].starts =
-                       address_range [i].timestamp = MIN_TIME;
-               address_range [i].ends = MIN_TIME;
-               address_range [i].subnet = subnet;
-               address_range [i].shared_network = share;
-               address_range [i].flags = dynamic ? DYNAMIC_BOOTP_OK : 0;
-
-               memcpy (&ia, address_range [i].ip_addr.iabuf, 4);
-
-               if (subnet -> group -> get_lease_hostnames) {
-                       h = gethostbyaddr ((char *)&ia, sizeof ia, AF_INET);
-                       if (!h)
-                               warn ("No hostname for %s", inet_ntoa (ia));
-                       else {
-                               address_range [i].hostname =
-                                       malloc (strlen (h -> h_name) + 1);
-                               if (!address_range [i].hostname)
-                                       error ("no memory for hostname %s.",
-                                              h -> h_name);
-                               strcpy (address_range [i].hostname,
-                                       h -> h_name);
-                       }
-               }
-
-               /* Link this entry into the list. */
-               address_range [i].next = share -> leases;
-               address_range [i].prev = (struct lease *)0;
-               share -> leases = &address_range [i];
-               if (address_range [i].next)
-                       address_range [i].next -> prev = share -> leases;
-               add_hash (lease_ip_addr_hash,
-                         address_range [i].ip_addr.iabuf,
-                         address_range [i].ip_addr.len,
-                         (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 iaddr lnet;
-               int lhost;
-
-               lnet = subnet_number (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 (addr_eq (lnet, subnet -> net) &&
-                   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, 0);
-                       free_lease (lp, "new_address_range");
-               } else
-                       plp = lp;
-       }
-}
-
-struct subnet *find_subnet (addr)
-       struct iaddr addr;
-{
-       struct subnet *rv;
-
-       for (rv = subnets; rv; rv = rv -> next_subnet) {
-               if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net))
-                       return rv;
-       }
-       return (struct subnet *)0;
-}
-
-struct subnet *find_grouped_subnet (share, addr)
-       struct shared_network *share;
-       struct iaddr addr;
-{
-       struct subnet *rv;
-
-       for (rv = share -> subnets; rv; rv = rv -> next_sibling) {
-               if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net))
-                       return rv;
-       }
-       return (struct subnet *)0;
-}
-
-/* Enter a new subnet into the subnet list. */
-
-void enter_subnet (subnet)
-       struct subnet *subnet;
-{
-       struct subnet *scan;
-
-       /* Check for duplicates... */
-       for (scan = subnets; scan; scan = scan -> next_subnet) {
-               if (addr_eq (subnet_number (subnet -> net, scan -> netmask),
-                            scan -> net) ||
-                   addr_eq (subnet_number (scan -> net, subnet -> netmask),
-                            subnet -> net)) {
-                       char n1buf [16];
-                       int i, j;
-                       for (i = 0; i < 32; i++)
-                               if (subnet -> netmask.iabuf [3 - (i >> 3)]
-                                   & (1 << (i & 7)))
-                                       break;
-                       for (j = 0; j < 32; j++)
-                               if (scan -> netmask.iabuf [3 - (j >> 3)]
-                                   & (1 << (j & 7)))
-                                       break;
-                       strcpy (n1buf, piaddr (subnet -> net));
-                       error ("subnet %s/%d conflicts with subnet %s/%d",
-                              n1buf, i, piaddr (scan -> net), j);
-               }
-       }
-
-       /* XXX Sort the nets into a balanced tree to make searching quicker. */
-       subnet -> next_subnet = subnets;
-       subnets = subnet;
-}
-       
-/* Enter a new shared network into the shared network list. */
-
-void enter_shared_network (share)
-       struct shared_network *share;
-{
-       /* XXX Sort the nets into a balanced tree to make searching quicker. */
-       share -> next = shared_networks;
-       shared_networks = share;
-}
-       
-/* 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",
-                              piaddr (lease -> ip_addr));
-               }
-               *comp = *lease;
-               lease -> next = dangling_leases;
-               lease -> prev = (struct lease *)0;
-               dangling_leases = lease;
-       } else {
-               supersede_lease (comp, lease, 0);
-       }
-}
-
-/* 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. */
-
-int supersede_lease (comp, lease, commit)
-       struct lease *comp, *lease;
-       int commit;
-{
-       int enter_uid = 0;
-       int enter_hwaddr = 0;
-       struct lease *lp;
-
-       /* Static leases are not currently kept in the database... */
-       if (lease -> flags & STATIC_LEASE)
-               return 1;
-
-       /* 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 the existing lease has a uid
-          and the new one doesn't, but they both have the same
-          hardware address, and dynamic bootp is allowed on this
-          lease, then we allow that, in case a dynamic BOOTP lease is
-          requested *after* a DHCP lease has been assigned. */
-
-       if (comp -> ends > cur_time &&
-           ((comp -> uid && (lease -> uid ||
-                             !(lease -> flags & DYNAMIC_BOOTP_OK)) &&
-             (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",
-                     piaddr (comp -> ip_addr));
-               return 0;
-       } 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 != lease -> uid) {
-                               uid_hash_delete (comp);
-                               enter_uid = 1;
-                               free (comp -> uid);
-                               comp -> uid = (unsigned char *)0;
-                       }
-               } else
-                       enter_uid = 1;
-
-               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))) {
-                       hw_hash_delete (comp);
-                       enter_hwaddr = 1;
-               } else if (!comp -> hardware_addr.htype)
-                       enter_hwaddr = 1;
-
-               /* Copy the data files, but not the linkages. */
-               comp -> starts = lease -> starts;
-               comp -> offered_expiry = lease -> offered_expiry;
-               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;
-               comp -> flags = ((lease -> flags & ~PERSISTENT_FLAGS) |
-                                (comp -> flags & ~EPHEMERAL_FLAGS));
-
-               /* Record the lease in the uid hash if necessary. */
-               if (enter_uid && lease -> uid) {
-                       uid_hash_add (comp);
-               }
-
-               /* Record it in the hardware address hash if necessary. */
-               if (enter_hwaddr && lease -> hardware_addr.htype) {
-                       hw_hash_add (comp);
-               }
-
-               /* Remove the lease from its current place in the 
-                  timeout sequence. */
-               if (comp -> prev) {
-                       comp -> prev -> next = comp -> next;
-               } else {
-                       comp -> shared_network -> leases = comp -> next;
-               }
-               if (comp -> next) {
-                       comp -> next -> prev = comp -> prev;
-               }
-               if (comp -> shared_network -> last_lease == comp) {
-                       comp -> shared_network -> last_lease = comp -> prev;
-               }
-
-               /* Find the last insertion point... */
-               if (comp == comp -> shared_network -> insertion_point ||
-                   !comp -> shared_network -> insertion_point) {
-                       lp = comp -> shared_network -> leases;
-               } else {
-                       lp = comp -> shared_network -> insertion_point;
-               }
-
-               if (!lp) {
-                       /* Nothing on the list yet?    Just make comp the
-                          head of the list. */
-                       comp -> shared_network -> leases = comp;
-                       comp -> shared_network -> last_lease = comp;
-               } else if (lp -> ends > lease -> ends) {
-                       /* Skip down the list until we run out of list
-                          or find a place for comp. */
-                       while (lp -> next && lp -> ends > lease -> ends) {
-                               lp = lp -> next;
-                       }
-                       if (lp -> ends > lease -> ends) {
-                               /* If we ran out of list, put comp
-                                  at the end. */
-                               lp -> next = comp;
-                               comp -> prev = lp;
-                               comp -> next = (struct lease *)0;
-                               comp -> shared_network -> last_lease = comp;
-                       } else {
-                               /* If we didn't, put it between lp and
-                                  the previous item on the list. */
-                               if ((comp -> prev = lp -> prev))
-                                       comp -> prev -> next = comp;
-                               comp -> next = lp;
-                               lp -> prev = comp;
-                       }
-               } else {
-                       /* Skip up the list until we run out of list
-                          or find a place for comp. */
-                       while (lp -> prev && lp -> ends < lease -> ends) {
-                               lp = lp -> prev;
-                       }
-                       if (lp -> ends < lease -> ends) {
-                               /* If we ran out of list, put comp
-                                  at the beginning. */
-                               lp -> prev = comp;
-                               comp -> next = lp;
-                               comp -> prev = (struct lease *)0;
-                               comp -> shared_network -> leases = comp;
-                       } else {
-                               /* If we didn't, put it between lp and
-                                  the next item on the list. */
-                               if ((comp -> next = lp -> next))
-                                       comp -> next -> prev = comp;
-                               comp -> prev = lp;
-                               lp -> next = comp;
-                       }
-               }
-               comp -> shared_network -> insertion_point = comp;
-               comp -> ends = lease -> ends;
-       }
-
-       /* Return zero if we didn't commit the lease to permanent storage;
-          nonzero if we did. */
-       return commit && write_lease (comp) && commit_leases ();
-}
-
-/* Release the specified lease and re-hash it as appropriate. */
-
-void release_lease (lease)
-       struct lease *lease;
-{
-       struct lease lt;
-
-       lt = *lease;
-       lt.ends = cur_time;
-       supersede_lease (lease, &lt, 1);
-}
-
-/* Abandon the specified lease (set its timeout to infinity and its
-   particulars to zero, and re-hash it as appropriate. */
-
-void abandon_lease (lease)
-       struct lease *lease;
-{
-       struct lease lt;
-
-       lt = *lease;
-       lt.ends = 0xFFFFFFFF;
-       warn ("Abandoning IP address %s\n",
-             piaddr (lease -> ip_addr));
-       lt.hardware_addr.htype = -1;
-       lt.hardware_addr.hlen = 0;
-       lt.uid = (unsigned char *)0;
-       lt.uid_len = 0;
-       supersede_lease (lease, &lt, 1);
-}
-
-/* Locate the lease associated with a given IP address... */
-
-struct lease *find_lease_by_ip_addr (addr)
-       struct iaddr addr;
-{
-       struct lease *lease = (struct lease *)hash_lookup (lease_ip_addr_hash,
-                                                          addr.iabuf,
-                                                          addr.len);
-       return lease;
-}
-
-struct lease *find_lease_by_uid (uid, len)
-       unsigned char *uid;
-       int len;
-{
-       struct lease *lease = (struct lease *)hash_lookup (lease_uid_hash,
-                                                          uid, len);
-       return lease;
-}
-
-struct lease *find_lease_by_hw_addr (hwaddr, hwlen)
-       unsigned char *hwaddr;
-       int hwlen;
-{
-       struct lease *lease = (struct lease *)hash_lookup (lease_hw_addr_hash,
-                                                          hwaddr, hwlen);
-       return lease;
-}
-
-/* Add the specified lease to the uid hash. */
-
-void uid_hash_add (lease)
-       struct lease *lease;
-{
-       struct lease *head =
-               find_lease_by_uid (lease -> uid, lease -> uid_len);
-       struct lease *scan;
-
-#ifdef DEBUG
-       if (lease -> n_uid)
-               abort ();
-#endif
-
-       /* If it's not in the hash, just add it. */
-       if (!head)
-               add_hash (lease_uid_hash, lease -> uid,
-                         lease -> uid_len, (unsigned char *)lease);
-       else {
-               /* Otherwise, attach it to the end of the list. */
-               for (scan = head; scan -> n_uid; scan = scan -> n_uid)
-#ifdef DEBUG
-                       if (scan == lease)
-                               abort ()
-#endif
-                                       ;
-               scan -> n_uid = lease;
-       }
-}
-
-/* Delete the specified lease from the uid hash. */
-
-void uid_hash_delete (lease)
-       struct lease *lease;
-{
-       struct lease *head =
-               find_lease_by_uid (lease -> uid, lease -> uid_len);
-       struct lease *scan;
-
-       /* If it's not in the hash, we have no work to do. */
-       if (!head) {
-               lease -> n_uid = (struct lease *)0;
-               return;
-       }
-
-       /* If the lease we're freeing is at the head of the list,
-          remove the hash table entry and add a new one with the
-          next lease on the list (if there is one). */
-       if (head == lease) {
-               delete_hash_entry (lease_uid_hash,
-                                  lease -> uid, lease -> uid_len);
-               if (lease -> n_uid)
-                       add_hash (lease_uid_hash,
-                                 lease -> n_uid -> uid,
-                                 lease -> n_uid -> uid_len,
-                                 (unsigned char *)(lease -> n_uid));
-       } else {
-               /* Otherwise, look for the lease in the list of leases
-                  attached to the hash table entry, and remove it if
-                  we find it. */
-               for (scan = head; scan -> n_uid; scan = scan -> n_uid) {
-                       if (scan -> n_uid == lease) {
-                               scan -> n_uid = scan -> n_uid -> n_uid;
-                               break;
-                       }
-               }
-       }
-       lease -> n_uid = (struct lease *)0;
-}
-
-/* Add the specified lease to the hardware address hash. */
-
-void hw_hash_add (lease)
-       struct lease *lease;
-{
-       struct lease *head =
-               find_lease_by_hw_addr (lease -> hardware_addr.haddr,
-                                      lease -> hardware_addr.hlen);
-       struct lease *scan;
-
-       /* If it's not in the hash, just add it. */
-       if (!head)
-               add_hash (lease_hw_addr_hash,
-                         lease -> hardware_addr.haddr,
-                         lease -> hardware_addr.hlen,
-                         (unsigned char *)lease);
-       else {
-               /* Otherwise, attach it to the end of the list. */
-               for (scan = head; scan -> n_hw; scan = scan -> n_hw)
-                       ;
-               scan -> n_hw = lease;
-       }
-}
-
-/* Delete the specified lease from the hardware address hash. */
-
-void hw_hash_delete (lease)
-       struct lease *lease;
-{
-       struct lease *head =
-               find_lease_by_hw_addr (lease -> hardware_addr.haddr,
-                                      lease -> hardware_addr.hlen);
-       struct lease *scan;
-
-       /* If it's not in the hash, we have no work to do. */
-       if (!head) {
-               lease -> n_hw = (struct lease *)0;
-               return;
-       }
-
-       /* If the lease we're freeing is at the head of the list,
-          remove the hash table entry and add a new one with the
-          next lease on the list (if there is one). */
-       if (head == lease) {
-               delete_hash_entry (lease_hw_addr_hash,
-                                  lease -> hardware_addr.haddr,
-                                  lease -> hardware_addr.hlen);
-               if (lease -> n_hw)
-                       add_hash (lease_hw_addr_hash,
-                                 lease -> n_hw -> hardware_addr.haddr,
-                                 lease -> n_hw -> hardware_addr.hlen,
-                                 (unsigned char *)(lease -> n_hw));
-       } else {
-               /* Otherwise, look for the lease in the list of leases
-                  attached to the hash table entry, and remove it if
-                  we find it. */
-               for (scan = head; scan -> n_hw; scan = scan -> n_hw) {
-                       if (scan -> n_hw == lease) {
-                               scan -> n_hw = scan -> n_hw -> n_hw;
-                               break;
-                       }
-               }
-       }
-       lease -> n_hw = (struct lease *)0;
-}
-
-
-struct class *add_class (type, name)
-       int type;
-       char *name;
-{
-       struct class *class = new_class ("add_class");
-       char *tname = (char *)malloc (strlen (name) + 1);
-
-       if (!vendor_class_hash)
-               vendor_class_hash = new_hash ();
-       if (!user_class_hash)
-               user_class_hash = new_hash ();
-
-       if (!tname || !class || !vendor_class_hash || !user_class_hash)
-               return (struct class *)0;
-
-       memset (class, 0, sizeof *class);
-       strcpy (tname, name);
-       class -> name = tname;
-
-       if (type)
-               add_hash (user_class_hash,
-                         tname, strlen (tname), (unsigned char *)class);
-       else
-               add_hash (vendor_class_hash,
-                         tname, strlen (tname), (unsigned char *)class);
-       return class;
-}
-
-struct class *find_class (type, name, len)
-       int type;
-       char *name;
-       int len;
-{
-       struct class *class =
-               (struct class *)hash_lookup (type
-                                            ? user_class_hash
-                                            : vendor_class_hash, name, len);
-       return class;
-}      
-
-struct group *clone_group (group, caller)
-       struct group *group;
-       char *caller;
-{
-       struct group *g = new_group (caller);
-       if (!g)
-               error ("%s: can't allocate new group", caller);
-       *g = *group;
-       return g;
-}
-
-/* Write all interesting leases to permanent storage. */
-
-void write_leases ()
-{
-       struct lease *l;
-       struct shared_network *s;
-
-       for (s = shared_networks; s; s = s -> next) {
-               for (l = s -> leases; l; l = l -> next) {
-                       if (l -> hardware_addr.hlen || l -> uid_len)
-                               if (!write_lease (l))
-                                       error ("Can't rewrite lease database");
-               }
-       }
-       if (!commit_leases ())
-               error ("Can't commit leases to new database: %m");
-}
-
-void dump_subnets ()
-{
-       struct lease *l;
-       struct shared_network *s;
-       struct subnet *n;
-
-       for (s = shared_networks; s; s = s -> next) {
-               for (n = subnets; n; n = n -> next_sibling) {
-                       debug ("Subnet %s", piaddr (n -> net));
-                       debug ("   netmask %s",
-                              piaddr (n -> netmask));
-               }
-               for (l = s -> leases; l; l = l -> next) {
-                       print_lease (l);
-               }
-               debug ("Last Lease:");
-               print_lease (s -> last_lease);
-       }
-}
diff --git a/nit.c b/nit.c
deleted file mode 100644 (file)
index 77c2ea1..0000000
--- a/nit.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/* nit.c
-
-   Network Interface Tap (NIT) network interface code, by Ted Lemon
-   with one crucial tidbit of help from Stu Grossmen. */
-
-/*
- * Copyright (c) 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.  */
-
-#ifndef lint
-static char copyright[] =
-"$Id: nit.c,v 1.12 1997/02/19 10:49:20 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#if defined (USE_NIT_SEND) || defined (USE_NIT_RECEIVE)
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include <sys/time.h>
-#include <net/nit.h>
-#include <net/nit_if.h>
-#include <net/nit_pf.h>
-#include <net/nit_buf.h>
-#include <sys/stropts.h>
-#include <net/packetfilt.h>
-
-#include <netinet/in_systm.h>
-#include "includes/netinet/ip.h"
-#include "includes/netinet/udp.h"
-#include "includes/netinet/if_ether.h"
-
-/* Reinitializes the specified interface after an address change.   This
-   is not required for packet-filter APIs. */
-
-#ifdef USE_NIT_SEND
-void if_reinitialize_send (info)
-       struct interface_info *info;
-{
-}
-#endif
-
-#ifdef USE_NIT_RECEIVE
-void if_reinitialize_receive (info)
-       struct interface_info *info;
-{
-}
-#endif
-
-/* Called by get_interface_list for each interface that's discovered.
-   Opens a packet filter for each interface and adds it to the select
-   mask. */
-
-int if_register_nit (info)
-       struct interface_info *info;
-{
-       int sock;
-       char filename[50];
-       struct ifreq ifr;
-       struct strioctl sio;
-
-       /* Open a NIT device */
-       sock = open ("/dev/nit", O_RDWR);
-       if (sock < 0)
-               error ("Can't open NIT device for %s: %m", info -> name);
-
-       /* Set the NIT device to point at this interface. */
-       sio.ic_cmd = NIOCBIND;
-       sio.ic_len = sizeof *(info -> ifp);
-       sio.ic_dp = (char *)(info -> ifp);
-       sio.ic_timout = INFTIM;
-       if (ioctl (sock, I_STR, &sio) < 0)
-               error ("Can't attach interface %s to nit device: %m",
-                      info -> name);
-
-       /* Get the low-level address... */
-       sio.ic_cmd = SIOCGIFADDR;
-       sio.ic_len = sizeof ifr;
-       sio.ic_dp = (char *)&ifr;
-       sio.ic_timout = INFTIM;
-       if (ioctl (sock, I_STR, &sio) < 0)
-               error ("Can't get physical layer address for %s: %m",
-                      info -> name);
-
-       /* XXX code below assumes ethernet interface! */
-       info -> hw_address.hlen = 6;
-       info -> hw_address.htype = ARPHRD_ETHER;
-       memcpy (info -> hw_address.haddr, ifr.ifr_ifru.ifru_addr.sa_data, 6);
-
-       if (ioctl (sock, I_PUSH, "pf") < 0)
-               error ("Can't push packet filter onto NIT for %s: %m",
-                      info -> name);
-
-       return sock;
-}
-#endif /* USE_NIT_SEND || USE_NIT_RECEIVE */
-
-#ifdef USE_NIT_SEND
-void if_register_send (info)
-       struct interface_info *info;
-{
-       /* If we're using the nit API for sending and receiving,
-          we don't need to register this interface twice. */
-#ifndef USE_NIT_RECEIVE
-       struct packetfilt pf;
-       struct strioctl sio;
-
-       info -> wfdesc = if_register_nit (info);
-
-       pf.Pf_Priority = 0;
-       pf.Pf_FilterLen = 1;
-       pf.Pf_Filter [0] = ENF_PUSHZERO;
-
-       /* Set up an NIT filter that rejects everything... */
-       sio.ic_cmd = NIOCSETF;
-       sio.ic_len = sizeof pf;
-       sio.ic_dp = (char *)&pf;
-       sio.ic_timout = INFTIM;
-       if (ioctl (info -> wfdesc, I_STR, &sio) < 0)
-               error ("Can't set NIT filter: %m");
-#else
-       info -> wfdesc = info -> rfdesc;
-#endif
-       note ("Sending on   NIT/%s/%s",
-             print_hw_addr (info -> hw_address.htype,
-                            info -> hw_address.hlen,
-                            info -> hw_address.haddr),
-             (info -> shared_network ?
-              info -> shared_network -> name : "unattached"));
-}
-#endif /* USE_NIT_SEND */
-
-#ifdef USE_NIT_RECEIVE
-/* Packet filter program...
-   XXX Changes to the filter program may require changes to the constant
-   offsets used in if_register_send to patch the NIT program! XXX */
-
-void if_register_receive (info)
-       struct interface_info *info;
-{
-       int flag = 1;
-       u_int32_t x;
-       struct packetfilt pf;
-       struct strioctl sio;
-       u_int16_t addr [2];
-       struct timeval t;
-
-       /* Open a NIT device and hang it on this interface... */
-       info -> rfdesc = if_register_nit (info);
-
-       /* Set the snap length to 0, which means always take the whole
-          packet. */
-       x = 0;
-       if (ioctl (info -> rfdesc, NIOCSSNAP, &x) < 0)
-               error ("Can't set NIT snap length on %s: %m", info -> name);
-
-       /* Set the stream to byte stream mode */
-       if (ioctl (info -> rfdesc, I_SRDOPT, RMSGN) != 0)
-               note ("I_SRDOPT failed on %s: %m", info -> name);
-
-#if 0
-       /* Push on the chunker... */
-       if (ioctl (info -> rfdesc, I_PUSH, "nbuf") < 0)
-               error ("Can't push chunker onto NIT STREAM: %m");
-
-       /* Set the timeout to zero. */
-       t.tv_sec = 0;
-       t.tv_usec = 0;
-       if (ioctl (info -> rfdesc, NIOCSTIME, &t) < 0)
-               error ("Can't set chunk timeout: %m");
-#endif
-
-       /* Ask for no header... */
-       x = 0;
-       if (ioctl (info -> rfdesc, NIOCSFLAGS, &x) < 0)
-               error ("Can't set NIT flags on %s: %m", info -> name);
-
-       /* Set up the NIT filter program. */
-       /* XXX Unlike the BPF filter program, this one won't work if the
-          XXX IP packet is fragmented or if there are options on the IP
-          XXX header. */
-       pf.Pf_Priority = 0;
-       pf.Pf_FilterLen = 0;
-
-       pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 6;
-       pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
-       pf.Pf_Filter [pf.Pf_FilterLen++] = htons (ETHERTYPE_IP);
-       pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT;
-       pf.Pf_Filter [pf.Pf_FilterLen++] = htons (IPPROTO_UDP);
-       pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 11;
-       pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_AND;
-       pf.Pf_Filter [pf.Pf_FilterLen++] = htons (0xFF);
-       pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_CAND;
-       pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 18;
-       pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
-       pf.Pf_Filter [pf.Pf_FilterLen++] = local_port;
-
-       /* Install the filter... */
-       sio.ic_cmd = NIOCSETF;
-       sio.ic_len = sizeof pf;
-       sio.ic_dp = (char *)&pf;
-       sio.ic_timout = INFTIM;
-       if (ioctl (info -> rfdesc, I_STR, &sio) < 0)
-               error ("Can't set NIT filter on %s: %m", info -> name);
-
-       note ("Listening on NIT/%s/%s",
-             print_hw_addr (info -> hw_address.htype,
-                            info -> hw_address.hlen,
-                            info -> hw_address.haddr),
-             (info -> shared_network ?
-              info -> shared_network -> name : "unattached"));
-}
-#endif /* USE_NIT_RECEIVE */
-
-#ifdef USE_NIT_SEND
-size_t send_packet (interface, packet, raw, len, from, to, hto)
-       struct interface_info *interface;
-       struct packet *packet;
-       struct dhcp_packet *raw;
-       size_t len;
-       struct in_addr from;
-       struct sockaddr_in *to;
-       struct hardware *hto;
-{
-       int bufp;
-       unsigned char buf [1536 + sizeof (struct sockaddr)];
-       struct sockaddr *junk;
-       struct strbuf ctl, data;
-       int hw_end;
-       struct sockaddr_in foo;
-
-       /* Start with the sockaddr struct... */
-       junk = (struct sockaddr *)&buf [0];
-       bufp = ((unsigned char *)&junk -> sa_data [0]) - &buf [0];
-
-       /* Assemble the headers... */
-       assemble_hw_header (interface, buf, &bufp, hto);
-       hw_end = bufp;
-       assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
-                               to -> sin_addr.s_addr, to -> sin_port,
-                               raw, len);
-
-       /* Copy the data into the buffer (yuk). */
-       memcpy (buf + bufp, raw, len);
-
-       /* Set up the sockaddr structure... */
-#if USE_SIN_LEN
-       junk -> sa_len = hw_end - 2; /* XXX */
-#endif
-       junk -> sa_family = AF_UNSPEC;
-
-#if 0 /* Already done. */
-       memcpy (junk.sa_data, buf, hw_len);
-#endif
-
-       /* Set up the msg_buf structure... */
-       ctl.buf = (char *)&buf [0];
-       ctl.maxlen = ctl.len = hw_end;
-       data.buf = (char *)&buf [hw_end];
-       data.maxlen = data.len = bufp + len - hw_end;
-
-       return putmsg (interface -> wfdesc, &ctl, &data, 0);
-}
-#endif /* USE_NIT_SEND */
-
-#ifdef USE_NIT_RECEIVE
-size_t receive_packet (interface, buf, len, from, hfrom)
-       struct interface_info *interface;
-       unsigned char *buf;
-       size_t len;
-       struct sockaddr_in *from;
-       struct hardware *hfrom;
-{
-       int nread;
-       int length = 0;
-       int offset = 0;
-       unsigned char ibuf [1536];
-       int bufix = 0;
-
-       length = read (interface -> rfdesc, ibuf, sizeof ibuf);
-       if (length <= 0)
-               return length;
-
-       /* Decode the physical header... */
-       offset = decode_hw_header (interface, ibuf, bufix, hfrom);
-
-       /* If a physical layer checksum failed (dunno of any
-          physical layer that supports this, but WTH), skip this
-          packet. */
-       if (offset < 0) {
-               return 0;
-       }
-
-       bufix += offset;
-       length -= offset;
-
-       /* Decode the IP and UDP headers... */
-       offset = decode_udp_ip_header (interface, ibuf, bufix,
-                                      from, (unsigned char *)0, length);
-
-       /* If the IP or UDP checksum was bad, skip the packet... */
-       if (offset < 0)
-               return 0;
-
-       bufix += offset;
-       length -= offset;
-
-       /* Copy out the data in the packet... */
-       memcpy (buf, &ibuf [bufix], length);
-       return length;
-}
-#endif
-
-#if defined (USE_NIT_SEND)
-void if_enable (interface)
-       struct interface_info *interface;
-{
-       struct ifreq ifr;
-
-       /* Bring the interface down and then up again to clear
-        * all its routes. */
-       strncpy(ifr.ifr_name, interface -> name, IFNAMSIZ);
-       if (ioctl(interface -> rfdesc, SIOCGIFFLAGS, &ifr) < 0)
-               error ("SIOCGIFFLAGS %s: %m", interface -> name);
-
-       ifr.ifr_flags |= (IFF_UP|IFF_RUNNING);
-       if (ioctl(interface -> rfdesc, SIOCSIFFLAGS, &ifr) == -1)
-               error ("SIOCSIFFLAGS %s: %m", interface -> name);
-}
-#endif
diff --git a/options.c b/options.c
deleted file mode 100644 (file)
index 6d18ad5..0000000
--- a/options.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/* options.c
-
-   DHCP options parsing and reassembly. */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: options.c,v 1.22 1997/02/22 08:32:04 mellon Exp $ Copyright (c) 1995, 1996 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_NON_UDP - 4);
-       /* 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
-                                       + 1);
-                       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 options into a big buffer, and then split them out into the
-   three seperate buffers if needed.  This allows us to cons up a set
-   of vendor options using the same routine. */
-
-int cons_options (inpacket, outpacket, options, overload, terminate)
-       struct packet *inpacket;
-       struct dhcp_packet *outpacket;
-       struct tree_cache **options;
-       int overload;   /* Overload flags that may be set. */
-       int terminate;
-{
-       unsigned char priority_list [300];
-       int priority_len;
-       unsigned char buffer [4096];    /* Really big buffer... */
-       int main_buffer_size;
-       int mainbufix, bufix;
-       int option_size;
-       int 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 && inpacket -> options [DHO_DHCP_MAX_MESSAGE_SIZE].data) {
-               main_buffer_size =
-                       (getUShort (inpacket -> options
-                                   [DHO_DHCP_MAX_MESSAGE_SIZE].data)
-                        - DHCP_FIXED_LEN);
-               /* Enforce a minimum packet size... */
-               if (main_buffer_size < (576 - DHCP_FIXED_LEN))
-                       main_buffer_size = 576 - DHCP_FIXED_LEN;
-       } else
-               main_buffer_size = 576 - DHCP_FIXED_LEN;
-
-       /* Preload the option priority list with mandatory options. */
-       priority_len = 0;
-       priority_list [priority_len++] = DHO_DHCP_MESSAGE_TYPE;
-       priority_list [priority_len++] = DHO_DHCP_SERVER_IDENTIFIER;
-       priority_list [priority_len++] = DHO_DHCP_LEASE_TIME;
-       priority_list [priority_len++] = DHO_DHCP_MESSAGE;
-
-       /* If the client has provided a list of options that it wishes
-          returned, use it to prioritize.  Otherwise, prioritize
-          based on the default priority list. */
-
-       if (inpacket &&
-           inpacket -> options [DHO_DHCP_PARAMETER_REQUEST_LIST].data) {
-               memcpy (&priority_list [priority_len],
-                       inpacket -> options
-                               [DHO_DHCP_PARAMETER_REQUEST_LIST].data,
-                       inpacket -> options
-                               [DHO_DHCP_PARAMETER_REQUEST_LIST].len);
-               priority_len +=
-                       inpacket -> options
-                               [DHO_DHCP_PARAMETER_REQUEST_LIST].len;
-       } else {
-               memcpy (&priority_list [priority_len],
-                       dhcp_option_default_priority_list,
-                       sizeof_dhcp_option_default_priority_list);
-               priority_len += sizeof_dhcp_option_default_priority_list;
-       }
-
-       /* Copy the options into the big buffer... */
-       option_size = store_options (buffer,
-                                    (main_buffer_size - 7 +
-                                     ((overload & 1) ? DHCP_FILE_LEN : 0) +
-                                     ((overload & 2) ? DHCP_SNAME_LEN : 0)),
-                                    options, priority_list, priority_len,
-                                    main_buffer_size,
-                                    (main_buffer_size +
-                                     ((overload & 1) ? DHCP_FILE_LEN : 0)),
-                                    terminate);
-
-       /* Put the cookie up front... */
-       memcpy (outpacket -> options, DHCP_OPTIONS_COOKIE, 4);
-       mainbufix = 4;
-
-       /* If we're going to have to overload, store the overload
-          option at the beginning.  If we can, though, just store the
-          whole thing in the packet's option buffer and leave it at
-          that. */
-       if (option_size <= main_buffer_size - mainbufix) {
-               memcpy (&outpacket -> options [mainbufix],
-                       buffer, option_size);
-               mainbufix += option_size;
-               if (mainbufix < main_buffer_size)
-                       outpacket -> options [mainbufix++]
-                               = DHO_END;
-               length = DHCP_FIXED_NON_UDP + mainbufix;
-       } else {
-               outpacket -> options [mainbufix++] =
-                       DHO_DHCP_OPTION_OVERLOAD;
-               outpacket -> options [mainbufix++] = 1;
-               if (option_size > main_buffer_size - mainbufix + DHCP_FILE_LEN)
-                       outpacket -> options [mainbufix++] = 3;
-               else
-                       outpacket -> options [mainbufix++] = 1;
-
-               memcpy (&outpacket -> options [mainbufix],
-                       buffer, main_buffer_size - mainbufix);
-               bufix = main_buffer_size - mainbufix;
-               length = DHCP_FIXED_NON_UDP + mainbufix;
-               if (overload & 1) {
-                       if (option_size - bufix <= DHCP_FILE_LEN) {
-                               memcpy (outpacket -> file,
-                                       &buffer [bufix], option_size - bufix);
-                               mainbufix = option_size - bufix;
-                               if (mainbufix < DHCP_FILE_LEN)
-                                       outpacket -> file [mainbufix++]
-                                               = DHO_END;
-                               while (mainbufix < DHCP_FILE_LEN)
-                                       outpacket -> file [mainbufix++]
-                                               = DHO_PAD;
-                       } else {
-                               memcpy (outpacket -> file,
-                                       &buffer [bufix], DHCP_FILE_LEN);
-                               bufix += DHCP_FILE_LEN;
-                       }
-               }
-               if ((overload & 2) && option_size < bufix) {
-                       memcpy (outpacket -> sname,
-                               &buffer [bufix], option_size - bufix);
-
-                       mainbufix = option_size - bufix;
-                       if (mainbufix < DHCP_SNAME_LEN)
-                               outpacket -> file [mainbufix++]
-                                       = DHO_END;
-                       while (mainbufix < DHCP_SNAME_LEN)
-                               outpacket -> file [mainbufix++]
-                                       = DHO_PAD;
-               }
-       }
-       return length;
-}
-
-/* Store all the requested options into the requested buffer. */
-
-int store_options (buffer, buflen, options, priority_list, priority_len,
-                  first_cutoff, second_cutoff, terminate)
-       unsigned char *buffer;
-       int buflen;
-       struct tree_cache **options;
-       unsigned char *priority_list;
-       int priority_len;
-       int first_cutoff, second_cutoff;
-       int terminate;
-{
-       int bufix = 0;
-       int option_stored [256];
-       int i;
-       int ix;
-       int tto;
-
-       /* Zero out the stored-lengths array. */
-       memset (option_stored, 0, sizeof option_stored);
-
-       /* Copy out the options in the order that they appear in the
-          priority list... */
-       for (i = 0; i < priority_len; i++) {
-               /* Code for next option to try to store. */
-               int code = priority_list [i];
-               int optstart;
-
-               /* 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 (!options [code]) {
-                       continue;
-               }
-
-               /* The client could ask for things that are mandatory,
-                  in which case we should avoid storing them twice... */
-               if (option_stored [code])
-                       continue;
-               option_stored [code] = 1;
-
-               /* Find the value of the option... */
-               if (!tree_evaluate (options [code])) {
-                       continue;
-               }
-
-               /* We should now have a constant length for the option. */
-               length = options [code] -> len;
-
-               /* Do we add a NUL? */
-               if (terminate && dhcp_options [code].format [0] == 't') {
-                       length++;
-                       tto = 1;
-               } else {
-                       tto = 0;
-               }
-
-               /* Try to store the option. */
-
-               /* If the option's length is more than 255, we must store it
-                  in multiple hunks.   Store 255-byte hunks first.  However,
-                  in any case, if the option data will cross a buffer
-                  boundary, split it across that boundary. */
-
-               ix = 0;
-
-               optstart = bufix;
-               while (length) {
-                       unsigned char incr = length > 255 ? 255 : length;
-
-                       /* If this hunk of the buffer will cross a
-                          boundary, only go up to the boundary in this
-                          pass. */
-                       if (bufix < first_cutoff &&
-                           bufix + incr > first_cutoff)
-                               incr = first_cutoff - bufix;
-                       else if (bufix < second_cutoff &&
-                                bufix + incr > second_cutoff)
-                               incr = second_cutoff - bufix;
-
-                       /* If this option is going to overflow the buffer,
-                          skip it. */
-                       if (bufix + 2 + incr > buflen) {
-                               bufix = optstart;
-                               break;
-                       }
-
-                       /* Everything looks good - copy it in! */
-                       buffer [bufix] = code;
-                       buffer [bufix + 1] = incr;
-                       if (tto && incr == length) {
-                               memcpy (buffer + bufix + 2,
-                                       options [code] -> value + ix,
-                                       incr - 1);
-                               buffer [bufix + 2 + incr - 1] = 0;
-                       } else {
-                               memcpy (buffer + bufix + 2,
-                                       options [code] -> value + ix, incr);
-                       }
-                       length -= incr;
-                       ix += incr;
-                       bufix += 2 + incr;
-               }
-       }
-       return bufix;
-}
-
-/* Format the specified option so that a human can easily read it. */
-
-char *pretty_print_option (code, data, len, emit_commas)
-       unsigned char code;
-       unsigned char *data;
-       int len;
-       int emit_commas;
-{
-       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;
-
-       /* 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':
-                               *op++ = '"';
-                               strcpy (op, dp);
-                               op += strlen (dp);
-                               *op++ = '"';
-                               *op = 0;
-                               break;
-                             case 'I':
-                               foo.s_addr = htonl (getULong (dp));
-                               strcpy (op, inet_ntoa (foo));
-                               dp += 4;
-                               break;
-                             case 'l':
-                               sprintf (op, "%ld", (long)getLong (dp));
-                               dp += 4;
-                               break;
-                             case 'L':
-                               sprintf (op, "%ld",
-                                        (unsigned long)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);
-                       if (j + 1 < numelem)
-                               *op++ = ' ';
-               }
-               if (i + 1 < numhunk) {
-                       if (emit_commas)
-                               *op++ = ',';
-                       *op++ = ' ';
-               }
-               
-       }
-       return optbuf;
-}
diff --git a/packet.c b/packet.c
deleted file mode 100644 (file)
index 1fc9a0b..0000000
--- a/packet.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/* packet.c
-
-   Packet assembly code, originally contributed by Archie Cobbs. */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: packet.c,v 1.12 1997/02/18 14:32:51 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#if defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING)
-#include <netinet/in_systm.h>
-#include "includes/netinet/ip.h"
-#include "includes/netinet/udp.h"
-#include "includes/netinet/if_ether.h"
-
-static u_int32_t checksum PROTO ((unsigned char *, int, u_int32_t));
-static u_int32_t wrapsum PROTO ((u_int32_t));
-
-/* Compute the easy part of the checksum on a range of bytes. */
-
-static u_int32_t checksum (buf, nbytes, sum)
-       unsigned char *buf;
-       int nbytes;
-       u_int32_t sum;
-{
-       int i;
-
-#ifdef DEBUG_CHECKSUM
-       debug ("checksum (%x %d %x)", buf, nbytes, sum);
-#endif
-
-       /* Checksum all the pairs of bytes first... */
-       for (i = 0; i < (nbytes & ~1); i += 2) {
-#ifdef DEBUG_CHECKSUM_VERBOSE
-               debug ("sum = %x", sum);
-#endif
-               sum += (u_int16_t) ntohs(*((u_int16_t *)buf)++);
-       }       
-
-       /* If there's a single byte left over, checksum it, too.   Network
-          byte order is big-endian, so the remaining byte is the high byte. */
-       if (i < nbytes) {
-#ifdef DEBUG_CHECKSUM_VERBOSE
-               debug ("sum = %x", sum);
-#endif
-               sum += (*buf) << 8;
-       }
-       
-       return sum;
-}
-
-/* Fold the upper sixteen bits of the checksum down into the lower bits,
-   complement the sum, and then put it into network byte order. */
-
-static u_int32_t wrapsum (sum)
-       u_int32_t sum;
-{
-#ifdef DEBUG_CHECKSUM
-       debug ("wrapsum (%x)", sum);
-#endif
-
-       while (sum > 0x10000) {
-               sum = (sum >> 16) + (sum & 0xFFFF);
-#ifdef DEBUG_CHECKSUM_VERBOSE
-               debug ("sum = %x", sum);
-#endif
-               sum += (sum >> 16);
-#ifdef DEBUG_CHECKSUM_VERBOSE
-               debug ("sum = %x", sum);
-#endif
-       }
-       sum = sum ^ 0xFFFF;
-#ifdef DEBUG_CHECKSUM_VERBOSE
-       debug ("sum = %x", sum);
-#endif
-       
-#ifdef DEBUG_CHECKSUM
-       debug ("wrapsum returns %x", htons (sum));
-#endif
-       return htons(sum);
-}
-#endif /* PACKET_ASSEMBLY || PACKET_DECODING */
-
-#ifdef PACKET_ASSEMBLY
-/* Assemble an hardware header... */
-/* XXX currently only supports ethernet; doesn't check for other types. */
-
-void assemble_hw_header (interface, buf, bufix, to)
-       struct interface_info *interface;
-       unsigned char *buf;
-       int *bufix;
-       struct hardware *to;
-{
-       struct ether_header eh;
-
-       if (to && to -> hlen == 6) /* XXX */
-               memcpy (eh.ether_dhost, to -> haddr, sizeof eh.ether_dhost);
-       else
-               memset (eh.ether_dhost, 0xff, sizeof (eh.ether_dhost));
-       if (interface -> hw_address.hlen == sizeof (eh.ether_shost))
-               memcpy (eh.ether_shost, interface -> hw_address.haddr,
-                       sizeof (eh.ether_shost));
-       else
-               memset (eh.ether_shost, 0x00, sizeof (eh.ether_shost));
-
-#ifdef BROKEN_FREEBSD_BPF /* Fixed in FreeBSD 2.2 */
-       eh.ether_type = ETHERTYPE_IP;
-#else
-       eh.ether_type = htons (ETHERTYPE_IP);
-#endif
-
-       memcpy (&buf [*bufix], &eh, sizeof eh);
-       *bufix += sizeof eh;
-}
-
-/* UDP header and IP header assembled together for convenience. */
-
-void assemble_udp_ip_header (interface, buf, bufix,
-                            from, to, port, data, len)
-       struct interface_info *interface;
-       unsigned char *buf;
-       int *bufix;
-       u_int32_t from;
-       u_int32_t to;
-       u_int16_t port;
-       unsigned char *data;
-       int len;
-{
-       struct ip ip;
-       struct udphdr udp;
-
-       /* Fill out the IP header */
-       ip.ip_v = 4;
-       ip.ip_hl = 5;
-       ip.ip_tos = IPTOS_LOWDELAY;
-       ip.ip_len = htons(sizeof(ip) + sizeof(udp) + len);
-       ip.ip_id = 0;
-       ip.ip_off = 0;
-       ip.ip_ttl = 16;
-       ip.ip_p = IPPROTO_UDP;
-       ip.ip_sum = 0;
-       ip.ip_src.s_addr = from;
-       ip.ip_dst.s_addr = to;
-       
-       /* Checksum the IP header... */
-       ip.ip_sum = wrapsum (checksum ((unsigned char *)&ip, sizeof ip, 0));
-       
-       /* Copy the ip header into the buffer... */
-       memcpy (&buf [*bufix], &ip, sizeof ip);
-       *bufix += sizeof ip;
-
-       /* Fill out the UDP header */
-       udp.uh_sport = local_port;              /* XXX */
-       udp.uh_dport = port;                    /* XXX */
-       udp.uh_ulen = htons(sizeof(udp) + len);
-       memset (&udp.uh_sum, 0, sizeof udp.uh_sum);
-
-       /* Compute UDP checksums, including the ``pseudo-header'', the UDP
-          header and the data. */
-
-#if 0
-       udp.uh_sum =
-               wrapsum (checksum ((unsigned char *)&udp, sizeof udp,
-                                  checksum (data, len, 
-                                            checksum ((unsigned char *)
-                                                      &ip.ip_src,
-                                                      sizeof ip.ip_src,
-                                                      IPPROTO_UDP +
-                                                      (u_int32_t)
-                                                      ntohs (udp.uh_ulen)))));
-#endif
-
-       /* Copy the udp header into the buffer... */
-       memcpy (&buf [*bufix], &udp, sizeof udp);
-       *bufix += sizeof udp;
-}
-#endif /* PACKET_ASSEMBLY */
-
-#ifdef PACKET_DECODING
-/* Decode a hardware header... */
-/* XXX currently only supports ethernet; doesn't check for other types. */
-
-size_t decode_hw_header (interface, buf, bufix, from)
-     struct interface_info *interface;
-     unsigned char *buf;
-     int bufix;
-     struct hardware *from;
-{
-  struct ether_header eh;
-
-  memcpy (&eh, buf + bufix, sizeof eh);
-
-#ifdef USERLAND_FILTER
-  if (ntohs (eh.ether_type) != ETHERTYPE_IP)
-         return -1;
-#endif
-  memcpy (from -> haddr, eh.ether_shost, sizeof (eh.ether_shost));
-  from -> htype = ARPHRD_ETHER;
-  from -> hlen = sizeof eh.ether_shost;
-
-  return sizeof eh;
-}
-
-/* UDP header and IP header decoded together for convenience. */
-
-size_t decode_udp_ip_header (interface, buf, bufix, from, data, len)
-       struct interface_info *interface;
-       unsigned char *buf;
-       int bufix;
-       struct sockaddr_in *from;
-       unsigned char *data;
-       int len;
-{
-  struct ip *ip;
-  struct udphdr *udp;
-  u_int32_t ip_len = (buf [bufix] & 0xf) << 2;
-  u_int32_t sum, usum;
-
-  ip = (struct ip *)(buf + bufix);
-  udp = (struct udphdr *)(buf + bufix + ip_len);
-
-#ifdef USERLAND_FILTER
-  /* Is it a UDP packet? */
-  if (ip -> ip_p != IPPROTO_UDP)
-         return -1;
-
-  /* Is it to the port we're serving? */
-  if (udp -> uh_dport != local_port)
-         return -1;
-#endif /* USERLAND_FILTER */
-
-  /* Check the IP header checksum - it should be zero. */
-  if (wrapsum (checksum (buf + bufix, ip_len, 0))) {
-         note ("Bad IP checksum: %x",
-               wrapsum (checksum (buf + bufix, sizeof *ip, 0)));
-         return -1;
-  }
-
-  /* Copy out the IP source address... */
-  memcpy (&from -> sin_addr, &ip -> ip_src, 4);
-
-  /* Compute UDP checksums, including the ``pseudo-header'', the UDP
-     header and the data.   If the UDP checksum field is zero, we're
-     not supposed to do a checksum. */
-
-  if (!data) {
-         data = buf + bufix + ip_len + sizeof *udp;
-         len -= ip_len + sizeof *udp;
-  }
-
-#if 0
-  usum = udp -> uh_sum;
-  udp -> uh_sum = 0;
-
-  sum = wrapsum (checksum ((unsigned char *)udp, sizeof *udp,
-                          checksum (data, len,
-                                    checksum ((unsigned char *)
-                                              &ip -> ip_src,
-                                              sizeof ip -> ip_src,
-                                              IPPROTO_UDP +
-                                              (u_int32_t)
-                                              ntohs (udp -> uh_ulen)))));
-
-  if (usum && usum != sum) {
-         note ("Bad udp checksum: %x %x", usum, sum);
-         return -1;
-  }
-#endif
-
-  /* Copy out the port... */
-  memcpy (&from -> sin_port, &udp -> uh_sport, sizeof udp -> uh_sport);
-
-  return ip_len + sizeof *udp;
-}
-#endif /* PACKET_DECODING */
diff --git a/parse.c b/parse.c
deleted file mode 100644 (file)
index 48ec6a4..0000000
--- a/parse.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/* parse.c
-
-   Common parser code for dhcpd and dhclient. */
-
-/*
- * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: parse.c,v 1.1 1997/02/18 14:27:33 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include "dhctoken.h"
-
-/* Skip to the semicolon ending the current statement.   If we encounter
-   braces, the matching closing brace terminates the statement.   If we
-   encounter a right brace but haven't encountered a left brace, return
-   leaving the brace in the token buffer for the caller.   If we see a
-   semicolon and haven't seen a left brace, return.   This lets us skip
-   over:
-
-       statement;
-       statement foo bar { }
-       statement foo bar { statement { } }
-       statement}
-       ...et cetera. */
-
-void skip_to_semi (cfile)
-       FILE *cfile;
-{
-       int token;
-       char *val;
-       int brace_count = 0;
-
-       do {
-               token = peek_token (&val, cfile);
-               if (token == RBRACE) {
-                       if (brace_count) {
-                               token = next_token (&val, cfile);
-                               if (!--brace_count)
-                                       return;
-                       } else
-                               return;
-               } else if (token == LBRACE) {
-                       brace_count++;
-               } else if (token == SEMI && !brace_count) {
-                       token = next_token (&val, cfile);
-                       return;
-               }
-               token = next_token (&val, cfile);
-       } while (token != EOF);
-}
-
-int parse_semi (cfile)
-       FILE *cfile;
-{
-       int token;
-       char *val;
-
-       token = next_token (&val, cfile);
-       if (token != SEMI) {
-               parse_warn ("semicolon expected.");
-               skip_to_semi (cfile);
-               return 0;
-       }
-       return 1;
-}
-
-/* string-parameter :== STRING SEMI */
-
-char *parse_string (cfile)
-       FILE *cfile;
-{
-       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);
-               return (char *)0;
-       }
-       s = (char *)malloc (strlen (val) + 1);
-       if (!s)
-               error ("no memory for string %s.", val);
-       strcpy (s, val);
-
-       if (!parse_semi (cfile))
-               return (char *)0;
-       return s;
-}
-
-/* hardware-parameter :== HARDWARE ETHERNET csns SEMI
-   csns :== NUMBER | csns COLON NUMBER */
-
-void parse_hardware_param (cfile, hardware)
-       FILE *cfile;
-       struct hardware *hardware;
-{
-       char *val;
-       int token;
-       int hlen;
-       unsigned char *t;
-
-       token = next_token (&val, cfile);
-       switch (token) {
-             case ETHERNET:
-               hardware -> htype = HTYPE_ETHER;
-               break;
-             case TOKEN_RING:
-               hardware -> htype = HTYPE_IEEE802;
-               break;
-             default:
-               parse_warn ("expecting a network hardware type");
-               skip_to_semi (cfile);
-               return;
-       }
-
-       /* Parse the hardware address information.   Technically,
-          it would make a lot of sense to restrict the length of the
-          data we'll accept here to the length of a particular hardware
-          address type.   Unfortunately, there are some broken clients
-          out there that put bogus data in the chaddr buffer, and we accept
-          that data in the lease file rather than simply failing on such
-          clients.   Yuck. */
-       hlen = 0;
-       t = parse_numeric_aggregate (cfile, (unsigned char *)0, &hlen,
-                                    COLON, 16, 8);
-       if (!t)
-               return;
-       if (hlen > sizeof hardware -> haddr) {
-               free (t);
-               parse_warn ("hardware address too long");
-       } else {
-               hardware -> hlen = hlen;
-               memcpy ((unsigned char *)&hardware -> haddr [0],
-                       t, hardware -> hlen);
-               free (t);
-       }
-       
-       token = next_token (&val, cfile);
-       if (token != SEMI) {
-               parse_warn ("expecting semicolon.");
-               skip_to_semi (cfile);
-       }
-}
-
-/* lease-time :== NUMBER SEMI */
-
-void parse_lease_time (cfile, timep)
-       FILE *cfile;
-       TIME *timep;
-{
-       char *val;
-       int token;
-
-       token = next_token (&val, cfile);
-       if (token != NUMBER) {
-               parse_warn ("Expecting numeric lease time");
-               skip_to_semi (cfile);
-               return;
-       }
-       convert_num ((unsigned char *)timep, val, 10, 32);
-       /* Unswap the number - convert_num returns stuff in NBO. */
-       *timep = ntohl (*timep); /* XXX */
-
-       parse_semi (cfile);
-}
-
-/* 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, buf,
-                                       max, seperator, base, size)
-       FILE *cfile;
-       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;
-                               if (token != RBRACE && token != LBRACE)
-                                       token = next_token (&val, cfile);
-                               parse_warn ("too few numbers.");
-                               if (token != SEMI)
-                                       skip_to_semi (cfile);
-                               return (unsigned char *)0;
-                       }
-                       token = next_token (&val, cfile);
-               }
-               token = next_token (&val, cfile);
-
-               if (token == EOF) {
-                       parse_warn ("unexpected end of file");
-                       break;
-               }
-
-               /* Allow NUMBER_OR_NAME if base is 16. */
-               if (token != NUMBER &&
-                   (base != 16 || token != NUMBER_OR_NAME)) {
-                       parse_warn ("expecting numeric value.");
-                       skip_to_semi (cfile);
-                       return (unsigned char *)0;
-               }
-               /* 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 = (unsigned 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 + count - size / 8;
-               *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)) + ((1 << (size - 1)) - 1);
-       if (val > max) {
-               switch (base) {
-                     case 8:
-                       warn ("value %s%o exceeds max (%d) for precision.",
-                             negative ? "-" : "", val, max);
-                       break;
-                     case 16:
-                       warn ("value %s%x exceeds max (%d) for precision.",
-                             negative ? "-" : "", val, max);
-                       break;
-                     default:
-                       warn ("value %s%u 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", size);
-                       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", size);
-                       break;
-               }
-       }
-}
-
-/* date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER 
-               NUMBER COLON NUMBER COLON NUMBER SEMI
-
-   Dates are always in GMT; first number is day of week; next is
-   year/month/day; next is hours:minutes:seconds on a 24-hour
-   clock. */
-
-TIME parse_date (cfile)
-       FILE *cfile;
-{
-       struct tm tm;
-       int guess;
-       char *val;
-       int token;
-       static int months [11] = { 31, 59, 90, 120, 151, 181,
-                                         212, 243, 273, 304, 334 };
-
-       /* 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);
-               return (TIME)0;
-       }
-       tm.tm_wday = atoi (val);
-
-       /* Year... */
-       token = next_token (&val, cfile);
-       if (token != NUMBER) {
-               parse_warn ("numeric year expected.");
-               if (token != SEMI)
-                       skip_to_semi (cfile);
-               return (TIME)0;
-       }
-       tm.tm_year = atoi (val);
-       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);
-               return (TIME)0;
-       }
-
-       /* Month... */
-       token = next_token (&val, cfile);
-       if (token != NUMBER) {
-               parse_warn ("numeric month expected.");
-               if (token != SEMI)
-                       skip_to_semi (cfile);
-               return (TIME)0;
-       }
-       tm.tm_mon = atoi (val) - 1;
-
-       /* 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);
-               return (TIME)0;
-       }
-
-       /* Month... */
-       token = next_token (&val, cfile);
-       if (token != NUMBER) {
-               parse_warn ("numeric day of month expected.");
-               if (token != SEMI)
-                       skip_to_semi (cfile);
-               return (TIME)0;
-       }
-       tm.tm_mday = atoi (val);
-
-       /* Hour... */
-       token = next_token (&val, cfile);
-       if (token != NUMBER) {
-               parse_warn ("numeric hour expected.");
-               if (token != SEMI)
-                       skip_to_semi (cfile);
-               return (TIME)0;
-       }
-       tm.tm_hour = atoi (val);
-
-       /* 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);
-               return (TIME)0;
-       }
-
-       /* Minute... */
-       token = next_token (&val, cfile);
-       if (token != NUMBER) {
-               parse_warn ("numeric minute expected.");
-               if (token != SEMI)
-                       skip_to_semi (cfile);
-               return (TIME)0;
-       }
-       tm.tm_min = atoi (val);
-
-       /* 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);
-               return (TIME)0;
-       }
-
-       /* Minute... */
-       token = next_token (&val, cfile);
-       if (token != NUMBER) {
-               parse_warn ("numeric minute expected.");
-               if (token != SEMI)
-                       skip_to_semi (cfile);
-               return (TIME)0;
-       }
-       tm.tm_sec = atoi (val);
-       tm.tm_isdst = 0;
-
-       /* XXX */ /* We assume that mktime does not use tm_yday. */
-       tm.tm_yday = 0;
-
-       /* Make sure the date ends in a semicolon... */
-       token = next_token (&val, cfile);
-       if (token != SEMI) {
-               parse_warn ("semicolon expected.");
-               skip_to_semi (cfile);
-               return 0;
-       }
-
-       /* Guess the time value... */
-       guess = ((((((365 * (tm.tm_year - 70) + /* Days in years since '70 */
-                     (tm.tm_year - 72) / 4 +   /* Leap days since '70 */
-                     (tm.tm_mon                /* Days in months this year */
-                      ? months [tm.tm_mon - 1]
-                      : 0) +
-                     (tm.tm_mon > 1 &&         /* Leap day this year */
-                      ((tm.tm_year - 72) & 3)) +
-                     tm.tm_mday) * 24) +       /* Day of month */
-                   tm.tm_hour) * 60) +
-                 tm.tm_min) * 60) + tm.tm_sec;
-
-       /* This guess could be wrong because of leap seconds or other
-          weirdness we don't know about that the system does.   For
-          now, we're just going to accept the guess, but at some point
-          it might be nice to do a successive approximation here to
-          get an exact value.   Even if the error is small, if the
-          server is restarted frequently (and thus the lease database
-          is reread), the error could accumulate into something
-          significant. */
-
-       return guess;
-}
diff --git a/print.c b/print.c
deleted file mode 100644 (file)
index e43b58c..0000000
--- a/print.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/* print.c
-
-   Turn data structures into printable text. */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: print.c,v 1.12 1997/02/22 08:32:05 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-char *print_hw_addr (htype, hlen, data)
-       int htype;
-       int hlen;
-       unsigned char *data;
-{
-       static char habuf [49];
-       char *s;
-       int i;
-
-       if (htype == 0 || hlen == 0) {
-               strcpy (habuf, "<null>");
-       } else {
-               s = habuf;
-               for (i = 0; i < hlen; i++) {
-                       sprintf (s, "%x", data [i]);
-                       s += strlen (s);
-                       *s++ = ':';
-               }
-               *--s = 0;
-       }
-       return habuf;
-}
-
-void print_lease (lease)
-       struct lease *lease;
-{
-       struct tm *t;
-       char tbuf [32];
-
-       debug ("  Lease %s",
-              piaddr (lease -> ip_addr));
-       
-       t = gmtime (&lease -> starts);
-       strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
-       debug ("  start %s", tbuf);
-       
-       t = gmtime (&lease -> ends);
-       strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
-       debug ("  end %s", tbuf);
-       
-       t = gmtime (&lease -> timestamp);
-       strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
-       debug ("  stamp %s", tbuf);
-       
-       debug ("    hardware addr = %s",
-              print_hw_addr (lease -> hardware_addr.htype,
-                              lease -> hardware_addr.hlen,
-                              lease -> hardware_addr.haddr));
-       debug ("  host %s  state %x",
-              lease -> host ? lease -> host -> name : "<none>",
-              lease -> state);
-}      
-
-void dump_packet (tp)
-       struct packet *tp;
-{
-       struct dhcp_packet *tdp = tp -> raw;
-
-       debug ("packet length %d", tp -> packet_length);
-       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", inet_ntoa (tdp -> ciaddr));
-       debug ("yiaddr = %s", inet_ntoa (tdp -> yiaddr));
-       debug ("siaddr = %s", inet_ntoa (tdp -> siaddr));
-       debug ("giaddr = %s", 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]);
-       debug ("filename = %s", tdp -> file);
-       debug ("server_name = %s", tdp -> sname);
-       if (tp -> options_valid) {
-               int i;
-
-               for (i = 0; i < 256; i++) {
-                       if (tp -> options [i].data)
-                               debug ("  %s = %s",
-                                       dhcp_options [i].name,
-                                       pretty_print_option
-                                       (i, tp -> options [i].data,
-                                        tp -> options [i].len, 1));
-               }
-       }
-       debug ("");
-}
-
-void dump_raw (buf, len)
-       unsigned char *buf;
-       int len;
-{
-       int i;
-       char lbuf [80];
-       int lbix = 0;
-
-       lbuf [0] = 0;
-
-       for (i = 0; i < len; i++) {
-               if ((i & 15) == 0) {
-                       if (lbix)
-                               note (lbuf);
-                       sprintf (lbuf, "%03x:", i);
-                       lbix = 4;
-               } else if ((i & 7) == 0)
-                       lbuf [lbix++] = ' ';
-               sprintf (&lbuf [lbix], " %02x", buf [i]);
-               lbix += 3;
-       }
-       note (lbuf);
-}
-
-void hash_dump (table)
-       struct hash_table *table;
-{
-       int i;
-       struct hash_bucket *bp;
-
-       if (!table)
-               return;
-
-       for (i = 0; i < table -> hash_count; i++) {
-               if (!table -> buckets [i])
-                       continue;
-               note ("hash bucket %d:", i);
-               for (bp = table -> buckets [i]; bp; bp = bp -> next) {
-                       if (bp -> len)
-                               dump_raw (bp -> name, bp -> len);
-                       else
-                               note (bp -> name);
-               }
-       }
-}
diff --git a/raw.c b/raw.c
deleted file mode 100644 (file)
index 6d76416..0000000
--- a/raw.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/* socket.c
-
-   BSD raw socket interface code... */
-
-/* XXX
-
-   It's not clear how this should work, and that lack of clarity is
-   terribly detrimental to the NetBSD 1.1 kernel - it crashes and
-   burns.
-
-   Using raw sockets ought to be a big win over using BPF or something
-   like it, because you don't need to deal with the complexities of
-   the physical layer, but it appears not to be possible with existing
-   raw socket implementations.  This may be worth revisiting in the
-   future.  For now, this code can probably be considered a curiosity.
-   Sigh. */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.  */
-
-#ifndef lint
-static char copyright[] =
-"$Id: raw.c,v 1.10 1997/02/19 10:51:44 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-#if defined (USE_RAW_SEND)
-#include <sys/uio.h>
-
-/* Generic interface registration routine... */
-void if_register_send (info)
-       struct interface_info *info;
-{
-       struct sockaddr_in name;
-       int sock;
-       struct socklist *tmp;
-       int flag;
-
-       /* Set up the address we're going to connect to. */
-       name.sin_family = AF_INET;
-       name.sin_port = local_port;
-       name.sin_addr.s_addr = htonl (INADDR_BROADCAST);
-       memset (name.sin_zero, 0, sizeof (name.sin_zero));
-
-       /* List addresses on which we're listening. */
-       note ("Sending on %s, port %d",
-             piaddr (info -> address), htons (local_port));
-       if ((sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
-               error ("Can't create dhcp socket: %m");
-
-       /* Set the BROADCAST option so that we can broadcast DHCP responses. */
-       flag = 1;
-       if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
-                       &flag, sizeof flag) < 0)
-               error ("Can't set SO_BROADCAST option on dhcp socket: %m");
-
-       /* Set the IP_HDRINCL flag so that we can supply our own IP
-          headers... */
-       if (setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &flag, sizeof flag) < 0)
-               error ("Can't set IP_HDRINCL flag: %m");
-
-       info -> wfdesc = sock;
-       note ("Sending on   Raw/%s/%s",
-             info -> name,
-             (info -> shared_network ?
-              info -> shared_network -> name : "unattached"));
-}
-
-size_t send_packet (interface, packet, raw, len, from, to, hto)
-       struct interface_info *interface;
-       struct packet *packet;
-       struct dhcp_packet *raw;
-       size_t len;
-       struct in_addr from;
-       struct sockaddr_in *to;
-       struct hardware *hto;
-{
-       unsigned char buf [256];
-       int bufp = 0;
-       struct iovec iov [2];
-
-       /* Assemble the headers... */
-       assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
-                               to -> sin_addr.s_addr, to -> sin_port,
-                               (unsigned char *)raw, len);
-
-       /* Fire it off */
-       iov [0].iov_base = (char *)buf;
-       iov [0].iov_len = bufp;
-       iov [1].iov_base = (char *)raw;
-       iov [1].iov_len = len;
-
-       return writev(interface -> wfdesc, iov, 2);
-}
-#endif /* USE_SOCKET_SEND */
diff --git a/socket.c b/socket.c
deleted file mode 100644 (file)
index 952f190..0000000
--- a/socket.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/* socket.c
-
-   BSD socket interface code... */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * 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''.
- */
-
-/* SO_BINDTODEVICE support added by Elliot Poger (poger@leland.stanford.edu).
- * This sockopt allows a socket to be bound to a particular interface,
- * thus enabling the use of DHCPD on a multihomed host.
- * If SO_BINDTODEVICE is defined in your system header files, the use of
- * this sockopt will be automatically enabled. 
- * I have implemented it under Linux; other systems should be doable also.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: socket.c,v 1.19 1997/02/19 10:49:19 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-#ifdef USE_SOCKET_FALLBACK
-#  define USE_SOCKET_SEND
-#  define if_register_send if_register_fallback
-#  define send_packet send_fallback
-#  define if_reinitialize_send if_reinitialize_fallback
-#endif
-
-static int once = 0;
-
-/* Reinitializes the specified interface after an address change.   This
-   is not required for packet-filter APIs. */
-
-#ifdef USE_SOCKET_SEND
-void if_reinitialize_send (info)
-       struct interface_info *info;
-{
-#if 0
-#ifndef USE_SOCKET_RECEIVE
-       once = 0;
-       close (info -> wfdesc);
-#endif
-       if_register_send (info);
-#endif
-}
-#endif
-
-#ifdef USE_SOCKET_RECEIVE
-void if_reinitialize_receive (info)
-       struct interface_info *info;
-{
-#if 0
-       once = 0;
-       close (info -> rfdesc);
-       if_register_receive (info);
-#endif
-}
-#endif
-
-#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE)
-/* Generic interface registration routine... */
-int if_register_socket (info)
-       struct interface_info *info;
-{
-       struct sockaddr_in name;
-       int sock;
-       int flag;
-
-#ifndef SO_BINDTODEVICE
-       /* Make sure only one interface is registered. */
-       if (once)
-               error ("The standard socket API can only support %s%s%s%s%s",
-                      "hosts with a single network interface.   If you must ",
-                      "run dhcpd on a host with multiple interfaces, ",
-                      "you must compile in BPF or NIT support.   If neither ",
-                      "option is supported on your system, please let us ",
-                      "know.");
-       once = 1;
-#endif
-
-       /* Set up the address we're going to bind to. */
-       name.sin_family = AF_INET;
-       name.sin_port = local_port;
-       name.sin_addr.s_addr = INADDR_ANY;
-       memset (name.sin_zero, 0, sizeof (name.sin_zero));
-
-       /* Make a socket... */
-       if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
-               error ("Can't create dhcp socket: %m");
-
-       /* Set the REUSEADDR option so that we don't fail to start if
-          we're being restarted. */
-       flag = 1;
-       if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
-                       (char *)&flag, sizeof flag) < 0)
-               error ("Can't set SO_REUSEADDR option on dhcp socket: %m");
-
-       /* Set the BROADCAST option so that we can broadcast DHCP responses. */
-       if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
-                       (char *)&flag, sizeof flag) < 0)
-               error ("Can't set SO_BROADCAST option on dhcp socket: %m");
-
-#ifndef USE_SOCKET_FALLBACK
-       /* The following will make all-ones broadcasts go out this interface
-        * on those platforms which use the standard sockets API (assuming 
-        * the OS-specific routines called by enable_sending() are present
-        * for this platform). */
-       if_enable (info);
-#endif
-       /* Bind the socket to this interface's IP address. */
-       if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
-               error ("Can't bind to dhcp address: %m");
-
-#ifdef SO_BINDTODEVICE
-       /* Bind this socket to this interface. */
-       if (setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE,
-                       (char *)(info -> ifp), sizeof *(info -> ifp)) < 0) {
-               error("setting SO_BINDTODEVICE");
-       }
-#endif
-
-       return sock;
-}
-#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */
-
-#ifdef USE_SOCKET_SEND
-void if_register_send (info)
-       struct interface_info *info;
-{
-#ifndef USE_SOCKET_RECEIVE
-       info -> wfdesc = if_register_socket (info);
-#else
-       info -> wfdesc = info -> rfdesc;
-#endif
-       note ("Sending on   Socket/%s/%s",
-             info -> name,
-             (info -> shared_network ?
-              info -> shared_network -> name : "unattached"));
-
-}
-#endif /* USE_SOCKET_SEND */
-
-#ifdef USE_SOCKET_RECEIVE
-void if_register_receive (info)
-       struct interface_info *info;
-{
-       /* If we're using the socket API for sending and receiving,
-          we don't need to register this interface twice. */
-       info -> rfdesc = if_register_socket (info);
-       note ("Listening on Socket/%s/%s",
-             info -> name,
-             (info -> shared_network ?
-              info -> shared_network -> name : "unattached"));
-}
-#endif /* USE_SOCKET_RECEIVE */
-
-#ifdef USE_SOCKET_SEND
-size_t send_packet (interface, packet, raw, len, from, to, hto)
-       struct interface_info *interface;
-       struct packet *packet;
-       struct dhcp_packet *raw;
-       size_t len;
-       struct in_addr from;
-       struct sockaddr_in *to;
-       struct hardware *hto;
-{
-       return sendto (interface -> wfdesc, (char *)raw, len, 0,
-                      (struct sockaddr *)to, sizeof *to);
-}
-#endif /* USE_SOCKET_SEND */
-
-#ifdef USE_SOCKET_RECEIVE
-size_t receive_packet (interface, buf, len, from, hfrom)
-       struct interface_info *interface;
-       unsigned char *buf;
-       size_t len;
-       struct sockaddr_in *from;
-       struct hardware *hfrom;
-{
-       int flen = sizeof *from;
-
-       return recvfrom (interface -> rfdesc, buf, len, 0,
-                        (struct sockaddr *)from, &flen);
-}
-#endif /* USE_SOCKET_RECEIVE */
-
-#ifdef USE_SOCKET_FALLBACK
-/* This just reads in a packet and silently discards it. */
-
-size_t fallback_discard (interface)
-       struct interface_info *interface;
-{
-       char buf [1540];
-       struct sockaddr_in from;
-       int flen = sizeof from;
-
-       return recvfrom (interface -> wfdesc, buf, sizeof buf, 0,
-                        (struct sockaddr *)&from, &flen);
-}
-#endif /* USE_SOCKET_RECEIVE */
-
-#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
-/* If we're using the standard socket API without SO_BINDTODEVICE,
- * we need this kludge to force DHCP broadcasts to go out
- * this interface, even though it's not available for general
- * use until we get a lease!
- * This should work _OK_, but it will cause ALL all-ones
- * broadcasts on this host to go out this interface--it
- * could interfere with other interfaces.  And God help you
- * if you run this on multiple interfaces simultaneously.
- * SO_BINDTODEVICE really is better! */
-void if_enable (interface)
-     struct interface_info *interface;
-{
-#ifndef SO_BINDTODEVICE
-       struct in_addr broad_addr;
-       broad_addr.s_addr = htonl(INADDR_BROADCAST);
-
-       /* Delete old routes for broadcast address. */
-       remove_routes(NULL, &broad_addr);
-
-       /* Add a route for broadcast address to this interface. */
-       /* POTENTIAL PROBLEM: Don't do this to more than one interface! */
-       add_route_direct(interface, &broad_addr);
-#endif
-}
-#endif
diff --git a/tables.c b/tables.c
deleted file mode 100644 (file)
index e5c6ca2..0000000
--- a/tables.c
+++ /dev/null
@@ -1,690 +0,0 @@
-/* tables.c
-
-   Tables of information... */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: tables.c,v 1.11 1996/09/11 06:34:25 mellon Exp $ Copyright (c) 1995, 1996 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", "X",                &dhcp_universe, 61 },
-       { "option-62", "X",                             &dhcp_universe, 62 },
-       { "option-63", "X",                             &dhcp_universe, 63 },
-       { "option-64", "X",                             &dhcp_universe, 64 },
-       { "option-65", "X",                             &dhcp_universe, 65 },
-       { "option-66", "X",                             &dhcp_universe, 66 },
-       { "option-67", "X",                             &dhcp_universe, 67 },
-       { "option-68", "X",                             &dhcp_universe, 68 },
-       { "option-69", "X",                             &dhcp_universe, 69 },
-       { "option-70", "X",                             &dhcp_universe, 70 },
-       { "option-71", "X",                             &dhcp_universe, 71 },
-       { "option-72", "X",                             &dhcp_universe, 72 },
-       { "option-73", "X",                             &dhcp_universe, 73 },
-       { "option-74", "X",                             &dhcp_universe, 74 },
-       { "option-75", "X",                             &dhcp_universe, 75 },
-       { "option-76", "X",                             &dhcp_universe, 76 },
-       { "dhcp-user-class-identifier", "t",            &dhcp_universe, 77 },
-       { "option-78", "X",                             &dhcp_universe, 78 },
-       { "option-79", "X",                             &dhcp_universe, 79 },
-       { "option-80", "X",                             &dhcp_universe, 80 },
-       { "option-81", "X",                             &dhcp_universe, 81 },
-       { "option-82", "X",                             &dhcp_universe, 82 },
-       { "option-83", "X",                             &dhcp_universe, 83 },
-       { "option-84", "X",                             &dhcp_universe, 84 },
-       { "option-85", "X",                             &dhcp_universe, 85 },
-       { "option-86", "X",                             &dhcp_universe, 86 },
-       { "option-87", "X",                             &dhcp_universe, 87 },
-       { "option-88", "X",                             &dhcp_universe, 88 },
-       { "option-89", "X",                             &dhcp_universe, 89 },
-       { "option-90", "X",                             &dhcp_universe, 90 },
-       { "option-91", "X",                             &dhcp_universe, 91 },
-       { "option-92", "X",                             &dhcp_universe, 92 },
-       { "option-93", "X",                             &dhcp_universe, 93 },
-       { "option-94", "X",                             &dhcp_universe, 94 },
-       { "option-95", "X",                             &dhcp_universe, 95 },
-       { "option-96", "X",                             &dhcp_universe, 96 },
-       { "option-97", "X",                             &dhcp_universe, 97 },
-       { "option-98", "X",                             &dhcp_universe, 98 },
-       { "option-99", "X",                             &dhcp_universe, 99 },
-       { "option-100", "X",                            &dhcp_universe, 100 },
-       { "option-101", "X",                            &dhcp_universe, 101 },
-       { "option-102", "X",                            &dhcp_universe, 102 },
-       { "option-103", "X",                            &dhcp_universe, 103 },
-       { "option-104", "X",                            &dhcp_universe, 104 },
-       { "option-105", "X",                            &dhcp_universe, 105 },
-       { "option-106", "X",                            &dhcp_universe, 106 },
-       { "option-107", "X",                            &dhcp_universe, 107 },
-       { "option-108", "X",                            &dhcp_universe, 108 },
-       { "option-109", "X",                            &dhcp_universe, 109 },
-       { "option-110", "X",                            &dhcp_universe, 110 },
-       { "option-111", "X",                            &dhcp_universe, 111 },
-       { "option-112", "X",                            &dhcp_universe, 112 },
-       { "option-113", "X",                            &dhcp_universe, 113 },
-       { "option-114", "X",                            &dhcp_universe, 114 },
-       { "option-115", "X",                            &dhcp_universe, 115 },
-       { "option-116", "X",                            &dhcp_universe, 116 },
-       { "option-117", "X",                            &dhcp_universe, 117 },
-       { "option-118", "X",                            &dhcp_universe, 118 },
-       { "option-119", "X",                            &dhcp_universe, 119 },
-       { "option-120", "X",                            &dhcp_universe, 120 },
-       { "option-121", "X",                            &dhcp_universe, 121 },
-       { "option-122", "X",                            &dhcp_universe, 122 },
-       { "option-123", "X",                            &dhcp_universe, 123 },
-       { "option-124", "X",                            &dhcp_universe, 124 },
-       { "option-125", "X",                            &dhcp_universe, 125 },
-       { "option-126", "X",                            &dhcp_universe, 126 },
-       { "option-127", "X",                            &dhcp_universe, 127 },
-       { "option-128", "X",                            &dhcp_universe, 128 },
-       { "option-129", "X",                            &dhcp_universe, 129 },
-       { "option-130", "X",                            &dhcp_universe, 130 },
-       { "option-131", "X",                            &dhcp_universe, 131 },
-       { "option-132", "X",                            &dhcp_universe, 132 },
-       { "option-133", "X",                            &dhcp_universe, 133 },
-       { "option-134", "X",                            &dhcp_universe, 134 },
-       { "option-135", "X",                            &dhcp_universe, 135 },
-       { "option-136", "X",                            &dhcp_universe, 136 },
-       { "option-137", "X",                            &dhcp_universe, 137 },
-       { "option-138", "X",                            &dhcp_universe, 138 },
-       { "option-139", "X",                            &dhcp_universe, 139 },
-       { "option-140", "X",                            &dhcp_universe, 140 },
-       { "option-141", "X",                            &dhcp_universe, 141 },
-       { "option-142", "X",                            &dhcp_universe, 142 },
-       { "option-143", "X",                            &dhcp_universe, 143 },
-       { "option-144", "X",                            &dhcp_universe, 144 },
-       { "option-145", "X",                            &dhcp_universe, 145 },
-       { "option-146", "X",                            &dhcp_universe, 146 },
-       { "option-147", "X",                            &dhcp_universe, 147 },
-       { "option-148", "X",                            &dhcp_universe, 148 },
-       { "option-149", "X",                            &dhcp_universe, 149 },
-       { "option-150", "X",                            &dhcp_universe, 150 },
-       { "option-151", "X",                            &dhcp_universe, 151 },
-       { "option-152", "X",                            &dhcp_universe, 152 },
-       { "option-153", "X",                            &dhcp_universe, 153 },
-       { "option-154", "X",                            &dhcp_universe, 154 },
-       { "option-155", "X",                            &dhcp_universe, 155 },
-       { "option-156", "X",                            &dhcp_universe, 156 },
-       { "option-157", "X",                            &dhcp_universe, 157 },
-       { "option-158", "X",                            &dhcp_universe, 158 },
-       { "option-159", "X",                            &dhcp_universe, 159 },
-       { "option-160", "X",                            &dhcp_universe, 160 },
-       { "option-161", "X",                            &dhcp_universe, 161 },
-       { "option-162", "X",                            &dhcp_universe, 162 },
-       { "option-163", "X",                            &dhcp_universe, 163 },
-       { "option-164", "X",                            &dhcp_universe, 164 },
-       { "option-165", "X",                            &dhcp_universe, 165 },
-       { "option-166", "X",                            &dhcp_universe, 166 },
-       { "option-167", "X",                            &dhcp_universe, 167 },
-       { "option-168", "X",                            &dhcp_universe, 168 },
-       { "option-169", "X",                            &dhcp_universe, 169 },
-       { "option-170", "X",                            &dhcp_universe, 170 },
-       { "option-171", "X",                            &dhcp_universe, 171 },
-       { "option-172", "X",                            &dhcp_universe, 172 },
-       { "option-173", "X",                            &dhcp_universe, 173 },
-       { "option-174", "X",                            &dhcp_universe, 174 },
-       { "option-175", "X",                            &dhcp_universe, 175 },
-       { "option-176", "X",                            &dhcp_universe, 176 },
-       { "option-177", "X",                            &dhcp_universe, 177 },
-       { "option-178", "X",                            &dhcp_universe, 178 },
-       { "option-179", "X",                            &dhcp_universe, 179 },
-       { "option-180", "X",                            &dhcp_universe, 180 },
-       { "option-181", "X",                            &dhcp_universe, 181 },
-       { "option-182", "X",                            &dhcp_universe, 182 },
-       { "option-183", "X",                            &dhcp_universe, 183 },
-       { "option-184", "X",                            &dhcp_universe, 184 },
-       { "option-185", "X",                            &dhcp_universe, 185 },
-       { "option-186", "X",                            &dhcp_universe, 186 },
-       { "option-187", "X",                            &dhcp_universe, 187 },
-       { "option-188", "X",                            &dhcp_universe, 188 },
-       { "option-189", "X",                            &dhcp_universe, 189 },
-       { "option-190", "X",                            &dhcp_universe, 190 },
-       { "option-191", "X",                            &dhcp_universe, 191 },
-       { "option-192", "X",                            &dhcp_universe, 192 },
-       { "option-193", "X",                            &dhcp_universe, 193 },
-       { "option-194", "X",                            &dhcp_universe, 194 },
-       { "option-195", "X",                            &dhcp_universe, 195 },
-       { "option-196", "X",                            &dhcp_universe, 196 },
-       { "option-197", "X",                            &dhcp_universe, 197 },
-       { "option-198", "X",                            &dhcp_universe, 198 },
-       { "option-199", "X",                            &dhcp_universe, 199 },
-       { "option-200", "X",                            &dhcp_universe, 200 },
-       { "option-201", "X",                            &dhcp_universe, 201 },
-       { "option-202", "X",                            &dhcp_universe, 202 },
-       { "option-203", "X",                            &dhcp_universe, 203 },
-       { "option-204", "X",                            &dhcp_universe, 204 },
-       { "option-205", "X",                            &dhcp_universe, 205 },
-       { "option-206", "X",                            &dhcp_universe, 206 },
-       { "option-207", "X",                            &dhcp_universe, 207 },
-       { "option-208", "X",                            &dhcp_universe, 208 },
-       { "option-209", "X",                            &dhcp_universe, 209 },
-       { "option-210", "X",                            &dhcp_universe, 210 },
-       { "option-211", "X",                            &dhcp_universe, 211 },
-       { "option-212", "X",                            &dhcp_universe, 212 },
-       { "option-213", "X",                            &dhcp_universe, 213 },
-       { "option-214", "X",                            &dhcp_universe, 214 },
-       { "option-215", "X",                            &dhcp_universe, 215 },
-       { "option-216", "X",                            &dhcp_universe, 216 },
-       { "option-217", "X",                            &dhcp_universe, 217 },
-       { "option-218", "X",                            &dhcp_universe, 218 },
-       { "option-219", "X",                            &dhcp_universe, 219 },
-       { "option-220", "X",                            &dhcp_universe, 220 },
-       { "option-221", "X",                            &dhcp_universe, 221 },
-       { "option-222", "X",                            &dhcp_universe, 222 },
-       { "option-223", "X",                            &dhcp_universe, 223 },
-       { "option-224", "X",                            &dhcp_universe, 224 },
-       { "option-225", "X",                            &dhcp_universe, 225 },
-       { "option-226", "X",                            &dhcp_universe, 226 },
-       { "option-227", "X",                            &dhcp_universe, 227 },
-       { "option-228", "X",                            &dhcp_universe, 228 },
-       { "option-229", "X",                            &dhcp_universe, 229 },
-       { "option-230", "X",                            &dhcp_universe, 230 },
-       { "option-231", "X",                            &dhcp_universe, 231 },
-       { "option-232", "X",                            &dhcp_universe, 232 },
-       { "option-233", "X",                            &dhcp_universe, 233 },
-       { "option-234", "X",                            &dhcp_universe, 234 },
-       { "option-235", "X",                            &dhcp_universe, 235 },
-       { "option-236", "X",                            &dhcp_universe, 236 },
-       { "option-237", "X",                            &dhcp_universe, 237 },
-       { "option-238", "X",                            &dhcp_universe, 238 },
-       { "option-239", "X",                            &dhcp_universe, 239 },
-       { "option-240", "X",                            &dhcp_universe, 240 },
-       { "option-241", "X",                            &dhcp_universe, 241 },
-       { "option-242", "X",                            &dhcp_universe, 242 },
-       { "option-243", "X",                            &dhcp_universe, 243 },
-       { "option-244", "X",                            &dhcp_universe, 244 },
-       { "option-245", "X",                            &dhcp_universe, 245 },
-       { "option-246", "X",                            &dhcp_universe, 246 },
-       { "option-247", "X",                            &dhcp_universe, 247 },
-       { "option-248", "X",                            &dhcp_universe, 248 },
-       { "option-249", "X",                            &dhcp_universe, 249 },
-       { "option-250", "X",                            &dhcp_universe, 250 },
-       { "option-251", "X",                            &dhcp_universe, 251 },
-       { "option-252", "X",                            &dhcp_universe, 252 },
-       { "option-253", "X",                            &dhcp_universe, 253 },
-       { "option-254", "X",                            &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_DHCP_REQUESTED_ADDRESS,
-       DHO_DHCP_OPTION_OVERLOAD,
-       DHO_DHCP_MAX_MESSAGE_SIZE,
-       DHO_DHCP_RENEWAL_TIME,
-       DHO_DHCP_REBINDING_TIME,
-       DHO_DHCP_CLASS_IDENTIFIER,
-       DHO_DHCP_CLIENT_IDENTIFIER,
-       DHO_SUBNET_MASK,
-       DHO_TIME_OFFSET,
-       DHO_ROUTERS,
-       DHO_TIME_SERVERS,
-       DHO_NAME_SERVERS,
-       DHO_DOMAIN_NAME_SERVERS,
-       DHO_HOST_NAME,
-       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_PARAMETER_REQUEST_LIST,
-
-       /* Presently-undefined options... */
-       62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
-       78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
-       93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
-       107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
-       119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
-       131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
-       143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
-       155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
-       167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
-       179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
-       191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
-       203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
-       215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
-       227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
-       239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250,
-       251, 252, 253, 254,
-};
-
-int sizeof_dhcp_option_default_priority_list =
-       sizeof dhcp_option_default_priority_list;
-
-
-char *hardware_types [] = {
-       "unknown-0",
-       "ethernet",
-       "unknown-2",
-       "unknown-3",
-       "unknown-4",
-       "unknown-5",
-       "token-ring",
-       "unknown-7",
-       "unknown-8",
-       "unknown-9",
-       "unknown-10",
-       "unknown-11",
-       "unknown-12",
-       "unknown-13",
-       "unknown-14",
-       "unknown-15",
-       "unknown-16",
-       "unknown-17",
-       "unknown-18",
-       "unknown-19",
-       "unknown-20",
-       "unknown-21",
-       "unknown-22",
-       "unknown-23",
-       "unknown-24",
-       "unknown-25",
-       "unknown-26",
-       "unknown-27",
-       "unknown-28",
-       "unknown-29",
-       "unknown-30",
-       "unknown-31",
-       "unknown-32",
-       "unknown-33",
-       "unknown-34",
-       "unknown-35",
-       "unknown-36",
-       "unknown-37",
-       "unknown-38",
-       "unknown-39",
-       "unknown-40",
-       "unknown-41",
-       "unknown-42",
-       "unknown-43",
-       "unknown-44",
-       "unknown-45",
-       "unknown-46",
-       "unknown-47",
-       "unknown-48",
-       "unknown-49",
-       "unknown-50",
-       "unknown-51",
-       "unknown-52",
-       "unknown-53",
-       "unknown-54",
-       "unknown-55",
-       "unknown-56",
-       "unknown-57",
-       "unknown-58",
-       "unknown-59",
-       "unknown-60",
-       "unknown-61",
-       "unknown-62",
-       "unknown-63",
-       "unknown-64",
-       "unknown-65",
-       "unknown-66",
-       "unknown-67",
-       "unknown-68",
-       "unknown-69",
-       "unknown-70",
-       "unknown-71",
-       "unknown-72",
-       "unknown-73",
-       "unknown-74",
-       "unknown-75",
-       "unknown-76",
-       "unknown-77",
-       "unknown-78",
-       "unknown-79",
-       "unknown-80",
-       "unknown-81",
-       "unknown-82",
-       "unknown-83",
-       "unknown-84",
-       "unknown-85",
-       "unknown-86",
-       "unknown-87",
-       "unknown-88",
-       "unknown-89",
-       "unknown-90",
-       "unknown-91",
-       "unknown-92",
-       "unknown-93",
-       "unknown-94",
-       "unknown-95",
-       "unknown-96",
-       "unknown-97",
-       "unknown-98",
-       "unknown-99",
-       "unknown-100",
-       "unknown-101",
-       "unknown-102",
-       "unknown-103",
-       "unknown-104",
-       "unknown-105",
-       "unknown-106",
-       "unknown-107",
-       "unknown-108",
-       "unknown-109",
-       "unknown-110",
-       "unknown-111",
-       "unknown-112",
-       "unknown-113",
-       "unknown-114",
-       "unknown-115",
-       "unknown-116",
-       "unknown-117",
-       "unknown-118",
-       "unknown-119",
-       "unknown-120",
-       "unknown-121",
-       "unknown-122",
-       "unknown-123",
-       "unknown-124",
-       "unknown-125",
-       "unknown-126",
-       "unknown-127",
-       "unknown-128",
-       "unknown-129",
-       "unknown-130",
-       "unknown-131",
-       "unknown-132",
-       "unknown-133",
-       "unknown-134",
-       "unknown-135",
-       "unknown-136",
-       "unknown-137",
-       "unknown-138",
-       "unknown-139",
-       "unknown-140",
-       "unknown-141",
-       "unknown-142",
-       "unknown-143",
-       "unknown-144",
-       "unknown-145",
-       "unknown-146",
-       "unknown-147",
-       "unknown-148",
-       "unknown-149",
-       "unknown-150",
-       "unknown-151",
-       "unknown-152",
-       "unknown-153",
-       "unknown-154",
-       "unknown-155",
-       "unknown-156",
-       "unknown-157",
-       "unknown-158",
-       "unknown-159",
-       "unknown-160",
-       "unknown-161",
-       "unknown-162",
-       "unknown-163",
-       "unknown-164",
-       "unknown-165",
-       "unknown-166",
-       "unknown-167",
-       "unknown-168",
-       "unknown-169",
-       "unknown-170",
-       "unknown-171",
-       "unknown-172",
-       "unknown-173",
-       "unknown-174",
-       "unknown-175",
-       "unknown-176",
-       "unknown-177",
-       "unknown-178",
-       "unknown-179",
-       "unknown-180",
-       "unknown-181",
-       "unknown-182",
-       "unknown-183",
-       "unknown-184",
-       "unknown-185",
-       "unknown-186",
-       "unknown-187",
-       "unknown-188",
-       "unknown-189",
-       "unknown-190",
-       "unknown-191",
-       "unknown-192",
-       "unknown-193",
-       "unknown-194",
-       "unknown-195",
-       "unknown-196",
-       "unknown-197",
-       "unknown-198",
-       "unknown-199",
-       "unknown-200",
-       "unknown-201",
-       "unknown-202",
-       "unknown-203",
-       "unknown-204",
-       "unknown-205",
-       "unknown-206",
-       "unknown-207",
-       "unknown-208",
-       "unknown-209",
-       "unknown-210",
-       "unknown-211",
-       "unknown-212",
-       "unknown-213",
-       "unknown-214",
-       "unknown-215",
-       "unknown-216",
-       "unknown-217",
-       "unknown-218",
-       "unknown-219",
-       "unknown-220",
-       "unknown-221",
-       "unknown-222",
-       "unknown-223",
-       "unknown-224",
-       "unknown-225",
-       "unknown-226",
-       "unknown-227",
-       "unknown-228",
-       "unknown-229",
-       "unknown-230",
-       "unknown-231",
-       "unknown-232",
-       "unknown-233",
-       "unknown-234",
-       "unknown-235",
-       "unknown-236",
-       "unknown-237",
-       "unknown-238",
-       "unknown-239",
-       "unknown-240",
-       "unknown-241",
-       "unknown-242",
-       "unknown-243",
-       "unknown-244",
-       "unknown-245",
-       "unknown-246",
-       "unknown-247",
-       "unknown-248",
-       "unknown-249",
-       "unknown-250",
-       "unknown-251",
-       "unknown-252",
-       "unknown-253",
-       "unknown-254",
-       "unknown-255" };
-
-
-
-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);
-}
diff --git a/tree.c b/tree.c
deleted file mode 100644 (file)
index 8168522..0000000
--- a/tree.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/* tree.c
-
-   Routines for manipulating parse trees... */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: tree.c,v 1.9 1996/08/27 09:55:50 mellon Exp $ Copyright (c) 1995, 1996 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 = (unsigned char *)0;
-       tc -> len = tc -> buf_size = 0;
-       tc -> timeout = 0;
-       tc -> tree = tree;
-       return tc;
-}
-
-struct tree *tree_host_lookup (name)
-       char *name;
-{
-       struct 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 -> buf_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;
-
-#ifdef DEBUG_EVAL
-       debug ("time: now = %d  dns = %d %d  diff = %d",
-              cur_time, dns -> timeout, cur_time - dns -> timeout);
-#endif
-
-       /* If the record hasn't timed out, just copy the data and return. */
-       if (cur_time <= dns -> timeout) {
-#ifdef DEBUG_EVAL
-               debug ("easy copy: %x %d %x",
-                      dns -> data, dns -> data_len,
-                      dns -> data ? *(int *)(dns -> data) : 0);
-#endif
-               do_data_copy (bufix, bufp, bufcount,
-                             dns -> data, dns -> data_len);
-               return dns -> timeout;
-       }
-#ifdef DEBUG_EVAL
-       debug ("Looking up %s", dns -> hostname);
-#endif
-
-       /* 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;
-       }
-
-#ifdef DEBUG_EVAL
-       debug ("Lookup succeeded; first address is %x",
-              h -> h_addr_list [0]);
-#endif
-
-       /* 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 {
-                       if (dns -> data)
-                               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);
-       }
-#ifdef DEBUG_EVAL
-       debug ("dns -> data: %x  h -> h_addr_list [0]: %x",
-              *(int *)(dns -> data), h -> h_addr_list [0]);
-#endif
-       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;
-
-#ifdef DEBUG_EVAL
-       debug ("hard copy: %x %d %x",
-              dns -> data, dns -> data_len, *(int *)(dns -> data));
-#endif
-       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;
-}