mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-29 21:38:10 +00:00
Support variable scoping, malloc debug.
This commit is contained in:
parent
d4feef6509
commit
dbf6124ad2
229
common/options.c
229
common/options.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
static char copyright[] =
|
||||||
"$Id: options.c,v 1.50 2000/01/08 01:35:06 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
"$Id: options.c,v 1.51 2000/01/25 01:09:06 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#define DHCP_OPTION_DATA
|
#define DHCP_OPTION_DATA
|
||||||
@ -41,7 +41,7 @@ int parse_options (packet)
|
|||||||
struct option_cache *op = (struct option_cache *)0;
|
struct option_cache *op = (struct option_cache *)0;
|
||||||
|
|
||||||
/* Allocate a new option state. */
|
/* Allocate a new option state. */
|
||||||
if (!option_state_allocate (&packet -> options, "parse_options")) {
|
if (!option_state_allocate (&packet -> options, MDL)) {
|
||||||
packet -> options_valid = 0;
|
packet -> options_valid = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ int parse_option_buffer (packet, buffer, length)
|
|||||||
struct option_cache *op = (struct option_cache *)0;
|
struct option_cache *op = (struct option_cache *)0;
|
||||||
struct buffer *bp = (struct buffer *)0;
|
struct buffer *bp = (struct buffer *)0;
|
||||||
|
|
||||||
if (!buffer_allocate (&bp, length, "parse_option_buffer")) {
|
if (!buffer_allocate (&bp, length, MDL)) {
|
||||||
log_error ("no memory for option buffer.");
|
log_error ("no memory for option buffer.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ int parse_option_buffer (packet, buffer, length)
|
|||||||
if (offset + len + 2 > length) {
|
if (offset + len + 2 > length) {
|
||||||
log_error ("Client option %s (%d) larger than buffer.",
|
log_error ("Client option %s (%d) larger than buffer.",
|
||||||
dhcp_options [code].name, len);
|
dhcp_options [code].name, len);
|
||||||
buffer_dereference (&bp, "parse_option_buffer");
|
buffer_dereference (&bp, MDL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,24 +129,20 @@ int parse_option_buffer (packet, buffer, length)
|
|||||||
if (!parse_agent_information_option
|
if (!parse_agent_information_option
|
||||||
(packet, len, buffer + offset + 2)) {
|
(packet, len, buffer + offset + 2)) {
|
||||||
log_error ("bad agent information option.");
|
log_error ("bad agent information option.");
|
||||||
buffer_dereference (&bp,
|
buffer_dereference (&bp, MDL);
|
||||||
"parse_option_buffer");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!option_cache_allocate (&op,
|
if (!option_cache_allocate (&op, MDL)) {
|
||||||
"parse_option_buffer")) {
|
|
||||||
log_error ("No memory for option %s.",
|
log_error ("No memory for option %s.",
|
||||||
dhcp_options [code].name);
|
dhcp_options [code].name);
|
||||||
buffer_dereference (&bp,
|
buffer_dereference (&bp, MDL);
|
||||||
"parse_option_buffer");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reference buffer copy to option cache. */
|
/* Reference buffer copy to option cache. */
|
||||||
op -> data.buffer = (struct buffer *)0;
|
op -> data.buffer = (struct buffer *)0;
|
||||||
buffer_reference (&op -> data.buffer, bp,
|
buffer_reference (&op -> data.buffer, bp, MDL);
|
||||||
"parse_option_buffer");
|
|
||||||
|
|
||||||
/* Point option cache into buffer. */
|
/* Point option cache into buffer. */
|
||||||
op -> data.data = &bp -> data [offset + 2];
|
op -> data.data = &bp -> data [offset + 2];
|
||||||
@ -166,13 +162,12 @@ int parse_option_buffer (packet, buffer, length)
|
|||||||
save_option (&dhcp_universe, packet -> options, op);
|
save_option (&dhcp_universe, packet -> options, op);
|
||||||
|
|
||||||
/* And let go of our reference. */
|
/* And let go of our reference. */
|
||||||
option_cache_dereference (&op,
|
option_cache_dereference (&op, MDL);
|
||||||
"parse_option_buffer");
|
|
||||||
}
|
}
|
||||||
offset += len + 2;
|
offset += len + 2;
|
||||||
}
|
}
|
||||||
packet -> options_valid = 1;
|
packet -> options_valid = 1;
|
||||||
buffer_dereference (&bp, "parse_option_buffer");
|
buffer_dereference (&bp, MDL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,13 +176,14 @@ int parse_option_buffer (packet, buffer, length)
|
|||||||
of vendor options using the same routine. */
|
of vendor options using the same routine. */
|
||||||
|
|
||||||
int cons_options (inpacket, outpacket, lease, mms, in_options, cfg_options,
|
int cons_options (inpacket, outpacket, lease, mms, in_options, cfg_options,
|
||||||
overload, terminate, bootpp, prl)
|
scope, overload, terminate, bootpp, prl)
|
||||||
struct packet *inpacket;
|
struct packet *inpacket;
|
||||||
struct dhcp_packet *outpacket;
|
struct dhcp_packet *outpacket;
|
||||||
struct lease *lease;
|
struct lease *lease;
|
||||||
int mms;
|
int mms;
|
||||||
struct option_state *in_options;
|
struct option_state *in_options;
|
||||||
struct option_state *cfg_options;
|
struct option_state *cfg_options;
|
||||||
|
struct binding_scope *scope;
|
||||||
int overload; /* Overload flags that may be set. */
|
int overload; /* Overload flags that may be set. */
|
||||||
int terminate;
|
int terminate;
|
||||||
int bootpp;
|
int bootpp;
|
||||||
@ -215,11 +211,11 @@ int cons_options (inpacket, outpacket, lease, mms, in_options, cfg_options,
|
|||||||
if (!mms && inpacket &&
|
if (!mms && inpacket &&
|
||||||
(op = lookup_option (&dhcp_universe, inpacket -> options,
|
(op = lookup_option (&dhcp_universe, inpacket -> options,
|
||||||
DHO_DHCP_MAX_MESSAGE_SIZE))) {
|
DHO_DHCP_MAX_MESSAGE_SIZE))) {
|
||||||
evaluate_option_cache (&ds, inpacket, lease,
|
evaluate_option_cache (&ds, inpacket, lease, in_options,
|
||||||
in_options, cfg_options, op);
|
cfg_options, scope, op, MDL);
|
||||||
if (ds.len >= sizeof (u_int16_t))
|
if (ds.len >= sizeof (u_int16_t))
|
||||||
mms = getUShort (ds.data);
|
mms = getUShort (ds.data);
|
||||||
data_string_forget (&ds, "cons_options");
|
data_string_forget (&ds, MDL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the client has provided a maximum DHCP message size,
|
/* If the client has provided a maximum DHCP message size,
|
||||||
@ -315,7 +311,7 @@ int cons_options (inpacket, outpacket, lease, mms, in_options, cfg_options,
|
|||||||
((overload & 2) ? DHCP_SNAME_LEN : 0)),
|
((overload & 2) ? DHCP_SNAME_LEN : 0)),
|
||||||
inpacket,
|
inpacket,
|
||||||
lease,
|
lease,
|
||||||
in_options, cfg_options,
|
in_options, cfg_options, scope,
|
||||||
priority_list, priority_len,
|
priority_list, priority_len,
|
||||||
main_buffer_size,
|
main_buffer_size,
|
||||||
(main_buffer_size +
|
(main_buffer_size +
|
||||||
@ -394,7 +390,7 @@ int cons_options (inpacket, outpacket, lease, mms, in_options, cfg_options,
|
|||||||
/* Store all the requested options into the requested buffer. */
|
/* Store all the requested options into the requested buffer. */
|
||||||
|
|
||||||
int store_options (buffer, buflen, packet, lease,
|
int store_options (buffer, buflen, packet, lease,
|
||||||
in_options, cfg_options, priority_list,
|
in_options, cfg_options, scope, priority_list,
|
||||||
priority_len, first_cutoff, second_cutoff, terminate)
|
priority_len, first_cutoff, second_cutoff, terminate)
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
unsigned buflen;
|
unsigned buflen;
|
||||||
@ -402,6 +398,7 @@ int store_options (buffer, buflen, packet, lease,
|
|||||||
struct lease *lease;
|
struct lease *lease;
|
||||||
struct option_state *in_options;
|
struct option_state *in_options;
|
||||||
struct option_state *cfg_options;
|
struct option_state *cfg_options;
|
||||||
|
struct binding_scope *scope;
|
||||||
unsigned *priority_list;
|
unsigned *priority_list;
|
||||||
int priority_len;
|
int priority_len;
|
||||||
unsigned first_cutoff, second_cutoff;
|
unsigned first_cutoff, second_cutoff;
|
||||||
@ -459,8 +456,8 @@ int store_options (buffer, buflen, packet, lease,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Find the value of the option... */
|
/* Find the value of the option... */
|
||||||
evaluate_option_cache (&od, packet, lease,
|
evaluate_option_cache (&od, packet, lease, in_options,
|
||||||
in_options, cfg_options, oc);
|
cfg_options, scope, oc, MDL);
|
||||||
if (!od.len) {
|
if (!od.len) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -521,7 +518,7 @@ int store_options (buffer, buflen, packet, lease,
|
|||||||
ix += incr;
|
ix += incr;
|
||||||
bufix += 2 + incr;
|
bufix += 2 + incr;
|
||||||
}
|
}
|
||||||
data_string_forget (&od, "store_options");
|
data_string_forget (&od, MDL);
|
||||||
}
|
}
|
||||||
return bufix;
|
return bufix;
|
||||||
}
|
}
|
||||||
@ -577,7 +574,10 @@ const char *pretty_print_option (code, data, len, emit_commas, emit_quotes)
|
|||||||
!isprint (data [k]))
|
!isprint (data [k]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (k == len) {
|
/* If we found no bogus characters, or the bogus
|
||||||
|
character we found is a trailing NUL, it's
|
||||||
|
okay to print this option as text. */
|
||||||
|
if (k == len || (k + 1 == len && data [k] == 0)) {
|
||||||
fmtbuf [i] = 't';
|
fmtbuf [i] = 't';
|
||||||
numhunk = -2;
|
numhunk = -2;
|
||||||
} else {
|
} else {
|
||||||
@ -707,7 +707,7 @@ const char *pretty_print_option (code, data, len, emit_commas, emit_quotes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int hashed_option_get (result, universe, packet, lease,
|
int hashed_option_get (result, universe, packet, lease,
|
||||||
in_options, cfg_options, options, code)
|
in_options, cfg_options, options, scope, code)
|
||||||
struct data_string *result;
|
struct data_string *result;
|
||||||
struct universe *universe;
|
struct universe *universe;
|
||||||
struct packet *packet;
|
struct packet *packet;
|
||||||
@ -715,6 +715,7 @@ int hashed_option_get (result, universe, packet, lease,
|
|||||||
struct option_state *in_options;
|
struct option_state *in_options;
|
||||||
struct option_state *cfg_options;
|
struct option_state *cfg_options;
|
||||||
struct option_state *options;
|
struct option_state *options;
|
||||||
|
struct binding_scope *scope;
|
||||||
unsigned code;
|
unsigned code;
|
||||||
{
|
{
|
||||||
struct option_cache *oc;
|
struct option_cache *oc;
|
||||||
@ -724,14 +725,14 @@ int hashed_option_get (result, universe, packet, lease,
|
|||||||
oc = ((*universe -> lookup_func) (universe, options, code));
|
oc = ((*universe -> lookup_func) (universe, options, code));
|
||||||
if (!oc)
|
if (!oc)
|
||||||
return 0;
|
return 0;
|
||||||
if (!evaluate_option_cache (result, packet, lease,
|
if (!evaluate_option_cache (result, packet, lease, in_options,
|
||||||
in_options, cfg_options, oc))
|
cfg_options, scope, oc, MDL))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int agent_option_get (result, universe, packet, lease,
|
int agent_option_get (result, universe, packet, lease,
|
||||||
in_options, cfg_options, options, code)
|
in_options, cfg_options, options, scope, code)
|
||||||
struct data_string *result;
|
struct data_string *result;
|
||||||
struct universe *universe;
|
struct universe *universe;
|
||||||
struct packet *packet;
|
struct packet *packet;
|
||||||
@ -739,6 +740,7 @@ int agent_option_get (result, universe, packet, lease,
|
|||||||
struct option_state *in_options;
|
struct option_state *in_options;
|
||||||
struct option_state *cfg_options;
|
struct option_state *cfg_options;
|
||||||
struct option_state *options;
|
struct option_state *options;
|
||||||
|
struct binding_scope *scope;
|
||||||
unsigned code;
|
unsigned code;
|
||||||
{
|
{
|
||||||
struct agent_options *ao;
|
struct agent_options *ao;
|
||||||
@ -757,13 +759,12 @@ int agent_option_get (result, universe, packet, lease,
|
|||||||
for (t = ao -> first; t; t = t -> next) {
|
for (t = ao -> first; t; t = t -> next) {
|
||||||
if (t -> data [0] == code) {
|
if (t -> data [0] == code) {
|
||||||
result -> len = t -> data [1];
|
result -> len = t -> data [1];
|
||||||
if (!(buffer_allocate
|
if (!(buffer_allocate (&result -> buffer,
|
||||||
(&result -> buffer, result -> len + 1,
|
result -> len + 1,
|
||||||
"agent_suboption_get"))) {
|
MDL))) {
|
||||||
result -> len = 0;
|
result -> len = 0;
|
||||||
buffer_dereference
|
buffer_dereference
|
||||||
(&result -> buffer,
|
(&result -> buffer, MDL);
|
||||||
"agent_suboption_get");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
result -> data = &result -> buffer -> data [0];
|
result -> data = &result -> buffer -> data [0];
|
||||||
@ -818,40 +819,37 @@ void hashed_option_set (universe, options, option, op)
|
|||||||
}
|
}
|
||||||
/* If it's not an expression, make it into one. */
|
/* If it's not an expression, make it into one. */
|
||||||
if (!oc -> expression && oc -> data.len) {
|
if (!oc -> expression && oc -> data.len) {
|
||||||
if (!expression_allocate (&oc -> expression,
|
if (!expression_allocate (&oc -> expression, MDL)) {
|
||||||
"do_option_set")) {
|
|
||||||
log_error ("Can't allocate const expression.");
|
log_error ("Can't allocate const expression.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oc -> expression -> op = expr_const_data;
|
oc -> expression -> op = expr_const_data;
|
||||||
data_string_copy
|
data_string_copy
|
||||||
(&oc -> expression -> data.const_data,
|
(&oc -> expression -> data.const_data,
|
||||||
&oc -> data, "do_option_set");
|
&oc -> data, MDL);
|
||||||
data_string_forget (&oc -> data, "do_option_set");
|
data_string_forget (&oc -> data, MDL);
|
||||||
}
|
}
|
||||||
noc = (struct option_cache *)0;
|
noc = (struct option_cache *)0;
|
||||||
if (!option_cache_allocate (&noc, "do_option_set"))
|
if (!option_cache_allocate (&noc, MDL))
|
||||||
break;
|
break;
|
||||||
if (op == append_option_statement) {
|
if (op == append_option_statement) {
|
||||||
if (!make_concat (&noc -> expression,
|
if (!make_concat (&noc -> expression,
|
||||||
oc -> expression,
|
oc -> expression,
|
||||||
option -> expression)) {
|
option -> expression)) {
|
||||||
option_cache_dereference (&noc,
|
option_cache_dereference (&noc, MDL);
|
||||||
"do_option_set");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!make_concat (&noc -> expression,
|
if (!make_concat (&noc -> expression,
|
||||||
option -> expression,
|
option -> expression,
|
||||||
oc -> expression)) {
|
oc -> expression)) {
|
||||||
option_cache_dereference (&noc,
|
option_cache_dereference (&noc, MDL);
|
||||||
"do_option_set");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
noc -> option = oc -> option;
|
noc -> option = oc -> option;
|
||||||
save_option (universe, options, noc);
|
save_option (universe, options, noc);
|
||||||
option_cache_dereference (&noc, "do_option_set");
|
option_cache_dereference (&noc, MDL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -921,8 +919,7 @@ void save_hashed_option (universe, options, oc)
|
|||||||
|
|
||||||
/* If there's no hash table, make one. */
|
/* If there's no hash table, make one. */
|
||||||
if (!hash) {
|
if (!hash) {
|
||||||
hash = (pair *)dmalloc (OPTION_HASH_SIZE * sizeof *hash,
|
hash = (pair *)dmalloc (OPTION_HASH_SIZE * sizeof *hash, MDL);
|
||||||
"save_hashed_options");
|
|
||||||
if (!hash) {
|
if (!hash) {
|
||||||
log_error ("no memory to store %s.%s",
|
log_error ("no memory to store %s.%s",
|
||||||
universe -> name, oc -> option -> name);
|
universe -> name, oc -> option -> name);
|
||||||
@ -943,25 +940,23 @@ void save_hashed_option (universe, options, oc)
|
|||||||
in its place. */
|
in its place. */
|
||||||
if (bptr) {
|
if (bptr) {
|
||||||
option_cache_dereference
|
option_cache_dereference
|
||||||
((struct option_cache **)&bptr -> car,
|
((struct option_cache **)&bptr -> car, MDL);
|
||||||
"save_option");
|
|
||||||
option_cache_reference
|
option_cache_reference
|
||||||
((struct option_cache **)&bptr -> car,
|
((struct option_cache **)&bptr -> car,
|
||||||
oc, "save_option");
|
oc, MDL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, just put the new one at the head of the list. */
|
/* Otherwise, just put the new one at the head of the list. */
|
||||||
bptr = new_pair ("save_option");
|
bptr = new_pair (MDL);
|
||||||
if (!bptr) {
|
if (!bptr) {
|
||||||
log_error ("No memory for option_cache reference.");
|
log_error ("No memory for option_cache reference.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bptr -> cdr = hash [hashix];
|
bptr -> cdr = hash [hashix];
|
||||||
bptr -> car = 0;
|
bptr -> car = 0;
|
||||||
option_cache_reference ((struct option_cache **)&bptr -> car,
|
option_cache_reference ((struct option_cache **)&bptr -> car, oc, MDL);
|
||||||
oc, "save_option");
|
|
||||||
hash [hashix] = bptr;
|
hash [hashix] = bptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1006,21 +1001,21 @@ void delete_hashed_option (universe, options, code)
|
|||||||
else
|
else
|
||||||
hash [hashix] = bptr -> cdr;
|
hash [hashix] = bptr -> cdr;
|
||||||
option_cache_dereference
|
option_cache_dereference
|
||||||
((struct option_cache **)(&bptr -> car),
|
((struct option_cache **)(&bptr -> car), MDL);
|
||||||
"delete_option");
|
free_pair (bptr, MDL);
|
||||||
free_pair (bptr, "delete_option");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern struct option_cache *free_option_caches; /* XXX */
|
extern struct option_cache *free_option_caches; /* XXX */
|
||||||
|
|
||||||
int option_cache_dereference (ptr, name)
|
int option_cache_dereference (ptr, file, line)
|
||||||
struct option_cache **ptr;
|
struct option_cache **ptr;
|
||||||
const char *name;
|
const char *file;
|
||||||
|
int line;
|
||||||
{
|
{
|
||||||
if (!ptr || !*ptr) {
|
if (!ptr || !*ptr) {
|
||||||
log_error ("Null pointer in option_cache_dereference: %s",
|
log_error ("Null pointer in option_cache_dereference: %s(%d)",
|
||||||
name);
|
file, line);
|
||||||
#if defined (POINTER_DEBUG)
|
#if defined (POINTER_DEBUG)
|
||||||
abort ();
|
abort ();
|
||||||
#else
|
#else
|
||||||
@ -1029,6 +1024,7 @@ int option_cache_dereference (ptr, name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
(*ptr) -> refcnt--;
|
(*ptr) -> refcnt--;
|
||||||
|
rc_register (file, line, *ptr, (*ptr) -> refcnt);
|
||||||
if (!(*ptr) -> refcnt) {
|
if (!(*ptr) -> refcnt) {
|
||||||
if ((*ptr) -> data.buffer)
|
if ((*ptr) -> data.buffer)
|
||||||
data_string_forget (&(*ptr) -> data, name);
|
data_string_forget (&(*ptr) -> data, name);
|
||||||
@ -1037,6 +1033,18 @@ int option_cache_dereference (ptr, name)
|
|||||||
/* Put it back on the free list... */
|
/* Put it back on the free list... */
|
||||||
(*ptr) -> expression = (struct expression *)free_option_caches;
|
(*ptr) -> expression = (struct expression *)free_option_caches;
|
||||||
free_option_caches = *ptr;
|
free_option_caches = *ptr;
|
||||||
|
dmalloc_reuse (free_option_caches, (char *)0, 0, 0);
|
||||||
|
}
|
||||||
|
if ((*ptr) -> refcnt < 0) {
|
||||||
|
log_error ("%s(%d): negative refcnt!", file, line);
|
||||||
|
#if defined (DEBUG_RC_HISTORY)
|
||||||
|
dump_rc_history ();
|
||||||
|
#endif
|
||||||
|
#if defined (POINTER_DEBUG)
|
||||||
|
abort ();
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
*ptr = (struct option_cache *)0;
|
*ptr = (struct option_cache *)0;
|
||||||
return 1;
|
return 1;
|
||||||
@ -1062,13 +1070,12 @@ int hashed_option_state_dereference (universe, state)
|
|||||||
for (cp = heads [i]; cp; cp = next) {
|
for (cp = heads [i]; cp; cp = next) {
|
||||||
next = cp -> cdr;
|
next = cp -> cdr;
|
||||||
option_cache_dereference
|
option_cache_dereference
|
||||||
((struct option_cache **)&cp -> car,
|
((struct option_cache **)&cp -> car, MDL);
|
||||||
"option_state_dereference");
|
free_pair (cp, MDL);
|
||||||
free_pair (cp, "hashed_option_state_dereference");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dfree (heads, "hashed_option_state_dereference");
|
dfree (heads, MDL);
|
||||||
state -> universes [universe -> index] = (void *)0;
|
state -> universes [universe -> index] = (void *)0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1090,23 +1097,24 @@ int agent_option_state_dereference (universe, state)
|
|||||||
na = a -> next;
|
na = a -> next;
|
||||||
for (ot = a -> first; ot; ot = not) {
|
for (ot = a -> first; ot; ot = not) {
|
||||||
not = ot -> next;
|
not = ot -> next;
|
||||||
free (ot);
|
dfree (ot, MDL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dfree (state -> universes [universe -> index],
|
dfree (state -> universes [universe -> index], MDL);
|
||||||
"agent_option_state_dereference");
|
|
||||||
state -> universes [universe -> index] = (void *)0;
|
state -> universes [universe -> index] = (void *)0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int store_option (result, universe, packet, lease, in_options, cfg_options, oc)
|
int store_option (result, universe, packet, lease,
|
||||||
|
in_options, cfg_options, scope, oc)
|
||||||
struct data_string *result;
|
struct data_string *result;
|
||||||
struct universe *universe;
|
struct universe *universe;
|
||||||
struct packet *packet;
|
struct packet *packet;
|
||||||
struct lease *lease;
|
struct lease *lease;
|
||||||
struct option_state *in_options;
|
struct option_state *in_options;
|
||||||
struct option_state *cfg_options;
|
struct option_state *cfg_options;
|
||||||
|
struct binding_scope *scope;
|
||||||
struct option_cache *oc;
|
struct option_cache *oc;
|
||||||
{
|
{
|
||||||
struct data_string d1, d2;
|
struct data_string d1, d2;
|
||||||
@ -1114,15 +1122,14 @@ int store_option (result, universe, packet, lease, in_options, cfg_options, oc)
|
|||||||
memset (&d1, 0, sizeof d1);
|
memset (&d1, 0, sizeof d1);
|
||||||
memset (&d2, 0, sizeof d2);
|
memset (&d2, 0, sizeof d2);
|
||||||
|
|
||||||
if (evaluate_option_cache (&d2, packet, lease,
|
if (evaluate_option_cache (&d2, packet, lease, in_options,
|
||||||
in_options, cfg_options, oc)) {
|
cfg_options, scope, oc, MDL)) {
|
||||||
if (!buffer_allocate (&d1.buffer,
|
if (!buffer_allocate (&d1.buffer,
|
||||||
(result -> len +
|
(result -> len +
|
||||||
universe -> length_size +
|
universe -> length_size +
|
||||||
universe -> tag_size +
|
universe -> tag_size + d2.len), MDL)) {
|
||||||
d2.len), "store_option")) {
|
data_string_forget (result, MDL);
|
||||||
data_string_forget (result, "store_option");
|
data_string_forget (&d2, MDL);
|
||||||
data_string_forget (&d2, "store_option");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
d1.data = &d1.buffer -> data [0];
|
d1.data = &d1.buffer -> data [0];
|
||||||
@ -1138,22 +1145,23 @@ int store_option (result, universe, packet, lease, in_options, cfg_options, oc)
|
|||||||
d1.len += universe -> length_size;
|
d1.len += universe -> length_size;
|
||||||
memcpy (&d1.buffer -> data [d1.len], d2.data, d2.len);
|
memcpy (&d1.buffer -> data [d1.len], d2.data, d2.len);
|
||||||
d1.len += d2.len;
|
d1.len += d2.len;
|
||||||
data_string_forget (&d2, "store_option");
|
data_string_forget (&d2, MDL);
|
||||||
data_string_forget (result, "store_option");
|
data_string_forget (result, MDL);
|
||||||
data_string_copy (result, &d1, "store_option");
|
data_string_copy (result, &d1, MDL);
|
||||||
data_string_forget (&d1, "store_option");
|
data_string_forget (&d1, MDL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int option_space_encapsulate (result, packet, lease,
|
int option_space_encapsulate (result, packet, lease,
|
||||||
in_options, cfg_options, name)
|
in_options, cfg_options, scope, name)
|
||||||
struct data_string *result;
|
struct data_string *result;
|
||||||
struct packet *packet;
|
struct packet *packet;
|
||||||
struct lease *lease;
|
struct lease *lease;
|
||||||
struct option_state *in_options;
|
struct option_state *in_options;
|
||||||
struct option_state *cfg_options;
|
struct option_state *cfg_options;
|
||||||
|
struct binding_scope *scope;
|
||||||
struct data_string *name;
|
struct data_string *name;
|
||||||
{
|
{
|
||||||
struct universe *u;
|
struct universe *u;
|
||||||
@ -1167,19 +1175,20 @@ int option_space_encapsulate (result, packet, lease,
|
|||||||
|
|
||||||
if (u -> encapsulate)
|
if (u -> encapsulate)
|
||||||
return (*u -> encapsulate) (result, packet, lease,
|
return (*u -> encapsulate) (result, packet, lease,
|
||||||
in_options, cfg_options, u);
|
in_options, cfg_options, scope, u);
|
||||||
log_error ("encapsulation requested for %s with no support.",
|
log_error ("encapsulation requested for %s with no support.",
|
||||||
name -> data);
|
name -> data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hashed_option_space_encapsulate (result, packet, lease,
|
int hashed_option_space_encapsulate (result, packet, lease,
|
||||||
in_options, cfg_options, universe)
|
in_options, cfg_options, scope, universe)
|
||||||
struct data_string *result;
|
struct data_string *result;
|
||||||
struct packet *packet;
|
struct packet *packet;
|
||||||
struct lease *lease;
|
struct lease *lease;
|
||||||
struct option_state *in_options;
|
struct option_state *in_options;
|
||||||
struct option_state *cfg_options;
|
struct option_state *cfg_options;
|
||||||
|
struct binding_scope *scope;
|
||||||
struct universe *universe;
|
struct universe *universe;
|
||||||
{
|
{
|
||||||
pair p, *hash;
|
pair p, *hash;
|
||||||
@ -1197,7 +1206,7 @@ int hashed_option_space_encapsulate (result, packet, lease,
|
|||||||
for (i = 0; i < OPTION_HASH_SIZE; i++) {
|
for (i = 0; i < OPTION_HASH_SIZE; i++) {
|
||||||
for (p = hash [i]; p; p = p -> cdr) {
|
for (p = hash [i]; p; p = p -> cdr) {
|
||||||
if (store_option (result, universe, packet, lease,
|
if (store_option (result, universe, packet, lease,
|
||||||
in_options, cfg_options,
|
in_options, cfg_options, scope,
|
||||||
(struct option_cache *)p -> car))
|
(struct option_cache *)p -> car))
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
@ -1207,12 +1216,13 @@ int hashed_option_space_encapsulate (result, packet, lease,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int nwip_option_space_encapsulate (result, packet, lease,
|
int nwip_option_space_encapsulate (result, packet, lease,
|
||||||
in_options, cfg_options, universe)
|
in_options, cfg_options, scope, universe)
|
||||||
struct data_string *result;
|
struct data_string *result;
|
||||||
struct packet *packet;
|
struct packet *packet;
|
||||||
struct lease *lease;
|
struct lease *lease;
|
||||||
struct option_state *in_options;
|
struct option_state *in_options;
|
||||||
struct option_state *cfg_options;
|
struct option_state *cfg_options;
|
||||||
|
struct binding_scope *scope;
|
||||||
struct universe *universe;
|
struct universe *universe;
|
||||||
{
|
{
|
||||||
pair p, *hash;
|
pair p, *hash;
|
||||||
@ -1229,7 +1239,7 @@ int nwip_option_space_encapsulate (result, packet, lease,
|
|||||||
for (i = 0; hash && i < OPTION_HASH_SIZE; i++) {
|
for (i = 0; hash && i < OPTION_HASH_SIZE; i++) {
|
||||||
for (p = hash [i]; p; p = p -> cdr) {
|
for (p = hash [i]; p; p = p -> cdr) {
|
||||||
if (store_option (result, universe, packet, lease,
|
if (store_option (result, universe, packet, lease,
|
||||||
in_options, cfg_options,
|
in_options, cfg_options, scope,
|
||||||
(struct option_cache *)p -> car))
|
(struct option_cache *)p -> car))
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
@ -1243,36 +1253,30 @@ int nwip_option_space_encapsulate (result, packet, lease,
|
|||||||
memset (&ds, 0, sizeof ds);
|
memset (&ds, 0, sizeof ds);
|
||||||
ds.data = nni;
|
ds.data = nni;
|
||||||
ds.len = 2;
|
ds.len = 2;
|
||||||
if (option_cache_allocate
|
if (option_cache_allocate (&no_nwip, MDL))
|
||||||
(&no_nwip, "nwip_option_space_encapsulate")) {
|
data_string_copy (&no_nwip -> data, &ds, MDL);
|
||||||
data_string_copy
|
no_nwip -> option = nwip_universe.options [1];
|
||||||
(&no_nwip -> data, &ds,
|
|
||||||
"nwip_option_space_encapsulate");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (no_nwip) {
|
if (no_nwip) {
|
||||||
if (store_option (result, universe, packet, lease,
|
if (store_option (result, universe, packet, lease,
|
||||||
in_options, cfg_options,
|
in_options, cfg_options,
|
||||||
(struct option_cache *)p -> car))
|
scope, no_nwip))
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* If we have nwip options, the first one has to be the
|
/* If we have nwip options, the first one has to be the
|
||||||
nwip-exists-in-option-area option. */
|
nwip-exists-in-option-area option. */
|
||||||
if (!buffer_allocate (&ds.buffer, result -> len + 2,
|
if (!buffer_allocate (&ds.buffer, result -> len + 2, MDL)) {
|
||||||
"nwip_option_space_encapsulate")) {
|
data_string_forget (result, MDL);
|
||||||
data_string_forget (result,
|
|
||||||
"nwip_option_space_encapsulate");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ds.data = &ds.buffer -> data [0];
|
ds.data = &ds.buffer -> data [0];
|
||||||
ds.buffer -> data [0] = 2;
|
ds.buffer -> data [0] = 2;
|
||||||
ds.buffer -> data [1] = 0;
|
ds.buffer -> data [1] = 0;
|
||||||
memcpy (&ds.buffer -> data [2], result -> data, result -> len);
|
memcpy (&ds.buffer -> data [2], result -> data, result -> len);
|
||||||
data_string_forget (result, "nwip_option_space_encapsulate");
|
data_string_forget (result, MDL);
|
||||||
data_string_copy (result, &ds,
|
data_string_copy (result, &ds, MDL);
|
||||||
"nwip_option_space_encapsulate");
|
data_string_forget (&ds, MDL);
|
||||||
data_string_forget (&ds, "nwip_option_space_encapsulate");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -1289,9 +1293,12 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
|
|||||||
int i;
|
int i;
|
||||||
struct option_cache *op;
|
struct option_cache *op;
|
||||||
struct packet *decoded_packet;
|
struct packet *decoded_packet;
|
||||||
|
#if defined (DEBUG_MEMORY_LEAKAGE)
|
||||||
|
unsigned long previous_outstanding = dmalloc_outstanding;
|
||||||
|
#endif
|
||||||
|
|
||||||
decoded_packet = (struct packet *)0;
|
decoded_packet = (struct packet *)0;
|
||||||
if (!packet_allocate (&decoded_packet, "do_packet")) {
|
if (!packet_allocate (&decoded_packet, MDL)) {
|
||||||
log_error ("do_packet: no memory for incoming packet!");
|
log_error ("do_packet: no memory for incoming packet!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1303,7 +1310,7 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
|
|||||||
decoded_packet -> haddr = hfrom;
|
decoded_packet -> haddr = hfrom;
|
||||||
|
|
||||||
if (packet -> hlen > sizeof packet -> chaddr) {
|
if (packet -> hlen > sizeof packet -> chaddr) {
|
||||||
packet_dereference (&decoded_packet, "do_packet");
|
packet_dereference (&decoded_packet, MDL);
|
||||||
log_info ("Discarding packet with bogus hlen.");
|
log_info ("Discarding packet with bogus hlen.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1313,9 +1320,8 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
|
|||||||
if (!parse_options (decoded_packet)) {
|
if (!parse_options (decoded_packet)) {
|
||||||
if (decoded_packet -> options)
|
if (decoded_packet -> options)
|
||||||
option_state_dereference
|
option_state_dereference
|
||||||
(&decoded_packet -> options,
|
(&decoded_packet -> options, MDL);
|
||||||
"do_packet");
|
packet_dereference (&decoded_packet, MDL);
|
||||||
packet_dereference (&decoded_packet, "do_packet");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1328,12 +1334,14 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
|
|||||||
evaluate_option_cache (&dp, decoded_packet,
|
evaluate_option_cache (&dp, decoded_packet,
|
||||||
(struct lease *)0,
|
(struct lease *)0,
|
||||||
decoded_packet -> options,
|
decoded_packet -> options,
|
||||||
(struct option_state *)0, op);
|
(struct option_state *)0,
|
||||||
|
(struct binding_scope *)0,
|
||||||
|
op, MDL);
|
||||||
if (dp.len > 0)
|
if (dp.len > 0)
|
||||||
decoded_packet -> packet_type = dp.data [0];
|
decoded_packet -> packet_type = dp.data [0];
|
||||||
else
|
else
|
||||||
decoded_packet -> packet_type = 0;
|
decoded_packet -> packet_type = 0;
|
||||||
data_string_forget (&dp, "do_packet");
|
data_string_forget (&dp, MDL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1342,7 +1350,16 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
|
|||||||
else
|
else
|
||||||
bootp (decoded_packet);
|
bootp (decoded_packet);
|
||||||
|
|
||||||
|
#if defined (DEBUG_MEMORY_LEAKAGE)
|
||||||
|
log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
|
||||||
|
dmalloc_generation,
|
||||||
|
dmalloc_outstanding - previous_outstanding,
|
||||||
|
dmalloc_outstanding, dmalloc_longterm);
|
||||||
|
#endif
|
||||||
|
#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
|
||||||
|
dmalloc_dump_outstanding ();
|
||||||
|
#endif
|
||||||
/* If the caller kept the packet, they'll have upped the refcnt. */
|
/* If the caller kept the packet, they'll have upped the refcnt. */
|
||||||
packet_dereference (&decoded_packet, "do_packet");
|
packet_dereference (&decoded_packet, MDL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user