diff options
author | Chris Kuethe <ckuethe@cvs.openbsd.org> | 2006-06-14 14:58:53 +0000 |
---|---|---|
committer | Chris Kuethe <ckuethe@cvs.openbsd.org> | 2006-06-14 14:58:53 +0000 |
commit | 0edc08d91552b11f7caa2191b759b475bf31297c (patch) | |
tree | 0cb96e5eec6787f047319e7f136c93e6eaacc2d9 /usr.sbin | |
parent | 5a9b4670b341057df3e36cb54a9dd228dfb75da5 (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.8 | 14 | ||||
-rw-r--r-- | usr.sbin/dhcpd/dhcpd.c | 54 | ||||
-rw-r--r-- | usr.sbin/dhcpd/dhcpd.h | 3 | ||||
-rw-r--r-- | usr.sbin/dhcpd/memory.c | 4 | ||||
-rw-r--r-- | usr.sbin/dhcpd/pfutils.c | 56 |
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; } |