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
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
#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"
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]);
}
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;
/* 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",
lease -> prev = (struct lease *)0;
dangling_leases = lease;
} else {
- supersede_lease (comp, lease);
+printf ("superseding lease...\n");
+ supersede_lease (comp, lease, 0);
}
}
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;
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. */
lt = *lease;
lt.ends = cur_time;
- supersede_lease (lease, <);
+ supersede_lease (lease, <, 1);
}
/* Abandon the specified lease (set its timeout to infinity and its
lt.hardware_addr.hlen = 0;
lt.uid = (char *)0;
lt.uid_len = 0;
- supersede_lease (lease, <);
+ supersede_lease (lease, <, 1);
}
/* Locate the lease associated with a given IP address... */
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;
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
#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
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()
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 */
--- /dev/null
+/* 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);
+}
/* Record the transaction id... */
lt.xid = packet -> raw -> xid;
- /* Install the new information about this lease in the database. */
- supersede_lease (lease, <);
+ /* 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, <, offer == DHCPACK)
+ || offer != DHCPACK))
+ return;
/* Send a response to the client... */
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). */
/* 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
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";
#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
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 */
/* 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 *));
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));
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 */
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));
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));
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). */
#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
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 */
/* 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 *));
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));
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 */
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));
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));
#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"
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]);
}
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;
/* 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",
lease -> prev = (struct lease *)0;
dangling_leases = lease;
} else {
- supersede_lease (comp, lease);
+printf ("superseding lease...\n");
+ supersede_lease (comp, lease, 0);
}
}
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;
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. */
lt = *lease;
lt.ends = cur_time;
- supersede_lease (lease, <);
+ supersede_lease (lease, <, 1);
}
/* Abandon the specified lease (set its timeout to infinity and its
lt.hardware_addr.hlen = 0;
lt.uid = (char *)0;
lt.uid_len = 0;
- supersede_lease (lease, <);
+ supersede_lease (lease, <, 1);
}
/* Locate the lease associated with a given IP address... */
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;
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
#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
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 */
--- /dev/null
+/* 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);
+}
/* Record the transaction id... */
lt.xid = packet -> raw -> xid;
- /* Install the new information about this lease in the database. */
- supersede_lease (lease, <);
+ /* 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, <, offer == DHCPACK)
+ || offer != DHCPACK))
+ return;
/* Send a response to the client... */
/* 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
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";
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()