summaryrefslogtreecommitdiff
path: root/usr.sbin/dhcp/server/dhcp.c
diff options
context:
space:
mode:
authorBob Beck <beck@cvs.openbsd.org>2000-07-21 00:33:56 +0000
committerBob Beck <beck@cvs.openbsd.org>2000-07-21 00:33:56 +0000
commitaa389468cd20d9cba720513723e7cdd3c96b386c (patch)
tree1c74c8e85063e4316ac0e0f4ccaffed3a69f5567 /usr.sbin/dhcp/server/dhcp.c
parentf495a1173b9f029e6b881104194fae1926c4205e (diff)
Deal with a bunch of dhcp issues, ok fries@:
- some minor cleanup (syscall return codes, dead code, use strlcpy, etc) - sanity check dhcp option values recieved by dhclient so that things that should look like a hostname look like a hostname, and things that should look like an ip address look like an ip address, if they don't ignore the lease offer because it's bogus. - Make the dhcp server attempt to ping an address when it recieves a RELEASE from it. If the address answers a ping, ignore the release offer. This helps make spoofing releases to liberate addresses more difficult.
Diffstat (limited to 'usr.sbin/dhcp/server/dhcp.c')
-rw-r--r--usr.sbin/dhcp/server/dhcp.c55
1 files changed, 43 insertions, 12 deletions
diff --git a/usr.sbin/dhcp/server/dhcp.c b/usr.sbin/dhcp/server/dhcp.c
index 6cd75f2a654..5acd78cbd1a 100644
--- a/usr.sbin/dhcp/server/dhcp.c
+++ b/usr.sbin/dhcp/server/dhcp.c
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: dhcp.c,v 1.1 1998/08/18 03:43:34 deraadt Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhcp.c,v 1.2 2000/07/21 00:33:54 beck Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -342,19 +342,50 @@ void dhcprelease (packet)
}
- note ("DHCPRELEASE of %s from %s via %s (%sfound)",
- inet_ntoa (packet -> raw -> ciaddr),
- print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr),
- packet -> raw -> giaddr.s_addr
- ? inet_ntoa (packet -> raw -> giaddr)
- : packet -> interface -> name,
- lease ? "" : "not ");
-
/* If we found a lease, release it. */
if (lease) {
- release_lease (lease);
+ /* first, we ping this lease to see if it's still
+ * there. if it is, we don't release it.
+ * this avoids the problem of spoofed releases
+ * being used to liberate addresses from the
+ * server.
+ */
+ if (! lease->releasing) {
+ note ("DHCPRELEASE of %s from %s via %s (found)",
+ inet_ntoa (packet -> raw -> ciaddr),
+ print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr),
+ packet -> raw -> giaddr.s_addr
+ ? inet_ntoa (packet -> raw -> giaddr)
+ : packet -> interface -> name,
+ lease ? "" : "not ");
+
+ lease->releasing = 1;
+ add_timeout (cur_time + 1, lease_ping_timeout, lease);
+ icmp_echorequest (&(lease -> ip_addr));
+ ++outstanding_pings;
+ }
+ else {
+ note ("DHCPRELEASE of %s from %s via %s ignored (release already pending)",
+ inet_ntoa (packet -> raw -> ciaddr),
+ print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr),
+ packet -> raw -> giaddr.s_addr
+ ? inet_ntoa (packet -> raw -> giaddr)
+ : packet -> interface -> name);
+ }
+ }
+ else {
+ note ("DHCPRELEASE of %s from %s via %s for nonexistent lease",
+ inet_ntoa (packet -> raw -> ciaddr),
+ print_hw_addr (packet -> raw -> htype,
+ packet -> raw -> hlen,
+ packet -> raw -> chaddr),
+ packet -> raw -> giaddr.s_addr
+ ? inet_ntoa (packet -> raw -> giaddr)
+ : packet -> interface -> name);
}
}