]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Keep a persistent database of leases
authorTed Lemon <source@isc.org>
Sat, 2 Mar 1996 05:13:36 +0000 (05:13 +0000)
committerTed Lemon <source@isc.org>
Sat, 2 Mar 1996 05:13:36 +0000 (05:13 +0000)
21 files changed:
Makefile
common/memory.c
common/options.c
common/tables.c
confpars.c
db.c [new file with mode: 0644]
dhcp.c
dhcp.h
dhcpd.c
dhcpd.conf
dhcpd.h
includes/dhcp.h
includes/dhcpd.h
memory.c
options.c
server/confpars.c
server/db.c [new file with mode: 0644]
server/dhcp.c
server/dhcpd.c
server/dhcpd.conf
tables.c

index c90b3043babf90096b620632770127f0bfea8cf8..373cc0192f0c151fb5dbaf0dc4ca744a2c238ba1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 SRCS = dhcpd.c options.c errwarn.c convert.c conflex.c confpars.c \
        tree.c memory.c bootp.c dhcp.c alloc.c print.c socket.c \
-       hash.c tables.c inet.c
+       hash.c tables.c inet.c db.c
 PROG = dhcpd
 
 all:   dhcpd dhclient
@@ -12,7 +12,7 @@ CFLAGS += -DDEBUG -g -Wall -Wstrict-prototypes -Wno-unused \
 
 dhclient:      dhclient.o confpars.o alloc.o memory.o options.o \
                hash.o tables.o inet.o convert.o conflex.o errwarn.o \
-               tree.o print.o
+               tree.o print.o db.o
        cc -o dhclient dhclient.o confpars.o alloc.o memory.o options.o \
                hash.o tables.o inet.o convert.o conflex.o errwarn.o \
-               print.o tree.o
\ No newline at end of file
+               print.o tree.o db.o
\ No newline at end of file
index ac33d50b70f62b6c35ffcb8dfab4027bf9dbc188..b0e48cad59536e3d5f7105bc03def82bed47017a 100644 (file)
@@ -42,7 +42,7 @@
 
 #ifndef lint
 static char copyright[] =
-"@(#) Copyright (c) 1995 The Internet Software Consortium.  All rights reserved.\n";
+"@(#) Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -162,8 +162,8 @@ void new_address_range (low, high, subnet)
                if (address_range [i].next)
                        address_range [i].next -> prev = subnet -> leases;
                add_hash (lease_ip_addr_hash,
-                         (char *)&address_range [i].ip_addr,
-                         sizeof address_range [i].ip_addr,
+                         address_range [i].ip_addr.iabuf,
+                         address_range [i].ip_addr.len,
                          (unsigned char *)&address_range [i]);
        }
 
@@ -187,7 +187,7 @@ void new_address_range (low, high, subnet)
                                dangling_leases = lp -> next;
                        }
                        lp -> next = (struct lease *)0;
-                       supersede_lease (&address_range [lhost - i], lp);
+                       supersede_lease (&address_range [lhost - i], lp, 0);
                        free_lease (lp, "new_address_range");
                } else
                        plp = lp;
@@ -230,6 +230,7 @@ void enter_lease (lease)
        /* If we don't have a place for this lease yet, save it for
           later. */
        if (!comp) {
+printf ("didn't find the lease...\n");
                comp = new_lease ("enter_lease");
                if (!comp) {
                        error ("No memory for lease %s\n",
@@ -240,7 +241,8 @@ void enter_lease (lease)
                lease -> prev = (struct lease *)0;
                dangling_leases = lease;
        } else {
-               supersede_lease (comp, lease);
+printf ("superseding lease...\n");
+               supersede_lease (comp, lease, 0);
        }
 }
 
@@ -249,8 +251,9 @@ void enter_lease (lease)
    list of leases by expiry time so that we can always find the oldest
    lease. */
 
-void supersede_lease (comp, lease)
+int supersede_lease (comp, lease, commit)
        struct lease *comp, *lease;
+       int commit;
 {
        int enter_uid = 0;
        int enter_hwaddr = 0;
@@ -402,6 +405,10 @@ void supersede_lease (comp, lease)
                comp -> contain -> 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. */
@@ -413,7 +420,7 @@ void release_lease (lease)
 
        lt = *lease;
        lt.ends = cur_time;
-       supersede_lease (lease, &lt);
+       supersede_lease (lease, &lt, 1);
 }
 
 /* Abandon the specified lease (set its timeout to infinity and its
@@ -432,7 +439,7 @@ void abandon_lease (lease)
        lt.hardware_addr.hlen = 0;
        lt.uid = (char *)0;
        lt.uid_len = 0;
-       supersede_lease (lease, &lt);
+       supersede_lease (lease, &lt, 1);
 }
 
 /* Locate the lease associated with a given IP address... */
@@ -504,6 +511,23 @@ struct class *find_class (type, name, len)
        return class;
 }      
 
