#ifndef lint
static char copyright[] =
-"$Id: dhcp.c,v 1.47 1997/05/09 08:27:14 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhcp.c,v 1.48 1997/06/08 03:55:58 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
void dhcpdiscover (packet)
struct packet *packet;
{
- struct lease *lease = find_lease (packet, packet -> shared_network);
+ struct lease *lease = find_lease (packet, packet -> shared_network, 0);
struct host_decl *hp;
note ("DHCPDISCOVER from %s via %s",
struct lease *lease;
struct iaddr cip;
struct subnet *subnet;
+ int ours = 0;
if (packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len) {
cip.len = 4;
client. */
if (subnet)
- lease = find_lease (packet, subnet -> shared_network);
+ lease = find_lease (packet, subnet -> shared_network, &ours);
else
lease = (struct lease *)0;
client asked for, don't send it - some other server probably
made the cut. */
if (lease && !addr_eq (lease -> ip_addr, cip)) {
+ /* If we found the address the client asked for, but
+ it wasn't what got picked, the lease belongs to us,
+ so we can tenuously justify NAKing it. */
+ if (ours)
+ nak_lease (packet, &cip);
return;
}
void dhcprelease (packet)
struct packet *packet;
{
- struct lease *lease = find_lease (packet, packet -> shared_network);
+ struct lease *lease;
+
+ /* DHCPRELEASEmust specify address. */
+ if (!packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len) {
+ return;
+ }
+
+ cip.len = 4;
+ memcpy (cip.iabuf,
+ packet -> options [DHO_DHCP_REQUESTED_ADDRESS].data, 4);
+ lease = find_lease_by_ip_addr (cip);
note ("DHCPRELEASE of %s from %s via %s",
inet_ntoa (packet -> raw -> ciaddr),
void dhcpdecline (packet)
struct packet *packet;
{
- struct lease *lease = find_lease (packet, packet -> shared_network);
+ struct lease *lease;
struct iaddr cip;
- if (packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len) {
- cip.len = 4;
- memcpy (cip.iabuf,
- packet -> options [DHO_DHCP_REQUESTED_ADDRESS].data,
- 4);
- } else {
- cip.len = 0;
+ /* DHCPDECLINE must specify address. */
+ if (!packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len) {
+ return;
}
+ cip.len = 4;
+ memcpy (cip.iabuf,
+ packet -> options [DHO_DHCP_REQUESTED_ADDRESS].data, 4);
+ lease = find_lease_by_ip_addr (cip);
+
note ("DHCPDECLINE on %s from %s via %s",
piaddr (cip),
print_hw_addr (packet -> raw -> htype,
lease -> state = (struct lease_state *)0;
}
-struct lease *find_lease (packet, share)
+struct lease *find_lease (packet, share, ours)
struct packet *packet;
struct shared_network *share;
+ int *ours;
{
struct lease *uid_lease, *ip_lease, *hw_lease;
struct lease *lease = (struct lease *)0;
} else
ip_lease = (struct lease *)0;
+ /* If ip_lease is valid at this point, set ours to one, so that
+ even if we choose a different lease, we know that the address
+ the client was requesting was ours, and thus we can NAK it. */
+ if (ip_lease)
+ *ours = 1;
+
/* If the requested IP address isn't on the network the packet
came from, or if it's been abandoned, don't use it. */
if (ip_lease && (ip_lease -> shared_network != share ||