Commit 12c9957e authored by Ted Lemon's avatar Ted Lemon

New malloc debug scheme. Support variable scoping.

parent 3185c188
......@@ -22,7 +22,7 @@
#ifndef lint
static char copyright[] =
"$Id: bootp.c,v 1.58 2000/01/05 18:12:09 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
"$Id: bootp.c,v 1.59 2000/01/25 01:32:41 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
......@@ -115,44 +115,47 @@ void bootp (packet)
/* Run the executable statements to compute the client and server
options. */
option_state_allocate (&options, "bootrequest");
option_state_allocate (&options, MDL);
/* Execute the subnet statements. */
execute_statements_in_scope (packet, lease, packet -> options, options,
lease -> subnet -> group,
&lease -> scope, lease -> subnet -> group,
(struct group *)0);
/* Execute statements from class scopes. */
for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope
(packet, lease, packet -> options, options,
packet -> classes [i - 1] -> group,
&lease -> scope, packet -> classes [i - 1] -> group,
lease -> subnet -> group);
}
/* Execute the host statements. */
execute_statements_in_scope (packet, lease, packet -> options, options,
&lease -> scope,
hp -> group, subnet -> group);
/* Drop the request if it's not allowed for this client. */
if ((oc = lookup_option (&server_universe, options, SV_ALLOW_BOOTP)) &&
!evaluate_boolean_option_cache (&ignorep, packet, lease,
packet -> options, options, oc)) {
packet -> options, options,
&lease -> scope, oc, MDL)) {
if (!ignorep)
log_info ("%s: bootp disallowed", msgbuf);
option_state_dereference (&options, "bootrequest");
static_lease_dereference (lease, "bootrequest");
option_state_dereference (&options, MDL);
static_lease_dereference (lease, MDL);
return;
}
if ((oc = lookup_option (&server_universe,
options, SV_ALLOW_BOOTING)) &&
!evaluate_boolean_option_cache (&ignorep, packet, lease,
packet -> options, options, oc)) {
packet -> options, options,
&lease -> scope, oc, MDL)) {
if (!ignorep)
log_info ("%s: booting disallowed", msgbuf);
option_state_dereference (&options, "bootrequest");
static_lease_dereference (lease, "bootrequest");
option_state_dereference (&options, MDL);
static_lease_dereference (lease, MDL);
return;
}
......@@ -166,8 +169,9 @@ void bootp (packet)
if (!packet -> options_valid &&
!(evaluate_boolean_option_cache
(&ignorep, packet, lease, packet -> options, options,
&lease -> scope,
lookup_option (&server_universe, options,
SV_ALWAYS_REPLY_RFC1048)))) {
SV_ALWAYS_REPLY_RFC1048), MDL))) {
memcpy (outgoing.raw -> options,
packet -> raw -> options, DHCP_OPTION_LEN);
outgoing.packet_length = BOOTP_MIN_LEN;
......@@ -179,7 +183,7 @@ void bootp (packet)
oc = (struct option_cache *)0;
i = DHO_SUBNET_MASK;
if (!lookup_option (&dhcp_universe, options, i)) {
if (option_cache_allocate (&oc, "ack_lease")) {
if (option_cache_allocate (&oc, MDL)) {
if (make_const_data
(&oc -> expression,
lease -> subnet -> netmask.iabuf,
......@@ -189,7 +193,7 @@ void bootp (packet)
save_option (&dhcp_universe,
options, oc);
}
option_cache_dereference (&oc, "ack_lease");
option_cache_dereference (&oc, MDL);
}
}
......@@ -200,6 +204,7 @@ void bootp (packet)
outgoing.packet_length =
cons_options (packet, outgoing.raw, lease, 0,
packet -> options, options,
&lease -> scope,
0, 0, 1, (struct data_string *)0);
if (outgoing.packet_length < BOOTP_MIN_LEN)
outgoing.packet_length = BOOTP_MIN_LEN;
......@@ -222,7 +227,8 @@ void bootp (packet)
if ((oc = lookup_option (&server_universe,
options, SV_ALWAYS_BROADCAST)) &&
evaluate_boolean_option_cache (&ignorep, packet, lease,
packet -> options, options, oc))
packet -> options, options,
&lease -> scope, oc, MDL))
raw.flags |= htons (BOOTP_BROADCAST);
/* Figure out the address of the next server. */
......@@ -230,11 +236,12 @@ void bootp (packet)
oc = lookup_option (&server_universe, options, SV_NEXT_SERVER);
if (oc &&
evaluate_option_cache (&d1, packet, lease,
packet -> options, options, oc)) {
packet -> options, options,
&lease -> scope, oc, MDL)) {
/* If there was more than one answer, take the first. */
if (d1.len >= 4 && d1.data)
memcpy (&raw.siaddr, d1.data, 4);
data_string_forget (&d1, "bootrequest");
data_string_forget (&d1, MDL);
} else {
if (lease -> subnet -> shared_network -> interface)
raw.siaddr = (lease -> subnet -> shared_network ->
......@@ -249,13 +256,14 @@ void bootp (packet)
oc = lookup_option (&server_universe, options, SV_FILENAME);
if (oc &&
evaluate_option_cache (&d1, packet, lease,
packet -> options, options, oc)) {
packet -> options, options,
&lease -> scope, oc, MDL)) {
memcpy (raw.file, d1.data,
d1.len > sizeof raw.file ? sizeof raw.file : d1.len);
if (sizeof raw.file > d1.len)
memset (&raw.file [d1.len],
0, (sizeof raw.file) - d1.len);
data_string_forget (&d1, "bootrequest");
data_string_forget (&d1, MDL);
} else
memcpy (raw.file, packet -> raw -> file, sizeof raw.file);
......@@ -263,22 +271,23 @@ void bootp (packet)
oc = lookup_option (&server_universe, options, SV_SERVER_NAME);
if (oc &&
evaluate_option_cache (&d1, packet, lease,
packet -> options, options, oc)) {
packet -> options, options,
&lease -> scope, oc, MDL)) {
memcpy (raw.sname, d1.data,
d1.len > sizeof raw.sname ? sizeof raw.sname : d1.len);
if (sizeof raw.sname > d1.len)
memset (&raw.sname [d1.len],
0, (sizeof raw.sname) - d1.len);
data_string_forget (&d1, "bootrequest");
data_string_forget (&d1, MDL);
}
/* Execute the commit statements, if there are any. */
execute_statements (packet, lease, packet -> options,
options, lease -> on_commit);
options, &lease -> scope, lease -> on_commit);
/* We're done with the option state. */
option_state_dereference (&options, "bootrequest");
static_lease_dereference (lease, "bootrequest");
option_state_dereference (&options, MDL);
static_lease_dereference (lease, MDL);
/* Set up the hardware destination address... */
hto.hbuf [0] = packet -> raw -> htype;
......
......@@ -22,7 +22,7 @@
#ifndef lint
static char copyright[] =
"$Id: class.c,v 1.15 1999/10/21 03:09:13 mellon Exp $ Copyright (c) 1998 The Internet Software Consortium. All rights reserved.\n";
"$Id: class.c,v 1.16 2000/01/25 01:36:29 mellon Exp $ Copyright (c) 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
......@@ -46,14 +46,12 @@ void classification_setup ()
/* eval ... */
rules = (struct executable_statement *)0;
if (!executable_statement_allocate (&rules,
"default collection check rule"))
if (!executable_statement_allocate (&rules, MDL))
log_fatal ("Can't allocate check of default collection");
rules -> op = eval_statement;
/* check-collection "default" */
if (!expression_allocate (&rules -> data.eval,
"default check expression"))
if (!expression_allocate (&rules -> data.eval, MDL))
log_fatal ("Can't allocate default check expression");
rules -> data.eval -> op = expr_check;
rules -> data.eval -> data.check = &default_collection;
......@@ -65,7 +63,7 @@ void classify_client (packet)
struct packet *packet;
{
execute_statements (packet, (struct lease *)0, packet -> options,
(struct option_state *)0,
(struct option_state *)0, &global_scope,
default_classification_rules);
}
......@@ -91,7 +89,7 @@ int check_collection (packet, lease, collection)
status = (evaluate_data_expression
(&data, packet, lease,
packet -> options, (struct option_state *)0,
class -> submatch));
&lease -> scope, class -> submatch));
if (status) {
if ((nc = ((struct class *)
hash_lookup (class -> hash,
......@@ -102,21 +100,21 @@ int check_collection (packet, lease, collection)
print_hex_1 (data.len,
data.data, 60));
#endif
data_string_forget
(&data, "check_collection");
data_string_forget (&data, MDL);
classify (packet, nc);
matched = 1;
continue;
}
if (!class -> spawning)
if (!class -> spawning) {
data_string_forget (&data, MDL);
continue;
}
#if defined (DEBUG_CLASS_MATCHING)
log_info ("spawning subclass %s.",
print_hex_1 (data.len, data.data, 60));
#endif
nc = (struct class *)
dmalloc (sizeof (struct class),
"class spawn");
dmalloc (sizeof (struct class), MDL);
memset (nc, 0, sizeof *nc);
nc -> group = class -> group;
nc -> superclass = class;
......@@ -127,14 +125,16 @@ int check_collection (packet, lease, collection)
(dmalloc
(nc -> lease_limit *
sizeof (struct lease *),
"check_collection"));
MDL));
if (!nc -> billed_leases) {
log_error ("no memory for%s",
" billing");
data_string_forget
(&nc -> hash_string,
"check_collection");
dfree (nc, "check_collection");
MDL);
dfree (nc, MDL);
data_string_forget (&data,
MDL);
continue;
}
memset (nc -> billed_leases, 0,
......@@ -142,8 +142,8 @@ int check_collection (packet, lease, collection)
sizeof nc -> billed_leases));
}
data_string_copy (&nc -> hash_string, &data,
"check_collection");
data_string_forget (&data, "check_collection");
MDL);
data_string_forget (&data, MDL);
if (!class -> hash)
class -> hash = new_hash ();
add_hash (class -> hash,
......@@ -152,13 +152,12 @@ int check_collection (packet, lease, collection)
(unsigned char *)nc);
classify (packet, nc);
}
data_string_forget (&data, "check_collection");
}
status = (evaluate_boolean_expression_result
(&ignorep, packet, lease,
packet -> options, (struct option_state *)0,
class -> expr));
&lease -> scope, class -> expr));
if (status) {
matched = 1;
#if defined (DEBUG_CLASS_MATCHING)
......
......@@ -22,7 +22,7 @@
#ifndef lint
static char copyright[] =
"$Id: dhcp.c,v 1.132 2000/01/08 01:47:37 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
"$Id: dhcp.c,v 1.133 2000/01/25 01:35:38 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
......@@ -118,6 +118,10 @@ void dhcpdiscover (packet)
}
}
/* If it's an expired lease, get rid of any bindings. */
if (lease -> ends < cur_time && lease -> scope.bindings)
free_bindings (&lease -> scope, "dhcpdiscover");
/* Set the lease to really expire in 2 minutes, unless it has
not yet expired, in which case leave its expiry time alone. */
when = cur_time + 120;
......@@ -146,7 +150,7 @@ void dhcprequest (packet)
if (oc &&
evaluate_option_cache (&data, packet, (struct lease *)0,
packet -> options, (struct option_state *)0,
oc)) {
&global_scope, oc, MDL)) {
cip.len = 4;
memcpy (cip.iabuf, data.data, 4);
data_string_forget (&data, "dhcprequest");
......@@ -304,7 +308,7 @@ void dhcprelease (packet)
if (oc &&
evaluate_option_cache (&data, packet, (struct lease *)0,
packet -> options, (struct option_state *)0,
oc)) {
&global_scope, oc, MDL)) {
lease = find_lease_by_uid (data.data, data.len);
data_string_forget (&data, "dhcprelease");
......@@ -316,10 +320,12 @@ void dhcprelease (packet)
break;
}
}
} else {
/* The client is supposed to pass a valid client-identifier,
but the spec on this has changed historically, so try the
IP address in ciaddr if the client-identifier fails. */
}
/* The client is supposed to pass a valid client-identifier,
but the spec on this has changed historically, so try the
IP address in ciaddr if the client-identifier fails. */
if (!lease) {
cip.len = 4;
memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
lease = find_lease_by_ip_addr (cip);
......@@ -375,7 +381,7 @@ void dhcpdecline (packet)
if (!evaluate_option_cache (&data, packet, (struct lease *)0,
packet -> options,
(struct option_state *)0,
oc))
&global_scope, oc, MDL))
return;
cip.len = 4;
......@@ -388,24 +394,25 @@ void dhcpdecline (packet)
/* Execute statements in scope starting with the subnet scope. */
if (lease)
execute_statements_in_scope (packet, (struct lease *)0,
packet -> options,
options, lease -> subnet -> group,
packet -> options, options,
&global_scope,
lease -> subnet -> group,
(struct group *)0);
/* Execute statements in the class scopes. */
for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope
(packet, (struct lease *)0, packet -> options,
options, packet -> classes [i - 1] -> group,
(packet, (struct lease *)0, packet -> options, options,
&global_scope, packet -> classes [i - 1] -> group,
lease ? lease -> subnet -> group : (struct group *)0);
}
/* Drop the request if dhcpdeclines are being ignored. */
oc = lookup_option (&server_universe, options, SV_DECLINES);
if (!oc ||
evaluate_boolean_option_cache (&ignorep,
packet, lease, packet -> options,
options, oc)) {
evaluate_boolean_option_cache (&ignorep, packet, lease,
packet -> options, options,
&lease -> scope, oc, MDL)) {
/* If we found a lease, mark it as unusable and complain. */
if (lease) {
abandon_lease (lease, "declined.");
......@@ -510,15 +517,15 @@ void dhcpinform (packet)
/* Execute statements in scope starting with the subnet scope. */
if (subnet)
execute_statements_in_scope (packet, (struct lease *)0,
packet -> options,
options, subnet -> group,
packet -> options, options,
&global_scope, subnet -> group,
(struct group *)0);
/* Execute statements in the class scopes. */
for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope
(packet, (struct lease *)0, packet -> options,
options, packet -> classes [i - 1] -> group,
(packet, (struct lease *)0, packet -> options, options,
&global_scope, packet -> classes [i - 1] -> group,
subnet ? subnet -> group : (struct group *)0);
}
......@@ -528,7 +535,7 @@ void dhcpinform (packet)
if (oc &&
evaluate_option_cache (&d1, packet, (struct lease *)0,
packet -> options, (struct option_state *)0,
oc)) {
&global_scope, oc, MDL)) {
i = d1.len;
if (i > sizeof raw.file)
i = sizeof raw.file;
......@@ -543,7 +550,7 @@ void dhcpinform (packet)
if (oc &&
evaluate_option_cache (&d1, packet, (struct lease *)0,
packet -> options, (struct option_state *)0,
oc)) {
&global_scope, oc, MDL)) {
i = d1.len;
if (i > sizeof raw.sname)
i = sizeof raw.sname;
......@@ -560,7 +567,7 @@ void dhcpinform (packet)
DHO_HOST_NAME))) {
if (evaluate_option_cache (&d1, packet, (struct lease *)0,
packet -> options, options,
oc)) {
&global_scope, oc, MDL)) {
if (d1.data [d1.len - 1] == '\0')
nulltp = 1;
data_string_forget (&d1, "dhcpinform");
......@@ -599,7 +606,8 @@ void dhcpinform (packet)
from = packet -> interface -> primary_address;
} else {
if (evaluate_option_cache (&d1, packet, (struct lease *)0,
packet -> options, options, oc)) {
packet -> options, options,
&global_scope, oc, MDL)) {
if (!d1.len || d1.len != sizeof from) {
data_string_forget (&d1, "dhcpinform");
goto use_primary;
......@@ -651,7 +659,8 @@ void dhcpinform (packet)
if (!lookup_option (&dhcp_universe, options, i) &&
(oc = lookup_option (&server_universe, options, j)) &&
evaluate_option_cache (&d1, packet, (struct lease *)0,
packet -> options, options, oc)) {
packet -> options, options,
&global_scope, oc, MDL)) {
oc = (struct option_cache *)0;
if (option_cache_allocate (&oc, "dhcpinform")) {
if (make_encapsulation (&oc -> expression, &d1)) {
......@@ -668,7 +677,8 @@ void dhcpinform (packet)
i = SV_SITE_OPTION_SPACE;
if ((oc = lookup_option (&server_universe, options, i)) &&
evaluate_option_cache (&d1, packet, (struct lease *)0,
packet -> options, options, oc)) {
packet -> options, options,
&global_scope, oc, MDL)) {
const struct universe *u;
u = ((const struct universe *)
......@@ -703,7 +713,8 @@ void dhcpinform (packet)
if (oc)
evaluate_option_cache (&prl, packet, (struct lease *)0,
packet -> options, options, oc);
packet -> options, options,
&global_scope, oc, MDL);
#ifdef DEBUG_PACKET
dump_packet (packet);
......@@ -717,7 +728,8 @@ void dhcpinform (packet)
if ((oc =
lookup_option (&server_universe, options, SV_NEXT_SERVER))) {
if (evaluate_option_cache (&d1, packet, (struct lease *)0,
packet -> options, options, oc)) {
packet -> options, options,
&global_scope, oc, MDL)) {
/* If there was more than one answer,
take the first. */
if (d1.len >= 4 && d1.data)
......@@ -729,7 +741,8 @@ void dhcpinform (packet)
/* Set up the option buffer... */
outgoing.packet_length =
cons_options (packet, outgoing.raw, (struct lease *)0,
0, packet -> options, options, 0, nulltp, 0,
0, packet -> options, options, &global_scope,
0, nulltp, 0,
prl.len ? &prl : (struct data_string *)0);
option_state_dereference (&options, "dhcpinform");
data_string_forget (&prl, "dhcpinform");
......@@ -839,8 +852,8 @@ void nak_lease (packet, cip)
/* Set up the option buffer... */
outgoing.packet_length =
cons_options (packet, outgoing.raw, (struct lease *)0,
0, packet -> options, options, 0, 0, 0,
(struct data_string *)0);
0, packet -> options, options, &global_scope,
0, 0, 0, (struct data_string *)0);
option_state_dereference (&options, "nak_lease");
/* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
......@@ -966,8 +979,9 @@ void ack_lease (packet, lease, offer, when, msg)
if (oc)
s1 = evaluate_option_cache (&d1, packet, (struct lease *)0,
packet -> options,
(struct option_state *)0, oc);
if (oc && status &&
(struct option_state *)0,
&global_scope, oc, MDL);
if (oc && s1 &&
lease -> client_hostname &&
strlen (lease -> client_hostname) == d1.len &&
!memcmp (lease -> client_hostname, d1.data, d1.len)) {
......@@ -1021,7 +1035,7 @@ void ack_lease (packet, lease, offer, when, msg)
/* Execute statements in scope starting with the subnet scope. */
execute_statements_in_scope (packet, lease,
packet -> options,
state -> options,
state -> options, &lease -> scope,
lease -> subnet -> group,
(struct group *)0);
......@@ -1029,7 +1043,7 @@ void ack_lease (packet, lease, offer, when, msg)
if (lease -> pool)
execute_statements_in_scope (packet, lease,
packet -> options,
state -> options,
state -> options, &lease -> scope,
lease -> pool -> group,
lease -> subnet -> group);
......@@ -1037,7 +1051,7 @@ void ack_lease (packet, lease, offer, when, msg)
for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope
(packet, lease, packet -> options, state -> options,
packet -> classes [i - 1] -> group,
&lease -> scope, packet -> classes [i - 1] -> group,
(lease -> pool
? lease -> pool -> group
: lease -> subnet -> group));
......@@ -1047,7 +1061,7 @@ void ack_lease (packet, lease, offer, when, msg)
with its group. */
if (lease -> host)
execute_statements_in_scope (packet, lease, packet -> options,
state -> options,
state -> options, &lease -> scope,
lease -> host -> group,
(lease -> pool
? lease -> pool -> group
......@@ -1067,7 +1081,8 @@ void ack_lease (packet, lease, offer, when, msg)
SV_ONE_LEASE_PER_CLIENT)) &&
evaluate_boolean_option_cache (&ignorep,
packet, lease, packet -> options,
state -> options, oc)) {
state -> options, &lease -> scope,
oc, MDL)) {
struct lease *seek;
if (lease -> uid_len) {
do {
......@@ -1093,7 +1108,9 @@ void ack_lease (packet, lease, offer, when, msg)
SV_DUPLICATES)) &&
!evaluate_boolean_option_cache (&ignorep, packet, lease,
packet -> options,
state -> options, oc))) {
state -> options,
&lease -> scope,
oc, MDL))) {
do {
seek = (find_lease_by_hw_addr
(lease -> hardware_addr.hbuf,
......@@ -1119,11 +1136,11 @@ void ack_lease (packet, lease, offer, when, msg)
SV_MIN_SECS))) {
if (evaluate_option_cache (&d1, packet, lease,
packet -> options, state -> options,
oc)) {
&lease -> scope, oc, MDL)) {
if (d1.len && packet -> raw -> secs < d1.data [0]) {
data_string_forget (&d1, "ack_lease");
log_info ("%s: %d secs < %d", msg,
packet -> raw -> secs, d1.data [0]);
data_string_forget (&d1, "ack_lease");
free_lease_state (state, "ack_lease");
static_lease_dereference (lease, "ack_lease");
return;
......@@ -1146,7 +1163,7 @@ void ack_lease (packet, lease, offer, when, msg)
if (oc &&
evaluate_option_cache (&d1, packet, lease,
packet -> options, state -> options,
oc)) {
&lease -> scope, oc, MDL)) {
hp = find_hosts_by_uid (d1.data, d1.len);
data_string_forget (&d1, "dhcpdiscover");
if (!hp)
......@@ -1170,7 +1187,8 @@ void ack_lease (packet, lease, offer, when, msg)
SV_BOOT_UNKNOWN_CLIENTS)) &&
!evaluate_boolean_option_cache (&ignorep,
packet, lease, packet -> options,
state -> options, oc)) {
state -> options,
&lease -> scope, oc, MDL)) {
if (!ignorep)
log_info ("%s: unknown client", msg);
free_lease_state (state, "ack_lease");
......@@ -1184,7 +1202,8 @@ void ack_lease (packet, lease, offer, when, msg)
SV_ALLOW_BOOTP)) &&
!evaluate_boolean_option_cache (&ignorep,
packet, lease, packet -> options,
state -> options, oc)) {
state -> options,
&lease -> scope, oc, MDL)) {
if (!ignorep)
log_info ("%s: bootp disallowed", msg);
free_lease_state (state, "ack_lease");
......@@ -1198,7 +1217,8 @@ void ack_lease (packet, lease, offer, when, msg)
if (oc &&
!evaluate_boolean_option_cache (&ignorep,
packet, lease, packet -> options,
state -> options, oc)) {
state -> options,
&lease -> scope, oc, MDL)) {
if (!ignorep)
log_info ("%s: booting disallowed", msg);
free_lease_state (state, "ack_lease");
......@@ -1253,7 +1273,7 @@ void ack_lease (packet, lease, offer, when, msg)
if (oc)
evaluate_option_cache (&state -> filename, packet, lease,
packet -> options, state -> options,
oc);
&lease -> scope, oc, MDL);
/* Choose a server name as above. */
oc = lookup_option (&server_universe, state -> options,
......@@ -1261,7 +1281,7 @@ void ack_lease (packet, lease, offer, when, msg)
if (oc)
evaluate_option_cache (&state -> server_name, packet, lease,
packet -> options, state -> options,
oc);
&lease -> scope, oc, MDL);
/* At th