+/* Write all interesting leases to permanent storage. */
+
+void write_leases ()
+{
+       struct lease *l;
+       struct subnet *s;
+       int i;
+
+       for (s = subnets; s; s = s -> next) {
+               for (l = s -> leases; l; l = l -> next) {
+                       if (l -> hardware_addr.hlen || l -> uid_len)
+                               write_lease (l);
+               }
+       }
+       commit_leases ();
+}
+
 void dump_subnets ()
 {
        struct lease *l;
index 7c860727edf5c80b78de3c0e6d2cce8ef55eb405..a5ff795a9fdc20c84bbcbe1c5dab48e95557071e 100644 (file)
@@ -3,7 +3,8 @@
    DHCP options parsing and reassembly. */
 
 /*
- * Copyright (c) 1995 The Internet Software Consortium.  All rights reserved.
+ * 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
@@ -41,7 +42,7 @@
 
 #ifndef lint
 static char copyright[] =
-"@(#) Copyright (c) 1995 The Internet Software Consortium.  All rights reserved.\n";
+"@(#) Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #define DHCP_OPTION_DATA
index ada34a6a3ba2895a0133a585c8e5601d4a837a91..5b79b1458ec9285df4ed2de13fbad50a9d3641b4 100644 (file)
@@ -389,6 +389,266 @@ 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",
+       "unknown-6",
+       "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()
index 6f850448e1d027555176a75b1a6eda79eb95596b..f3cf4f30d79237396951a5d0c55068302cd12798 100644 (file)
@@ -70,6 +70,38 @@ void readconf (void)
                        break;
                parse_statement (cfile);
        } while (1);
+       token = next_token (&val, cfile);
+}
+
+void read_leases (void)
+{
+       FILE *cfile;
+       char *val;
+       int token;
+       jmp_buf bc;
+
+       /* Open the lease file... */
+       if ((cfile = fopen (_PATH_DHCPD_DB, "r")) == NULL)
+               warn ("Can't open lease database %s: %m", _PATH_DHCPD_DB);
+       do {
+               token = next_token (&val, cfile);
+printf ("token = %d\n", token);
+               if (token == EOF)
+                       break;
+               if (token != LEASE) {
+                       warn ("Corrupt lease file - possible data loss!");
+                       skip_to_semi (cfile);
+               } else {
+                       if (!setjmp (bc)) {
+                               struct lease *lease;
+printf ("Parsing a lease...\n");
+                               lease = parse_lease_statement (cfile, &bc);
+                               enter_lease (lease);
+print_lease (lease);
+                       }
+               }
+
+       } while (1);
 }
 
 /* statement :== host_statement */
