Routines for manipulating parse trees... */
/*
- * Copyright (c) 1995-2000 Internet Software Consortium.
+ * Copyright (c) 1995-2001 Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#ifndef lint
static char copyright[] =
-"$Id: tree.c,v 1.101 2001/04/18 18:54:47 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: tree.c,v 1.102 2001/06/27 00:30:00 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
return 1;
}
-int make_const_data (expr, data, len, terminated, allocate)
- struct expression **expr;
- const unsigned char *data;
- unsigned len;
- int terminated;
- int allocate;
+int make_const_data (struct expression **expr, const unsigned char *data,
+ unsigned len, int terminated, int allocate,
+ const char *file, int line)
{
struct expression *nt;
- if (!expression_allocate (expr, MDL)) {
+ if (!expression_allocate (expr, file, line)) {
log_error ("No memory for make_const_data tree node.");
return 0;
}
if (len) {
if (allocate) {
if (!buffer_allocate (&nt -> data.const_data.buffer,
- len + terminated, MDL)) {
+ len + terminated, file, line)) {
log_error ("Can't allocate const_data buffer");
- expression_dereference (expr, MDL);
+ expression_dereference (expr, file, line);
return 0;
}
nt -> data.const_data.data =
unsigned long val;
{
if (!expression_allocate (expr, MDL)) {
- log_error ("No memory for make_const_data tree node.");
+ log_error ("No memory for make_const_int tree node.");
return 0;
}
return 1;
}
-int option_cache (oc, dp, expr, option)
- struct option_cache **oc;
- struct data_string *dp;
- struct expression *expr;
- struct option *option;
+int option_cache (struct option_cache **oc, struct data_string *dp,
+ struct expression *expr, struct option *option,
+ const char *file, int line)
{
- if (!option_cache_allocate (oc, MDL))
+ if (!option_cache_allocate (oc, file, line))
return 0;
if (dp)
- data_string_copy (&(*oc) -> data, dp, MDL);
+ data_string_copy (&(*oc) -> data, dp, file, line);
if (expr)
- expression_reference (&(*oc) -> expression, expr, MDL);
+ expression_reference (&(*oc) -> expression, expr, file, line);
(*oc) -> option = option;
return 1;
}
}
int evaluate_expression (result, packet, lease, client_state,
- in_options, cfg_options, scope, expr)
+ in_options, cfg_options, scope, expr, file, line)
struct binding_value **result;
struct packet *packet;
struct lease *lease;
struct option_state *cfg_options;
struct binding_scope **scope;
struct expression *expr;
+ const char *file;
+ int line;
{
struct binding_value *bv;
int status;
if (result)
binding_value_reference (result,
binding -> value,
- MDL);
+ file, line);
return 1;
} else
return 0;
evaluate_expression (&nb -> value, packet, lease,
client_state,
in_options, cfg_options, scope,
- arg -> data.arg.val);
+ arg -> data.arg.val, file, line);
nb -> next = ns -> bindings;
ns -> bindings = nb;
arg = arg -> data.arg.next;
bv -> type = binding_data;
status = (evaluate_data_expression
(&bv -> value.data, packet, lease, client_state,
- in_options, cfg_options, scope, expr));
+ in_options, cfg_options, scope, expr, MDL));
} else if (is_dns_expression (expr)) {
#if defined (NSUPDATE)
if (!binding_value_allocate (&bv, MDL))
return 0;
}
if (result && status)
- binding_value_reference (result, bv, MDL);
+ binding_value_reference (result, bv, file, line);
binding_value_dereference (&bv, MDL);
return status;
/* Decrement the reference count. If it's nonzero, we're
done. */
--(bv -> refcnt);
- rc_register (file, line, v, bv, bv -> refcnt);
+ rc_register (file, line, v, bv, bv -> refcnt, 1);
if (bv -> refcnt > 0)
return 1;
if (bv -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (bv);
#endif
#if defined (POINTER_DEBUG)
abort ();
r1 = evaluate_data_expression (&name, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.ns_add.rrname);
+ expr -> data.ns_add.rrname,
+ MDL);
if (r1) {
/* The result of the evaluation may or may not
be NUL-terminated, but we need it
r2 = evaluate_data_expression
(&data, packet, lease, client_state,
in_options, cfg_options, scope,
- expr -> data.ns_add.rrdata);
+ expr -> data.ns_add.rrdata, MDL);
}
} else
r2 = 0;
bv = obv = (struct binding_value *)0;
sleft = evaluate_expression (&bv, packet, lease, client_state,
in_options, cfg_options, scope,
- expr -> data.equal [0]);
+ expr -> data.equal [0], MDL);
sright = evaluate_expression (&obv, packet, lease,
client_state, in_options,
cfg_options, scope,
- expr -> data.equal [1]);
+ expr -> data.equal [1], MDL);
if (sleft && sright) {
if (bv -> type != obv -> type)
*result = expr -> op == expr_not_equal;
!get_option (&left, expr -> data.exists -> universe,
packet, lease, client_state,
in_options, cfg_options, in_options,
- scope, expr -> data.exists -> code))
+ scope, expr -> data.exists -> code, MDL))
*result = 0;
else {
*result = 1;
bv = (struct binding_value *)0;
sleft = evaluate_expression (&bv, packet, lease, client_state,
in_options, cfg_options,
- scope, expr);
+ scope, expr, MDL);
if (sleft) {
if (bv -> type != binding_boolean)
log_error ("%s() returned type %d in %s.",
}
int evaluate_data_expression (result, packet, lease, client_state,
- in_options, cfg_options, scope, expr)
+ in_options, cfg_options, scope, expr, file, line)
struct data_string *result;
struct packet *packet;
struct lease *lease;
struct option_state *cfg_options;
struct binding_scope **scope;
struct expression *expr;
+ const char *file;
+ int line;
{
struct data_string data, other;
unsigned long offset, len, i;
s0 = evaluate_data_expression (&data, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.substring.expr);
+ expr -> data.substring.expr,
+ MDL);
/* Evaluate the offset and length. */
s1 = evaluate_numeric_expression
return an empty string. Otherwise, do the
adjustments and return what's left. */
if (data.len > offset) {
- data_string_copy (result, &data, MDL);
+ data_string_copy (result, &data, file, line);
result -> len -= offset;
if (result -> len > len) {
result -> len = len;
s0 = evaluate_data_expression (&data, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.suffix.expr);
+ expr -> data.suffix.expr, MDL);
/* Evaluate the length. */
s1 = evaluate_numeric_expression (&len, packet, lease,
client_state,
scope,
expr -> data.suffix.len);
if (s0 && s1) {
- data_string_copy (result, &data, MDL);
+ data_string_copy (result, &data, file, line);
/* If we are returning the last N bytes of a
string whose length is <= N, just return
result -> data += data.len - len;
result -> len = len;
}
+ data_string_forget (&data, MDL);
}
#if defined (DEBUG_EXPRESSIONS)
/* Extract an option. */
case expr_option:
if (in_options)
- s0 = get_option (result,
- expr -> data.option -> universe,
- packet, lease, client_state,
- in_options, cfg_options, in_options,
- scope, expr -> data.option -> code);
+ s0 = get_option (result,
+ expr -> data.option -> universe,
+ packet, lease, client_state,
+ in_options, cfg_options, in_options,
+ scope, expr -> data.option -> code,
+ file, line);
else
s0 = 0;
case expr_config_option:
if (cfg_options)
- s0 = get_option (result,
- expr -> data.option -> universe,
- packet, lease, client_state,
- in_options, cfg_options, cfg_options,
- scope, expr -> data.option -> code);
+ s0 = get_option (result,
+ expr -> data.option -> universe,
+ packet, lease, client_state,
+ in_options, cfg_options, cfg_options,
+ scope, expr -> data.option -> code,
+ file, line);
else
s0 = 0;
/* Combine the hardware type and address. */
case expr_hardware:
+ /* On the client, hardware is our hardware. */
+ if (client_state) {
+ memset (result, 0, sizeof *result);
+ result -> data =
+ client_state -> interface -> hw_address.hbuf;
+ result -> len =
+ client_state -> interface -> hw_address.hlen;
+#if defined (DEBUG_EXPRESSIONS)
+ log_debug ("data: hardware = %s",
+ print_hex_1 (result -> len,
+ result -> data, 60));
+#endif
+ return 1;
+ }
+
+ /* The server cares about the client's hardware address,
+ so only in the case where we are examining a packet can
+ we return anything. */
if (!packet || !packet -> raw) {
log_error ("data: hardware: raw packet not available");
return 0;
return 0;
}
result -> len = packet -> raw -> hlen + 1;
- if (buffer_allocate (&result -> buffer, result -> len, MDL)) {
+ if (buffer_allocate (&result -> buffer, result -> len,
+ file, line)) {
result -> data = &result -> buffer -> data [0];
result -> buffer -> data [0] = packet -> raw -> htype;
memcpy (&result -> buffer -> data [1],
else
result -> len = len;
if (buffer_allocate (&result -> buffer,
- result -> len, MDL)) {
+ result -> len, file, line)) {
result -> data = &result -> buffer -> data [0];
memcpy (result -> buffer -> data,
(((unsigned char *)(packet -> raw))
expr -> data.const_data.data, 60));
#endif
data_string_copy (result,
- &expr -> data.const_data, MDL);
+ &expr -> data.const_data, file, line);
return 1;
/* Hostname lookup... */
s0 = evaluate_data_expression (&data, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.concat [0]);
+ expr -> data.concat [0], MDL);
memset (&other, 0, sizeof other);
s1 = evaluate_data_expression (&other, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.concat [1]);
+ expr -> data.concat [1], MDL);
if (s0 && s1) {
- result -> len = data.len + other.len;
- if (!buffer_allocate (&result -> buffer,
- (result -> len +
- other.terminated), MDL)) {
+ result -> len = data.len + other.len;
+ if (!buffer_allocate (&result -> buffer,
+ (result -> len + other.terminated),
+ file, line)) {
log_error ("data: concat: no memory");
result -> len = 0;
data_string_forget (&data, MDL);
memcpy (result -> buffer -> data, data.data, data.len);
memcpy (&result -> buffer -> data [data.len],
other.data, other.len + other.terminated);
- } else if (s0)
+ }
+
+ if (s0)
data_string_forget (&data, MDL);
- else if (s1)
+ if (s1)
data_string_forget (&other, MDL);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("data: concat (%s, %s) = %s",
expr -> data.encode_int);
if (s0) {
result -> len = 1;
- if (!buffer_allocate (&result -> buffer, 1, MDL)) {
+ if (!buffer_allocate (&result -> buffer,
+ 1, file, line)) {
log_error ("data: encode_int8: no memory");
result -> len = 0;
s0 = 0;
expr -> data.encode_int);
if (s0) {
result -> len = 2;
- if (!buffer_allocate (&result -> buffer, 2, MDL)) {
+ if (!buffer_allocate (&result -> buffer, 2,
+ file, line)) {
log_error ("data: encode_int16: no memory");
result -> len = 0;
s0 = 0;
expr -> data.encode_int);
if (s0) {
result -> len = 4;
- if (!buffer_allocate (&result -> buffer, 4, MDL)) {
+ if (!buffer_allocate (&result -> buffer, 4,
+ file, line)) {
log_error ("data: encode_int32: no memory");
result -> len = 0;
s0 = 0;
s2 = evaluate_data_expression (&data, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.b2a.seperator);
+ expr -> data.b2a.seperator,
+ MDL);
/* Evaluate the data to be converted. */
memset (&other, 0, sizeof other);
s3 = evaluate_data_expression (&other, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.b2a.buffer);
+ expr -> data.b2a.buffer, MDL);
if (s0 && s1 && s2 && s3) {
unsigned buflen, i;
}
if (!buffer_allocate (&result -> buffer,
- buflen + 1, MDL)) {
+ buflen + 1, file, line)) {
log_error ("data: binary-to-ascii: no memory");
status = 0;
goto b2a_out;
s1 = evaluate_data_expression (&data, packet, lease,
client_state,
in_options, cfg_options, scope,
- expr -> data.reverse.buffer);
+ expr -> data.reverse.buffer,
+ MDL);
if (s0 && s1) {
char *upper;
/* XXX reverse in place? I don't think we can. */
if (!buffer_allocate (&result -> buffer,
- data.len, MDL)) {
+ data.len, file, line)) {
log_error ("data: reverse: no memory");
status = 0;
goto reverse_out;
return 0;
}
result -> len = lease -> ip_addr.len;
- if (buffer_allocate (&result -> buffer, result -> len, MDL)) {
+ if (buffer_allocate (&result -> buffer, result -> len,
+ file, line)) {
result -> data = &result -> buffer -> data [0];
memcpy (&result -> buffer -> data [0],
lease -> ip_addr.iabuf, lease -> ip_addr.len);
if ((evaluate_data_expression
(result, packet,
lease, client_state, in_options, cfg_options,
- scope, expr -> data.pick_first_value.car))) {
+ scope, expr -> data.pick_first_value.car, MDL))) {
#if defined (DEBUG_EXPRESSIONS)
log_debug ("data: pick_first_value (%s, xxx)",
print_hex_1 (result -> len,
(evaluate_data_expression
(result, packet,
lease, client_state, in_options, cfg_options,
- scope, expr -> data.pick_first_value.cdr))) {
+ scope, expr -> data.pick_first_value.cdr, MDL))) {
#if defined (DEBUG_EXPRESSIONS)
log_debug ("data: pick_first_value (NULL, %s)",
print_hex_1 (result -> len,
}
result -> len = strlen (lease -> host -> name);
if (buffer_allocate (&result -> buffer,
- result -> len + 1, MDL)) {
+ result -> len + 1, file, line)) {
result -> data = &result -> buffer -> data [0];
strcpy ((char *)&result -> buffer -> data [0],
lease -> host -> name);
if (binding -> value -> type == binding_data) {
data_string_copy (result,
&binding -> value -> value.data,
- MDL);
+ file, line);
s0 = 1;
} else if (binding -> value -> type != binding_data) {
log_error ("binding type %d in %s.",
bv = (struct binding_value *)0;
s0 = evaluate_expression (&bv, packet, lease, client_state,
in_options, cfg_options,
- scope, expr);
+ scope, expr, MDL);
if (s0) {
if (bv -> type != binding_data)
log_error ("%s() returned type %d in %s.",
"evaluate_data_expression");
else
data_string_copy (result, &bv -> value.data,
- MDL);
+ file, line);
binding_value_dereference (&bv, MDL);
}
#if defined (DEBUG_EXPRESSIONS)
sizeof packet -> raw -> file);
result -> len = fn - &(packet -> raw -> file [0]);
if (buffer_allocate (&result -> buffer,
- result -> len + 1, MDL)) {
+ result -> len + 1, file, line)) {
result -> data = &result -> buffer -> data [0];
memcpy (&result -> buffer -> data [0],
packet -> raw -> file,
sizeof packet -> raw -> sname);
result -> len = fn - &packet -> raw -> sname [0];
if (buffer_allocate (&result -> buffer,
- result -> len + 1, MDL)) {
+ result -> len + 1, file, line)) {
result -> data = &result -> buffer -> data [0];
memcpy (&result -> buffer -> data [0],
packet -> raw -> sname,
memset (&data, 0, sizeof data);
status = evaluate_data_expression
(&data, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.extract_int);
+ cfg_options, scope, expr -> data.extract_int, MDL);
if (status)
*result = data.data [0];
#if defined (DEBUG_EXPRESSIONS)
memset (&data, 0, sizeof data);
status = (evaluate_data_expression
(&data, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.extract_int));
+ cfg_options, scope, expr -> data.extract_int, MDL));
if (status && data.len >= 2)
*result = getUShort (data.data);
#if defined (DEBUG_EXPRESSIONS)
memset (&data, 0, sizeof data);
status = (evaluate_data_expression
(&data, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.extract_int));
+ cfg_options, scope, expr -> data.extract_int, MDL));
if (status && data.len >= 4)
*result = getULong (data.data);
#if defined (DEBUG_EXPRESSIONS)
status = evaluate_expression (&bv, packet, lease,
client_state,
in_options, cfg_options,
- scope, expr);
+ scope, expr, MDL);
if (status) {
if (bv -> type != binding_numeric)
log_error ("%s() returned type %d in %s.",
return 0;
return evaluate_data_expression (result, packet, lease, client_state,
in_options, cfg_options, scope,
- oc -> expression);
+ oc -> expression, file, line);
}
/* Evaluate an option cache and extract a boolean from the result,
/* Decrement the reference count. If it's nonzero, we're
done. */
--(expr -> refcnt);
- rc_register (file, line, eptr, expr, expr -> refcnt);
+ rc_register (file, line, eptr, expr, expr -> refcnt, 1);
if (expr -> refcnt > 0)
return;
if (expr -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (expr);
#endif
#if defined (POINTER_DEBUG)
abort ();
binding_scope = *ptr;
*ptr = (struct binding_scope *)0;
--binding_scope -> refcnt;
- rc_register (file, line, ptr, binding_scope, binding_scope -> refcnt);
+ rc_register (file, line, ptr,
+ binding_scope, binding_scope -> refcnt, 1);
if (binding_scope -> refcnt > 0)
return 1;
if (binding_scope -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (binding_scope);
#endif
#if defined (POINTER_DEBUG)
abort ();
}
bp -> refcnt--;
- rc_register (file, line, ptr, bp, bp -> refcnt);
+ rc_register (file, line, ptr, bp, bp -> refcnt, 1);
if (bp -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
+ dump_rc_history (bp);
#endif
#if defined (POINTER_DEBUG)
abort ();