DHCP Protocol engine. */
/*
- * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#ifndef lint
static char copyright[] =
-"$Id: dhcp.c,v 1.61 1998/03/17 18:14:51 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhcp.c,v 1.62 1998/04/09 04:41:52 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
return;
}
+ /* Make sure this packet satisfies the configured minimum
+ number of seconds. */
+ if (packet -> raw -> secs <
+ packet -> shared_network -> group -> min_secs)
+ return;
+
/* If we didn't find a lease, try to allocate one... */
if (!lease) {
lease = packet -> shared_network -> last_lease;
lease_time = (lease -> subnet ->
group -> max_lease_time);
}
+
} else {
if (lease -> host
&& lease -> host -> group -> default_lease_time)
group -> default_lease_time);
}
+ /* Enforce a minimum lease time, if specified. */
+ if (lease -> host) {
+ if (lease_time <
+ lease -> host -> group -> min_lease_time)
+ lease_time = (lease ->
+ host -> group -> min_lease_time);
+ } else {
+ if (lease_time <
+ lease -> subnet -> group -> min_lease_time)
+ lease_time = (lease -> subnet ->
+ group -> min_lease_time);
+ }
+
state -> offered_expiry = cur_time + lease_time;
if (when)
lt.ends = when;
state -> options [i] -> tree = (struct tree *)0;
i = DHO_DHCP_SERVER_IDENTIFIER;
- state -> options [i] = new_tree_cache ("server-id");
- state -> options [i] -> value =
- (unsigned char *)&state -> ip -> primary_address;
- state -> options [i] -> len =
- sizeof state -> ip -> primary_address;
- state -> options [i] -> buf_size = state -> options [i] -> len;
- state -> options [i] -> timeout = 0xFFFFFFFF;
- state -> options [i] -> tree = (struct tree *)0;
+ if (!state -> options [i]) {
+ state -> options [i] = new_tree_cache ("server-id");
+ state -> options [i] -> value =
+ (unsigned char *)&state ->
+ ip -> primary_address;
+ state -> options [i] -> len =
+ sizeof state -> ip -> primary_address;
+ state -> options [i] -> buf_size
+ = state -> options [i] -> len;
+ state -> options [i] -> timeout = 0xFFFFFFFF;
+ state -> options [i] -> tree = (struct tree *)0;
+ }
/* Sanity check the lease time. */
if ((state -> offered_expiry - cur_time) < 15)
state -> options [i] -> tree = (struct tree *)0;
}
+ /* If so directed, use the leased IP address as the router address.
+ This supposedly makes Win95 machines ARP for all IP addresses,
+ so if the local router does proxy arp, you win. */
+ if ((lease -> host &&
+ lease -> host -> group -> use_lease_addr_for_default_route) ||
+ (lease -> subnet -> group -> use_lease_addr_for_default_route)) {
+ i = DHO_ROUTERS;
+
+ if (state -> options [i] &&
+ state -> options [i] -> flags & TC_TEMPORARY)
+ free_tree_cache (state -> options [i], "dhcp_reply");
+
+ state -> options [i] = new_tree_cache ("routers");
+ state -> options [i] -> flags = TC_TEMPORARY;
+ state -> options [i] -> value =
+ lease -> ip_addr.iabuf;
+ state -> options [i] -> len = lease -> ip_addr.len;
+ state -> options [i] -> buf_size = lease -> ip_addr.len;
+ state -> options [i] -> timeout = 0xFFFFFFFF;
+ state -> options [i] -> tree = (struct tree *)0;
+ }
+
#ifdef DEBUG_PACKET
dump_packet (packet);
dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
int i = DHO_DHCP_CLIENT_IDENTIFIER;
/* If for some reason the client has more than one lease
on the subnet that matches its uid, pick the one that
- it asked for. It might be nice in some cases to
- release the extraneous leases, but better to leave
- that to a human. */
+ it asked for. If we have a host */
if (packet -> options [i].data &&
ip_lease -> uid_len == packet -> options [i].len &&
!memcmp (packet -> options [i].data,
a better offer, use that; otherwise, release it. */
if (ip_lease) {
if (lease) {
- release_lease (ip_lease);
+ if (packet -> packet_type == DHCPREQUEST)
+ release_lease (ip_lease);
} else {
lease = ip_lease;
lease -> host = (struct host_decl *)0;
the lease that matched the client identifier. */
if (uid_lease) {
if (lease) {
- release_lease (uid_lease);
+ if (packet -> packet_type == DHCPREQUEST)
+ dissociate_lease (uid_lease);
} else {
lease = uid_lease;
lease -> host = (struct host_decl *)0;
/* The lease that matched the hardware address is treated likewise. */
if (hw_lease) {
if (lease) {
- release_lease (hw_lease);
+ if (packet -> packet_type == DHCPREQUEST)
+ dissociate_lease (hw_lease);
} else {
lease = hw_lease;
lease -> host = (struct host_decl *)0;