diff --git a/db.c b/db.c
new file mode 100644 (file)
index 0000000..e7f348d
--- /dev/null
+++ b/db.c
@@ -0,0 +1,135 @@
+/* db.c
+
+   Persistent database management routines for DHCPD... */
+
+/*
+ * 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[] =
+"@(#) Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+FILE *db_file;
+
+/* Write the specified lease to the current lease database file. */
+
+int write_lease (lease)
+       struct lease *lease;
+{
+       struct tm *t;
+       char tbuf [64];
+
+       errno = 0;
+       fprintf (db_file, "lease %s\n", piaddr (lease -> ip_addr));
+
+       t = gmtime (&lease -> starts);
+       strftime (tbuf, sizeof tbuf, "%w %Y/%m/%d %H:%M:%S", t);
+       fprintf (db_file, "\tstarts %s\n", tbuf);
+
+       t = gmtime (&lease -> ends);
+       strftime (tbuf, sizeof tbuf, "%w %Y/%m/%d %H:%M:%S", t);
+       fprintf (db_file, "\tends %s", tbuf);
+
+       if (lease -> hardware_addr.hlen) {
+               fprintf (db_file, "\n\thardware %s %s",
+                        hardware_types [lease -> hardware_addr.htype],
+                        print_hw_addr (lease -> hardware_addr.htype,
+                                       lease -> hardware_addr.hlen,
+                                       lease -> hardware_addr.haddr));
+       }
+       if (lease -> uid_len) {
+               int i;
+               fprintf (db_file, "\n\tuid %x", lease -> uid [0]);
+               for (i = 1; i < lease -> uid_len; i++)
+                       fprintf (db_file, ":%x", lease -> uid [i]);
+       }
+       fputs (";\n", db_file);
+       return !errno;
+}
+
+/* Commit any leases that have been written out... */
+
+int commit_leases ()
+{
+       if (fflush (db_file) == EOF)
+               return 0;
+       if (fsync (fileno (db_file)) < 0)
+               return 0;
+       return 1;
+}
+
+void db_startup ()
+{
+       /* Read in the existing lease file... */
+       read_leases ();
+
+       new_lease_file ();
+}
+
+void new_lease_file ()
+{
+       char newfname [512];
+       char backfname [512];
+       TIME t;
+
+       /* If we already have an open database, close it. */
+       if (db_file) {
+               fclose (db_file);
+       }
+
+       /* Make a temporary lease file... */
+       time (&t);
+       sprintf (newfname, "%s.%d", _PATH_DHCPD_DB, t & 32767);
+       if ((db_file = fopen (newfname, "w")) == NULL) {
+               error ("Can't start new lease file: %m");
+       }
+
+       /* Write out all the leases that we know of... */
+       write_leases ();
+
+       /* Get the old database out of the way... */
+       sprintf (backfname, "%s~", _PATH_DHCPD_DB);
+       unlink (backfname);
+       link (_PATH_DHCPD_DB, backfname);
+       
+       /* Move in the new file... */
+       rename (newfname, _PATH_DHCPD_DB);
+}
diff --git a/dhcp.c b/dhcp.c
index 29e49cf75fa8d736b5bf14deb52522aef54dcf9d..e418da6d245f9d4ac0cec0482243c4dc82b2695a 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -379,8 +379,12 @@ void ack_lease (packet, lease, offer, when)
        /* Record the transaction id... */
        lt.xid = packet -> raw -> xid;
 
-       /* Install the new information about this lease in the database. */
-       supersede_lease (lease, &lt);
+       /* Install the new information about this lease in the database.
+          If this is a DHCPACK and we can't write the lease, don't
+          ACK it either. */
+       if (!(supersede_lease (lease, &lt, offer == DHCPACK)
+             || offer != DHCPACK))
+         return;
 
        /* Send a response to the client... */
 
