summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Lemon <source@isc.org>1999-07-02 20:58:48 +0000
committerTed Lemon <source@isc.org>1999-07-02 20:58:48 +0000
commitda38df14336d62b999bdba8f600d86777e98653a (patch)
tree1486bbae2f42d28a21a0cfd0bd72b4b23ba84a23
parent15eda2482666252724334793c1fef856ea61003f (diff)
downloadisc-dhcp-da38df14336d62b999bdba8f600d86777e98653a.tar.gz
Pervasive changes to support leased_address, reverse and binary_to_ascii.
-rw-r--r--client/dhclient.c54
-rw-r--r--common/convert.c64
-rw-r--r--common/execute.c19
-rw-r--r--common/memory.c4
-rw-r--r--common/options.c43
-rw-r--r--common/parse.c80
-rw-r--r--common/tree.c327
-rw-r--r--includes/dhcpd.h38
-rw-r--r--includes/dhctoken.h3
-rw-r--r--includes/tree.h17
-rw-r--r--server/bootp.c25
-rw-r--r--server/class.c13
-rw-r--r--server/dhcp.c136
13 files changed, 662 insertions, 161 deletions
diff --git a/client/dhclient.c b/client/dhclient.c
index 1000b03d..7a9d01d2 100644
--- a/client/dhclient.c
+++ b/client/dhclient.c
@@ -22,7 +22,7 @@
#ifndef lint
static char ocopyright[] =
-"$Id: dhclient.c,v 1.77 1999/05/07 17:32:37 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhclient.c,v 1.78 1999/07/02 20:57:06 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -267,8 +267,9 @@ struct class *find_class (s)
return (struct class *)0;
}
-int check_collection (packet, collection)
+int check_collection (packet, lease, collection)
struct packet *packet;
+ struct lease *lease;
struct collection *collection;
{
return 0;
@@ -511,7 +512,8 @@ void dhcpack (packet)
memset (&ds, 0, sizeof ds);
if (oc &&
evaluate_option_cache (&ds, packet,
- client -> new -> options, oc)) {
+ client -> new -> options,
+ (struct lease *)0, oc)) {
if (ds.len > 3)
client -> new -> expiry = getULong (ds.data);
else
@@ -539,8 +541,8 @@ void dhcpack (packet)
oc = lookup_option (&dhcp_universe, client -> new -> options,
DHO_DHCP_RENEWAL_TIME);
if (oc &&
- evaluate_option_cache (&ds, packet,
- client -> new -> options, oc)) {
+ evaluate_option_cache (&ds, packet, client -> new -> options,
+ (struct lease *)0, oc)) {
if (ds.len > 3)
client -> new -> renewal = getULong (ds.data);
else
@@ -559,7 +561,8 @@ void dhcpack (packet)
DHO_DHCP_REBINDING_TIME);
if (oc &&
evaluate_option_cache (&ds, packet,
- client -> new -> options, oc)) {
+ client -> new -> options,
+ (struct lease *)0, oc)) {
if (ds.len > 3)
client -> new -> rebind = getULong (ds.data);
else
@@ -667,7 +670,9 @@ void state_bound (cpp)
DHO_DHCP_SERVER_IDENTIFIER);
if (oc &&
evaluate_option_cache (&ds, (struct packet *)0,
- client -> active -> options, oc)) {
+ client -> active -> options,
+ (struct lease *)0,
+ oc)) {
if (ds.len > 3) {
memcpy (client -> destination.iabuf, ds.data, 4);
client -> destination.len = 4;
@@ -906,7 +911,8 @@ struct client_lease *packet_to_lease (packet)
DHO_DHCP_OPTION_OVERLOAD);
memset (&data, 0, sizeof data);
if (oc &&
- evaluate_option_cache (&data, packet, lease -> options, oc)) {
+ evaluate_option_cache (&data, packet, lease -> options,
+ (struct lease *)0, oc)) {
if (data.len > 0)
i = data.data [0];
else
@@ -1482,10 +1488,9 @@ void make_client_options (client, lease, type, sid, rip, prl, op)
/* Run statements that need to be run on transmission. */
if (client -> config -> on_transmission)
execute_statements_in_scope
- ((struct packet *)0, (lease
- ? lease -> options
- : (struct option_state *)0), *op,
- client -> config -> on_transmission,
+ ((struct packet *)0, (struct lease *)0,
+ (lease ? lease -> options : (struct option_state *)0),
+ *op, client -> config -> on_transmission,
(struct group *)0);
}
@@ -1508,7 +1513,8 @@ void make_discover (client, lease)
/* Set up the option buffer... */
client -> packet_length =
- cons_options ((struct packet *)0, &client -> packet, 0,
+ cons_options ((struct packet *)0, &client -> packet,
+ (struct lease *)0, 0,
options, 0, 0, 0, (struct data_string *)0);
if (client -> packet_length < BOOTP_MIN_LEN)
client -> packet_length = BOOTP_MIN_LEN;
@@ -1574,7 +1580,8 @@ void make_request (client, lease)
/* Set up the option buffer... */
client -> packet_length =
- cons_options ((struct packet *)0, &client -> packet, 0,
+ cons_options ((struct packet *)0, &client -> packet,
+ (struct lease *)0, 0,
options, 0, 0, 0, (struct data_string *)0);
if (client -> packet_length < BOOTP_MIN_LEN)
client -> packet_length = BOOTP_MIN_LEN;
@@ -1637,7 +1644,8 @@ void make_decline (client, lease)
/* Set up the option buffer... */
memset (&client -> packet, 0, sizeof (client -> packet));
client -> packet_length =
- cons_options ((struct packet *)0, &client -> packet, 0,
+ cons_options ((struct packet *)0, &client -> packet,
+ (struct lease *)0, 0,
options, 0, 0, 0, (struct data_string *)0);
if (client -> packet_length < BOOTP_MIN_LEN)
client -> packet_length = BOOTP_MIN_LEN;
@@ -1693,7 +1701,8 @@ void make_release (client, lease)
/* Set up the option buffer... */
client -> packet_length =
- cons_options ((struct packet *)0, &client -> packet, 0,
+ cons_options ((struct packet *)0, &client -> packet,
+ (struct lease *)0, 0,
options, 0, 0, 0, (struct data_string *)0);
if (client -> packet_length < BOOTP_MIN_LEN)
client -> packet_length = BOOTP_MIN_LEN;
@@ -1838,7 +1847,8 @@ void write_client_lease (client, lease, rewrite)
for (p = hash [i]; p; p = p -> cdr) {
oc = (struct option_cache *)p -> car;
if (evaluate_option_cache (&ds, (struct packet *)0,
- lease -> options, oc)) {
+ lease -> options,
+ (struct lease *)0, oc)) {
fprintf (leaseFile,
" option %s %s;\n",
oc -> option -> name,
@@ -1950,7 +1960,8 @@ void script_write_params (client, prefix, lease)
memset (&data, 0, sizeof data);
oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK);
if (oc && evaluate_option_cache (&data, (struct packet *)0,
- lease -> options, oc)) {
+ lease -> options,
+ (struct lease *)0, oc)) {
if (data.len > 3) {
struct iaddr netmask, subnet, broadcast;
@@ -1973,6 +1984,7 @@ void script_write_params (client, prefix, lease)
!evaluate_option_cache (&data,
(struct packet *)0,
lease -> options,
+ (struct lease *)0,
oc)) {
broadcast = broadcast_addr (subnet,
netmask);
@@ -2004,7 +2016,8 @@ void script_write_params (client, prefix, lease)
fprintf (scriptFile, "export %sserver_name\n", prefix);
}
- execute_statements_in_scope ((struct packet *)0, lease -> options,
+ execute_statements_in_scope ((struct packet *)0,
+ (struct lease *)0, lease -> options,
lease -> options,
client -> config -> on_receipt,
(struct group *)0);
@@ -2017,7 +2030,8 @@ void script_write_params (client, prefix, lease)
oc = (struct option_cache *)hp -> car;
if (evaluate_option_cache (&data, (struct packet *)0,
- lease -> options, oc)) {
+ lease -> options,
+ (struct lease *)0, oc)) {
if (data.len) {
char *s = (dhcp_option_ev_name
diff --git a/common/convert.c b/common/convert.c
index 88f335f1..a1206648 100644
--- a/common/convert.c
+++ b/common/convert.c
@@ -23,7 +23,7 @@
#ifndef lint
static char copyright[] =
-"$Id: convert.c,v 1.7 1999/04/05 15:33:52 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: convert.c,v 1.8 1999/07/02 20:57:24 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -108,3 +108,65 @@ u_int32_t getUChar (obuf)
{
return obuf [0];
}
+
+int converted_length (buf, base, width)
+ unsigned char *buf;
+ unsigned int base;
+ unsigned int width;
+{
+ u_int32_t number;
+ int column;
+ int power = 1;
+ int newcolumn = base;
+
+ if (base > 16)
+ return 0;
+
+ if (width == 1)
+ number = getUChar (buf);
+ else if (width == 2)
+ number = getUShort (buf);
+ else if (width == 4)
+ number = getULong (buf);
+
+ do {
+ column = newcolumn;
+
+ if (number < column)
+ return power;
+ power++;
+ newcolumn = column * base;
+ /* If we wrap around, it must be the next power of two up. */
+ } while (column > newcolumn);
+
+ return power;
+}
+
+int binary_to_ascii (outbuf, inbuf, base, width)
+ unsigned char *outbuf;
+ unsigned char *inbuf;
+ unsigned int base;
+ unsigned int width;
+{
+ u_int32_t number;
+ static char h2a [] = "0123456789abcdef";
+ int power = 0;
+ int i, j;
+
+ if (base > 16)
+ return 0;
+
+ if (width == 1)
+ number = getUChar (inbuf);
+ else if (width == 2)
+ number = getUShort (inbuf);
+ else if (width == 4)
+ number = getULong (inbuf);
+
+ for (i = 0; number; i++) {
+ outbuf [i] = h2a [number % base];
+ number /= base;
+ power++;
+ }
+ return power;
+}
diff --git a/common/execute.c b/common/execute.c
index de1e94a4..2c4eb8c4 100644
--- a/common/execute.c
+++ b/common/execute.c
@@ -22,13 +22,14 @@
#ifndef lint
static char copyright[] =
-"$Id: execute.c,v 1.9 1999/04/05 15:35:54 mellon Exp $ Copyright (c) 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: execute.c,v 1.10 1999/07/02 20:57:24 mellon Exp $ Copyright (c) 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
-int execute_statements (packet, in_options, out_options, statements)
+int execute_statements (packet, lease, in_options, out_options, statements)
struct packet *packet;
+ struct lease *lease;
struct option_state *in_options;
struct option_state *out_options;
struct executable_statement *statements;
@@ -45,7 +46,7 @@ int execute_statements (packet, in_options, out_options, statements)
case if_statement:
status = evaluate_boolean_expression
(&result, packet,
- in_options, r -> data.ie.expr);
+ in_options, lease, r -> data.ie.expr);
#if defined (DEBUG_EXPRESSIONS)
log_info ("exec: if %s", (status
@@ -56,7 +57,7 @@ int execute_statements (packet, in_options, out_options, statements)
if (!status)
result = 0;
if (!execute_statements
- (packet, in_options, out_options,
+ (packet, lease, in_options, out_options,
result ? r -> data.ie.true : r -> data.ie.false))
return 0;
break;
@@ -64,7 +65,7 @@ int execute_statements (packet, in_options, out_options, statements)
case eval_statement:
status = evaluate_boolean_expression
(&result,
- packet, in_options, r -> data.eval);
+ packet, in_options, lease, r -> data.eval);
#if defined (DEBUG_EXPRESSIONS)
log_info ("exec: evaluate: %s",
(status
@@ -138,9 +139,10 @@ int execute_statements (packet, in_options, out_options, statements)
specific scopes, so we recursively traverse the scope list, executing
the most outer scope first. */
-void execute_statements_in_scope (packet, in_options, out_options,
+void execute_statements_in_scope (packet, lease, in_options, out_options,
group, limiting_group)
struct packet *packet;
+ struct lease *lease;
struct option_state *in_options;
struct option_state *out_options;
struct group *group;
@@ -182,8 +184,9 @@ void execute_statements_in_scope (packet, in_options, out_options,
}
if (group -> next)
- execute_statements_in_scope (packet, in_options, out_options,
+ execute_statements_in_scope (packet, lease,
+ in_options, out_options,
group -> next, limiting_group);
- execute_statements (packet,
+ execute_statements (packet, lease,
in_options, out_options, group -> statements);
}
diff --git a/common/memory.c b/common/memory.c
index fc1c09bb..cd506c6b 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -22,7 +22,7 @@
#ifndef lint
static char copyright[] =
-"$Id: memory.c,v 1.51 1999/07/01 18:45:28 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: memory.c,v 1.52 1999/07/02 20:57:24 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -87,6 +87,7 @@ void enter_host (hd)
(&hd -> client_identifier,
(struct packet *)0,
(struct option_state *)0,
+ (struct lease *)0,
esp -> data.option);
break;
}
@@ -176,6 +177,7 @@ struct subnet *find_host_for_network (host, addr, share)
continue;
if (!evaluate_data_expression (&fixed_addr, (struct packet *)0,
(struct option_state *)0,
+ (struct lease *)0,
hp -> fixed_addr -> expression))
continue;
for (i = 0; i < fixed_addr.len; i += 4) {
diff --git a/common/options.c b/common/options.c
index 246b983b..591181c1 100644
--- a/common/options.c
+++ b/common/options.c
@@ -22,7 +22,7 @@
#ifndef lint
static char copyright[] =
-"$Id: options.c,v 1.42 1999/05/07 17:36:36 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: options.c,v 1.43 1999/07/02 20:57:25 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#define DHCP_OPTION_DATA
@@ -233,10 +233,11 @@ int parse_agent_information_option (packet, len, data)
three seperate buffers if needed. This allows us to cons up a set
of vendor options using the same routine. */
-int cons_options (inpacket, outpacket,
+int cons_options (inpacket, outpacket, lease,
mms, options, overload, terminate, bootpp, prl)
struct packet *inpacket;
struct dhcp_packet *outpacket;
+ struct lease *lease;
int mms;
struct option_state *options;
int overload; /* Overload flags that may be set. */
@@ -267,7 +268,7 @@ int cons_options (inpacket, outpacket,
(op = lookup_option (&dhcp_universe, inpacket -> options,
DHO_DHCP_MAX_MESSAGE_SIZE))) {
evaluate_option_cache (&ds, inpacket,
- inpacket -> options, op);
+ inpacket -> options, lease, op);
if (ds.len >= sizeof (u_int16_t))
mms = getUShort (ds.data);
data_string_forget (&ds, "cons_options");
@@ -363,6 +364,7 @@ int cons_options (inpacket, outpacket,
(main_buffer_size - 7 +
((overload & 1) ? DHCP_FILE_LEN : 0) +
((overload & 2) ? DHCP_SNAME_LEN : 0)),
+ lease,
options,
priority_list, priority_len,
main_buffer_size,
@@ -472,10 +474,11 @@ int cons_options (inpacket, outpacket,
/* Store all the requested options into the requested buffer. */
-int store_options (buffer, buflen, options, priority_list, priority_len,
+int store_options (buffer, buflen, lease, options, priority_list, priority_len,
first_cutoff, second_cutoff, terminate)
unsigned char *buffer;
int buflen;
+ struct lease *lease;
struct option_state *options;
int *priority_list;
int priority_len;
@@ -534,7 +537,8 @@ int store_options (buffer, buflen, options, priority_list, priority_len,
}
/* Find the value of the option... */
- evaluate_option_cache (&od, (struct packet *)0, options, oc);
+ evaluate_option_cache (&od, (struct packet *)0,
+ options, lease, oc);
if (!od.len) {
continue;
}
@@ -805,7 +809,8 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
DHO_DHCP_MESSAGE_TYPE))) {
struct data_string dp;
memset (&dp, 0, sizeof dp);
- evaluate_option_cache (&dp, &tp, tp.options, op);
+ evaluate_option_cache (&dp, &tp, tp.options,
+ (struct lease *)0, op);
if (dp.len > 0)
tp.packet_type = dp.data [0];
else
@@ -821,9 +826,11 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
option_state_dereference (&tp.options, "do_packet");
}
-int hashed_option_get (result, universe, options, code)
+int hashed_option_get (result, universe, packet, lease, options, code)
struct data_string *result;
struct universe *universe;
+ struct packet *packet;
+ struct lease *lease;
struct option_state *options;
int code;
{
@@ -834,14 +841,17 @@ int hashed_option_get (result, universe, options, code)
oc = ((*universe -> lookup_func) (universe, options, code));
if (!oc)
return 0;
- if (!evaluate_option_cache (result, (struct packet *)0, options, oc))
+ if (!evaluate_option_cache (result, packet,
+ options, lease, oc))
return 0;
return 1;
}
-int agent_option_get (result, universe, options, code)
+int agent_option_get (result, universe, packet, lease, options, code)
struct data_string *result;
struct universe *universe;
+ struct packet *packet;
+ struct lease *lease;
struct option_state *options;
int code;
{
@@ -1204,9 +1214,10 @@ int agent_option_state_dereference (universe, state)
return 1;
}
-int store_option (result, universe, oc)
+int store_option (result, universe, lease, oc)
struct data_string *result;
struct universe *universe;
+ struct lease *lease;
struct option_cache *oc;
{
struct data_string d1, d2;
@@ -1215,7 +1226,7 @@ int store_option (result, universe, oc)
memset (&d2, 0, sizeof d2);
if (evaluate_option_cache (&d2, (struct packet *)0,
- (struct option_state *)0, oc)) {
+ (struct option_state *)0, lease, oc)) {
if (!buffer_allocate (&d1.buffer,
(result -> len +
universe -> length_size +
@@ -1245,9 +1256,10 @@ int store_option (result, universe, oc)
return 0;
}
-int option_space_encapsulate (result, options, name)
+int option_space_encapsulate (result, options, lease, name)
struct data_string *result;
struct option_state *options;
+ struct lease *lease;
struct data_string *name;
{
struct universe *u;
@@ -1260,15 +1272,16 @@ int option_space_encapsulate (result, options, name)
}
if (u -> encapsulate)
- return (*u -> encapsulate) (result, options, u);
+ return (*u -> encapsulate) (result, options, lease, u);
log_error ("encapsulation requested for %s with no support.",
name -> data);
return 0;
}
-int hashed_option_space_encapsulate (result, options, universe)
+int hashed_option_space_encapsulate (result, options, lease, universe)
struct data_string *result;
struct option_state *options;
+ struct lease *lease;
struct universe *universe;
{
pair p, *hash;
@@ -1285,7 +1298,7 @@ int hashed_option_space_encapsulate (result, options, universe)
status = 0;
for (i = 0; i < OPTION_HASH_SIZE; i++) {
for (p = hash [i]; p; p = p -> cdr) {
- if (store_option (result, universe,
+ if (store_option (result, universe, lease,
(struct option_cache *)p -> car))
status = 1;
}
diff --git a/common/parse.c b/common/parse.c
index ab44c8f9..19ae0d7e 100644
--- a/common/parse.c
+++ b/common/parse.c
@@ -22,7 +22,7 @@
#ifndef lint
static char copyright[] =
-"$Id: parse.c,v 1.25 1999/07/01 18:53:46 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: parse.c,v 1.26 1999/07/02 20:57:25 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -1676,6 +1676,76 @@ int parse_non_binary (expr, cfile, lose, context)
goto norparen;
break;
+ case BINARY_TO_ASCII:
+ token = next_token (&val, cfile);
+ if (!expression_allocate (expr, "parse_expression: B2A"))
+ log_fatal ("can't allocate expression");
+ (*expr) -> op = expr_concat;
+
+ token = next_token (&val, cfile);
+ if (token != LPAREN)
+ goto nolparen;
+
+ if (!parse_numeric_expression (&(*expr) -> data.b2a.base,
+ cfile, lose))
+ goto nodata;
+
+ token = next_token (&val, cfile);
+ if (token != COMMA)
+ goto nocomma;
+
+ if (!parse_numeric_expression (&(*expr) -> data.b2a.width,
+ cfile, lose))
+ goto nodata;
+
+ token = next_token (&val, cfile);
+ if (token != COMMA)
+ goto nocomma;
+
+ if (!parse_data_expression (&(*expr) -> data.b2a.seperator,
+ cfile, lose))
+ goto nodata;
+
+ token = next_token (&val, cfile);
+ if (token != COMMA)
+ goto nocomma;
+
+ if (!parse_data_expression (&(*expr) -> data.b2a.buffer,
+ cfile, lose))
+ goto nodata;
+
+ token = next_token (&val, cfile);
+ if (token != RPAREN)
+ goto norparen;
+ break;
+
+ case REVERSE:
+ token = next_token (&val, cfile);
+ if (!expression_allocate (expr, "parse_expression: REVERSE"))
+ log_fatal ("can't allocate expression");
+ (*expr) -> op = expr_concat;
+
+ token = next_token (&val, cfile);
+ if (token != LPAREN)
+ goto nolparen;
+
+ if (!(parse_numeric_expression
+ (&(*expr) -> data.reverse.width, cfile, lose)))
+ goto nodata;
+
+ token = next_token (&val, cfile);
+ if (token != COMMA)
+ goto nocomma;
+
+ if (!(parse_data_expression
+ (&(*expr) -> data.reverse.buffer, cfile, lose)))
+ goto nodata;
+
+ token = next_token (&val, cfile);
+ if (token != RPAREN)
+ goto norparen;
+ break;
+
case OPTION:
token = next_token (&val, cfile);
if (!expression_allocate (expr, "parse_expression: OPTION"))
@@ -1697,6 +1767,14 @@ int parse_non_binary (expr, cfile, lose, context)
(*expr) -> op = expr_hardware;
break;
+ case LEASED_ADDRESS:
+ token = next_token (&val, cfile);
+ if (!expression_allocate (expr,
+ "parse_expression: LEASED_ADDRESS"))
+ log_fatal ("can't allocate expression");
+ (*expr) -> op = expr_leased_address;
+ break;
+
case PACKET:
token = next_token (&val, cfile);
if (!expression_allocate (expr, "parse_expression: PACKET"))
diff --git a/common/tree.c b/common/tree.c
index ae6a2841..618ea803 100644
--- a/common/tree.c
+++ b/common/tree.c
@@ -22,7 +22,7 @@
#ifndef lint
static char copyright[] =
-"$Id: tree.c,v 1.29 1999/05/27 14:30:00 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
+"$Id: tree.c,v 1.30 1999/07/02 20:57:26 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -378,10 +378,11 @@ int do_host_lookup (result, dns)
return 1;
}
-int evaluate_boolean_expression (result, packet, options, expr)
+int evaluate_boolean_expression (result, packet, options, lease, expr)
int *result;
struct packet *packet;
struct option_state *options;
+ struct lease *lease;
struct expression *expr;
{
struct data_string left, right;
@@ -390,7 +391,8 @@ int evaluate_boolean_expression (result, packet, options, expr)
switch (expr -> op) {
case expr_check:
- *result = check_collection (packet, expr -> data.check);
+ *result = check_collection (packet, lease,
+ expr -> data.check);
#if defined (DEBUG_EXPRESSIONS)
log_info ("bool: check (%s) returns %s",
expr -> data.check -> name, *result ? "true" : "false");
@@ -400,9 +402,11 @@ int evaluate_boolean_expression (result, packet, options, expr)
case expr_equal:
memset (&left, 0, sizeof left);
sleft = evaluate_data_expression (&left, packet, options,
+ lease,
expr -> data.equal [0]);
memset (&right, 0, sizeof right);
sright = evaluate_data_expression (&right, packet, options,
+ lease,
expr -> data.equal [1]);
if (sleft && sright) {
if (left.len == right.len &&
@@ -431,8 +435,10 @@ int evaluate_boolean_expression (result, packet, options, expr)
case expr_and:
sleft = evaluate_boolean_expression (&bleft, packet, options,
+ lease,
expr -> data.and [0]);
sright = evaluate_boolean_expression (&bright, packet, options,
+ lease,
expr -> data.and [1]);
#if defined (DEBUG_EXPRESSIONS)
@@ -450,8 +456,10 @@ int evaluate_boolean_expression (result, packet, options, expr)
case expr_or:
sleft = evaluate_boolean_expression (&bleft, packet, options,
+ lease,
expr -> data.or [0]);
sright = evaluate_boolean_expression (&bright, packet, options,
+ lease,
expr -> data.or [1]);
#if defined (DEBUG_EXPRESSIONS)
log_info ("bool: or (%s, %s) = %s",
@@ -468,6 +476,7 @@ int evaluate_boolean_expression (result, packet, options, expr)
case expr_not:
sleft = evaluate_boolean_expression (&bleft, packet, options,
+ lease,
expr -> data.not);
#if defined (DEBUG_EXPRESSIONS)
log_info ("bool: not (%s) = %s",
@@ -487,7 +496,7 @@ int evaluate_boolean_expression (result, packet, options, expr)
if (!options ||
!((*expr -> data.option -> universe -> get_func)
(&left, expr -> data.exists -> universe,
- options, expr -> data.exists -> code)))
+ packet, lease, options, expr -> data.exists -> code)))
*result = 0;
else {
*result = 1;
@@ -527,6 +536,9 @@ int evaluate_boolean_expression (result, packet, options, expr)
case expr_encode_int8:
case expr_encode_int16:
case expr_encode_int32:
+ case expr_binary_to_ascii:
+ case expr_reverse:
+ case expr_leased_address:
log_error ("Data opcode in evaluate_boolean_expression: %d",
expr -> op);
return 0;
@@ -545,28 +557,31 @@ int evaluate_boolean_expression (result, packet, options, expr)
return 0;
}
-int evaluate_data_expression (result, packet, options, expr)
+int evaluate_data_expression (result, packet, options, lease, expr)
struct data_string *result;
struct packet *packet;
struct option_state *options;
+ struct lease *lease;
struct expression *expr;
{
struct data_string data, other;
unsigned long offset, len;
int s0, s1, s2, s3;
+ int status;
switch (expr -> op) {
/* Extract N bytes starting at byte M of a data string. */
case expr_substring:
memset (&data, 0, sizeof data);
s0 = evaluate_data_expression (&data, packet, options,
+ lease,
expr -> data.substring.expr);
/* Evaluate the offset and length. */
s1 = evaluate_numeric_expression
- (&offset,
- packet, options, expr -> data.substring.offset);
- s2 = evaluate_numeric_expression (&len, packet, options,
+ (&offset, packet, options, lease,
+ expr -> data.substring.offset);
+ s2 = evaluate_numeric_expression (&len, packet, options, lease,
expr -> data.substring.len);
if (s0 && s1 && s2) {
@@ -604,10 +619,10 @@ int evaluate_data_expression (result, packet, options, expr)
/* Extract the last N bytes of a data string. */
case expr_suffix:
memset (&data, 0, sizeof data);
- s0 = evaluate_data_expression (&data, packet, options,
+ s0 = evaluate_data_expression (&data, packet, options, lease,
expr -> data.suffix.expr);
/* Evaluate the length. */
- s1 = evaluate_numeric_expression (&len, packet, options,
+ s1 = evaluate_numeric_expression (&len, packet, options, lease,
expr -> data.substring.len);
if (s0 && s1) {
data_string_copy (result, &data,
@@ -639,7 +654,8 @@ int evaluate_data_expression (result, packet, options, expr)
if (options)
s0 = ((*expr -> data.option -> universe -> get_func)
(result, expr -> data.option -> universe,
- options, expr -> data.option -> code));
+ packet, lease, options,
+ expr -> data.option -> code));
else
s0 = 0;
@@ -688,9 +704,10 @@ int evaluate_data_expression (result, packet, options, expr)
return 0;
}
- s0 = evaluate_numeric_expression (&len, packet, options,
+ s0 = evaluate_numeric_expression (&len, packet, options, lease,
expr -> data.packet.len);
- s1 = evaluate_numeric_expression (&offset, packet, options,
+ s1 = evaluate_numeric_expression (&offset,
+ packet, options, lease,
expr -> data.packet.len);
if (s0 && s1 && offset < packet -> packet_length) {
if (offset + len > packet -> packet_length)
@@ -725,7 +742,8 @@ int evaluate_data_expression (result, packet, options, expr)
case expr_encapsulate:
if (options)
s0 = option_space_encapsulate
- (result, options, &expr -> data.encapsulate);
+ (result, options, lease,
+ &expr -> data.encapsulate);
else
s0 = 0;
@@ -764,10 +782,10 @@ int evaluate_data_expression (result, packet, options, expr)
/* Concatenation... */
case expr_concat:
memset (&data, 0, sizeof data);
- s0 = evaluate_data_expression (&data, packet, options,
+ s0 = evaluate_data_expression (&data, packet, options, lease,
expr -> data.concat [0]);
memset (&other, 0, sizeof other);
- s1 = evaluate_data_expression (&other, packet, options,
+ s1 = evaluate_data_expression (&other, packet, options, lease,
expr -> data.concat [1]);
if (s0 && s1) {
@@ -801,7 +819,7 @@ int evaluate_data_expression (result, packet, options, expr)
return s0 || s1;
case expr_encode_int8:
- s0 = evaluate_numeric_expression (&len, packet, options,
+ s0 = evaluate_numeric_expression (&len, packet, options, lease,
expr -> data.packet.len);
if (s0) {
result -> len = 1;
@@ -829,7 +847,7 @@ int evaluate_data_expression (result, packet, options, expr)
case expr_encode_int16:
- s0 = evaluate_numeric_expression (&len, packet, options,
+ s0 = evaluate_numeric_expression (&len, packet, options, lease,
expr -> data.packet.len);
if (s0) {
result -> len = 2;
@@ -856,7 +874,7 @@ int evaluate_data_expression (result, packet, options, expr)
return s0;
case expr_encode_int32:
- s0 = evaluate_numeric_expression (&len, packet, options,
+ s0 = evaluate_numeric_expression (&len, packet, options, lease,
expr -> data.packet.len);
if (s0) {
result -> len = 4;
@@ -882,6 +900,212 @@ int evaluate_data_expression (result, packet, options, expr)
#endif
return s0;
+ case expr_binary_to_ascii:
+ /* Evaluate the base (offset) and width (len): */
+ s0 = evaluate_numeric_expression
+ (&offset, packet, options, lease,
+ expr -> data.substring.offset);
+ s1 = evaluate_numeric_expression (&len, packet, options, lease,
+ expr -> data.substring.len);
+
+ /* Evaluate the seperator string. */
+ memset (&data, 0, sizeof data);
+ s2 = evaluate_data_expression (&data, packet, options, lease,
+ expr -> data.b2a.seperator);
+
+ /* Evaluate the data to be converted. */
+ memset (&other, 0, sizeof other);
+ s3 = evaluate_data_expression (&data, packet, options, lease,
+ expr -> data.b2a.buffer);
+
+ if (s0 && s1 && s2 && s3) {
+ int buflen, i;
+
+ if (len != 8 && len != 16 && len != 32) {
+ log_info ("binary_to_ascii: %s %d!",
+ "invalid width", len);
+ goto b2a_out;
+ }
+ len /= 8;
+
+ /* The buffer must be a multiple of the number's
+ width. */
+ if (other.len % len) {
+ log_info ("binary-to-ascii: %s %d %s %d!",
+ "length of buffer", other.len,
+ "not a multiple of width", len);
+ status = 0;
+ goto b2a_out;
+ }
+
+ /* Count the width of the output. */
+ buflen = 0;
+ for (i = 0; i < other.len; i += len) {
+ if (len == 1) {
+ if (offset == 8) {
+ if (other.data [i] < 8)
+ buflen++;
+ else if (other.data [i] < 64)
+ buflen += 2;
+ else
+ buflen += 3;
+ } else if (offset == 10) {
+ if (other.data [i] < 10)
+ buflen++;
+ else if (other.data [i] < 100)
+ buflen += 2;
+ else
+ buflen += 3;
+ } else if (offset == 10) {
+ if (other.data [i] < 16)
+ buflen++;
+ else
+ buflen += 2;
+ } else
+ buflen += (converted_length
+ (&other.data [i],
+ offset, 1));
+ } else
+ buflen += (converted_length
+ (&other.data [i],
+ offset, len));
+ if (i + len != other.len)
+ buflen += data.len;
+ }
+
+ if (!buffer_allocate (&result -> buffer, buflen + 1,
+ "binary-to-ascii")) {
+ log_error ("data: binary-to-ascii: no memory");
+ status = 0;
+ goto b2a_out;
+ }
+ result -> data = &result -> buffer -> data [0];
+ result -> len = buflen;
+ result -> terminated = 1;
+
+ buflen = 0;
+ for (i = 0; i < other.len; i += len) {
+ buflen += (binary_to_ascii
+ (&result -> data [buflen],
+ &other.data [i], offset, len));
+ if (i + len != other.len) {
+ memcpy (&result -> data [buflen],
+ data.data, data.len);
+ buflen += data.len;
+ }
+ }
+ /* NUL terminate. */
+ result -> data [buflen] = 0;
+ status = 1;
+ } else
+ status = 0;
+
+ b2a_out:
+#if defined (DEBUG_EXPRESSIONS)
+ log_info ("data: binary-to-ascii (%s, %s, %s, %s) = %s",
+ s0 ? print_dec_1 (offset) : "NULL",
+ s1 ? print_dec_2 (len) : "NULL",
+ s2 ? print_hex_1 (data.len, data.data, 30) : "NULL",
+ s3 ? print_hex_2 (other.len, other.data, 30) : "NULL",
+ (status ? print_hex_3 (result -> len, result -> data, 30)
+ : "NULL"));
+#endif
+ if (s2)
+ data_string_forget (&data, "binary-to-ascii");
+ if (s3)
+ data_string_forget (&other, "binary-to-ascii");
+ if (status)
+ return 1;
+ return 0;
+
+ case expr_reverse:
+ /* Evaluate the width (len): */
+ s0 = evaluate_numeric_expression
+ (&len, packet, options, lease,
+ expr -> data.substring.offset);
+
+ /* Evaluate the data. */
+ memset (&data, 0, sizeof data);
+ s1 = evaluate_data_expression (&data, packet, options, lease,
+ expr -> data.b2a.seperator);
+
+ if (len != 8 && len != 16 && len != 32) {
+ log_info ("reverse: invalid width %d!", len);
+ goto b2a_out;
+ }
+ len /= 8;
+
+ if (s0 && s1) {
+ char *upper;
+ int i;
+
+ /* The buffer must be a multiple of the number's
+ width. */
+ if (other.len % len) {
+ log_info ("binary-to-ascii: %s %d %s %d!",
+ "length of buffer", other.len,
+ "not a multiple of width", len);
+ status = 0;
+ goto reverse_out;
+ }
+
+ /* XXX reverse in place? I don't think we can. */
+ if (!buffer_allocate (&result -> buffer, data.len,
+ "reverse")) {
+ log_error ("data: reverse: no memory");
+ status = 0;
+ goto reverse_out;
+ }
+ result -> data = &result -> buffer -> data [0];
+ result -> len = data.len;
+ result -> terminated = 0;
+
+ for (i = 0; i < data.len; i += len) {
+ memcpy (&result -> data [i],
+ &data.data [data.len - i - len], len);
+ }
+ status = 1;
+ } else
+ status = 0;
+
+ reverse_out:
+#if defined (DEBUG_EXPRESSIONS)
+ log_info ("data: reverse (%s, %s) = %s",
+ s0 ? print_dec_1 (offset) : "NULL",
+ s1 ? print_hex_1 (data.len, data.data, 30) : "NULL",
+ (status ? print_hex_3 (result -> len, result -> data, 30)
+ : "NULL"));
+#endif
+ if (s0)
+ data_string_forget (&data, "evaluate_data_expression");
+ if (status)
+ return 1;
+ return 0;
+
+ case expr_leased_address:
+ if (!lease) {
+ log_error ("data: leased_address: not available");
+ return 0;
+ }
+ result -> len = lease -> ip_addr.len;
+ if (buffer_allocate (&result -> buffer, result -> len,
+ "leased-address")) {
+ result -> data = &result -> buffer -> data [0];
+ memcpy (&result -> data [0],
+ lease -> ip_addr.iabuf, lease -> ip_addr.len);
+ result -> terminated = 0;
+ } else {
+ log_error ("data: leased-address: no memory.");
+ return 0;
+ }
+#if defined (DEBUG_EXPRESSIONS)
+ log_info ("data: leased-address = %s",
+ print_hex_1 (result -> len, result -> data, 60));
+#endif
+ return 1;
+
+
+
case expr_check:
case expr_equal:
case expr_and:
@@ -906,10 +1130,11 @@ int evaluate_data_expression (result, packet, options, expr)
return 0;
}
-int evaluate_numeric_expression (result, packet, options, expr)
+int evaluate_numeric_expression (result, packet, options, lease, expr)
unsigned long *result;
struct packet *packet;
struct option_state *options;
+ struct lease *lease;
struct expression *expr;
{
struct data_string data;
@@ -939,6 +1164,9 @@ int evaluate_numeric_expression (result, packet, options, expr)
case expr_encode_int8:
case expr_encode_int16:
case expr_encode_int32:
+ case expr_binary_to_ascii:
+ case expr_reverse:
+ case expr_leased_address:
log_error ("Data opcode in evaluate_numeric_expression: %d",
expr -> op);
return 0;
@@ -947,7 +1175,7 @@ int evaluate_numeric_expression (result, packet, options, expr)
memset (&data, 0, sizeof data);
status = evaluate_data_expression
(&data, packet,
- options, expr -> data.extract_int);
+ options, lease, expr -> data.extract_int);
if (status)
*result = data.data [0];
#if defined (DEBUG_EXPRESSIONS)
@@ -962,7 +1190,7 @@ int evaluate_numeric_expression (result, packet, options, expr)
case expr_extract_int16:
memset (&data, 0, sizeof data);
status = (evaluate_data_expression
- (&data, packet, options,
+ (&data, packet, options, lease,
expr -> data.extract_int));
if (status && data.len >= 2)
*result = getUShort (data.data);
@@ -979,7 +1207,7 @@ int evaluate_numeric_expression (result, packet, options, expr)
case expr_extract_int32:
memset (&data, 0, sizeof data);
status = (evaluate_data_expression
- (&data, packet, options,
+ (&data, packet, options, lease,
expr -> data.extract_int));
if (status && data.len >= 4)
*result = getULong (data.data);
@@ -1007,10 +1235,11 @@ int evaluate_numeric_expression (result, packet, options, expr)
result of that evaluation. There should never be both an expression
and a valid data_string. */
-int evaluate_option_cache (result, packet, options, oc)
+int evaluate_option_cache (result, packet, options, lease, oc)
struct data_string *result;
struct packet *packet;
struct option_state *options;
+ struct lease *lease;
struct option_cache *oc;
{
if (oc -> data.len) {
@@ -1020,16 +1249,17 @@ int evaluate_option_cache (result, packet, options, oc)
}
if (!oc -> expression)
return 0;
- return evaluate_data_expression (result,
- packet, options, oc -> expression);
+ return evaluate_data_expression (result, packet, options, lease,
+ oc -> expression);
}
/* Evaluate an option cache and extract a boolean from the result,
returning the boolean. Return false if there is no data. */
-int evaluate_boolean_option_cache (packet, options, oc)
+int evaluate_boolean_option_cache (packet, options, lease, oc)
struct packet *packet;
struct option_state *options;
+ struct lease *lease;
struct option_cache *oc;
{
struct data_string ds;
@@ -1040,7 +1270,7 @@ int evaluate_boolean_option_cache (packet, options, oc)
return 0;
memset (&ds, 0, sizeof ds);
- if (!evaluate_option_cache (&ds, packet, options, oc))
+ if (!evaluate_option_cache (&ds, packet, options, lease, oc))
return 0;
if (ds.len && ds.data [0])
@@ -1055,9 +1285,10 @@ int evaluate_boolean_option_cache (packet, options, oc)
/* Evaluate a boolean expression and return the result of the evaluation,
or FALSE if it failed. */
-int evaluate_boolean_expression_result (packet, options, expr)
+int evaluate_boolean_expression_result (packet, options, lease, expr)
struct packet *packet;
struct option_state *options;
+ struct lease *lease;
struct expression *expr;
{
int result;
@@ -1066,7 +1297,8 @@ int evaluate_boolean_expression_result (packet, options, expr)
if (!expr)
return 0;
- if (!evaluate_boolean_expression (&result, packet, options, expr))
+ if (!evaluate_boolean_expression (&result,
+ packet, options, lease, expr))
return 0;
return result;
@@ -1172,7 +1404,30 @@ void expression_dereference (eptr, name)
name);
break;
+ case expr_binary_to_ascii:
+ if (expr -> data.b2a.base)
+ expression_dereference (&expr -> data.b2a.base, name);
+ if (expr -> data.b2a.width)
+ expression_dereference (&expr -> data.b2a.width, name);
+ if (expr -> data.b2a.seperator)
+ expression_dereference (&expr -> data.b2a.seperator,
+ name);
+ if (expr -> data.b2a.buffer)
+ expression_dereference (&expr -> data.b2a.buffer,
+ name);
+ break;
+
+ case expr_reverse:
+ if (expr -> data.reverse.width)
+ expression_dereference (&expr -> data.reverse.width,
+ name);
+ if (expr -> data.reverse.buffer)
+ expression_dereference
+ (&expr -> data.reverse.buffer, name);
+ break;
+
/* No subexpressions. */
+ case expr_leased_address:
case expr_const_int:
case expr_check:
case expr_option:
@@ -1253,7 +1508,10 @@ int is_data_expression (expr)
expr -> op == expr_encode_int8 ||
expr -> op == expr_encode_int16 ||
expr -> op == expr_encode_int32 ||
- expr -> op == expr_host_lookup);
+ expr -> op == expr_host_lookup ||
+ expr -> op == expr_binary_to_ascii ||
+ expr -> op == expr_reverse ||
+ expr -> op == expr_leased_address);
}
int is_numeric_expression (expr)
@@ -1293,6 +1551,9 @@ static int op_val (op)
case expr_const_int:
case expr_exists:
case expr_known:
+ case expr_binary_to_ascii:
+ case expr_reverse:
+ case expr_leased_address:
return 100;
case expr_equal:
@@ -1319,6 +1580,7 @@ enum expression_context op_context (op)
enum expr_op op;
{
switch (op) {
+/* XXX Why aren't these specific? */
case expr_none:
case expr_match:
case expr_check:
@@ -1341,6 +1603,9 @@ enum expression_context op_context (op)
case expr_const_int:
case expr_exists:
case expr_known:
+ case expr_binary_to_ascii:
+ case expr_reverse:
+ case expr_leased_address:
return context_any;
case expr_equal:
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index 741b80f8..ebb19ccb 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -773,20 +773,23 @@ typedef unsigned char option_mask [16];
int parse_options PROTO ((struct packet *));
int parse_option_buffer PROTO ((struct packet *, unsigned char *, int));
int parse_agent_information_option PROTO ((struct packet *, int, u_int8_t *));
-int cons_options PROTO ((struct packet *, struct dhcp_packet *, int,
- struct option_state *,
+int cons_options PROTO ((struct packet *, struct dhcp_packet *, struct lease *,
+ int, struct option_state *,
int, int, int, struct data_string *));
-int store_options PROTO ((unsigned char *, int, struct option_state *,
- int *, int, int, int, int));
+int store_options PROTO ((unsigned char *, int,
+ struct lease *, struct option_state *,
+ int *, int, int, int, int));
char *pretty_print_option PROTO ((unsigned int,
unsigned char *, int, int, int));
void do_packet PROTO ((struct interface_info *,
struct dhcp_packet *, int,
unsigned int, struct iaddr, struct hardware *));
-int hashed_option_get PROTO ((struct data_string *,
- struct universe *, struct option_state *, int));
+int hashed_option_get PROTO ((struct data_string *, struct universe *,
+ struct packet *, struct lease *,
+ struct option_state *, int));
int agent_option_get PROTO ((struct data_string *, struct universe *,
- struct option_state *, int));
+ struct packet *, struct lease *,
+ struct option_state *, int));
void hashed_option_set PROTO ((struct universe *, struct option_state *,
struct option_cache *,
enum statement_op));
@@ -807,15 +810,19 @@ int hashed_option_state_dereference PROTO ((struct universe *,
int agent_option_state_dereference PROTO ((struct universe *,
struct option_state *));
int store_option PROTO ((struct data_string *,
- struct universe *, struct option_cache *));
+ struct universe *, struct lease *,
+ struct option_cache *));
int option_space_encapsulate PROTO ((struct data_string *,
struct option_state *,
+ struct lease *,
struct data_string *));
int hashed_option_space_encapsulate PROTO ((struct data_string *,
struct option_state *,
+ struct lease *,
struct universe *));
int agent_option_space_encapsulate PROTO ((struct data_string *,
struct option_state *,
+ struct lease *,
struct universe *));
/* errwarn.c */
@@ -934,22 +941,27 @@ int option_cache PROTO ((struct option_cache **, struct data_string *,
struct expression *, struct option *));
int evaluate_boolean_expression PROTO ((int *,
struct packet *, struct option_state *,
+ struct lease *,
struct expression *));
int evaluate_data_expression PROTO ((struct data_string *,
struct packet *, struct option_state *,
+ struct lease *,
struct expression *));
int evaluate_numeric_expression PROTO
((unsigned long *, struct packet *,
- struct option_state *, struct expression *));
+ struct option_state *, struct lease *, struct expression *));
int evaluate_option_cache PROTO ((struct data_string *,
struct packet *,
struct option_state *,
+ struct lease *,
struct option_cache *));
int evaluate_boolean_option_cache PROTO ((struct packet *,
struct option_state *,
+ struct lease *,
struct option_cache *));
int evaluate_boolean_expression_result PROTO ((struct packet *,
struct option_state *,
+ struct lease *,
struct expression *));
void expression_dereference PROTO ((struct expression **, char *));
void data_string_copy PROTO ((struct data_string *,
@@ -1302,6 +1314,9 @@ void putLong PROTO ((unsigned char *, int32_t));
void putUShort PROTO ((unsigned char *, u_int32_t));
void putShort PROTO ((unsigned char *, int32_t));
void putUChar PROTO ((unsigned char *, u_int32_t));
+int converted_length PROTO ((unsigned char *, unsigned int, unsigned int));
+int binary_to_ascii PROTO ((unsigned char *, unsigned char *,
+ unsigned int, unsigned int));
/* inet.c */
struct iaddr subnet_number PROTO ((struct iaddr, struct iaddr));
@@ -1511,7 +1526,8 @@ struct executable_statement *default_classification_rules;
void classification_setup PROTO ((void));
void classify_client PROTO ((struct packet *));
-int check_collection PROTO ((struct packet *, struct collection *));
+int check_collection PROTO ((struct packet *, struct lease *,
+ struct collection *));
void classify PROTO ((struct packet *, struct class *));
struct class *find_class PROTO ((char *));
int unbill_class PROTO ((struct lease *, struct class *));
@@ -1519,9 +1535,11 @@ int bill_class PROTO ((struct lease *, struct class *));
/* execute.c */
int execute_statements PROTO ((struct packet *,
+ struct lease *,
struct option_state *, struct option_state *,
struct executable_statement *));
void execute_statements_in_scope PROTO ((struct packet *,
+ struct lease *,
struct option_state *,
struct option_state *,
struct group *, struct group *));
diff --git a/includes/dhctoken.h b/includes/dhctoken.h
index b9892497..0dcf2b65 100644
--- a/includes/dhctoken.h
+++ b/includes/dhctoken.h
@@ -179,6 +179,9 @@ enum dhcp_token {
ENCODE_INT = 399,
DDNS_FWD_NAME = 400,
DDNS_REV_NAME = 401,
+ REVERSE = 402,
+ LEASED_ADDRESS = 403,
+ BINARY_TO_ASCII = 404,
};
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
diff --git a/includes/tree.h b/includes/tree.h
index f8589f97..5a44e1f3 100644
--- a/includes/tree.h
+++ b/includes/tree.h
@@ -83,6 +83,9 @@ enum expr_op {
expr_exists,
expr_encapsulate,
expr_known,
+ expr_reverse,
+ expr_leased_address,
+ expr_binary_to_ascii,
};
struct expression {
@@ -116,6 +119,16 @@ struct expression {
struct dns_host_entry *host_lookup;
struct option *exists;
struct data_string encapsulate;
+ struct {
+ struct expression *base;
+ struct expression *width;
+ struct expression *seperator;
+ struct expression *buffer;
+ } b2a;
+ struct {
+ struct expression *width;
+ struct expression *buffer;
+ } reverse;
} data;
int flags;
# define EXPR_EPHEMERAL 1
@@ -134,6 +147,7 @@ struct data_string; /* forward */
struct packet; /* forward */
struct option_state; /* forward */
struct decoded_option_state; /* forward */
+struct lease; /* forward */
struct universe {
char *name;
@@ -143,6 +157,7 @@ struct universe {
void (*save_func) PROTO ((struct universe *, struct option_state *,
struct option_cache *));
int (*get_func) PROTO ((struct data_string *, struct universe *,
+ struct packet *, struct lease *,
struct option_state *, int));
void (*set_func) PROTO ((struct universe *, struct option_state *,
struct option_cache *, enum statement_op));
@@ -152,7 +167,7 @@ struct universe {
int (*option_state_dereference) PROTO ((struct universe *,
struct option_state *));
int (*encapsulate) PROTO ((struct data_string *, struct option_state *,
- struct universe *));
+ struct lease *, struct universe *));
void (*store_tag) PROTO ((unsigned char *, u_int32_t));
void (*store_length) PROTO ((unsigned char *, u_int32_t));
int tag_size, length_size;
diff --git a/server/bootp.c b/server/bootp.c
index 18612cc0..5bb62968 100644
--- a/server/bootp.c
+++ b/server/bootp.c
@@ -22,7 +22,7 @@
#ifndef lint
static char copyright[] =
-"$Id: bootp.c,v 1.49 1999/07/01 20:02:58 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: bootp.c,v 1.50 1999/07/02 20:58:48 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -117,24 +117,24 @@ void bootp (packet)
option_state_allocate (&options, "bootrequest");
/* Execute the subnet statements. */
- execute_statements_in_scope (packet, packet -> options, options,
+ execute_statements_in_scope (packet, lease, packet -> options, options,
lease -> subnet -> group,
(struct group *)0);
/* Execute statements from class scopes. */
for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope
- (packet, packet -> options, options,
+ (packet, lease, packet -> options, options,
packet -> classes [i - 1] -> group,
lease -> subnet -> group);
}
/* Execute the host statements. */
- execute_statements_in_scope (packet, packet -> options, options,
+ execute_statements_in_scope (packet, lease, packet -> options, options,
hp -> group, subnet -> group);
/* Drop the request if it's not allowed for this client. */
- if (evaluate_boolean_option_cache (packet, options,
+ if (evaluate_boolean_option_cache (packet, options, lease,
lookup_option (&server_universe,
options,
SV_ALLOW_BOOTP))) {
@@ -143,7 +143,7 @@ void bootp (packet)
return;
}
- if (evaluate_boolean_option_cache (packet, options,
+ if (evaluate_boolean_option_cache (packet, options, lease,
lookup_option (&server_universe,
options,
SV_ALLOW_BOOTING))) {
@@ -161,7 +161,7 @@ void bootp (packet)
just copy the input options to the output. */
if (!packet -> options_valid &&
!(evaluate_boolean_option_cache
- (packet, options,
+ (packet, options, lease,
lookup_option (&server_universe, options,
SV_ALWAYS_REPLY_RFC1048)))) {
memcpy (outgoing.raw -> options,
@@ -194,7 +194,7 @@ void bootp (packet)
name buffers. */
outgoing.packet_length =
- cons_options (packet, outgoing.raw, 0, options,
+ cons_options (packet, outgoing.raw, lease, 0, options,
0, 0, 1, (struct data_string *)0);
if (outgoing.packet_length < BOOTP_MIN_LEN)
outgoing.packet_length = BOOTP_MIN_LEN;
@@ -216,14 +216,15 @@ void bootp (packet)
the broadcast bit in the bootp flags field. */
if ((oc = lookup_option (&server_universe,
options, SV_ALWAYS_BROADCAST)) &&
- evaluate_boolean_option_cache (packet, packet -> options, oc))
+ evaluate_boolean_option_cache (packet, packet -> options,
+ lease, oc))
raw.flags |= htons (BOOTP_BROADCAST);
/* Figure out the address of the next server. */
memset (&d1, 0, sizeof d1);
oc = lookup_option (&server_universe, options, SV_NEXT_SERVER);
if (oc &&
- evaluate_option_cache (&d1, packet, options, oc)) {
+ evaluate_option_cache (&d1, packet, options, lease, oc)) {
/* If there was more than one answer, take the first. */
if (d1.len >= 4 && d1.data)
memcpy (&raw.siaddr, d1.data, 4);
@@ -241,7 +242,7 @@ void bootp (packet)
/* Figure out the filename. */
oc = lookup_option (&server_universe, options, SV_FILENAME);
if (oc &&
- evaluate_option_cache (&d1, packet, options, oc)) {
+ evaluate_option_cache (&d1, packet, options, lease, oc)) {
memcpy (raw.file, d1.data,
d1.len > sizeof raw.file ? sizeof raw.file : d1.len);
if (sizeof raw.file > d1.len)
@@ -254,7 +255,7 @@ void bootp (packet)
/* Choose a server name as above. */
oc = lookup_option (&server_universe, options, SV_SERVER_NAME);
if (oc &&
- evaluate_option_cache (&d1, packet, options, oc)) {
+ evaluate_option_cache (&d1, packet, options, lease, oc)) {
memcpy (raw.sname, d1.data,
d1.len > sizeof raw.sname ? sizeof raw.sname : d1.len);
if (sizeof raw.sname > d1.len)
diff --git a/server/class.c b/server/class.c
index d63de40f..90cdc4d0 100644
--- a/server/class.c
+++ b/server/class.c
@@ -22,7 +22,7 @@
#ifndef lint
static char copyright[] =
-"$Id: class.c,v 1.11 1999/04/05 16:34:33 mellon Exp $ Copyright (c) 1998 The Internet Software Consortium. All rights reserved.\n";
+"$Id: class.c,v 1.12 1999/07/02 20:58:48 mellon Exp $ Copyright (c) 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -70,13 +70,14 @@ void classification_setup ()
void classify_client (packet)
struct packet *packet;
{
- execute_statements (packet, packet -> options,
+ execute_statements (packet, (struct lease *)0, packet -> options,
(struct option_state *)0,
default_classification_rules);
}
-int check_collection (packet, collection)
+int check_collection (packet, lease, collection)
struct packet *packet;
+ struct lease *lease;
struct collection *collection;
{
struct class *class, *nc;
@@ -92,8 +93,10 @@ int check_collection (packet, collection)
/* If a class is for billing, don't put the client in the
class if we've already billed it to a different class. */
if (class -> submatch) {
- status = evaluate_data_expression (&data, packet,
+ status = evaluate_data_expression (&data,
+ packet,
packet -> options,
+ lease,
class -> submatch);
if (status) {
if ((nc = ((struct class *)
@@ -159,7 +162,7 @@ int check_collection (packet, collection)
}
status = (evaluate_boolean_expression_result
- (packet, packet -> options, class -> expr));
+ (packet, packet -> options, lease, class -> expr));
if (status) {
matched = 1;
#if defined (DEBUG_CLASS_MATCHING)
diff --git a/server/dhcp.c b/server/dhcp.c
index 466490a7..f0a0bb29 100644
--- a/server/dhcp.c
+++ b/server/dhcp.c
@@ -22,7 +22,7 @@
#ifndef lint
static char copyright[] =
-"$Id: dhcp.c,v 1.97 1999/07/02 17:47:42 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhcp.c,v 1.98 1999/07/02 20:58:48 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -122,7 +122,8 @@ void dhcprequest (packet)
DHO_DHCP_REQUESTED_ADDRESS);
memset (&data, 0, sizeof data);
if (oc &&
- evaluate_option_cache (&data, packet, packet -> options, oc)) {
+ evaluate_option_cache (&data, packet, packet -> options,
+ (struct lease *)0, oc)) {
cip.len = 4;
memcpy (cip.iabuf, data.data, 4);
data_string_forget (&data, "dhcprequest");
@@ -264,7 +265,8 @@ void dhcprelease (packet)
DHO_DHCP_CLIENT_IDENTIFIER);
memset (&data, 0, sizeof data);
if (oc &&
- evaluate_option_cache (&data, packet, packet -> options, oc)) {
+ evaluate_option_cache (&data, packet, packet -> options,
+ (struct lease *)0, oc)) {
lease = find_lease_by_uid (data.data, data.len);
data_string_forget (&data, "dhcprelease");
} else
@@ -312,7 +314,8 @@ void dhcpdecline (packet)
DHO_DHCP_REQUESTED_ADDRESS)))
return;
memset (&data, 0, sizeof data);
- if (!evaluate_option_cache (&data, packet, packet -> options, oc))
+ if (!evaluate_option_cache (&data, packet, packet -> options,
+ (struct lease *)0, oc))
return;
cip.len = 4;
@@ -390,14 +393,15 @@ void dhcpinform (packet)
/* Execute statements in scope starting with the subnet scope. */
if (subnet)
- execute_statements_in_scope (packet, packet -> options,
+ execute_statements_in_scope (packet, (struct lease *)0,
+ packet -> options,
options, subnet -> group,
(struct group *)0);
/* Execute statements in the class scopes. */
for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope
- (packet, packet -> options,
+ (packet, (struct lease *)0, packet -> options,
options, packet -> classes [i - 1] -> group,
subnet ? subnet -> group : (struct group *)0);
}
@@ -405,7 +409,8 @@ void dhcpinform (packet)
/* Figure out the filename. */
memset (&d1, 0, sizeof d1);
oc = lookup_option (&server_universe, options, SV_FILENAME);
- if (oc && evaluate_option_cache (&d1, packet, packet -> options, oc)) {
+ if (oc && evaluate_option_cache (&d1, packet, packet -> options,
+ (struct lease *)0, oc)) {
i = d1.len;
if (i > sizeof raw.file)
i = sizeof raw.file;
@@ -417,7 +422,8 @@ void dhcpinform (packet)
/* Choose a server name as above. */
oc = lookup_option (&server_universe, options, SV_SERVER_NAME);
- if (oc && evaluate_option_cache (&d1, packet, packet -> options, oc)) {
+ if (oc && evaluate_option_cache (&d1, packet, packet -> options,
+ (struct lease *)0, oc)) {
i = d1.len;
if (i > sizeof raw.sname)
i = sizeof raw.sname;
@@ -432,8 +438,8 @@ void dhcpinform (packet)
nulltp = 0;
if ((oc = lookup_option (&dhcp_universe, packet -> options,
DHO_HOST_NAME))) {
- if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ if (evaluate_option_cache (&d1, packet, packet -> options,
+ (struct lease *)0, oc)) {
if (d1.data [d1.len - 1] == '\0')
nulltp = 1;
data_string_forget (&d1, "dhcpinform");
@@ -471,8 +477,8 @@ void dhcpinform (packet)
}
from = packet -> interface -> primary_address;
} else {
- if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ if (evaluate_option_cache (&d1, packet, packet -> options,
+ (struct lease *)0, oc)) {
if (!d1.len || d1.len != sizeof from) {
data_string_forget (&d1, "dhcpinform");
goto use_primary;
@@ -506,7 +512,8 @@ void dhcpinform (packet)
j = SV_VENDOR_OPTION_SPACE;
if (!lookup_option (&dhcp_universe, options, i) &&
(oc = lookup_option (&server_universe, options, j)) &&
- evaluate_option_cache (&d1, packet, packet -> options, oc)) {
+ evaluate_option_cache (&d1, packet, packet -> options,
+ (struct lease *)0, oc)) {
oc = (struct option_cache *)0;
if (option_cache_allocate (&oc, "dhcpinform")) {
if (make_encapsulation (&oc -> expression, &d1)) {
@@ -522,7 +529,8 @@ void dhcpinform (packet)
site option codes. */
i = SV_SITE_OPTION_SPACE;
if ((oc = lookup_option (&server_universe, options, i)) &&
- evaluate_option_cache (&d1, packet, packet -> options, oc)) {
+ evaluate_option_cache (&d1, packet,
+ packet -> options, (struct lease *)0, oc)) {
struct universe *u;
u = ((struct universe *)
@@ -555,7 +563,8 @@ void dhcpinform (packet)
DHO_DHCP_PARAMETER_REQUEST_LIST);
if (oc)
- evaluate_option_cache (&prl, packet, packet -> options, oc);
+ evaluate_option_cache (&prl, packet, packet -> options,
+ (struct lease *)0, oc);
#ifdef DEBUG_PACKET
dump_packet (packet);
@@ -568,8 +577,8 @@ void dhcpinform (packet)
raw.siaddr = from;
if ((oc =
lookup_option (&server_universe, options, SV_NEXT_SERVER))) {
- if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ if (evaluate_option_cache (&d1, packet, packet -> options,
+ (struct lease *)0, oc)) {
/* If there was more than one answer,
take the first. */
if (d1.len >= 4 && d1.data)
@@ -580,8 +589,8 @@ void dhcpinform (packet)
/* Set up the option buffer... */
outgoing.packet_length =
- cons_options (packet, outgoing.raw, 0, options,
- 0, nulltp, 0,
+ cons_options (packet, outgoing.raw, (struct lease *)0,
+ 0, options, 0, nulltp, 0,
prl.len ? &prl : (struct data_string *)0);
option_state_dereference (&options, "dhcpinform");
data_string_forget (&prl, "dhcpinform");
@@ -690,8 +699,8 @@ void nak_lease (packet, cip)
/* Set up the option buffer... */
outgoing.packet_length =
- cons_options (packet, outgoing.raw, 0, options,
- 0, 0, 0,
+ cons_options (packet, outgoing.raw, (struct lease *)0,
+ 0, options, 0, 0, 0,
(struct data_string *)0);
option_state_dereference (&options, "nak_lease");
@@ -810,8 +819,8 @@ void ack_lease (packet, lease, offer, when, msg)
oc = lookup_option (&dhcp_universe, packet -> options, DHO_HOST_NAME);
memset (&d1, 0, sizeof d1);
if (oc)
- s1 = evaluate_option_cache (&d1, packet,
- packet -> options, oc);
+ s1 = evaluate_option_cache (&d1, packet, packet -> options,
+ (struct lease *)0, oc);
if (oc && status &&
lease -> client_hostname &&
strlen (lease -> client_hostname) == d1.len &&
@@ -844,14 +853,16 @@ void ack_lease (packet, lease, offer, when, msg)
}
/* Execute statements in scope starting with the subnet scope. */
- execute_statements_in_scope (packet, packet -> options,
+ execute_statements_in_scope (packet, lease,
+ packet -> options,
state -> options,
lease -> subnet -> group,
(struct group *)0);
/* If the lease is from a pool, run the pool scope. */
if (lease -> pool)
- execute_statements_in_scope (packet, packet -> options,
+ execute_statements_in_scope (packet, lease,
+ packet -> options,
state -> options,
lease -> pool -> group,
lease -> subnet -> group);
@@ -859,7 +870,7 @@ void ack_lease (packet, lease, offer, when, msg)
/* Execute statements from class scopes. */
for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope
- (packet, packet -> options, state -> options,
+ (packet, lease, packet -> options, state -> options,
packet -> classes [i - 1] -> group,
(lease -> pool
? lease -> pool -> group
@@ -869,7 +880,7 @@ void ack_lease (packet, lease, offer, when, msg)
/* If we have a host_decl structure, run the options associated
with its group. */
if (lease -> host)
- execute_statements_in_scope (packet, packet -> options,
+ execute_statements_in_scope (packet, lease, packet -> options,
state -> options,
lease -> host -> group,
(lease -> pool
@@ -888,7 +899,8 @@ void ack_lease (packet, lease, offer, when, msg)
if (offer == DHCPREQUEST &&
(oc = lookup_option (&server_universe, state -> options,
SV_ONE_LEASE_PER_CLIENT)) &&
- evaluate_boolean_option_cache (packet, packet -> options, oc)) {
+ evaluate_boolean_option_cache (packet,
+ packet -> options, lease, oc)) {
struct lease *seek;
if (lease -> uid_len) {
do {
@@ -931,7 +943,7 @@ void ack_lease (packet, lease, offer, when, msg)
(oc = lookup_option (&server_universe, state -> options,
SV_MIN_SECS))) {
if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ packet -> options, lease, oc)) {
if (d1.len && packet -> raw -> secs < d1.data [0]) {
data_string_forget (&d1, "ack_lease");
log_info ("%s: %d secs < %d",
@@ -956,7 +968,7 @@ void ack_lease (packet, lease, offer, when, msg)
DHO_DHCP_CLIENT_IDENTIFIER);
if (oc &&
evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ packet -> options, lease, oc)) {
hp = find_hosts_by_uid (d1.data, d1.len);
data_string_forget (&d1, "dhcpdiscover");
if (!hp)
@@ -978,7 +990,7 @@ void ack_lease (packet, lease, offer, when, msg)
(oc = lookup_option (&server_universe, state -> options,
SV_BOOT_UNKNOWN_CLIENTS))) {
if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ packet -> options, lease, oc)) {
if (d1.len && !d1.data [0]) {
log_info ("%s: unknown", msg);
data_string_forget (&d1, "ack_lease");
@@ -994,7 +1006,7 @@ void ack_lease (packet, lease, offer, when, msg)
(oc = lookup_option (&server_universe, state -> options,
SV_ALLOW_BOOTP))) {
if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ packet -> options, lease, oc)) {
if (d1.len && !d1.data [0]) {
data_string_forget (&d1, "ack_lease");
log_info ("%s: bootp disallowed", msg);
@@ -1009,7 +1021,8 @@ void ack_lease (packet, lease, offer, when, msg)
oc = lookup_option (&server_universe, state -> options,
SV_ALLOW_BOOTING);
if (oc &&
- evaluate_option_cache (&d1, packet, packet -> options, oc)) {
+ evaluate_option_cache (&d1, packet, packet -> options,
+ lease, oc)) {
if (d1.len && !d1.data [0]) {
log_info ("%s: booting disallowed", msg);
data_string_forget (&d1, "ack_lease");
@@ -1062,14 +1075,14 @@ void ack_lease (packet, lease, offer, when, msg)
oc = lookup_option (&server_universe, state -> options, SV_FILENAME);
if (oc)
evaluate_option_cache (&state -> filename,
- packet, packet -> options, oc);
+ packet, packet -> options, lease, oc);
/* Choose a server name as above. */
oc = lookup_option (&server_universe, state -> options,
SV_SERVER_NAME);
if (oc)
evaluate_option_cache (&state -> server_name, packet,
- packet -> options, oc);
+ packet -> options, lease, oc);
/* At this point, we have a lease that we can offer the client.
Now we construct a lease structure that contains what we want,
@@ -1090,7 +1103,8 @@ void ack_lease (packet, lease, offer, when, msg)
if ((oc = lookup_option (&server_universe, state -> options,
SV_DEFAULT_LEASE_TIME))) {
if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ packet -> options,
+ lease, oc)) {
if (d1.len == sizeof (u_int32_t))
default_lease_time =
getULong (d1.data);
@@ -1101,7 +1115,8 @@ void ack_lease (packet, lease, offer, when, msg)
if ((oc = lookup_option (&dhcp_universe, packet -> options,
DHO_DHCP_LEASE_TIME)))
s1 = evaluate_option_cache (&d1, packet,
- packet -> options, oc);
+ packet -> options,
+ lease, oc);
else
s1 = 0;
if (s1 && d1.len == sizeof (u_int32_t)) {
@@ -1113,7 +1128,7 @@ void ack_lease (packet, lease, offer, when, msg)
SV_MAX_LEASE_TIME))) {
if (evaluate_option_cache (&d1, packet,
packet -> options,
- oc)) {
+ lease, oc)) {
if (d1.len == sizeof (u_int32_t))
max_lease_time =
getULong (d1.data);
@@ -1133,7 +1148,8 @@ void ack_lease (packet, lease, offer, when, msg)
if ((oc = lookup_option (&server_universe, state -> options,
SV_MIN_LEASE_TIME))) {
if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ packet -> options,
+ lease, oc)) {
if (d1.len == sizeof (u_int32_t))
min_lease_time = getULong (d1.data);
data_string_forget (&d1, "ack_lease");
@@ -1158,7 +1174,8 @@ void ack_lease (packet, lease, offer, when, msg)
if ((oc = lookup_option (&server_universe, state -> options,
SV_BOOTP_LEASE_LENGTH))) {
if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ packet -> options, lease,
+ oc)) {
if (d1.len == sizeof (u_int32_t))
lease_time = getULong (d1.data);
data_string_forget (&d1, "ack_lease");
@@ -1168,7 +1185,8 @@ void ack_lease (packet, lease, offer, when, msg)
if ((oc = lookup_option (&server_universe, state -> options,
SV_BOOTP_LEASE_CUTOFF))) {
if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ packet -> options,
+ lease, oc)) {
if (d1.len == sizeof (u_int32_t))
lease_time = (getULong (d1.data) -
cur_time);
@@ -1186,7 +1204,8 @@ void ack_lease (packet, lease, offer, when, msg)
oc = lookup_option (&dhcp_universe, packet -> options,
DHO_DHCP_CLIENT_IDENTIFIER);
if (oc &&
- evaluate_option_cache (&d1, packet, packet -> options, oc)) {
+ evaluate_option_cache (&d1, packet, packet -> options,
+ lease, oc)) {
if (d1.len <= sizeof lt.uid_buf) {
memcpy (lt.uid_buf, d1.data, d1.len);
lt.uid = lt.uid_buf;
@@ -1258,7 +1277,7 @@ void ack_lease (packet, lease, offer, when, msg)
if ((oc = lookup_option (&dhcp_universe, packet -> options,
DHO_HOST_NAME))) {
if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ packet -> options, lease, oc)) {
if (d1.data [d1.len - 1] == '\0')
lease -> flags |= MS_NULL_TERMINATION;
data_string_forget (&d1, "ack_lease");
@@ -1278,7 +1297,8 @@ void ack_lease (packet, lease, offer, when, msg)
the broadcast bit in the bootp flags field. */
if ((oc = lookup_option (&server_universe, state -> options,
SV_ALWAYS_BROADCAST)) &&
- evaluate_boolean_option_cache (packet, packet -> options, oc))
+ evaluate_boolean_option_cache (packet, packet -> options,
+ lease, oc))
state -> bootp_flags |= htons (BOOTP_BROADCAST);
/* Get the Maximum Message Size option from the packet, if one
@@ -1286,7 +1306,8 @@ void ack_lease (packet, lease, offer, when, msg)
oc = lookup_option (&dhcp_universe, packet -> options,
DHO_DHCP_MAX_MESSAGE_SIZE);
if (oc &&
- evaluate_option_cache (&d1, packet, packet -> options, oc)) {
+ evaluate_option_cache (&d1, packet, packet -> options,
+ lease, oc)) {
if (d1.len == sizeof (u_int16_t))
state -> max_message_size = getUShort (d1.data);
data_string_forget (&d1, "ack_lease");
@@ -1333,7 +1354,8 @@ void ack_lease (packet, lease, offer, when, msg)
state -> from.len);
} else {
if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ packet -> options,
+ lease, oc)) {
if (!d1.len ||
d1.len > sizeof state -> from.iabuf) {
data_string_forget (&d1, "ack_lease");
@@ -1422,7 +1444,7 @@ void ack_lease (packet, lease, offer, when, msg)
lookup_option (&server_universe,
state -> options, SV_NEXT_SERVER))) {
if (evaluate_option_cache (&d1, packet,
- packet -> options, oc)) {
+ packet -> options, lease, oc)) {
/* If there was more than one answer,
take the first. */
if (d1.len >= 4 && d1.data)
@@ -1456,7 +1478,7 @@ void ack_lease (packet, lease, offer, when, msg)
if (!lookup_option (&dhcp_universe, state -> options, i) &&
lease -> host && lease -> host -> name &&
(evaluate_boolean_option_cache
- (packet, packet -> options,
+ (packet, packet -> options, lease,
(lookup_option
(&server_universe, state -> options, j))))) {
oc = (struct option_cache *)0;
@@ -1479,7 +1501,7 @@ void ack_lease (packet, lease, offer, when, msg)
j = SV_GET_LEASE_HOSTNAMES;
if (!lookup_option (&server_universe, state -> options, i) &&
(evaluate_boolean_option_cache
- (packet, packet -> options,
+ (packet, packet -> options, lease,
lookup_option (&server_universe, state -> options, j)))) {
struct in_addr ia;
struct hostent *h;
@@ -1512,7 +1534,7 @@ void ack_lease (packet, lease, offer, when, msg)
so if the local router does proxy arp, you win. */
if (evaluate_boolean_option_cache
- (packet, state -> options,
+ (packet, state -> options, lease,
lookup_option (&server_universe, state -> options,
SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE))) {
i = DHO_ROUTERS;
@@ -1543,7 +1565,7 @@ void ack_lease (packet, lease, offer, when, msg)
if (!lookup_option (&dhcp_universe, state -> options, i) &&
(oc = lookup_option (&server_universe, state -> options, j)) &&
evaluate_option_cache (&d1,
- packet, state -> options, oc)) {
+ packet, state -> options, lease, oc)) {
oc = (struct option_cache *)0;
if (option_cache_allocate (&oc, "ack_lease")) {
if (make_encapsulation (&oc -> expression, &d1)) {
@@ -1560,7 +1582,7 @@ void ack_lease (packet, lease, offer, when, msg)
site option codes. */
i = SV_SITE_OPTION_SPACE;
if ((oc = lookup_option (&server_universe, state -> options, i)) &&
- evaluate_option_cache (&d1, packet, state -> options, oc)) {
+ evaluate_option_cache (&d1, packet, state -> options, lease, oc)) {
struct universe *u;
u = ((struct universe *)
@@ -1591,7 +1613,7 @@ void ack_lease (packet, lease, offer, when, msg)
DHO_DHCP_PARAMETER_REQUEST_LIST);
if (oc)
evaluate_option_cache (&state -> parameter_request_list,
- packet, packet -> options, oc);
+ packet, packet -> options, lease, oc);
#ifdef DEBUG_PACKET
dump_packet (packet);
@@ -1685,7 +1707,7 @@ void dhcp_reply (lease)
bootpp = 1;
/* Insert such options as will fit into the buffer. */
- packet_length = cons_options ((struct packet *)0, &raw,
+ packet_length = cons_options ((struct packet *)0, &raw, lease,
state -> max_message_size,
state -> options,
bufs, nulltp, bootpp,
@@ -1839,7 +1861,8 @@ struct lease *find_lease (packet, share, ours)
DHO_DHCP_REQUESTED_ADDRESS);
memset (&d1, 0, sizeof d1);
if (oc &&
- evaluate_option_cache (&d1, packet, packet -> options, oc)) {
+ evaluate_option_cache (&d1, packet, packet -> options,
+ (struct lease *)0, oc)) {
packet -> got_requested_address = 1;
cip.len = 4;
memcpy (cip.iabuf, d1.data, cip.len);
@@ -1857,7 +1880,8 @@ struct lease *find_lease (packet, share, ours)
memset (&client_identifier, 0, sizeof client_identifier);
if (oc &&
evaluate_option_cache (&client_identifier,
- packet, packet -> options, oc)) {
+ packet, packet -> options,
+ (struct lease *)0, oc)) {
/* Remember this for later. */
have_client_identifier = 1;