summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorChris Kuethe <ckuethe@cvs.openbsd.org>2006-06-14 14:58:53 +0000
committerChris Kuethe <ckuethe@cvs.openbsd.org>2006-06-14 14:58:53 +0000
commit0edc08d91552b11f7caa2191b759b475bf31297c (patch)
tree0cb96e5eec6787f047319e7f136c93e6eaacc2d9 /usr.sbin
parent5a9b4670b341057df3e36cb54a9dd228dfb75da5 (diff)
This diff allows dhcpd to put active leases into a pf table. Dhcpd will then
periodically - based on the length of the shortest lease time - walk across all leases searching for expired leases which are then removed from the pf table. ok henning
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/dhcpd/dhcpd.814
-rw-r--r--usr.sbin/dhcpd/dhcpd.c54
-rw-r--r--usr.sbin/dhcpd/dhcpd.h3
-rw-r--r--usr.sbin/dhcpd/memory.c4
-rw-r--r--usr.sbin/dhcpd/pfutils.c56
5 files changed, 111 insertions, 20 deletions
diff --git a/usr.sbin/dhcpd/dhcpd.8 b/usr.sbin/dhcpd/dhcpd.8
index d5abc76049a..9da7203e6e3 100644
--- a/usr.sbin/dhcpd/dhcpd.8
+++ b/usr.sbin/dhcpd/dhcpd.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: dhcpd.8,v 1.10 2006/05/31 09:05:42 jmc Exp $
+.\" $OpenBSD: dhcpd.8,v 1.11 2006/06/14 14:58:51 ckuethe Exp $
.\"
.\" Copyright (c) 1995, 1996 The Internet Software Consortium.
.\" All rights reserved.
@@ -48,6 +48,7 @@
.Op Fl dfn
.Op Fl A Ar abandoned_ip_table
.Op Fl C Ar changed_ip_table
+.Op Fl L Ar leased_ip_table
.Op Fl c Ar config-file
.Op Fl l Ar lease-file
.Op Fl p Ar pf-device
@@ -178,6 +179,17 @@ When the address is leased to a different machine,
.Nm
can remove the address from the overload table, thus allowing a well-behaved
machine to reuse the address.
+.It Fl L Ar leased_ip_table
+When an address is leased
+.Nm
+will insert it into the
+.Xr pf 4
+table named
+.Ar leased_ip_table .
+Addresses are removed from the table when the lease expires.
+Combined with the table of abandoned addresses, this can help enforce a
+requirement to use DHCP on a network, or can place DHCP users in a different
+class of service.
Users are cautioned against placing much trust in Ethernet or IP addresses;
.Xr ifconfig 8
can be used to trivially change the interface's address, and on a busy DHCP
diff --git a/usr.sbin/dhcpd/dhcpd.c b/usr.sbin/dhcpd/dhcpd.c
index 6a32c42e85b..504cbbbe814 100644
--- a/usr.sbin/dhcpd/dhcpd.c
+++ b/usr.sbin/dhcpd/dhcpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhcpd.c,v 1.27 2006/06/01 06:06:27 ckuethe Exp $ */
+/* $OpenBSD: dhcpd.c,v 1.28 2006/06/14 14:58:52 ckuethe Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@cvs.openbsd.org>
@@ -60,6 +60,7 @@ char *path_dhcpd_conf = _PATH_DHCPD_CONF;
char *path_dhcpd_db = _PATH_DHCPD_DB;
char *abandoned_tab = NULL;
char *changedmac_tab = NULL;
+char *leased_tab = NULL;
int
main(int argc, char *argv[])
@@ -71,7 +72,7 @@ main(int argc, char *argv[])
openlog(__progname, LOG_NDELAY, DHCPD_LOG_FACILITY);
setlogmask(LOG_UPTO(LOG_INFO));
- while ((ch = getopt(argc, argv, "A:C:c:dfl:nq")) != -1)
+ while ((ch = getopt(argc, argv, "A:C:L:c:dfl:nq")) != -1)
switch (ch) {
case 'A':
abandoned_tab = optarg;
@@ -79,6 +80,9 @@ main(int argc, char *argv[])
case 'C':
changedmac_tab = optarg;
break;
+ case 'L':
+ leased_tab = optarg;
+ break;
case 'c':
path_dhcpd_conf = optarg;
break;
@@ -141,7 +145,9 @@ main(int argc, char *argv[])
daemon(0, 0);
/* don't go near /dev/pf unless we actually intend to use it */
- if ((abandoned_tab != NULL) || (changedmac_tab != NULL)){
+ if ((abandoned_tab != NULL) ||
+ (changedmac_tab != NULL) ||
+ (leased_tab != NULL)){
if (pipe(pfpipe) == -1)
error("pipe (%m)");
switch (pfproc_pid = fork()){
@@ -170,6 +176,7 @@ main(int argc, char *argv[])
error("can't drop privileges: %m");
bootp_packet_handler = do_packet;
+ add_timeout(cur_time + 5, periodic_scan, NULL);
dispatch();
/* not reached */
@@ -183,8 +190,9 @@ usage(void)
fprintf(stderr, "usage: %s [-dfn] [-A abandoned_ip_table]", __progname);
fprintf(stderr, " [-C changed_ip_table]\n");
- fprintf(stderr, "\t[-c config-file] [-l lease-file]");
- fprintf(stderr, " [-p pf-device] [if0 [...ifN]]\n");
+ fprintf(stderr, "\t[-L leased_ip_table] [-c config-file]");
+ fprintf(stderr, " [-l lease-file]\n");
+ fprintf(stderr, "\t[-p pf-device] [if0 [...ifN]]\n");
exit(1);
}
@@ -250,3 +258,39 @@ lease_ping_timeout(void *vlp)
} else
dhcp_reply(lp);
}
+
+/* from memory.c - needed to be able to walk the lease table */
+extern struct subnet *subnets;
+
+void
+periodic_scan(void *p)
+{
+ time_t x, y;
+ struct subnet *n;
+ struct group *g;
+ struct shared_network *s;
+ struct lease *l;
+
+ /* find the shortest lease this server gives out */
+ x = MIN(root_group.default_lease_time, root_group.max_lease_time);
+ for (n = subnets; n; n = n->next_subnet)
+ for (g = n->group; g; g = g->next)
+ x = MIN(x, g->default_lease_time);
+
+ /* use half of the shortest lease as the scan interval */
+ y = x / 2;
+ if (y < 1)
+ y = 1;
+
+ /* walk across all leases to find the exired ones */
+ for (n = subnets; n; n = n->next_subnet)
+ for (g = n->group; g; g = g->next)
+ for (s = g->shared_network; s; s = s->next)
+ for (l = s->leases; l && l->ends; l = l->next)
+ if (cur_time >= l->ends){
+ release_lease(l);
+ pfmsg('R', l);
+ }
+
+ add_timeout(cur_time + y, periodic_scan, NULL);
+}
diff --git a/usr.sbin/dhcpd/dhcpd.h b/usr.sbin/dhcpd/dhcpd.h
index 317b7a0ee62..541f7e6c046 100644
--- a/usr.sbin/dhcpd/dhcpd.h
+++ b/usr.sbin/dhcpd/dhcpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhcpd.h,v 1.20 2006/06/14 14:49:46 ckuethe Exp $ */
+/* $OpenBSD: dhcpd.h,v 1.21 2006/06/14 14:58:52 ckuethe Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998, 1999
@@ -566,6 +566,7 @@ int main(int, char *[]);
void cleanup(void);
void lease_pinged(struct iaddr, u_int8_t *, int);
void lease_ping_timeout(void *);
+void periodic_scan(void *);
/* conflex.c */
extern int lexline, lexchar;
diff --git a/usr.sbin/dhcpd/memory.c b/usr.sbin/dhcpd/memory.c
index a1f97ae4cde..4d73499da82 100644
--- a/usr.sbin/dhcpd/memory.c
+++ b/usr.sbin/dhcpd/memory.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: memory.c,v 1.12 2006/06/14 14:49:46 ckuethe Exp $ */
+/* $OpenBSD: memory.c,v 1.13 2006/06/14 14:58:52 ckuethe Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
@@ -40,7 +40,7 @@
#include "dhcpd.h"
-static struct subnet *subnets;
+struct subnet *subnets;
static struct shared_network *shared_networks;
static struct hash_table *host_hw_addr_hash;
static struct hash_table *host_uid_hash;
diff --git a/usr.sbin/dhcpd/pfutils.c b/usr.sbin/dhcpd/pfutils.c
index 15b06c8138c..ac414a5f95a 100644
--- a/usr.sbin/dhcpd/pfutils.c
+++ b/usr.sbin/dhcpd/pfutils.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfutils.c,v 1.4 2006/06/14 14:49:46 ckuethe Exp $ */
+/* $OpenBSD: pfutils.c,v 1.5 2006/06/14 14:58:52 ckuethe Exp $ */
/*
* Copyright (c) 2006 Chris Kuethe <ckuethe@openbsd.org>
*
@@ -43,6 +43,7 @@ extern int pfpipe[2];
extern int gotpipe;
extern char *abandoned_tab;
extern char *changedmac_tab;
+extern char *leased_tab;
__dead void
pftable_handler()
@@ -80,16 +81,44 @@ pftable_handler()
error("pf pipe error: %m");
switch (cmd.type){
- case 'A':
- pf_change_table(fd, 1, cmd.ip, abandoned_tab);
- pf_kill_state(fd, cmd.ip);
- break;
- case 'C':
- pf_change_table(fd, 0, cmd.ip, abandoned_tab);
- pf_change_table(fd, 0, cmd.ip, changedmac_tab);
- break;
- case 'L':
- pf_change_table(fd, 0, cmd.ip, abandoned_tab);
+ case 'A':
+ /*
+ * When we abandon an address, we add it to the
+ * the table of abandoned addresses, and remove
+ * it from the table of active leases.
+ */
+ pf_change_table(fd, 1, cmd.ip, abandoned_tab);
+ pf_change_table(fd, 0, cmd.ip, leased_tab);
+ pf_kill_state(fd, cmd.ip);
+ break;
+ case 'C':
+ /*
+ * When the hardware address for an IP changes,
+ * remove it from the table of abandoned
+ * addresses, and from the table of overloaded
+ * addresses.
+ */
+ pf_change_table(fd, 0, cmd.ip, abandoned_tab);
+ pf_change_table(fd, 0, cmd.ip, changedmac_tab);
+ break;
+ case 'L':
+ /*
+ * When a lease is granted or renewed, remove
+ * it from the table of abandoned addresses,
+ * and ensure it is in the table of active
+ * leases.
+ */
+ pf_change_table(fd, 0, cmd.ip, abandoned_tab);
+ pf_change_table(fd, 1, cmd.ip, leased_tab);
+ break;
+ case 'R':
+ /*
+ * When we release or expire a lease, remove
+ * it from the table of active leases. As long
+ * as dhcpd doesn't abandon the address, no
+ * further action is required.
+ */
+ pf_change_table(fd, 0, cmd.ip, leased_tab);
break;
default:
break;
@@ -219,6 +248,11 @@ pfmsg(char c, struct lease *lp)
(void)atomicio(vwrite, pfpipe[1], &cmd,
sizeof(struct pf_cmd));
break;
+ case 'R': /* Address is being released or lease has expired */
+ if (leased_tab != NULL)
+ (void)atomicio(vwrite, pfpipe[1], &cmd,
+ sizeof(struct pf_cmd));
+ break;
default: /* silently ignore unknown commands */
break;
}