diff --git a/dhcp.h b/dhcp.h
index ac88e393d9577f08dee3a6706ec5b026eba2727e..8bee3732f4dc33070cbe8e945f8e27bccea869bd 100644 (file)
--- a/dhcp.h
+++ b/dhcp.h
@@ -63,8 +63,8 @@ struct dhcp_packet {
        struct in_addr siaddr;  /* IP address of next server to talk to */
        struct in_addr giaddr;  /* DHCP relay agent IP address */
        char chaddr [16];       /* Client hardware address */
-       char sname [64];        /* Server name */
-       char file [128];        /* Boot filename */
+       char sname [DHCP_SNAME_LEN];    /* Server name */
+       char file [DHCP_FILE_LEN];      /* Boot filename */
        unsigned char options [DHCP_OPTION_LEN];
                                /* Optional parameters
                                   (actual length dependent on MTU). */
diff --git a/dhcpd.c b/dhcpd.c
index 85d0f5b170fafebf937de399ea3a9b047ee00b3f..f0452b498f4f41ef65cd38f0afa1d798b13a91c5 100644 (file)
--- a/dhcpd.c
+++ b/dhcpd.c
@@ -132,6 +132,9 @@ int main (argc, argv, envp)
        /* Read the dhcpd.conf file... */
        readconf ();
 
+       /* Start up the database... */
+       db_startup ();
+
 #if 0
        /* If addresses were specified on the command line, resolve them;
           otherwise, just get a list of the addresses that are configured
index 53c657f692d98c616c3f431414a810c6076a7f02..b14de2d4d27311a19003d1464fe7029fc2db7986 100644 (file)
@@ -1,34 +1,7 @@
 subnet 204.254.239.0 netmask 255.255.255.0
-  range 204.254.239.11 204.254.239.17;
-
-subnet 204.254.240.0 netmask 255.255.255.0
-  range 204.254.240.11 204.254.240.12;
-
-host minuet
-       hardware ethernet 08:00:2b:35:0c:18
-       filename "/tftpboot/netbsd.minuet"
-       fixed-address minuet.fugue.com;
-
-host allegro
-       hardware ethernet 08:00:2b:1c:07:b6
-       filename "/tftpboot/netbsd.allegro"
-       fixed-address allegro.fugue.com;
-
-host fantasia
-       hardware ethernet 8:0:7:26:c0:a5
-       fixed-address fantasia.fugue.com
-       option routers prelude.fugue.com
-       option name-servers toccata.fugue.com, passacaglia.fugue.com
-       option domain-name "fugue.com";
-
-host avogadro
-       hardware ethernet 08:00:2b:4c:39:12
-       option routers prelude.fugue.com
-       option name-servers toccata.fugue.com
-       option domain-name "fugue.com";
-
-lease 204.254.239.11
-       starts 2 96/2/6 10:14:02
-       ends 2 96/2/6 11:15:02
-       hardware ethernet 08:00:2b:4c:39:12
-       host avogadro;
+  range 204.254.239.10 204.254.239.20
+  option subnet-mask 255.255.255.0 option broadcast-address 204.254.239.255
+  default-lease-time 600 max-lease-time 7200
+  option routers 204.254.239.1
+  option domain-name-servers 204.254.239.2
+  option domain-name "fugue.com";
diff --git a/dhcpd.h b/dhcpd.h
index 4d1863e510f513ef743f450de01342dc69f38195..0ff116df3a9b568954d03e0de1638ff0351f7d5c 100644 (file)
--- a/dhcpd.h
+++ b/dhcpd.h
@@ -154,8 +154,10 @@ typedef unsigned char option_mask [16];
 #ifndef _PATH_DHCPD_CONF
 #ifdef DEBUG
 #define _PATH_DHCPD_CONF       "dhcpd.conf"
+#define _PATH_DHCPD_DB         "dhcpd.leases"
 #else
 #define _PATH_DHCPD_CONF       "/etc/dhcpd.conf"
+#define _PATH_DHCPD_CONF       "/etc/dhcpd.leases"
 #endif
 #endif
 
@@ -170,12 +172,12 @@ void parse_options PROTO ((struct packet *));
 void parse_option_buffer PROTO ((struct packet *, unsigned char *, int));
 void cons_options PROTO ((struct packet *, struct packet *,
                          struct tree_cache **, int));
-void new_cons_options PROTO ((struct packet *, struct packet *,
-                         struct tree_cache **, int));
+/* void new_cons_options PROTO ((struct packet *, struct packet *,
+                         struct tree_cache **, int)); */
 int store_options PROTO ((unsigned char *, int, struct tree_cache **,
-                          unsigned char *, int));
-int store_option PROTO ((struct tree_cache **, unsigned char,
-                        unsigned char *, int, int *));
+                          unsigned char *, int, int, int));
+/* int store_option PROTO ((struct tree_cache **, unsigned char,
+                        unsigned char *, int, int *)); */
 char *pretty_print_option PROTO ((unsigned char, unsigned char *, int));
 
 /* errwarn.c */
@@ -209,6 +211,7 @@ int peek_token PROTO ((char **, FILE *));
 
 /* confpars.c */
 void readconf PROTO ((void));
+void read_leases PROTO ((void));
 void parse_statement PROTO ((FILE *));
 void skip_to_semi PROTO ((FILE *));
 struct host_decl *parse_host_statement PROTO ((FILE *, jmp_buf *));
