diff options
author | Ted Lemon <source@isc.org> | 1999-07-02 20:58:48 +0000 |
---|---|---|
committer | Ted Lemon <source@isc.org> | 1999-07-02 20:58:48 +0000 |
commit | da38df14336d62b999bdba8f600d86777e98653a (patch) | |
tree | 1486bbae2f42d28a21a0cfd0bd72b4b23ba84a23 | |
parent | 15eda2482666252724334793c1fef856ea61003f (diff) | |
download | isc-dhcp-da38df14336d62b999bdba8f600d86777e98653a.tar.gz |
Pervasive changes to support leased_address, reverse and binary_to_ascii.
-rw-r--r-- | client/dhclient.c | 54 | ||||
-rw-r--r-- | common/convert.c | 64 | ||||
-rw-r--r-- | common/execute.c | 19 | ||||
-rw-r--r-- | common/memory.c | 4 | ||||
-rw-r--r-- | common/options.c | 43 | ||||
-rw-r--r-- | common/parse.c | 80 | ||||
-rw-r--r-- | common/tree.c | 327 | ||||
-rw-r--r-- | includes/dhcpd.h | 38 | ||||
-rw-r--r-- | includes/dhctoken.h | 3 | ||||
-rw-r--r-- | includes/tree.h | 17 | ||||
-rw-r--r-- | server/bootp.c | 25 | ||||
-rw-r--r-- | server/class.c | 13 | ||||
-rw-r--r-- | server/dhcp.c | 136 |
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; |