2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-31 14:25:41 +00:00

Merge changes between 3.0rc7 and 3.0rc8pl2.

This commit is contained in:
Ted Lemon
2001-06-27 00:31:20 +00:00
parent 07b958004f
commit d758ad8cac
99 changed files with 5909 additions and 2698 deletions

View File

@@ -41,7 +41,7 @@
#ifndef lint
static char ocopyright[] =
"$Id: dhclient.c,v 1.129 2001/04/16 22:07:33 mellon Exp $ Copyright (c) 1995-2001 Internet Software Consortium. All rights reserved.\n";
"$Id: dhclient.c,v 1.130 2001/06/27 00:29:29 mellon Exp $ Copyright (c) 1995-2001 Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -445,7 +445,8 @@ int main (argc, argv, envp)
/* Set up the bootp packet handler... */
bootp_packet_handler = do_packet;
#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
dmalloc_cutoff_generation = dmalloc_generation;
dmalloc_longterm = dmalloc_outstanding;
dmalloc_outstanding = 0;
@@ -551,7 +552,8 @@ void state_reboot (cpp)
/* If we don't remember an active lease, go straight to INIT. */
if (!client -> active ||
client -> active -> is_bootp) {
client -> active -> is_bootp ||
client -> active -> expiry <= cur_time) {
state_init (client);
return;
}
@@ -880,6 +882,7 @@ void bind_lease (client)
client -> state = S_BOUND;
reinitialize_interfaces ();
go_daemon ();
client_dns_update (client, 1);
}
/* state_bound is called when we've successfully bound to a particular
@@ -925,6 +928,32 @@ void state_bound (cpp)
send_request (client);
}
/* state_stop is called when we've been told to shut down. We unconfigure
the interfaces, and then stop operating until told otherwise. */
void state_stop (cpp)
void *cpp;
{
struct client_state *client = cpp;
int i;
/* Cancel all timeouts. */
cancel_timeout (state_selecting, client);
cancel_timeout (send_discover, client);
cancel_timeout (send_request, client);
cancel_timeout (state_bound, client);
/* If we have an address, unconfigure it. */
if (client -> active) {
script_init (client, "STOP", client -> active -> medium);
script_write_params (client, "old_", client -> active);
if (client -> alias)
script_write_params (client, "alias_",
client -> alias);
script_go (client);
}
}
int commit_leases ()
{
return 0;
@@ -1021,6 +1050,7 @@ void dhcpoffer (packet)
const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
struct iaddrlist *ap;
struct option_cache *oc;
char obuf [1024];
#ifdef DEBUG_PACKET
dump_packet (packet);
@@ -1045,17 +1075,20 @@ void dhcpoffer (packet)
return;
}
log_info ("%s from %s", name, piaddr (packet -> client_addr));
sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr));
/* If this lease doesn't supply the minimum required parameters,
blow it off. */
if (client -> config -> required_options) {
for (i = 0; client -> config -> required_options [i]; i++) {
if (!lookup_option
(&dhcp_universe, packet -> options,
client -> config -> required_options [i])) {
log_info ("%s isn't satisfactory.", name);
for (i = 0; client -> config -> required_options [i]; i++) {
if (!lookup_option
(&dhcp_universe, packet -> options,
client -> config -> required_options [i])) {
log_info ("%s: no %s option.",
obuf, (dhcp_universe.options
[client -> config -> required_options [i]]
-> name));
return;
}
}
@@ -1066,14 +1099,14 @@ void dhcpoffer (packet)
if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
!memcmp (lease -> address.iabuf,
&packet -> raw -> yiaddr, lease -> address.len)) {
log_debug ("%s already seen.", name);
log_debug ("%s: already seen.", obuf);
return;
}
}
lease = packet_to_lease (packet, client);
if (!lease) {
log_info ("packet_to_lease failed.");
log_info ("%s: packet_to_lease failed.", obuf);
return;
}
@@ -1114,11 +1147,12 @@ void dhcpoffer (packet)
state_selecting(). Otherwise, time out into
state_selecting at the select interval. */
if (stop_selecting <= 0)
state_selecting (ip);
state_selecting (client);
else {
add_timeout (stop_selecting, state_selecting, client, 0, 0);
cancel_timeout (send_discover, client);
}
log_info ("%s", obuf);
}
/* Allocate a client_lease structure and initialize it from the parameters
@@ -1741,6 +1775,10 @@ void make_client_options (client, lease, type, sid, rip, prl, op)
struct option_cache *oc;
struct buffer *bp = (struct buffer *)0;
/* If there are any leftover options, get rid of them. */
if (*op)
option_state_dereference (op, MDL);
/* Allocate space for options. */
option_state_allocate (op, MDL);
@@ -1870,7 +1908,6 @@ void make_request (client, lease)
int i, j;
unsigned char *tmp, *digest;
unsigned char *old_digest_loc;
struct option_state *options = (struct option_state *)0;
struct option_cache *oc;
memset (&client -> packet, 0, sizeof (client -> packet));
@@ -1887,13 +1924,13 @@ void make_request (client, lease)
? &lease -> address
: (struct iaddr *)0),
client -> config -> requested_options,
&options);
&client -> sent_options);
/* Set up the option buffer... */
client -> packet_length =
cons_options ((struct packet *)0, &client -> packet,
(struct lease *)0, client, 0,
(struct option_state *)0, options,
(struct option_state *)0, client -> sent_options,
&global_scope, 0, 0, 0, (struct data_string *)0,
client -> config -> vendor_space_name);
if (client -> packet_length < BOOTP_MIN_LEN)
@@ -2750,6 +2787,7 @@ void do_release(client)
if (client -> alias)
script_write_params (client, "alias_",
client -> alias);
script_write_params (client, "old_", client -> active);
script_go (client);
}
@@ -2886,3 +2924,153 @@ unsigned cons_agent_information_options (cfg_options, outpacket,
{
return length;
}
static void shutdown_exit (void *foo)
{
exit (0);
}
isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
control_object_state_t newstate)
{
struct interface_info *ip;
struct client_state *client;
/* Do the right thing for each interface. */
for (ip = interfaces; ip; ip = ip -> next) {
for (client = ip -> client; client; client = client -> next) {
switch (newstate) {
case server_startup:
return ISC_R_SUCCESS;
case server_running:
return ISC_R_SUCCESS;
case server_shutdown:
if (client -> active &&
client -> active -> expiry > cur_time) {
client_dns_update (client, 0);
do_release (client);
}
break;
case server_hibernate:
state_stop (client);
break;
case server_awaken:
state_reboot (client);
break;
}
}
}
if (newstate == server_shutdown)
add_timeout (cur_time + 1, shutdown_exit, 0, 0, 0);
return ISC_R_SUCCESS;
}
/* See if we should do a DNS update, and if so, do it. */
void client_dns_update (struct client_state *client, int addp)
{
struct data_string ddns_fqdn, ddns_fwd_name,
ddns_dhcid, client_identifier;
struct option_cache *oc;
int ignorep;
int result;
isc_result_t rcode;
/* If we didn't send an FQDN option, we certainly aren't going to
be doing an update. */
if (!client -> sent_options)
return;
/* If we don't have a lease, we can't do an update. */
if (!client -> active)
return;
/* If we set the no client update flag, don't do the update. */
if ((oc = lookup_option (&fqdn_universe, client -> sent_options,
FQDN_NO_CLIENT_UPDATE)) &&
evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
(struct lease *)0, client,
client -> sent_options,
(struct option_state *)0,
&global_scope, oc, MDL))
return;
/* If we set the "server, please update" flag, or didn't set it
to false, don't do the update. */
if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
FQDN_SERVER_UPDATE)) ||
evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
(struct lease *)0, client,
client -> sent_options,
(struct option_state *)0,
&global_scope, oc, MDL))
return;
/* If no FQDN option was supplied, don't do the update. */
memset (&ddns_fwd_name, 0, sizeof ddns_fwd_name);
if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
FQDN_FQDN)) ||
!evaluate_option_cache (&ddns_fwd_name, (struct packet *)0,
(struct lease *)0, client,
client -> sent_options,
(struct option_state *)0,
&global_scope, oc, MDL))
return;
/* Make a dhcid string out of either the client identifier,
if we are sending one, or the interface's MAC address,
otherwise. */
memset (&ddns_dhcid, 0, sizeof ddns_dhcid);
memset (&client_identifier, 0, sizeof client_identifier);
if ((oc = lookup_option (&dhcp_universe, client -> sent_options,
DHO_DHCP_CLIENT_IDENTIFIER)) &&
evaluate_option_cache (&client_identifier, (struct packet *)0,
(struct lease *)0, client,
client -> sent_options,
(struct option_state *)0,
&global_scope, oc, MDL)) {
result = get_dhcid (&ddns_dhcid,
DHO_DHCP_CLIENT_IDENTIFIER,
client_identifier.data,
client_identifier.len);
data_string_forget (&client_identifier, MDL);
} else
result = get_dhcid (&ddns_dhcid, 0,
client -> interface -> hw_address.hbuf,
client -> interface -> hw_address.hlen);
if (!result) {
data_string_forget (&ddns_fwd_name, MDL);
return;
}
/* Start the resolver, if necessary. */
if (!resolver_inited) {
minires_ninit (&resolver_state);
resolver_inited = 1;
resolver_state.retrans = 1;
resolver_state.retry = 1;
}
/*
* Perform updates.
*/
if (ddns_fwd_name.len && ddns_dhcid.len) {
if (addp)
rcode = ddns_update_a (&ddns_fwd_name,
client -> active -> address,
&ddns_dhcid, DEFAULT_DDNS_TTL,
1);
else
rcode = ddns_remove_a (&ddns_fwd_name,
client -> active -> address,
&ddns_dhcid);
}
data_string_forget (&ddns_fwd_name, MDL);
data_string_forget (&ddns_dhcid, MDL);
}