@@ -266,7 +269,7 @@ void new_address_range PROTO ((struct iaddr, struct iaddr,
 extern struct subnet *find_subnet (struct iaddr);
 void enter_subnet (struct subnet *);
 void enter_lease PROTO ((struct lease *));
-void supersede_lease PROTO ((struct lease *, struct lease *));
+int supersede_lease PROTO ((struct lease *, struct lease *, int));
 void release_lease PROTO ((struct lease *));
 void abandon_lease PROTO ((struct lease *));
 struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
@@ -274,6 +277,7 @@ struct lease *find_lease_by_hw_addr PROTO ((unsigned char *, int));
 struct lease *find_lease_by_ip_addr PROTO ((struct iaddr));
 struct class *add_class PROTO ((int, char *));
 struct class *find_class PROTO ((int, char *, int));
+void write_leases PROTO ((void));
 void dump_subnets PROTO ((void));
 
 /* alloc.c */
@@ -319,6 +323,7 @@ unsigned char *hash_lookup PROTO ((struct hash_table *, char *, int));
 extern struct option dhcp_options [256];
 extern unsigned char dhcp_option_default_priority_list [];
 extern int sizeof_dhcp_option_default_priority_list;
+extern char *hardware_types [256];
 extern struct hash_table universe_hash;
 extern struct universe dhcp_universe;
 void initialize_universes PROTO ((void));
@@ -334,12 +339,17 @@ void putUShort PROTO ((unsigned char *, unsigned short));
 void putShort PROTO ((unsigned char *, short));
 
 /* inet.c */
-struct iaddr subnet_number (struct iaddr, struct iaddr);
-struct iaddr ip_addr (struct iaddr, struct iaddr, unsigned long);
-unsigned long host_addr (struct iaddr, struct iaddr);
-int addr_eq (struct iaddr, struct iaddr);
-char *piaddr (struct iaddr);
+struct iaddr subnet_number PROTO ((struct iaddr, struct iaddr));
+struct iaddr ip_addr PROTO ((struct iaddr, struct iaddr, unsigned long));
+unsigned long host_addr PROTO ((struct iaddr, struct iaddr));
+int addr_eq PROTO ((struct iaddr, struct iaddr));
+char *piaddr PROTO ((struct iaddr));
 
 /* dhclient.c */
-void parse_client_statement (FILE *, struct host_decl *);
+void parse_client_statement PROTO ((FILE *, struct host_decl *));
 
+/* db.c */
+int write_lease PROTO ((struct lease *));
+int commit_leases PROTO ((void));
+void db_startup PROTO ((void));
+void new_lease_file PROTO ((void));
index ac88e393d9577f08dee3a6706ec5b026eba2727e..8bee3732f4dc33070cbe8e945f8e27bccea869bd 100644 (file)
@@ -63,8 +63,8 @@ struct dhcp_packet {
        struct in_addr siaddr;  /* IP address of next server to talk to */
        struct in_addr giaddr;  /* DHCP relay agent IP address */
        char chaddr [16];       /* Client hardware address */
-       char sname [64];        /* Server name */
-       char file [128];        /* Boot filename */
+       char sname [DHCP_SNAME_LEN];    /* Server name */
+       char file [DHCP_FILE_LEN];      /* Boot filename */
        unsigned char options [DHCP_OPTION_LEN];
                                /* Optional parameters
                                   (actual length dependent on MTU). */
index 4d1863e510f513ef743f450de01342dc69f38195..0ff116df3a9b568954d03e0de1638ff0351f7d5c 100644 (file)
@@ -154,8 +154,10 @@ typedef unsigned char option_mask [16];
 #ifndef _PATH_DHCPD_CONF
 #ifdef DEBUG
 #define _PATH_DHCPD_CONF       "dhcpd.conf"
+#define _PATH_DHCPD_DB         "dhcpd.leases"
 #else
 #define _PATH_DHCPD_CONF       "/etc/dhcpd.conf"
+#define _PATH_DHCPD_CONF       "/etc/dhcpd.leases"
 #endif
 #endif
 
@@ -170,12 +172,12 @@ void parse_options PROTO ((struct packet *));
 void parse_option_buffer PROTO ((struct packet *, unsigned char *, int));
 void cons_options PROTO ((struct packet *, struct packet *,
                          struct tree_cache **, int));
-void new_cons_options PROTO ((struct packet *, struct packet *,
-                         struct tree_cache **, int));
+/* void new_cons_options PROTO ((struct packet *, struct packet *,
+                         struct tree_cache **, int)); */
 int store_options PROTO ((unsigned char *, int, struct tree_cache **,
-                          unsigned char *, int));
-int store_option PROTO ((struct tree_cache **, unsigned char,
-                        unsigned char *, int, int *));
+                          unsigned char *, int, int, int));
+/* int store_option PROTO ((struct tree_cache **, unsigned char,
+                        unsigned char *, int, int *)); */
 char *pretty_print_option PROTO ((unsigned char, unsigned char *, int));
 
 /* errwarn.c */
@@ -209,6 +211,7 @@ int peek_token PROTO ((char **, FILE *));
 
 /* confpars.c */
 void readconf PROTO ((void));
+void read_leases PROTO ((void));
 void parse_statement PROTO ((FILE *));
 void skip_to_semi PROTO ((FILE *));
 struct host_decl *parse_host_statement PROTO ((FILE *, jmp_buf *));
@@ -266,7 +269,7 @@ void new_address_range PROTO ((struct iaddr, struct iaddr,
 extern struct subnet *find_subnet (struct iaddr);
 void enter_subnet (struct subnet *);
 void enter_lease PROTO ((struct lease *));
-void supersede_lease PROTO ((struct lease *, struct lease *));
+int supersede_lease PROTO ((struct lease *, struct lease *, int));
 void release_lease PROTO ((struct lease *));
 void abandon_lease PROTO ((struct lease *));
 struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
@@ -274,6 +277,7 @@ struct lease *find_lease_by_hw_addr PROTO ((unsigned char *, int));
 struct lease *find_lease_by_ip_addr PROTO ((struct iaddr));
 struct class *add_class PROTO ((int, char *));
 struct class *find_class PROTO ((int, char *, int));
+void write_leases PROTO ((void));
 void dump_subnets PROTO ((void));
 
 /* alloc.c */
@@ -319,6 +323,7 @@ unsigned char *hash_lookup PROTO ((struct hash_table *, char *, int));
 extern struct option dhcp_options [256];
 extern unsigned char dhcp_option_default_priority_list [];
 extern int sizeof_dhcp_option_default_priority_list;
+extern char *hardware_types [256];
 extern struct hash_table universe_hash;
 extern struct universe dhcp_universe;
 void initialize_universes PROTO ((void));
@@ -334,12 +339,17 @@ void putUShort PROTO ((unsigned char *, unsigned short));
 void putShort PROTO ((unsigned char *, short));
 
 /* inet.c */
-struct iaddr subnet_number (struct iaddr, struct iaddr);
-struct iaddr ip_addr (struct iaddr, struct iaddr, unsigned long);
-unsigned long host_addr (struct iaddr, struct iaddr);
-int addr_eq (struct iaddr, struct iaddr);
-char *piaddr (struct iaddr);
+struct iaddr subnet_number PROTO ((struct iaddr, struct iaddr));
+struct iaddr ip_addr PROTO ((struct iaddr, struct iaddr, unsigned long));
+unsigned long host_addr PROTO ((struct iaddr, struct iaddr));
+int addr_eq PROTO ((struct iaddr, struct iaddr));
+char *piaddr PROTO ((struct iaddr));
 
 /* dhclient.c */
-void parse_client_statement (FILE *, struct host_decl *);
+void parse_client_statement PROTO ((FILE *, struct host_decl *));
 
+/* db.c */
+int write_lease PROTO ((struct lease *));
+int commit_leases PROTO ((void));
+void db_startup PROTO ((void));
+void new_lease_file PROTO ((void));
index ac33d50b70f62b6c35ffcb8dfab4027bf9dbc188..b0e48cad59536e3d5f7105bc03def82bed47017a 100644 (file)
--- a/memory.c
+++ b/memory.c
@@ -42,7 +42,7 @@
 
 #ifndef lint
 static char copyright[] =
-"@(#) Copyright (c) 1995 The Internet Software Consortium.  All rights reserved.\n";
+"@(#) Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -162,8 +162,8 @@ void new_address_range (low, high, subnet)
                if (address_range [i].next)
                        address_range [i].next -> prev = subnet -> leases;
                add_hash (lease_ip_addr_hash,
-                         (char *)&address_range [i].ip_addr,
-                         sizeof address_range [i].ip_addr,
+                         address_range [i].ip_addr.iabuf,
+                         address_range [i].ip_addr.len,
                          (unsigned char *)&address_range [i]);
        }
 
@@ -187,7 +187,7 @@ void new_address_range (low, high, subnet)
                                dangling_leases = lp -> next;
                        }
                        lp -> next = (struct lease *)0;
-                       supersede_lease (&address_range [lhost - i], lp);
+                       supersede_lease (&address_range [lhost - i], lp, 0);
                        free_lease (lp, "new_address_range");
                } else
                        plp = lp;
