#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"
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;
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
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
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
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;
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
/* 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);
}
/* 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;
/* 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;
/* 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;
/* 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;
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,
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;
!evaluate_option_cache (&data,
(struct packet *)0,
lease -> options,
+ (struct lease *)0,
oc)) {
broadcast = broadcast_addr (subnet,
netmask);
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);
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
#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"
{
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;
+}
#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;
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
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;
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
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;
}
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);
}
#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"
(&hd -> client_identifier,
(struct packet *)0,
(struct option_state *)0,
+ (struct lease *)0,
esp -> data.option);
break;
}
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) {
#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
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. */
(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");
(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,
/* 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;
}
/* 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;
}
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
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;
{
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;
{
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;
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 +
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;
}
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;
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;
}
#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"
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"))
(*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"))
#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"
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;
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");
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 &&
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)
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",
case expr_not:
sleft = evaluate_boolean_expression (&bleft, packet, options,
+ lease,
expr -> data.not);
#if defined (DEBUG_EXPRESSIONS)
log_info ("bool: not (%s) = %s",
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;
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;
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) {
/* 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,
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;
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)
case expr_encapsulate:
if (options)
s0 = option_space_encapsulate
- (result, options, &expr -> data.encapsulate);
+ (result, options, lease,
+ &expr -> data.encapsulate);
else
s0 = 0;
/* 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) {
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;
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;
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;
#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:
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;
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;
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)
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);
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);
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) {
}
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;
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])
/* 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;
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;
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:
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)
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:
enum expr_op op;
{
switch (op) {
+/* XXX Why aren't these specific? */
case expr_none:
case expr_match:
case expr_check:
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:
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));
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 */
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 *,
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));
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 *));
/* 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 *));
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 && \
expr_exists,
expr_encapsulate,
expr_known,
+ expr_reverse,
+ expr_leased_address,
+ expr_binary_to_ascii,
};
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
struct packet; /* forward */
struct option_state; /* forward */
struct decoded_option_state; /* forward */
+struct lease; /* forward */
struct universe {
char *name;
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));
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;
#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"
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))) {
return;
}
- if (evaluate_boolean_option_cache (packet, options,
+ if (evaluate_boolean_option_cache (packet, options, lease,
lookup_option (&server_universe,
options,
SV_ALLOW_BOOTING))) {
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,
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;
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);
/* 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)
/* 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)
#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"
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;
/* 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 *)
}
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)
#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"
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");
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
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;
/* 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);
}
/* 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;
/* 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;
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");
}
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;
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)) {
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 *)
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);
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)
/* 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");
/* 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");
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 &&
}
/* 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);
/* 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
/* 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
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 {
(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",
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)
(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");
(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);
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");
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,
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);
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)) {
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);
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");
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");
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);
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;
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");
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
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");
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");
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)
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;
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;
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;
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)) {
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 *)
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);
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,
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);
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;