@@ -230,6 +230,7 @@ void enter_lease (lease)
        /* If we don't have a place for this lease yet, save it for
           later. */
        if (!comp) {
+printf ("didn't find the lease...\n");
                comp = new_lease ("enter_lease");
                if (!comp) {
                        error ("No memory for lease %s\n",
@@ -240,7 +241,8 @@ void enter_lease (lease)
                lease -> prev = (struct lease *)0;
                dangling_leases = lease;
        } else {
-               supersede_lease (comp, lease);
+printf ("superseding lease...\n");
+               supersede_lease (comp, lease, 0);
        }
 }
 
@@ -249,8 +251,9 @@ void enter_lease (lease)
    list of leases by expiry time so that we can always find the oldest
    lease. */
 
-void supersede_lease (comp, lease)
+int supersede_lease (comp, lease, commit)
        struct lease *comp, *lease;
+       int commit;
 {
        int enter_uid = 0;
        int enter_hwaddr = 0;
@@ -402,6 +405,10 @@ void supersede_lease (comp, lease)
                comp -> contain -> 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. */
@@ -413,7 +420,7 @@ void release_lease (lease)
 
        lt = *lease;
        lt.ends = cur_time;
-       supersede_lease (lease, &lt);
+       supersede_lease (lease, &lt, 1);
 }
 
 /* Abandon the specified lease (set its timeout to infinity and its
@@ -432,7 +439,7 @@ void abandon_lease (lease)
        lt.hardware_addr.hlen = 0;
        lt.uid = (char *)0;
        lt.uid_len = 0;
-       supersede_lease (lease, &lt);
+       supersede_lease (lease, &lt, 1);
 }
 
 /* Locate the lease associated with a given IP address... */
@@ -504,6 +511,23 @@ struct class *find_class (type, name, len)
        return class;
 }      
 
+/* Write all interesting leases to permanent storage. */
+
+void write_leases ()
+{
+       struct lease *l;
+       struct subnet *s;
+       int i;
+
+       for (s = subnets; s; s = s -> next) {
+               for (l = s -> leases; l; l = l -> next) {
+                       if (l -> hardware_addr.hlen || l -> uid_len)
+                               write_lease (l);
+               }
+       }
+       commit_leases ();
+}
+
 void dump_subnets ()
 {
        struct lease *l;
index 7c860727edf5c80b78de3c0e6d2cce8ef55eb405..a5ff795a9fdc20c84bbcbe1c5dab48e95557071e 100644 (file)
--- a/options.c
+++ b/options.c
@@ -3,7 +3,8 @@
    DHCP options parsing and reassembly. */
 
 /*
- * Copyright (c) 1995 The Internet Software Consortium.  All rights reserved.
+ * 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
@@ -41,7 +42,7 @@
 
 #ifndef lint
 static char copyright[] =
-"@(#) Copyright (c) 1995 The Internet Software Consortium.  All rights reserved.\n";
+"@(#) Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #define DHCP_OPTION_DATA
index 6f850448e1d027555176a75b1a6eda79eb95596b..f3cf4f30d79237396951a5d0c55068302cd12798 100644 (file)
@@ -70,6 +70,38 @@ void readconf (void)
                        break;
                parse_statement (cfile);
        } while (1);
+       token = next_token (&val, cfile);
+}
+
+void read_leases (void)
+{
+       FILE *cfile;
+       char *val;
+       int token;
+       jmp_buf bc;
+
+       /* Open the lease file... */
+       if ((cfile = fopen (_PATH_DHCPD_DB, "r")) == NULL)
+               warn ("Can't open lease database %s: %m", _PATH_DHCPD_DB);
+       do {
+               token = next_token (&val, cfile);
+printf ("token = %d\n", token);
+               if (token == EOF)
+                       break;
+               if (token != LEASE) {
+                       warn ("Corrupt lease file - possible data loss!");
+                       skip_to_semi (cfile);
+               } else {
+                       if (!setjmp (bc)) {
+                               struct lease *lease;
+printf ("Parsing a lease...\n");
+                               lease = parse_lease_statement (cfile, &bc);
+                               enter_lease (lease);
+print_lease (lease);
+                       }
+               }
+
+       } while (1);
 }
 
 /* statement :== host_statement */
diff --git a/server/db.c b/server/db.c
new file mode 100644 (file)
index 0000000..e7f348d
--- /dev/null
@@ -0,0 +1,135 @@
+/* db.c
+
+   Persistent database management routines for DHCPD... */
+
+/*
+ * 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[] =
+"@(#) Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+FILE *db_file;
+
+/* Write the specified lease to the current lease database file. */
+
+int write_lease (lease)
+       struct lease *lease;
+{
+       struct tm *t;
+       char tbuf [64];
+
+       errno = 0;
+       fprintf (db_file, "lease %s\n", piaddr (lease -> ip_addr));
+
+       t = gmtime (&lease -> starts);
+       strftime (tbuf, sizeof tbuf, "%w %Y/%m/%d %H:%M:%S", t);
+       fprintf (db_file, "\tstarts %s\n", tbuf);
+
+       t = gmtime (&lease -> ends);
+       strftime (tbuf, sizeof tbuf, "%w %Y/%m/%d %H:%M:%S", t);
+       fprintf (db_file, "\tends %s", tbuf);
+
+       if (lease -> hardware_addr.hlen) {
+               fprintf (db_file, "\n\thardware %s %s",
+                        hardware_types [lease -> hardware_addr.htype],
+                        print_hw_addr (lease -> hardware_addr.htype,
+                                       lease -> hardware_addr.hlen,
+                                       lease -> hardware_addr.haddr));
+       }
+       if (lease -> uid_len) {
+               int i;
+               fprintf (db_file, "\n\tuid %x", lease -> uid [0]);
+               for (i = 1; i < lease -> uid_len; i++)
+                       fprintf (db_file, ":%x", lease -> uid [i]);
+       }
+       fputs (";\n", db_file);
+       return !errno;
+}
+
+/* Commit any leases that have been written out... */
+
+int commit_leases ()
+{
+       if (fflush (db_file) == EOF)
+               return 0;
+       if (fsync (fileno (db_file)) < 0)
+               return 0;
+       return 1;
+}
+
+void db_startup ()
+{
+       /* Read in the existing lease file... */
+       read_leases ();
+
+       new_lease_file ();
+}
+
+void new_lease_file ()
+{
+       char newfname [512];
+       char backfname [512];
+       TIME t;
+
+       /* If we already have an open database, close it. */
+       if (db_file) {
+               fclose (db_file);
+       }
+
+       /* Make a temporary lease file... */
+       time (&t);
+       sprintf (newfname, "%s.%d", _PATH_DHCPD_DB, t & 32767);
+       if ((db_file = fopen (newfname, "w")) == NULL) {
+               error ("Can't start new lease file: %m");
+       }
+
+       /* Write out all the leases that we know of... */
+       write_leases ();
+
+       /* Get the old database out of the way... */
+       sprintf (backfname, "%s~", _PATH_DHCPD_DB);
+       unlink (backfname);
+       link (_PATH_DHCPD_DB, backfname);
+       
+       /* Move in the new file... */
+       rename (newfname, _PATH_DHCPD_DB);
+}
index 29e49cf75fa8d736b5bf14deb52522aef54dcf9d..e418da6d245f9d4ac0cec0482243c4dc82b2695a 100644 (file)
@@ -379,8 +379,12 @@ void ack_lease (packet, lease, offer, when)
        /* Record the transaction id... */
        lt.xid = packet -> raw -> xid;
 
-       /* Install the new information about this lease in the database. */
-       supersede_lease (lease, &lt);
+       /* Install the new information about this lease in the database.
+          If this is a DHCPACK and we can't write the lease, don't
+          ACK it either. */
+       if (!(supersede_lease (lease, &lt, offer == DHCPACK)
+             || offer != DHCPACK))
+         return;
 
        /* Send a response to the client... */
 
index 85d0f5b170fafebf937de399ea3a9b047ee00b3f..f0452b498f4f41ef65cd38f0afa1d798b13a91c5 100644 (file)
@@ -132,6 +132,9 @@ int main (argc, argv, envp)
        /* Read the dhcpd.conf file... */
        readconf ();
 
+       /* Start up the database... */
+       db_startup ();
+
 #if 0
        /* If addresses were specified on the command line, resolve them;
           otherwise, just get a list of the addresses that are configured
index 53c657f692d98c616c3f431414a810c6076a7f02..b14de2d4d27311a19003d1464fe7029fc2db7986 100644 (file)
@@ -1,34 +1,7 @@
 subnet 204.254.239.0 netmask 255.255.255.0
-  range 204.254.239.11 204.254.239.17;
-
-subnet 204.254.240.0 netmask 255.255.255.0
-  range 204.254.240.11 204.254.240.12;
-
-host minuet
-       hardware ethernet 08:00:2b:35:0c:18
-       filename "/tftpboot/netbsd.minuet"
-       fixed-address minuet.fugue.com;
-
-host allegro
-       hardware ethernet 08:00:2b:1c:07:b6
-       filename "/tftpboot/netbsd.allegro"
-       fixed-address allegro.fugue.com;
-
-host fantasia
-       hardware ethernet 8:0:7:26:c0:a5
-       fixed-address fantasia.fugue.com
-       option routers prelude.fugue.com
-       option name-servers toccata.fugue.com, passacaglia.fugue.com
-       option domain-name "fugue.com";
-
-host avogadro
-       hardware ethernet 08:00:2b:4c:39:12
-       option routers prelude.fugue.com
-       option name-servers toccata.fugue.com
-       option domain-name "fugue.com";
-
-lease 204.254.239.11
-       starts 2 96/2/6 10:14:02
-       ends 2 96/2/6 11:15:02
-       hardware ethernet 08:00:2b:4c:39:12
-       host avogadro;
+  range 204.254.239.10 204.254.239.20
+  option subnet-mask 255.255.255.0 option broadcast-address 204.254.239.255
+  default-lease-time 600 max-lease-time 7200
+  option routers 204.254.239.1
+  option domain-name-servers 204.254.239.2
+  option domain-name "fugue.com";
index ada34a6a3ba2895a0133a585c8e5601d4a837a91..5b79b1458ec9285df4ed2de13fbad50a9d3641b4 100644 (file)
--- a/tables.c
+++ b/tables.c
@@ -389,6 +389,266 @@ 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",
+       "unknown-6",
+       "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()