1 /* $NetBSD: tree.c,v 1.1.1.3 2014/07/12 11:57:48 spz Exp $ */
4 Routines for manipulating parse trees... */
7 * Copyright (c) 2011-2014 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
9 * Copyright (c) 1995-2003 by Internet Software Consortium
11 * Permission to use, copy, modify, and distribute this software for any
12 * purpose with or without fee is hereby granted, provided that the above
13 * copyright notice and this permission notice appear in all copies.
15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Internet Systems Consortium, Inc.
25 * Redwood City, CA 94063
27 * https://www.isc.org/
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: tree.c,v 1.1.1.3 2014/07/12 11:57:48 spz Exp $");
35 #include <omapip/omapip_p.h>
43 struct binding_scope
*global_scope
;
45 static int do_host_lookup (struct data_string
*, struct dns_host_entry
*);
47 #define DS_SPRINTF_SIZE 128
50 * If we are using a data_string structure to hold a NUL-terminated
51 * ASCII string, this function can be used to append a printf-formatted
52 * string to the end of it. The data_string structure will be resized to
53 * be big enough to hold the new string.
55 * If the append works, then 1 is returned.
57 * If it is not possible to allocate a buffer big enough to hold the
58 * new value, then the old data_string is unchanged, and 0 is returned.
61 data_string_sprintfa(struct data_string
*ds
, const char *fmt
, ...) {
67 struct buffer
*tmp_buffer
;
70 * If the data_string is empty, then initialize it.
72 if (ds
->data
== NULL
) {
73 /* INSIST(ds.buffer == NULL); */
74 if (!buffer_allocate(&ds
->buffer
, DS_SPRINTF_SIZE
, MDL
)) {
77 ds
->data
= ds
->buffer
->data
;
78 ds
->len
= DS_SPRINTF_SIZE
;
79 *((char *)ds
->data
) = '\0';
83 * Get the length of the string, and figure out how much space
86 cur_strlen
= strlen((char *)ds
->data
);
87 max
= ds
->len
- cur_strlen
;
90 * Use vsnprintf(), which won't write past our space, but will
91 * tell us how much space it wants.
94 vsnprintf_ret
= vsnprintf((char *)ds
->data
+cur_strlen
, max
, fmt
, args
);
96 /* INSIST(vsnprintf_ret >= 0); */
99 * If our buffer is not big enough, we need a new buffer.
101 if (vsnprintf_ret
>= max
) {
103 * Figure out a size big enough.
105 new_len
= ds
->len
* 2;
106 while (new_len
<= cur_strlen
+ vsnprintf_ret
) {
111 * Create a new buffer and fill it.
114 if (!buffer_allocate(&tmp_buffer
, new_len
, MDL
)) {
116 * If we can't create a big enough buffer,
117 * we should remove any truncated output that we had.
119 *((char *)ds
->data
+cur_strlen
) = '\0';
123 memcpy(tmp_buffer
->data
, ds
->data
, cur_strlen
);
125 /* Rerun the vsprintf. */
127 vsprintf((char *)tmp_buffer
->data
+ cur_strlen
, fmt
, args
);
131 * Replace our old buffer with the new buffer.
133 buffer_dereference(&ds
->buffer
, MDL
);
134 buffer_reference(&ds
->buffer
, tmp_buffer
, MDL
);
135 buffer_dereference(&tmp_buffer
, MDL
);
136 ds
->data
= ds
->buffer
->data
;
146 pair foo
= (pair
)dmalloc (sizeof *foo
, MDL
);
148 log_fatal ("no memory for cons.");
154 int make_const_option_cache (oc
, buffer
, data
, len
, option
, file
, line
)
155 struct option_cache
**oc
;
156 struct buffer
**buffer
;
159 struct option
*option
;
169 bp
= (struct buffer
*)0;
170 if (!buffer_allocate (&bp
, len
, file
, line
)) {
171 log_error ("%s(%d): can't allocate buffer.",
177 if (!option_cache_allocate (oc
, file
, line
)) {
178 log_error ("%s(%d): can't allocate option cache.", file
, line
);
179 buffer_dereference (&bp
, file
, line
);
183 (*oc
) -> data
.len
= len
;
184 (*oc
) -> data
.buffer
= bp
;
185 (*oc
) -> data
.data
= &bp
-> data
[0];
186 (*oc
) -> data
.terminated
= 0;
188 memcpy (&bp
-> data
[0], data
, len
);
189 option_reference(&((*oc
)->option
), option
, MDL
);
193 int make_host_lookup (expr
, name
)
194 struct expression
**expr
;
197 if (!expression_allocate (expr
, MDL
)) {
198 log_error ("No memory for host lookup tree node.");
201 (*expr
) -> op
= expr_host_lookup
;
202 if (!enter_dns_host (&((*expr
) -> data
.host_lookup
), name
)) {
203 expression_dereference (expr
, MDL
);
209 int enter_dns_host (dh
, name
)
210 struct dns_host_entry
**dh
;
213 /* XXX This should really keep a hash table of hostnames
214 XXX and just add a new reference to a hostname that
215 XXX already exists, if possible, rather than creating
216 XXX a new structure. */
217 if (!dns_host_entry_allocate (dh
, name
, MDL
)) {
218 log_error ("Can't allocate space for new host.");
224 int make_const_data (struct expression
**expr
, const unsigned char *data
,
225 unsigned len
, int terminated
, int allocate
,
226 const char *file
, int line
)
228 struct expression
*nt
;
230 if (!expression_allocate (expr
, file
, line
)) {
231 log_error ("No memory for make_const_data tree node.");
238 if (!buffer_allocate (&nt
-> data
.const_data
.buffer
,
239 len
+ terminated
, file
, line
)) {
240 log_error ("Can't allocate const_data buffer");
241 expression_dereference (expr
, file
, line
);
244 nt
-> data
.const_data
.data
=
245 &nt
-> data
.const_data
.buffer
-> data
[0];
246 memcpy (nt
-> data
.const_data
.buffer
-> data
,
247 data
, len
+ terminated
);
249 nt
-> data
.const_data
.data
= data
;
250 nt
-> data
.const_data
.terminated
= terminated
;
252 nt
-> data
.const_data
.data
= 0;
254 nt
-> op
= expr_const_data
;
255 nt
-> data
.const_data
.len
= len
;
259 int make_const_int (expr
, val
)
260 struct expression
**expr
;
263 if (!expression_allocate (expr
, MDL
)) {
264 log_error ("No memory for make_const_int tree node.");
268 (*expr
) -> op
= expr_const_int
;
269 (*expr
) -> data
.const_int
= val
;
273 int make_concat (expr
, left
, right
)
274 struct expression
**expr
;
275 struct expression
*left
, *right
;
277 /* If we're concatenating a null tree to a non-null tree, just
278 return the non-null tree; if both trees are null, return
283 expression_reference (expr
, right
, MDL
);
287 expression_reference (expr
, left
, MDL
);
291 /* Otherwise, allocate a new node to concatenate the two. */
292 if (!expression_allocate (expr
, MDL
)) {
293 log_error ("No memory for concatenation expression node.");
297 (*expr
) -> op
= expr_concat
;
298 expression_reference (&(*expr
) -> data
.concat
[0], left
, MDL
);
299 expression_reference (&(*expr
) -> data
.concat
[1], right
, MDL
);
303 int make_encapsulation (expr
, name
)
304 struct expression
**expr
;
305 struct data_string
*name
;
307 /* Allocate a new node to store the encapsulation. */
308 if (!expression_allocate (expr
, MDL
)) {
309 log_error ("No memory for encapsulation expression node.");
313 (*expr
) -> op
= expr_encapsulate
;
314 data_string_copy (&(*expr
) -> data
.encapsulate
, name
, MDL
);
318 int make_substring (new, expr
, offset
, length
)
319 struct expression
**new;
320 struct expression
*expr
;
321 struct expression
*offset
;
322 struct expression
*length
;
324 /* Allocate an expression node to compute the substring. */
325 if (!expression_allocate (new, MDL
)) {
326 log_error ("no memory for substring expression.");
329 (*new) -> op
= expr_substring
;
330 expression_reference (&(*new) -> data
.substring
.expr
, expr
, MDL
);
331 expression_reference (&(*new) -> data
.substring
.offset
, offset
, MDL
);
332 expression_reference (&(*new) -> data
.substring
.len
, length
, MDL
);
336 int make_limit (new, expr
, limit
)
337 struct expression
**new;
338 struct expression
*expr
;
341 /* Allocate a node to enforce a limit on evaluation. */
342 if (!expression_allocate (new, MDL
))
343 log_error ("no memory for limit expression");
344 (*new) -> op
= expr_substring
;
345 expression_reference (&(*new) -> data
.substring
.expr
, expr
, MDL
);
347 /* Offset is a constant 0. */
348 if (!expression_allocate (&(*new) -> data
.substring
.offset
, MDL
)) {
349 log_error ("no memory for limit offset expression");
350 expression_dereference (new, MDL
);
353 (*new) -> data
.substring
.offset
-> op
= expr_const_int
;
354 (*new) -> data
.substring
.offset
-> data
.const_int
= 0;
356 /* Length is a constant: the specified limit. */
357 if (!expression_allocate (&(*new) -> data
.substring
.len
, MDL
)) {
358 log_error ("no memory for limit length expression");
359 expression_dereference (new, MDL
);
362 (*new) -> data
.substring
.len
-> op
= expr_const_int
;
363 (*new) -> data
.substring
.len
-> data
.const_int
= limit
;
368 int option_cache (struct option_cache
**oc
, struct data_string
*dp
,
369 struct expression
*expr
, struct option
*option
,
370 const char *file
, int line
)
372 if (!option_cache_allocate (oc
, file
, line
))
375 data_string_copy (&(*oc
) -> data
, dp
, file
, line
);
377 expression_reference (&(*oc
) -> expression
, expr
, file
, line
);
378 option_reference(&(*oc
)->option
, option
, MDL
);
382 int make_let (result
, name
)
383 struct executable_statement
**result
;
386 if (!(executable_statement_allocate (result
, MDL
)))
389 (*result
) -> op
= let_statement
;
390 (*result
) -> data
.let
.name
= dmalloc (strlen (name
) + 1, MDL
);
391 if (!(*result
) -> data
.let
.name
) {
392 executable_statement_dereference (result
, MDL
);
395 strcpy ((*result
) -> data
.let
.name
, name
);
399 static int do_host_lookup (result
, dns
)
400 struct data_string
*result
;
401 struct dns_host_entry
*dns
;
408 log_debug ("time: now = %d dns = %d diff = %d",
409 cur_time
, dns
-> timeout
, cur_time
- dns
-> timeout
);
412 /* If the record hasn't timed out, just copy the data and return. */
413 if (cur_time
<= dns
-> timeout
) {
415 log_debug ("easy copy: %d %s",
418 ? inet_ntoa (*(struct in_addr
*)(dns
-> data
.data
))
421 data_string_copy (result
, &dns
-> data
, MDL
);
425 log_debug ("Looking up %s", dns
-> hostname
);
428 /* Otherwise, look it up... */
429 h
= gethostbyname (dns
-> hostname
);
435 log_error ("%s: host unknown.", dns
-> hostname
);
439 log_error ("%s: temporary name server failure",
443 log_error ("%s: name server failed", dns
-> hostname
);
446 log_error ("%s: no A record associated with address",
449 #endif /* !NO_H_ERRNO */
451 /* Okay to try again after a minute. */
452 dns
-> timeout
= cur_time
+ 60;
453 data_string_forget (&dns
-> data
, MDL
);
458 log_debug ("Lookup succeeded; first address is %s",
459 inet_ntoa (h
-> h_addr_list
[0]));
462 /* Count the number of addresses we got... */
463 for (count
= 0; h
-> h_addr_list
[count
]; count
++)
466 /* Dereference the old data, if any. */
467 data_string_forget (&dns
-> data
, MDL
);
469 /* Do we need to allocate more memory? */
470 new_len
= count
* h
-> h_length
;
471 if (!buffer_allocate (&dns
-> data
.buffer
, new_len
, MDL
))
473 log_error ("No memory for %s.", dns
-> hostname
);
477 dns
-> data
.data
= &dns
-> data
.buffer
-> data
[0];
478 dns
-> data
.len
= new_len
;
479 dns
-> data
.terminated
= 0;
481 /* Addresses are conveniently stored one to the buffer, so we
482 have to copy them out one at a time... :'( */
483 for (i
= 0; i
< count
; i
++) {
484 memcpy (&dns
-> data
.buffer
-> data
[h
-> h_length
* i
],
485 h
-> h_addr_list
[i
], (unsigned)(h
-> h_length
));
488 log_debug ("dns -> data: %x h -> h_addr_list [0]: %x",
489 *(int *)(dns
-> buffer
), h
-> h_addr_list
[0]);
492 /* XXX Set the timeout for an hour from now.
493 XXX This should really use the time on the DNS reply. */
494 dns
-> timeout
= cur_time
+ 3600;
497 log_debug ("hard copy: %d %s", dns
-> data
.len
,
499 ? inet_ntoa (*(struct in_addr
*)(dns
-> data
.data
)) : 0));
501 data_string_copy (result
, &dns
-> data
, MDL
);
505 int evaluate_expression (result
, packet
, lease
, client_state
,
506 in_options
, cfg_options
, scope
, expr
, file
, line
)
507 struct binding_value
**result
;
508 struct packet
*packet
;
510 struct client_state
*client_state
;
511 struct option_state
*in_options
;
512 struct option_state
*cfg_options
;
513 struct binding_scope
**scope
;
514 struct expression
*expr
;
518 struct binding_value
*bv
;
520 struct binding
*binding
;
522 bv
= (struct binding_value
*)0;
524 if (expr
-> op
== expr_variable_reference
) {
525 if (!scope
|| !*scope
)
528 binding
= find_binding (*scope
, expr
-> data
.variable
);
530 if (binding
&& binding
-> value
) {
532 binding_value_reference (result
,
538 } else if (expr
-> op
== expr_funcall
) {
539 struct string_list
*s
;
540 struct expression
*arg
;
541 struct binding_scope
*ns
;
544 if (!scope
|| !*scope
) {
545 log_error ("%s: no such function.",
546 expr
-> data
.funcall
.name
);
550 binding
= find_binding (*scope
, expr
-> data
.funcall
.name
);
552 if (!binding
|| !binding
-> value
) {
553 log_error ("%s: no such function.",
554 expr
-> data
.funcall
.name
);
557 if (binding
-> value
-> type
!= binding_function
) {
558 log_error ("%s: not a function.",
559 expr
-> data
.funcall
.name
);
563 /* Create a new binding scope in which to define
564 the arguments to the function. */
565 ns
= (struct binding_scope
*)0;
566 if (!binding_scope_allocate (&ns
, MDL
)) {
567 log_error ("%s: can't allocate argument scope.",
568 expr
-> data
.funcall
.name
);
572 arg
= expr
-> data
.funcall
.arglist
;
573 s
= binding
-> value
-> value
.fundef
-> args
;
575 nb
= dmalloc (sizeof *nb
, MDL
);
578 binding_scope_dereference (&ns
, MDL
);
581 memset (nb
, 0, sizeof *nb
);
582 nb
-> name
= dmalloc (strlen (s
-> string
) + 1,
585 strcpy (nb
-> name
, s
-> string
);
591 evaluate_expression (&nb
-> value
, packet
, lease
,
593 in_options
, cfg_options
, scope
,
594 arg
-> data
.arg
.val
, file
, line
);
595 nb
-> next
= ns
-> bindings
;
597 arg
= arg
-> data
.arg
.next
;
601 log_error ("%s: too many arguments.",
602 expr
-> data
.funcall
.name
);
603 binding_scope_dereference (&ns
, MDL
);
607 log_error ("%s: too few arguments.",
608 expr
-> data
.funcall
.name
);
609 binding_scope_dereference (&ns
, MDL
);
614 binding_scope_reference (&ns
-> outer
, *scope
, MDL
);
616 status
= (execute_statements
618 lease
, client_state
, in_options
, cfg_options
, &ns
,
619 binding
->value
->value
.fundef
->statements
, NULL
));
620 binding_scope_dereference (&ns
, MDL
);
624 } else if (is_boolean_expression (expr
)) {
625 if (!binding_value_allocate (&bv
, MDL
))
627 bv
-> type
= binding_boolean
;
628 status
= (evaluate_boolean_expression
629 (&bv
-> value
.boolean
, packet
, lease
, client_state
,
630 in_options
, cfg_options
, scope
, expr
));
631 } else if (is_numeric_expression (expr
)) {
632 if (!binding_value_allocate (&bv
, MDL
))
634 bv
-> type
= binding_numeric
;
635 status
= (evaluate_numeric_expression
636 (&bv
-> value
.intval
, packet
, lease
, client_state
,
637 in_options
, cfg_options
, scope
, expr
));
638 } else if (is_data_expression (expr
)) {
639 if (!binding_value_allocate (&bv
, MDL
))
641 bv
-> type
= binding_data
;
642 status
= (evaluate_data_expression
643 (&bv
-> value
.data
, packet
, lease
, client_state
,
644 in_options
, cfg_options
, scope
, expr
, MDL
));
646 log_error ("%s: invalid expression type: %d",
647 "evaluate_expression", expr
-> op
);
650 if (result
&& status
)
651 binding_value_reference (result
, bv
, file
, line
);
652 binding_value_dereference (&bv
, MDL
);
657 int binding_value_dereference (struct binding_value
**v
,
658 const char *file
, int line
)
660 struct binding_value
*bv
= *v
;
662 *v
= (struct binding_value
*)0;
664 /* Decrement the reference count. If it's nonzero, we're
667 rc_register (file
, line
, v
, bv
, bv
-> refcnt
, 1, RC_MISC
);
668 if (bv
-> refcnt
> 0)
670 if (bv
-> refcnt
< 0) {
671 log_error ("%s(%d): negative refcnt!", file
, line
);
672 #if defined (DEBUG_RC_HISTORY)
673 dump_rc_history (bv
);
675 #if defined (POINTER_DEBUG)
682 switch (bv
-> type
) {
683 case binding_boolean
:
684 case binding_numeric
:
687 if (bv
-> value
.data
.buffer
)
688 data_string_forget (&bv
-> value
.data
, file
, line
);
691 log_error ("%s(%d): invalid binding type: %d",
692 file
, line
, bv
-> type
);
695 free_binding_value(bv
, file
, line
);
699 int evaluate_boolean_expression (result
, packet
, lease
, client_state
,
700 in_options
, cfg_options
, scope
, expr
)
702 struct packet
*packet
;
704 struct client_state
*client_state
;
705 struct option_state
*in_options
;
706 struct option_state
*cfg_options
;
707 struct binding_scope
**scope
;
708 struct expression
*expr
;
710 struct data_string left
, right
;
713 struct binding
*binding
;
714 struct binding_value
*bv
, *obv
;
716 int regflags
= REG_EXTENDED
| REG_NOSUB
;
720 switch (expr
-> op
) {
722 *result
= check_collection (packet
, lease
,
724 #if defined (DEBUG_EXPRESSIONS)
725 log_debug ("bool: check (%s) returns %s",
726 expr
-> data
.check
-> name
,
727 *result
? "true" : "false");
733 bv
= obv
= (struct binding_value
*)0;
734 sleft
= evaluate_expression (&bv
, packet
, lease
, client_state
,
735 in_options
, cfg_options
, scope
,
736 expr
-> data
.equal
[0], MDL
);
737 sright
= evaluate_expression (&obv
, packet
, lease
,
738 client_state
, in_options
,
740 expr
-> data
.equal
[1], MDL
);
741 if (sleft
&& sright
) {
742 if (bv
-> type
!= obv
-> type
)
743 *result
= expr
-> op
== expr_not_equal
;
745 switch (obv
-> type
) {
746 case binding_boolean
:
747 if (bv
-> value
.boolean
== obv
-> value
.boolean
)
748 *result
= expr
-> op
== expr_equal
;
750 *result
= expr
-> op
== expr_not_equal
;
754 if ((bv
-> value
.data
.len
==
755 obv
-> value
.data
.len
) &&
756 !memcmp (bv
-> value
.data
.data
,
757 obv
-> value
.data
.data
,
758 obv
-> value
.data
.len
))
759 *result
= expr
-> op
== expr_equal
;
761 *result
= expr
-> op
== expr_not_equal
;
764 case binding_numeric
:
765 if (bv
-> value
.intval
== obv
-> value
.intval
)
766 *result
= expr
-> op
== expr_equal
;
768 *result
= expr
-> op
== expr_not_equal
;
771 case binding_function
:
772 if (bv
-> value
.fundef
== obv
-> value
.fundef
)
773 *result
= expr
-> op
== expr_equal
;
775 *result
= expr
-> op
== expr_not_equal
;
778 *result
= expr
-> op
== expr_not_equal
;
782 } else if (!sleft
&& !sright
)
783 *result
= expr
-> op
== expr_equal
;
785 *result
= expr
-> op
== expr_not_equal
;
787 #if defined (DEBUG_EXPRESSIONS)
788 log_debug ("bool: %sequal = %s",
789 expr
-> op
== expr_not_equal
? "not" : "",
790 (*result
? "true" : "false"));
793 binding_value_dereference (&bv
, MDL
);
795 binding_value_dereference (&obv
, MDL
);
798 case expr_iregex_match
:
800 regflags
|= REG_ICASE
;
803 case expr_regex_match
:
805 memset(&left
, 0, sizeof left
);
806 bleft
= evaluate_data_expression(&left
, packet
, lease
,
808 in_options
, cfg_options
,
810 expr
->data
.equal
[0], MDL
);
811 memset(&right
, 0, sizeof right
);
812 bright
= evaluate_data_expression(&right
, packet
, lease
,
814 in_options
, cfg_options
,
816 expr
->data
.equal
[1], MDL
);
819 memset(&re
, 0, sizeof(re
));
820 if (bleft
&& bright
&&
821 (left
.data
!= NULL
) && (right
.data
!= NULL
) &&
822 (regcomp(&re
, (char *)right
.data
, regflags
) == 0) &&
823 (regexec(&re
, (char *)left
.data
, (size_t)0, NULL
, 0) == 0))
826 #if defined (DEBUG_EXPRESSIONS)
827 log_debug("bool: %s ~= %s yields %s",
828 bleft
? print_hex_1(left
.len
, left
.data
, 20)
830 bright
? print_hex_2 (right
.len
, right
.data
, 20)
832 *result
? "true" : "false");
836 data_string_forget(&left
, MDL
);
838 data_string_forget(&right
, MDL
);
843 * If we have bleft and bright then we have a good
844 * syntax, otherwise not.
846 * XXX: we don't warn on invalid regular expression
849 return bleft
&& bright
;
851 /* It shouldn't be possible to configure a regex operator
852 * when there's no support.
854 log_fatal("Impossible condition at %s:%d.", MDL
);
859 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
861 in_options
, cfg_options
,
863 expr
-> data
.and [0]);
865 sright
= evaluate_boolean_expression
866 (&bright
, packet
, lease
, client_state
,
867 in_options
, cfg_options
,
868 scope
, expr
-> data
.and [1]);
872 #if defined (DEBUG_EXPRESSIONS)
873 log_debug ("bool: and (%s, %s) = %s",
874 sleft
? (bleft
? "true" : "false") : "NULL",
875 sright
? (bright
? "true" : "false") : "NULL",
877 ? (bleft
&& bright
? "true" : "false") : "NULL"));
879 if (sleft
&& sright
) {
880 *result
= bleft
&& bright
;
887 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
889 in_options
, cfg_options
,
891 expr
-> data
.or [0]);
892 if (!sleft
|| !bleft
)
893 sright
= evaluate_boolean_expression
894 (&bright
, packet
, lease
, client_state
,
895 in_options
, cfg_options
,
896 scope
, expr
-> data
.or [1]);
899 #if defined (DEBUG_EXPRESSIONS)
900 log_debug ("bool: or (%s, %s) = %s",
901 sleft
? (bleft
? "true" : "false") : "NULL",
902 sright
? (bright
? "true" : "false") : "NULL",
904 ? (bleft
|| bright
? "true" : "false") : "NULL"));
906 if (sleft
|| sright
) {
907 *result
= bleft
|| bright
;
913 sleft
= evaluate_boolean_expression(&bleft
, packet
, lease
,
915 in_options
, cfg_options
,
918 #if defined (DEBUG_EXPRESSIONS)
919 log_debug("bool: not (%s) = %s",
920 sleft
? (bleft
? "true" : "false") : "NULL",
921 sleft
? (!bleft
? "true" : "false") : "NULL");
930 memset (&left
, 0, sizeof left
);
932 !get_option (&left
, expr
-> data
.exists
-> universe
,
933 packet
, lease
, client_state
,
934 in_options
, cfg_options
, in_options
,
935 scope
, expr
-> data
.exists
-> code
, MDL
))
939 data_string_forget (&left
, MDL
);
941 #if defined (DEBUG_EXPRESSIONS)
942 log_debug ("bool: exists %s.%s = %s",
943 expr
-> data
.option
-> universe
-> name
,
944 expr
-> data
.option
-> name
,
945 *result
? "true" : "false");
951 #if defined (DEBUG_EXPRESSIONS)
952 log_debug ("bool: known = NULL");
956 #if defined (DEBUG_EXPRESSIONS)
957 log_debug ("bool: known = %s",
958 packet
-> known
? "true" : "false");
960 *result
= packet
-> known
;
964 if (!lease
|| !(lease
-> flags
& STATIC_LEASE
)) {
965 #if defined (DEBUG_EXPRESSIONS)
966 log_debug ("bool: static = false (%s %s %s %d)",
968 (lease
&& (lease
-> flags
& STATIC_LEASE
)
970 piaddr (lease
-> ip_addr
),
971 lease
? lease
-> flags
: 0);
976 #if defined (DEBUG_EXPRESSIONS)
977 log_debug ("bool: static = true");
982 case expr_variable_exists
:
983 if (scope
&& *scope
) {
984 binding
= find_binding (*scope
, expr
-> data
.variable
);
987 if (binding
-> value
)
995 #if defined (DEBUG_EXPRESSIONS)
996 log_debug ("boolean: %s? = %s", expr
-> data
.variable
,
997 *result
? "true" : "false");
1001 case expr_variable_reference
:
1002 if (scope
&& *scope
) {
1003 binding
= find_binding (*scope
, expr
-> data
.variable
);
1005 if (binding
&& binding
-> value
) {
1006 if (binding
-> value
-> type
==
1008 *result
= binding
-> value
-> value
.boolean
;
1011 log_error ("binding type %d in %s.",
1012 binding
-> value
-> type
,
1013 "evaluate_boolean_expression");
1020 #if defined (DEBUG_EXPRESSIONS)
1021 log_debug ("boolean: %s = %s", expr
-> data
.variable
,
1022 sleft
? (*result
? "true" : "false") : "NULL");
1027 bv
= (struct binding_value
*)0;
1028 sleft
= evaluate_expression (&bv
, packet
, lease
, client_state
,
1029 in_options
, cfg_options
,
1032 if (bv
-> type
!= binding_boolean
)
1033 log_error ("%s() returned type %d in %s.",
1034 expr
-> data
.funcall
.name
,
1036 "evaluate_boolean_expression");
1038 *result
= bv
-> value
.boolean
;
1039 binding_value_dereference (&bv
, MDL
);
1041 #if defined (DEBUG_EXPRESSIONS)
1042 log_debug ("boolean: %s() = %s", expr
-> data
.funcall
.name
,
1043 sleft
? (*result
? "true" : "false") : "NULL");
1049 case expr_substring
:
1055 case expr_const_data
:
1058 case expr_encapsulate
:
1059 case expr_host_lookup
:
1060 case expr_encode_int8
:
1061 case expr_encode_int16
:
1062 case expr_encode_int32
:
1063 case expr_binary_to_ascii
:
1065 case expr_pick_first_value
:
1066 case expr_host_decl_name
:
1067 case expr_config_option
:
1068 case expr_leased_address
:
1072 case expr_gethostname
:
1074 log_error ("Data opcode in evaluate_boolean_expression: %d",
1078 case expr_extract_int8
:
1079 case expr_extract_int16
:
1080 case expr_extract_int32
:
1081 case expr_const_int
:
1082 case expr_lease_time
:
1083 case expr_dns_transaction
:
1088 case expr_remainder
:
1089 case expr_binary_and
:
1090 case expr_binary_or
:
1091 case expr_binary_xor
:
1092 case expr_client_state
:
1093 log_error ("Numeric opcode in evaluate_boolean_expression: %d",
1098 case expr_ns_delete
:
1099 case expr_ns_exists
:
1100 case expr_ns_not_exists
:
1101 log_error ("dns opcode in evaluate_boolean_expression: %d",
1106 log_error ("function definition in evaluate_boolean_expr");
1113 log_error ("Bogus opcode in evaluate_boolean_expression: %d",
1118 int evaluate_data_expression (result
, packet
, lease
, client_state
,
1119 in_options
, cfg_options
, scope
, expr
, file
, line
)
1120 struct data_string
*result
;
1121 struct packet
*packet
;
1122 struct lease
*lease
;
1123 struct client_state
*client_state
;
1124 struct option_state
*in_options
;
1125 struct option_state
*cfg_options
;
1126 struct binding_scope
**scope
;
1127 struct expression
*expr
;
1131 struct data_string data
, other
;
1132 unsigned long offset
, len
, i
;
1135 struct binding
*binding
;
1137 struct binding_value
*bv
;
1138 struct packet
*relay_packet
;
1139 struct option_state
*relay_options
;
1141 switch (expr
-> op
) {
1142 /* Extract N bytes starting at byte M of a data string. */
1143 case expr_substring
:
1144 memset (&data
, 0, sizeof data
);
1145 s0
= evaluate_data_expression (&data
, packet
, lease
,
1147 in_options
, cfg_options
, scope
,
1148 expr
-> data
.substring
.expr
,
1151 /* Evaluate the offset and length. */
1152 s1
= evaluate_numeric_expression
1153 (&offset
, packet
, lease
, client_state
, in_options
,
1154 cfg_options
, scope
, expr
-> data
.substring
.offset
);
1155 s2
= evaluate_numeric_expression (&len
, packet
, lease
,
1157 in_options
, cfg_options
,
1159 expr
-> data
.substring
.len
);
1161 if (s0
&& s1
&& s2
) {
1162 /* If the offset is after end of the string,
1163 return an empty string. Otherwise, do the
1164 adjustments and return what's left. */
1165 if (data
.len
> offset
) {
1166 data_string_copy (result
, &data
, file
, line
);
1167 result
-> len
-= offset
;
1168 if (result
-> len
> len
) {
1169 result
-> len
= len
;
1170 result
-> terminated
= 0;
1172 result
-> data
+= offset
;
1178 #if defined (DEBUG_EXPRESSIONS)
1179 log_debug ("data: substring (%s, %s, %s) = %s",
1180 s0
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1181 s1
? print_dec_1 (offset
) : "NULL",
1182 s2
? print_dec_2 (len
) : "NULL",
1183 (s3
? print_hex_2 (result
-> len
, result
-> data
, 30)
1187 data_string_forget (&data
, MDL
);
1192 /* Extract the last N bytes of a data string. */
1194 memset (&data
, 0, sizeof data
);
1195 s0
= evaluate_data_expression (&data
, packet
, lease
,
1197 in_options
, cfg_options
, scope
,
1198 expr
-> data
.suffix
.expr
, MDL
);
1199 /* Evaluate the length. */
1200 s1
= evaluate_numeric_expression (&len
, packet
, lease
,
1202 in_options
, cfg_options
,
1204 expr
-> data
.suffix
.len
);
1206 data_string_copy (result
, &data
, file
, line
);
1208 /* If we are returning the last N bytes of a
1209 string whose length is <= N, just return
1210 the string - otherwise, compute a new
1211 starting address and decrease the
1213 if (data
.len
> len
) {
1214 result
-> data
+= data
.len
- len
;
1215 result
-> len
= len
;
1218 data_string_forget (&data
, MDL
);
1221 #if defined (DEBUG_EXPRESSIONS)
1222 log_debug ("data: suffix (%s, %s) = %s",
1223 s0
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1224 s1
? print_dec_1 (len
) : "NULL",
1226 ? print_hex_2 (result
-> len
, result
-> data
, 30)
1232 /* Convert string to lowercase. */
1234 memset(&data
, 0, sizeof data
);
1235 s0
= evaluate_data_expression(&data
, packet
, lease
,
1237 in_options
, cfg_options
, scope
,
1238 expr
->data
.lcase
, MDL
);
1241 result
->len
= data
.len
;
1242 if (buffer_allocate(&result
->buffer
,
1243 result
->len
+ data
.terminated
,
1245 result
->data
= &result
->buffer
->data
[0];
1246 memcpy(result
->buffer
->data
, data
.data
,
1247 data
.len
+ data
.terminated
);
1248 result
->terminated
= data
.terminated
;
1249 s
= (unsigned char *)result
->data
;
1250 for (i
= 0; i
< result
->len
; i
++, s
++)
1254 log_error("data: lcase: no buffer memory.");
1258 #if defined (DEBUG_EXPRESSIONS)
1259 log_debug("data: lcase (%s) = %s",
1260 s0
? print_hex_1(data
.len
, data
.data
, 30) : "NULL",
1261 s1
? print_hex_2(result
->len
, result
->data
, 30)
1265 data_string_forget(&data
, MDL
);
1268 /* Convert string to uppercase. */
1270 memset(&data
, 0, sizeof data
);
1271 s0
= evaluate_data_expression(&data
, packet
, lease
,
1273 in_options
, cfg_options
, scope
,
1274 expr
->data
.lcase
, MDL
);
1277 result
->len
= data
.len
;
1278 if (buffer_allocate(&result
->buffer
,
1279 result
->len
+ data
.terminated
,
1281 result
->data
= &result
->buffer
->data
[0];
1282 memcpy(result
->buffer
->data
, data
.data
,
1283 data
.len
+ data
.terminated
);
1284 result
->terminated
= data
.terminated
;
1285 s
= (unsigned char *)result
->data
;
1286 for (i
= 0; i
< result
->len
; i
++, s
++)
1290 log_error("data: lcase: no buffer memory.");
1294 #if defined (DEBUG_EXPRESSIONS)
1295 log_debug("data: ucase (%s) = %s",
1296 s0
? print_hex_1(data
.len
, data
.data
, 30) : "NULL",
1297 s1
? print_hex_2(result
->len
, result
->data
, 30)
1301 data_string_forget(&data
, MDL
);
1305 /* Extract an option. */
1308 s0
= get_option (result
,
1309 expr
-> data
.option
-> universe
,
1310 packet
, lease
, client_state
,
1311 in_options
, cfg_options
, in_options
,
1312 scope
, expr
-> data
.option
-> code
,
1317 #if defined (DEBUG_EXPRESSIONS)
1318 log_debug ("data: option %s.%s = %s",
1319 expr
-> data
.option
-> universe
-> name
,
1320 expr
-> data
.option
-> name
,
1321 s0
? print_hex_1 (result
-> len
, result
-> data
, 60)
1326 case expr_config_option
:
1328 s0
= get_option (result
,
1329 expr
-> data
.option
-> universe
,
1330 packet
, lease
, client_state
,
1331 in_options
, cfg_options
, cfg_options
,
1332 scope
, expr
-> data
.option
-> code
,
1337 #if defined (DEBUG_EXPRESSIONS)
1338 log_debug ("data: config-option %s.%s = %s",
1339 expr
-> data
.option
-> universe
-> name
,
1340 expr
-> data
.option
-> name
,
1341 s0
? print_hex_1 (result
-> len
, result
-> data
, 60)
1346 /* Combine the hardware type and address. */
1348 /* On the client, hardware is our hardware. */
1350 memset(result
, 0, sizeof(*result
));
1351 result
->data
= client_state
->interface
->hw_address
.hbuf
;
1352 result
->len
= client_state
->interface
->hw_address
.hlen
;
1353 #if defined (DEBUG_EXPRESSIONS)
1354 log_debug("data: hardware = %s",
1355 print_hex_1(result
->len
, result
->data
, 60));
1360 /* The server cares about the client's hardware address,
1361 so only in the case where we are examining a packet or have
1362 a lease with a hardware address can we return anything. */
1364 if (packet
!= NULL
&& packet
->raw
!= NULL
) {
1365 if (packet
->raw
->hlen
> sizeof(packet
->raw
->chaddr
)) {
1366 log_error("data: hardware: invalid hlen (%d)\n",
1370 result
->len
= packet
->raw
->hlen
+ 1;
1371 if (buffer_allocate(&result
->buffer
, result
->len
, MDL
)){
1372 result
->data
= &result
->buffer
->data
[0];
1373 result
->buffer
->data
[0] = packet
->raw
->htype
;
1374 memcpy(&result
->buffer
->data
[1],
1375 packet
->raw
->chaddr
, packet
->raw
->hlen
);
1376 result
->terminated
= 0;
1378 log_error("data: hardware: "
1379 "no memory for buffer.");
1382 } else if (lease
!= NULL
) {
1383 result
->len
= lease
->hardware_addr
.hlen
;
1384 if (buffer_allocate(&result
->buffer
, result
->len
, MDL
)){
1385 result
->data
= &result
->buffer
->data
[0];
1386 memcpy(result
->buffer
->data
,
1387 lease
->hardware_addr
.hbuf
, result
->len
);
1388 result
->terminated
= 0;
1390 log_error("data: hardware: "
1391 "no memory for buffer.");
1395 log_error("data: hardware: no raw packet or lease "
1400 #if defined (DEBUG_EXPRESSIONS)
1401 log_debug("data: hardware = %s",
1402 print_hex_1(result
->len
, result
->data
, 60));
1406 /* Extract part of the raw packet. */
1408 if (!packet
|| !packet
-> raw
) {
1409 log_error ("data: packet: raw packet not available");
1413 s0
= evaluate_numeric_expression (&offset
, packet
, lease
,
1415 in_options
, cfg_options
,
1417 expr
-> data
.packet
.offset
);
1418 s1
= evaluate_numeric_expression (&len
,
1419 packet
, lease
, client_state
,
1420 in_options
, cfg_options
,
1422 expr
-> data
.packet
.len
);
1423 if (s0
&& s1
&& offset
< packet
-> packet_length
) {
1424 if (offset
+ len
> packet
-> packet_length
)
1426 packet
-> packet_length
- offset
;
1428 result
-> len
= len
;
1429 if (buffer_allocate (&result
-> buffer
,
1430 result
-> len
, file
, line
)) {
1431 result
-> data
= &result
-> buffer
-> data
[0];
1432 memcpy (result
-> buffer
-> data
,
1433 (((unsigned char *)(packet
-> raw
))
1434 + offset
), result
-> len
);
1435 result
-> terminated
= 0;
1437 log_error ("data: packet: no buffer memory.");
1443 #if defined (DEBUG_EXPRESSIONS)
1444 log_debug ("data: packet (%ld, %ld) = %s",
1446 s2
? print_hex_1 (result
-> len
,
1447 result
-> data
, 60) : NULL
);
1451 /* The encapsulation of all defined options in an
1453 case expr_encapsulate
:
1455 s0
= option_space_encapsulate
1456 (result
, packet
, lease
, client_state
,
1457 in_options
, cfg_options
, scope
,
1458 &expr
-> data
.encapsulate
);
1462 #if defined (DEBUG_EXPRESSIONS)
1463 log_debug ("data: encapsulate (%s) = %s",
1464 expr
-> data
.encapsulate
.data
,
1465 s0
? print_hex_1 (result
-> len
,
1466 result
-> data
, 60) : "NULL");
1470 /* Some constant data... */
1471 case expr_const_data
:
1472 #if defined (DEBUG_EXPRESSIONS)
1473 log_debug ("data: const = %s",
1474 print_hex_1 (expr
-> data
.const_data
.len
,
1475 expr
-> data
.const_data
.data
, 60));
1477 data_string_copy (result
,
1478 &expr
-> data
.const_data
, file
, line
);
1481 /* Hostname lookup... */
1482 case expr_host_lookup
:
1483 s0
= do_host_lookup (result
, expr
-> data
.host_lookup
);
1484 #if defined (DEBUG_EXPRESSIONS)
1485 log_debug ("data: DNS lookup (%s) = %s",
1486 expr
-> data
.host_lookup
-> hostname
,
1488 ? print_dotted_quads (result
-> len
, result
-> data
)
1493 /* Concatenation... */
1495 memset (&data
, 0, sizeof data
);
1496 s0
= evaluate_data_expression (&data
, packet
, lease
,
1498 in_options
, cfg_options
, scope
,
1499 expr
-> data
.concat
[0], MDL
);
1500 memset (&other
, 0, sizeof other
);
1501 s1
= evaluate_data_expression (&other
, packet
, lease
,
1503 in_options
, cfg_options
, scope
,
1504 expr
-> data
.concat
[1], MDL
);
1507 result
-> len
= data
.len
+ other
.len
;
1508 if (!buffer_allocate (&result
-> buffer
,
1509 (result
-> len
+ other
.terminated
),
1511 log_error ("data: concat: no memory");
1513 data_string_forget (&data
, MDL
);
1514 data_string_forget (&other
, MDL
);
1517 result
-> data
= &result
-> buffer
-> data
[0];
1518 memcpy (result
-> buffer
-> data
, data
.data
, data
.len
);
1519 memcpy (&result
-> buffer
-> data
[data
.len
],
1520 other
.data
, other
.len
+ other
.terminated
);
1524 data_string_forget (&data
, MDL
);
1526 data_string_forget (&other
, MDL
);
1527 #if defined (DEBUG_EXPRESSIONS)
1528 log_debug ("data: concat (%s, %s) = %s",
1529 s0
? print_hex_1 (data
.len
, data
.data
, 20) : "NULL",
1530 s1
? print_hex_2 (other
.len
, other
.data
, 20) : "NULL",
1532 ? print_hex_3 (result
-> len
, result
-> data
, 30)
1537 case expr_encode_int8
:
1538 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1540 in_options
, cfg_options
,
1542 expr
-> data
.encode_int
);
1545 if (!buffer_allocate (&result
-> buffer
,
1547 log_error ("data: encode_int8: no memory");
1551 result
-> data
= &result
-> buffer
-> data
[0];
1552 result
-> buffer
-> data
[0] = len
;
1557 #if defined (DEBUG_EXPRESSIONS)
1559 log_debug ("data: encode_int8 (NULL) = NULL");
1561 log_debug ("data: encode_int8 (%ld) = %s", len
,
1562 print_hex_2 (result
-> len
,
1563 result
-> data
, 20));
1568 case expr_encode_int16
:
1569 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1571 in_options
, cfg_options
,
1573 expr
-> data
.encode_int
);
1576 if (!buffer_allocate (&result
-> buffer
, 2,
1578 log_error ("data: encode_int16: no memory");
1582 result
-> data
= &result
-> buffer
-> data
[0];
1583 putUShort (result
-> buffer
-> data
, len
);
1588 #if defined (DEBUG_EXPRESSIONS)
1590 log_debug ("data: encode_int16 (NULL) = NULL");
1592 log_debug ("data: encode_int16 (%ld) = %s", len
,
1593 print_hex_2 (result
-> len
,
1594 result
-> data
, 20));
1598 case expr_encode_int32
:
1599 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1601 in_options
, cfg_options
,
1603 expr
-> data
.encode_int
);
1606 if (!buffer_allocate (&result
-> buffer
, 4,
1608 log_error ("data: encode_int32: no memory");
1612 result
-> data
= &result
-> buffer
-> data
[0];
1613 putULong (result
-> buffer
-> data
, len
);
1618 #if defined (DEBUG_EXPRESSIONS)
1620 log_debug ("data: encode_int32 (NULL) = NULL");
1622 log_debug ("data: encode_int32 (%ld) = %s", len
,
1623 print_hex_2 (result
-> len
,
1624 result
-> data
, 20));
1628 case expr_binary_to_ascii
:
1629 /* Evaluate the base (offset) and width (len): */
1630 s0
= evaluate_numeric_expression
1631 (&offset
, packet
, lease
, client_state
, in_options
,
1632 cfg_options
, scope
, expr
-> data
.b2a
.base
);
1633 s1
= evaluate_numeric_expression (&len
, packet
, lease
,
1635 in_options
, cfg_options
,
1637 expr
-> data
.b2a
.width
);
1639 /* Evaluate the separator string. */
1640 memset (&data
, 0, sizeof data
);
1641 s2
= evaluate_data_expression (&data
, packet
, lease
,
1643 in_options
, cfg_options
, scope
,
1644 expr
-> data
.b2a
.separator
,
1647 /* Evaluate the data to be converted. */
1648 memset (&other
, 0, sizeof other
);
1649 s3
= evaluate_data_expression (&other
, packet
, lease
,
1651 in_options
, cfg_options
, scope
,
1652 expr
-> data
.b2a
.buffer
, MDL
);
1654 if (s0
&& s1
&& s2
&& s3
) {
1657 if (len
!= 8 && len
!= 16 && len
!= 32) {
1658 log_info ("binary_to_ascii: %s %ld!",
1659 "invalid width", len
);
1665 /* The buffer must be a multiple of the number's
1667 if (other
.len
% len
) {
1668 log_info ("binary-to-ascii: %s %d %s %ld!",
1669 "length of buffer", other
.len
,
1670 "not a multiple of width", len
);
1675 /* Count the width of the output. */
1677 for (i
= 0; i
< other
.len
; i
+= len
) {
1680 if (other
.data
[i
] < 8)
1682 else if (other
.data
[i
] < 64)
1686 } else if (offset
== 10) {
1687 if (other
.data
[i
] < 10)
1689 else if (other
.data
[i
] < 100)
1693 } else if (offset
== 16) {
1694 if (other
.data
[i
] < 16)
1699 buflen
+= (converted_length
1703 buflen
+= (converted_length
1706 if (i
+ len
!= other
.len
)
1710 if (!buffer_allocate (&result
-> buffer
,
1711 buflen
+ 1, file
, line
)) {
1712 log_error ("data: binary-to-ascii: no memory");
1716 result
-> data
= &result
-> buffer
-> data
[0];
1717 result
-> len
= buflen
;
1718 result
-> terminated
= 1;
1721 for (i
= 0; i
< other
.len
; i
+= len
) {
1722 buflen
+= (binary_to_ascii
1723 (&result
-> buffer
-> data
[buflen
],
1724 &other
.data
[i
], offset
, len
));
1725 if (i
+ len
!= other
.len
) {
1727 buffer
-> data
[buflen
],
1728 data
.data
, data
.len
);
1732 /* NUL terminate. */
1733 result
-> buffer
-> data
[buflen
] = 0;
1739 #if defined (DEBUG_EXPRESSIONS)
1740 log_debug ("data: binary-to-ascii (%s, %s, %s, %s) = %s",
1741 s0
? print_dec_1 (offset
) : "NULL",
1742 s1
? print_dec_2 (len
) : "NULL",
1743 s2
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1744 s3
? print_hex_2 (other
.len
, other
.data
, 30) : "NULL",
1745 (status
? print_hex_3 (result
-> len
, result
-> data
, 30)
1749 data_string_forget (&data
, MDL
);
1751 data_string_forget (&other
, MDL
);
1757 /* Evaluate the width (len): */
1758 s0
= evaluate_numeric_expression
1759 (&len
, packet
, lease
, client_state
, in_options
,
1760 cfg_options
, scope
, expr
-> data
.reverse
.width
);
1762 /* Evaluate the data. */
1763 memset (&data
, 0, sizeof data
);
1764 s1
= evaluate_data_expression (&data
, packet
, lease
,
1766 in_options
, cfg_options
, scope
,
1767 expr
-> data
.reverse
.buffer
,
1773 /* The buffer must be a multiple of the number's
1775 if (data
.len
% len
) {
1776 log_info ("reverse: %s %d %s %ld!",
1777 "length of buffer", data
.len
,
1778 "not a multiple of width", len
);
1783 /* XXX reverse in place? I don't think we can. */
1784 if (!buffer_allocate (&result
-> buffer
,
1785 data
.len
, file
, line
)) {
1786 log_error ("data: reverse: no memory");
1790 result
-> data
= &result
-> buffer
-> data
[0];
1791 result
-> len
= data
.len
;
1792 result
-> terminated
= 0;
1794 for (i
= 0; i
< data
.len
; i
+= len
) {
1795 memcpy (&result
-> buffer
-> data
[i
],
1796 &data
.data
[data
.len
- i
- len
], len
);
1803 #if defined (DEBUG_EXPRESSIONS)
1804 log_debug ("data: reverse (%s, %s) = %s",
1805 s0
? print_dec_1 (len
) : "NULL",
1806 s1
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1807 (status
? print_hex_3 (result
-> len
, result
-> data
, 30)
1811 data_string_forget (&data
, MDL
);
1816 case expr_leased_address
:
1818 log_debug("data: \"leased-address\" configuration "
1819 "directive: there is no lease associated "
1820 "with this client.");
1823 result
-> len
= lease
-> ip_addr
.len
;
1824 if (buffer_allocate (&result
-> buffer
, result
-> len
,
1826 result
-> data
= &result
-> buffer
-> data
[0];
1827 memcpy (&result
-> buffer
-> data
[0],
1828 lease
-> ip_addr
.iabuf
, lease
-> ip_addr
.len
);
1829 result
-> terminated
= 0;
1831 log_error ("data: leased-address: no memory.");
1834 #if defined (DEBUG_EXPRESSIONS)
1835 log_debug ("data: leased-address = %s",
1836 print_hex_1 (result
-> len
, result
-> data
, 60));
1840 case expr_pick_first_value
:
1841 memset (&data
, 0, sizeof data
);
1842 if ((evaluate_data_expression
1844 lease
, client_state
, in_options
, cfg_options
,
1845 scope
, expr
-> data
.pick_first_value
.car
, MDL
))) {
1846 #if defined (DEBUG_EXPRESSIONS)
1847 log_debug ("data: pick_first_value (%s, xxx)",
1848 print_hex_1 (result
-> len
,
1849 result
-> data
, 40));
1854 if (expr
-> data
.pick_first_value
.cdr
&&
1855 (evaluate_data_expression
1857 lease
, client_state
, in_options
, cfg_options
,
1858 scope
, expr
-> data
.pick_first_value
.cdr
, MDL
))) {
1859 #if defined (DEBUG_EXPRESSIONS)
1860 log_debug ("data: pick_first_value (NULL, %s)",
1861 print_hex_1 (result
-> len
,
1862 result
-> data
, 40));
1867 #if defined (DEBUG_EXPRESSIONS)
1868 log_debug ("data: pick_first_value (NULL, NULL) = NULL");
1872 case expr_host_decl_name
:
1873 if (!lease
|| !lease
-> host
) {
1874 log_error ("data: host_decl_name: not available");
1877 result
-> len
= strlen (lease
-> host
-> name
);
1878 if (buffer_allocate (&result
-> buffer
,
1879 result
-> len
+ 1, file
, line
)) {
1880 result
-> data
= &result
-> buffer
-> data
[0];
1881 strcpy ((char *)&result
-> buffer
-> data
[0],
1882 lease
-> host
-> name
);
1883 result
-> terminated
= 1;
1885 log_error ("data: host-decl-name: no memory.");
1888 #if defined (DEBUG_EXPRESSIONS)
1889 log_debug ("data: host-decl-name = %s", lease
-> host
-> name
);
1894 #if defined (DEBUG_EXPRESSIONS)
1895 log_debug ("data: null = NULL");
1899 case expr_variable_reference
:
1900 if (scope
&& *scope
) {
1901 binding
= find_binding (*scope
, expr
-> data
.variable
);
1903 if (binding
&& binding
-> value
) {
1904 if (binding
-> value
-> type
== binding_data
) {
1905 data_string_copy (result
,
1906 &binding
-> value
-> value
.data
,
1909 } else if (binding
-> value
-> type
!= binding_data
) {
1910 log_error ("binding type %d in %s.",
1911 binding
-> value
-> type
,
1912 "evaluate_data_expression");
1920 #if defined (DEBUG_EXPRESSIONS)
1921 log_debug ("data: %s = %s", expr
-> data
.variable
,
1922 s0
? print_hex_1 (result
-> len
,
1923 result
-> data
, 50) : "NULL");
1928 bv
= (struct binding_value
*)0;
1929 s0
= evaluate_expression (&bv
, packet
, lease
, client_state
,
1930 in_options
, cfg_options
,
1933 if (bv
-> type
!= binding_data
)
1934 log_error ("%s() returned type %d in %s.",
1935 expr
-> data
.funcall
.name
,
1937 "evaluate_data_expression");
1939 data_string_copy (result
, &bv
-> value
.data
,
1941 binding_value_dereference (&bv
, MDL
);
1943 #if defined (DEBUG_EXPRESSIONS)
1944 log_debug ("data: %s = %s", expr
-> data
.funcall
.name
,
1945 s0
? print_hex_1 (result
-> len
,
1946 result
-> data
, 50) : "NULL");
1950 /* Extract the filename. */
1952 if (packet
&& packet
-> raw
-> file
[0]) {
1954 memchr (packet
-> raw
-> file
, 0,
1955 sizeof packet
-> raw
-> file
);
1957 fn
= ((char *)packet
-> raw
-> file
+
1958 sizeof packet
-> raw
-> file
);
1959 result
-> len
= fn
- &(packet
-> raw
-> file
[0]);
1960 if (buffer_allocate (&result
-> buffer
,
1961 result
-> len
+ 1, file
, line
)) {
1962 result
-> data
= &result
-> buffer
-> data
[0];
1963 memcpy (&result
-> buffer
-> data
[0],
1964 packet
-> raw
-> file
,
1966 result
-> buffer
-> data
[result
-> len
] = 0;
1967 result
-> terminated
= 1;
1970 log_error ("data: filename: no memory.");
1976 #if defined (DEBUG_EXPRESSIONS)
1977 log_info ("data: filename = \"%s\"",
1978 s0
? (const char *)(result
-> data
) : "NULL");
1982 /* Extract the server name. */
1984 if (packet
&& packet
-> raw
-> sname
[0]) {
1986 memchr (packet
-> raw
-> sname
, 0,
1987 sizeof packet
-> raw
-> sname
);
1989 fn
= ((char *)packet
-> raw
-> sname
+
1990 sizeof packet
-> raw
-> sname
);
1991 result
-> len
= fn
- &packet
-> raw
-> sname
[0];
1992 if (buffer_allocate (&result
-> buffer
,
1993 result
-> len
+ 1, file
, line
)) {
1994 result
-> data
= &result
-> buffer
-> data
[0];
1995 memcpy (&result
-> buffer
-> data
[0],
1996 packet
-> raw
-> sname
,
1998 result
-> buffer
-> data
[result
-> len
] = 0;
1999 result
-> terminated
= 1;
2002 log_error ("data: sname: no memory.");
2008 #if defined (DEBUG_EXPRESSIONS)
2009 log_info ("data: sname = \"%s\"",
2010 s0
? (const char *)(result
-> data
) : "NULL");
2014 /* Provide the system's local hostname as a return value. */
2015 case expr_gethostname
:
2017 * Allocate a buffer to return.
2019 * The largest valid hostname is maybe 64 octets at a single
2020 * label, or 255 octets if you think a hostname is allowed
2021 * to contain labels (plus termination).
2023 memset(result
, 0, sizeof(*result
));
2024 if (!buffer_allocate(&result
->buffer
, 255, file
, line
)) {
2025 log_error("data: gethostname(): no memory for buffer");
2028 result
->data
= result
->buffer
->data
;
2031 * On successful completion, gethostname() resturns 0. It may
2032 * not null-terminate the string if there was insufficient
2035 if (!gethostname((char *)result
->buffer
->data
, 255)) {
2036 if (result
->buffer
->data
[255] == '\0')
2038 strlen((char *)result
->buffer
->data
);
2044 data_string_forget(result
, MDL
);
2047 /* Find an option within a v6relay context
2049 * The numeric expression in relay indicates which relay
2050 * to try and use as the context. The relays are numbered
2051 * 1 to 32 with 1 being the one closest to the client and
2052 * 32 closest to the server. A value of greater than 33
2053 * indicates using the one closest to the server whatever
2054 * the count. A value of 0 indicates not using the relay
2055 * options, this is included for completeness and consistency
2056 * with the host-identier code.
2058 * The data expression in roption is evaluated in that
2059 * context and the result returned.
2064 memset (&data
, 0, sizeof data
);
2066 /* Evaluate the relay count */
2067 s0
= evaluate_numeric_expression(&len
, packet
, lease
,
2069 in_options
, cfg_options
,
2071 expr
->data
.v6relay
.relay
);
2073 /* no number or an obviously invalid number */
2076 ((packet
== NULL
) ||
2077 (packet
->dhcpv6_container_packet
== NULL
)))) {
2078 #if defined (DEBUG_EXPRESSIONS)
2079 log_debug("data: v6relay(%d) = NULL", len
);
2084 /* Find the correct packet for the requested relay */
2086 relay_packet
= packet
;
2087 relay_options
= in_options
;
2089 (relay_packet
->dhcpv6_container_packet
!= NULL
)) {
2090 relay_packet
= relay_packet
->dhcpv6_container_packet
;
2091 relay_options
= relay_packet
->options
;
2094 /* We wanted a specific relay but were unable to find it */
2095 if ((len
<= MAX_V6RELAY_HOPS
) && (i
!= 0)) {
2096 #if defined (DEBUG_EXPRESSIONS)
2097 log_debug("data: v6relay(%d) = NULL", len
);
2102 s1
= evaluate_data_expression(&data
, relay_packet
, lease
,
2103 client_state
, relay_options
,
2105 expr
->data
.v6relay
.roption
,
2109 data_string_copy(result
, &data
, file
, line
);
2110 data_string_forget(&data
, MDL
);
2113 #if defined (DEBUG_EXPRESSIONS)
2114 log_debug("data: v6relay(%d) = %s", len
,
2115 s1
? print_hex_3(result
->len
, result
->data
, 30)
2122 case expr_not_equal
:
2123 case expr_regex_match
:
2124 case expr_iregex_match
:
2133 case expr_variable_exists
:
2134 log_error ("Boolean opcode in evaluate_data_expression: %d",
2138 case expr_extract_int8
:
2139 case expr_extract_int16
:
2140 case expr_extract_int32
:
2141 case expr_const_int
:
2142 case expr_lease_time
:
2143 case expr_dns_transaction
:
2148 case expr_remainder
:
2149 case expr_binary_and
:
2150 case expr_binary_or
:
2151 case expr_binary_xor
:
2152 case expr_client_state
:
2153 log_error ("Numeric opcode in evaluate_data_expression: %d",
2158 case expr_ns_delete
:
2159 case expr_ns_exists
:
2160 case expr_ns_not_exists
:
2161 log_error ("dns opcode in evaluate_boolean_expression: %d",
2166 log_error ("function definition in evaluate_data_expression");
2173 log_error ("Bogus opcode in evaluate_data_expression: %d", expr
-> op
);
2177 int evaluate_numeric_expression (result
, packet
, lease
, client_state
,
2178 in_options
, cfg_options
, scope
, expr
)
2179 unsigned long *result
;
2180 struct packet
*packet
;
2181 struct lease
*lease
;
2182 struct client_state
*client_state
;
2183 struct option_state
*in_options
;
2184 struct option_state
*cfg_options
;
2185 struct binding_scope
**scope
;
2186 struct expression
*expr
;
2188 struct data_string data
;
2189 int status
, sleft
, sright
;
2191 struct binding
*binding
;
2192 struct binding_value
*bv
;
2193 unsigned long ileft
, iright
;
2196 switch (expr
-> op
) {
2199 case expr_not_equal
:
2200 case expr_regex_match
:
2201 case expr_iregex_match
:
2210 case expr_variable_exists
:
2211 log_error ("Boolean opcode in evaluate_numeric_expression: %d",
2215 case expr_substring
:
2221 case expr_const_data
:
2224 case expr_encapsulate
:
2225 case expr_host_lookup
:
2226 case expr_encode_int8
:
2227 case expr_encode_int16
:
2228 case expr_encode_int32
:
2229 case expr_binary_to_ascii
:
2233 case expr_pick_first_value
:
2234 case expr_host_decl_name
:
2235 case expr_config_option
:
2236 case expr_leased_address
:
2238 case expr_gethostname
:
2240 log_error ("Data opcode in evaluate_numeric_expression: %d",
2244 case expr_extract_int8
:
2245 memset (&data
, 0, sizeof data
);
2246 status
= evaluate_data_expression
2247 (&data
, packet
, lease
, client_state
, in_options
,
2248 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
);
2250 *result
= data
.data
[0];
2251 #if defined (DEBUG_EXPRESSIONS)
2252 log_debug ("num: extract_int8 (%s) = %s",
2253 status
? print_hex_1 (data
.len
, data
.data
, 60) : "NULL",
2254 status
? print_dec_1 (*result
) : "NULL" );
2256 if (status
) data_string_forget (&data
, MDL
);
2259 case expr_extract_int16
:
2260 memset(&data
, 0, sizeof(data
));
2261 status
= (evaluate_data_expression
2262 (&data
, packet
, lease
, client_state
, in_options
,
2263 cfg_options
, scope
, expr
->data
.extract_int
, MDL
));
2264 if (status
&& data
.len
>= 2) {
2265 *result
= getUShort(data
.data
);
2268 #if defined (DEBUG_EXPRESSIONS)
2270 log_debug("num: extract_int16 (%s) = %ld",
2271 print_hex_1(data
.len
, data
.data
, 60),
2274 log_debug("num: extract_int16 (NULL) = NULL");
2278 data_string_forget(&data
, MDL
);
2282 case expr_extract_int32
:
2283 memset (&data
, 0, sizeof data
);
2284 status
= (evaluate_data_expression
2285 (&data
, packet
, lease
, client_state
, in_options
,
2286 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
));
2287 if (status
&& data
.len
>= 4) {
2288 *result
= getULong (data
.data
);
2291 #if defined (DEBUG_EXPRESSIONS)
2293 log_debug ("num: extract_int32 (%s) = %ld",
2294 print_hex_1 (data
.len
, data
.data
, 60),
2297 log_debug ("num: extract_int32 (NULL) = NULL");
2300 if (status
) data_string_forget (&data
, MDL
);
2303 case expr_const_int
:
2304 *result
= expr
-> data
.const_int
;
2305 #if defined (DEBUG_EXPRESSIONS)
2306 log_debug ("number: CONSTANT = %ld", *result
);
2310 case expr_lease_time
:
2312 log_error("data: leased_lease: not available");
2315 if (lease
->ends
< cur_time
) {
2316 log_error("%s %lu when it is now %lu",
2317 "data: lease_time: lease ends at",
2318 (long)(lease
->ends
), (long)cur_time
);
2321 *result
= lease
->ends
- cur_time
;
2322 #if defined (DEBUG_EXPRESSIONS)
2323 log_debug("number: lease-time = (%lu - %lu) = %ld",
2324 (long unsigned)lease
->ends
,
2325 (long unsigned)cur_time
, *result
);
2329 case expr_variable_reference
:
2330 if (scope
&& *scope
) {
2331 binding
= find_binding (*scope
, expr
-> data
.variable
);
2333 if (binding
&& binding
-> value
) {
2334 if (binding
-> value
-> type
== binding_numeric
) {
2335 *result
= binding
-> value
-> value
.intval
;
2338 log_error ("binding type %d in %s.",
2339 binding
-> value
-> type
,
2340 "evaluate_numeric_expression");
2347 #if defined (DEBUG_EXPRESSIONS)
2349 log_debug ("numeric: %s = %ld",
2350 expr
-> data
.variable
, *result
);
2352 log_debug ("numeric: %s = NULL",
2353 expr
-> data
.variable
);
2358 bv
= (struct binding_value
*)0;
2359 status
= evaluate_expression (&bv
, packet
, lease
,
2361 in_options
, cfg_options
,
2364 if (bv
-> type
!= binding_numeric
)
2365 log_error ("%s() returned type %d in %s.",
2366 expr
-> data
.funcall
.name
,
2368 "evaluate_numeric_expression");
2370 *result
= bv
-> value
.intval
;
2371 binding_value_dereference (&bv
, MDL
);
2373 #if defined (DEBUG_EXPRESSIONS)
2374 log_debug ("data: %s = %ld", expr
-> data
.funcall
.name
,
2375 status
? *result
: 0);
2380 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2382 in_options
, cfg_options
,
2384 expr
-> data
.and [0]);
2385 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2387 in_options
, cfg_options
,
2389 expr
-> data
.and [1]);
2391 #if defined (DEBUG_EXPRESSIONS)
2392 if (sleft
&& sright
)
2393 log_debug ("num: %ld + %ld = %ld",
2394 ileft
, iright
, ileft
+ iright
);
2396 log_debug ("num: %ld + NULL = NULL", ileft
);
2398 log_debug ("num: NULL + %ld = NULL", iright
);
2400 if (sleft
&& sright
) {
2401 *result
= ileft
+ iright
;
2407 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2409 in_options
, cfg_options
,
2411 expr
-> data
.and [0]);
2412 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2414 in_options
, cfg_options
,
2416 expr
-> data
.and [1]);
2418 #if defined (DEBUG_EXPRESSIONS)
2419 if (sleft
&& sright
)
2420 log_debug ("num: %ld - %ld = %ld",
2421 ileft
, iright
, ileft
- iright
);
2423 log_debug ("num: %ld - NULL = NULL", ileft
);
2425 log_debug ("num: NULL - %ld = NULL", iright
);
2427 if (sleft
&& sright
) {
2428 *result
= ileft
- iright
;
2434 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2436 in_options
, cfg_options
,
2438 expr
-> data
.and [0]);
2439 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2441 in_options
, cfg_options
,
2443 expr
-> data
.and [1]);
2445 #if defined (DEBUG_EXPRESSIONS)
2446 if (sleft
&& sright
)
2447 log_debug ("num: %ld * %ld = %ld",
2448 ileft
, iright
, ileft
* iright
);
2450 log_debug ("num: %ld * NULL = NULL", ileft
);
2452 log_debug ("num: NULL * %ld = NULL", iright
);
2454 if (sleft
&& sright
) {
2455 *result
= ileft
* iright
;
2461 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2463 in_options
, cfg_options
,
2465 expr
-> data
.and [0]);
2466 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2468 in_options
, cfg_options
,
2470 expr
-> data
.and [1]);
2472 #if defined (DEBUG_EXPRESSIONS)
2473 if (sleft
&& sright
) {
2475 log_debug ("num: %ld / %ld = %ld",
2476 ileft
, iright
, ileft
/ iright
);
2478 log_debug ("num: %ld / %ld = NULL",
2481 log_debug ("num: %ld / NULL = NULL", ileft
);
2483 log_debug ("num: NULL / %ld = NULL", iright
);
2485 if (sleft
&& sright
&& iright
) {
2486 *result
= ileft
/ iright
;
2491 case expr_remainder
:
2492 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2494 in_options
, cfg_options
,
2496 expr
-> data
.and [0]);
2497 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2499 in_options
, cfg_options
,
2501 expr
-> data
.and [1]);
2503 #if defined (DEBUG_EXPRESSIONS)
2504 if (sleft
&& sright
) {
2506 log_debug ("num: %ld %% %ld = %ld",
2507 ileft
, iright
, ileft
% iright
);
2509 log_debug ("num: %ld %% %ld = NULL",
2512 log_debug ("num: %ld %% NULL = NULL", ileft
);
2514 log_debug ("num: NULL %% %ld = NULL", iright
);
2516 if (sleft
&& sright
&& iright
) {
2517 *result
= ileft
% iright
;
2522 case expr_binary_and
:
2523 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2525 in_options
, cfg_options
,
2527 expr
-> data
.and [0]);
2528 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2530 in_options
, cfg_options
,
2532 expr
-> data
.and [1]);
2534 #if defined (DEBUG_EXPRESSIONS)
2535 if (sleft
&& sright
)
2536 log_debug ("num: %ld | %ld = %ld",
2537 ileft
, iright
, ileft
& iright
);
2539 log_debug ("num: %ld & NULL = NULL", ileft
);
2541 log_debug ("num: NULL & %ld = NULL", iright
);
2543 if (sleft
&& sright
) {
2544 *result
= ileft
& iright
;
2549 case expr_binary_or
:
2550 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2552 in_options
, cfg_options
,
2554 expr
-> data
.and [0]);
2555 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2557 in_options
, cfg_options
,
2559 expr
-> data
.and [1]);
2561 #if defined (DEBUG_EXPRESSIONS)
2562 if (sleft
&& sright
)
2563 log_debug ("num: %ld | %ld = %ld",
2564 ileft
, iright
, ileft
| iright
);
2566 log_debug ("num: %ld | NULL = NULL", ileft
);
2568 log_debug ("num: NULL | %ld = NULL", iright
);
2570 if (sleft
&& sright
) {
2571 *result
= ileft
| iright
;
2576 case expr_binary_xor
:
2577 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2579 in_options
, cfg_options
,
2581 expr
-> data
.and [0]);
2582 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2584 in_options
, cfg_options
,
2586 expr
-> data
.and [1]);
2588 #if defined (DEBUG_EXPRESSIONS)
2589 if (sleft
&& sright
)
2590 log_debug ("num: %ld ^ %ld = %ld",
2591 ileft
, iright
, ileft
^ iright
);
2593 log_debug ("num: %ld ^ NULL = NULL", ileft
);
2595 log_debug ("num: NULL ^ %ld = NULL", iright
);
2597 if (sleft
&& sright
) {
2598 *result
= ileft
^ iright
;
2603 case expr_client_state
:
2605 #if defined (DEBUG_EXPRESSIONS)
2606 log_debug ("num: client-state = %d",
2607 client_state
-> state
);
2609 *result
= client_state
-> state
;
2612 #if defined (DEBUG_EXPRESSIONS)
2613 log_debug ("num: client-state = NULL");
2619 log_error ("function definition in evaluate_numeric_expr");
2626 log_fatal("Impossible case at %s:%d. Undefined operator "
2627 "%d.", MDL
, expr
->op
);
2631 log_error ("evaluate_numeric_expression: bogus opcode %d", expr
-> op
);
2636 * Return data hanging off of an option cache structure, or if there
2637 * isn't any, evaluate the expression hanging off of it and return the
2638 * result of that evaluation. There should never be both an expression
2639 * and a valid data_string.
2641 * returns 0 if there wasn't an expression or it couldn't be evaluated
2642 * returns non-zero if there was an expression or string that was evaluated
2643 * When it returns zero the arguements, in particualr resutl, should not
2647 int evaluate_option_cache (result
, packet
, lease
, client_state
,
2648 in_options
, cfg_options
, scope
, oc
, file
, line
)
2649 struct data_string
*result
;
2650 struct packet
*packet
;
2651 struct lease
*lease
;
2652 struct client_state
*client_state
;
2653 struct option_state
*in_options
;
2654 struct option_state
*cfg_options
;
2655 struct binding_scope
**scope
;
2656 struct option_cache
*oc
;
2660 if (oc
->data
.data
!= NULL
) {
2661 data_string_copy (result
, &oc
-> data
, file
, line
);
2664 if (!oc
-> expression
)
2666 return evaluate_data_expression (result
, packet
, lease
, client_state
,
2667 in_options
, cfg_options
, scope
,
2668 oc
-> expression
, file
, line
);
2671 /* Evaluate an option cache and extract a boolean from the result,
2672 returning the boolean. Return false if there is no data. */
2674 int evaluate_boolean_option_cache (ignorep
, packet
,
2675 lease
, client_state
, in_options
,
2676 cfg_options
, scope
, oc
, file
, line
)
2678 struct packet
*packet
;
2679 struct lease
*lease
;
2680 struct client_state
*client_state
;
2681 struct option_state
*in_options
;
2682 struct option_state
*cfg_options
;
2683 struct binding_scope
**scope
;
2684 struct option_cache
*oc
;
2688 struct data_string ds
;
2691 /* So that we can be called with option_lookup as an argument. */
2692 if (!oc
|| !in_options
)
2695 memset (&ds
, 0, sizeof ds
);
2696 if (!evaluate_option_cache (&ds
, packet
,
2697 lease
, client_state
, in_options
,
2698 cfg_options
, scope
, oc
, file
, line
))
2701 /* The boolean option cache is actually a trinary value. Zero is
2702 * off, one is on, and 2 is 'ignore'.
2705 result
= ds
.data
[0];
2708 if (ignorep
!= NULL
)
2710 } else if (ignorep
!= NULL
)
2714 data_string_forget (&ds
, MDL
);
2719 /* Evaluate a boolean expression and return the result of the evaluation,
2720 or FALSE if it failed. */
2722 int evaluate_boolean_expression_result (ignorep
, packet
, lease
, client_state
,
2723 in_options
, cfg_options
, scope
, expr
)
2725 struct packet
*packet
;
2726 struct lease
*lease
;
2727 struct client_state
*client_state
;
2728 struct option_state
*in_options
;
2729 struct option_state
*cfg_options
;
2730 struct binding_scope
**scope
;
2731 struct expression
*expr
;
2735 /* So that we can be called with option_lookup as an argument. */
2739 if (!evaluate_boolean_expression (&result
, packet
, lease
, client_state
,
2740 in_options
, cfg_options
,
2753 /* Dereference an expression node, and if the reference count goes to zero,
2754 dereference any data it refers to, and then free it. */
2755 void expression_dereference (eptr
, file
, line
)
2756 struct expression
**eptr
;
2760 struct expression
*expr
= *eptr
;
2762 /* Zero the pointer. */
2763 *eptr
= (struct expression
*)0;
2765 /* Decrement the reference count. If it's nonzero, we're
2768 rc_register (file
, line
, eptr
, expr
, expr
-> refcnt
, 1, RC_MISC
);
2769 if (expr
-> refcnt
> 0)
2771 if (expr
-> refcnt
< 0) {
2772 log_error ("%s(%d): negative refcnt!", file
, line
);
2773 #if defined (DEBUG_RC_HISTORY)
2774 dump_rc_history (expr
);
2776 #if defined (POINTER_DEBUG)
2783 /* Dereference subexpressions. */
2784 switch (expr
-> op
) {
2785 /* All the binary operators can be handled the same way. */
2787 case expr_not_equal
:
2788 case expr_regex_match
:
2789 case expr_iregex_match
:
2797 case expr_remainder
:
2798 case expr_binary_and
:
2799 case expr_binary_or
:
2800 case expr_binary_xor
:
2801 case expr_client_state
:
2802 if (expr
-> data
.equal
[0])
2803 expression_dereference (&expr
-> data
.equal
[0],
2805 if (expr
-> data
.equal
[1])
2806 expression_dereference (&expr
-> data
.equal
[1],
2810 case expr_substring
:
2811 if (expr
-> data
.substring
.expr
)
2812 expression_dereference (&expr
-> data
.substring
.expr
,
2814 if (expr
-> data
.substring
.offset
)
2815 expression_dereference (&expr
-> data
.substring
.offset
,
2817 if (expr
-> data
.substring
.len
)
2818 expression_dereference (&expr
-> data
.substring
.len
,
2823 if (expr
-> data
.suffix
.expr
)
2824 expression_dereference (&expr
-> data
.suffix
.expr
,
2826 if (expr
-> data
.suffix
.len
)
2827 expression_dereference (&expr
-> data
.suffix
.len
,
2832 if (expr
->data
.lcase
)
2833 expression_dereference(&expr
->data
.lcase
, MDL
);
2837 if (expr
->data
.ucase
)
2838 expression_dereference(&expr
->data
.ucase
, MDL
);
2842 if (expr
-> data
.not)
2843 expression_dereference (&expr
-> data
.not, file
, line
);
2847 if (expr
-> data
.packet
.offset
)
2848 expression_dereference (&expr
-> data
.packet
.offset
,
2850 if (expr
-> data
.packet
.len
)
2851 expression_dereference (&expr
-> data
.packet
.len
,
2855 case expr_extract_int8
:
2856 case expr_extract_int16
:
2857 case expr_extract_int32
:
2858 if (expr
-> data
.extract_int
)
2859 expression_dereference (&expr
-> data
.extract_int
,
2863 case expr_encode_int8
:
2864 case expr_encode_int16
:
2865 case expr_encode_int32
:
2866 if (expr
-> data
.encode_int
)
2867 expression_dereference (&expr
-> data
.encode_int
,
2871 case expr_encapsulate
:
2872 case expr_const_data
:
2873 data_string_forget (&expr
-> data
.const_data
, file
, line
);
2876 case expr_host_lookup
:
2877 if (expr
-> data
.host_lookup
)
2878 dns_host_entry_dereference (&expr
-> data
.host_lookup
,
2882 case expr_binary_to_ascii
:
2883 if (expr
-> data
.b2a
.base
)
2884 expression_dereference (&expr
-> data
.b2a
.base
,
2886 if (expr
-> data
.b2a
.width
)
2887 expression_dereference (&expr
-> data
.b2a
.width
,
2889 if (expr
-> data
.b2a
.separator
)
2890 expression_dereference (&expr
-> data
.b2a
.separator
,
2892 if (expr
-> data
.b2a
.buffer
)
2893 expression_dereference (&expr
-> data
.b2a
.buffer
,
2897 case expr_pick_first_value
:
2898 if (expr
-> data
.pick_first_value
.car
)
2899 expression_dereference (&expr
-> data
.pick_first_value
.car
,
2901 if (expr
-> data
.pick_first_value
.cdr
)
2902 expression_dereference (&expr
-> data
.pick_first_value
.cdr
,
2907 if (expr
-> data
.reverse
.width
)
2908 expression_dereference (&expr
-> data
.reverse
.width
,
2910 if (expr
-> data
.reverse
.buffer
)
2911 expression_dereference
2912 (&expr
-> data
.reverse
.buffer
, file
, line
);
2915 case expr_variable_reference
:
2916 case expr_variable_exists
:
2917 if (expr
-> data
.variable
)
2918 dfree (expr
-> data
.variable
, file
, line
);
2922 if (expr
-> data
.funcall
.name
)
2923 dfree (expr
-> data
.funcall
.name
, file
, line
);
2924 if (expr
-> data
.funcall
.arglist
)
2925 expression_dereference (&expr
-> data
.funcall
.arglist
,
2930 if (expr
-> data
.arg
.val
)
2931 expression_dereference (&expr
-> data
.arg
.val
,
2933 if (expr
-> data
.arg
.next
)
2934 expression_dereference (&expr
-> data
.arg
.next
,
2939 fundef_dereference (&expr
-> data
.func
, file
, line
);
2943 if (expr
->data
.v6relay
.relay
)
2944 expression_dereference(&expr
->data
.v6relay
.relay
,
2947 if (expr
->data
.v6relay
.roption
)
2948 expression_dereference(&expr
->data
.v6relay
.roption
,
2952 /* No subexpressions. */
2953 case expr_leased_address
:
2954 case expr_lease_time
:
2957 case expr_const_int
:
2964 case expr_gethostname
:
2970 free_expression (expr
, MDL
);
2973 int is_boolean_expression (expr
)
2974 struct expression
*expr
;
2976 return (expr
-> op
== expr_check
||
2977 expr
-> op
== expr_exists
||
2978 expr
-> op
== expr_variable_exists
||
2979 expr
-> op
== expr_equal
||
2980 expr
-> op
== expr_not_equal
||
2981 expr
->op
== expr_regex_match
||
2982 expr
->op
== expr_iregex_match
||
2983 expr
-> op
== expr_and
||
2984 expr
-> op
== expr_or
||
2985 expr
-> op
== expr_not
||
2986 expr
-> op
== expr_known
||
2987 expr
-> op
== expr_static
);
2990 int is_data_expression (expr
)
2991 struct expression
*expr
;
2993 return (expr
->op
== expr_substring
||
2994 expr
->op
== expr_suffix
||
2995 expr
->op
== expr_lcase
||
2996 expr
->op
== expr_ucase
||
2997 expr
->op
== expr_option
||
2998 expr
->op
== expr_hardware
||
2999 expr
->op
== expr_const_data
||
3000 expr
->op
== expr_packet
||
3001 expr
->op
== expr_concat
||
3002 expr
->op
== expr_encapsulate
||
3003 expr
->op
== expr_encode_int8
||
3004 expr
->op
== expr_encode_int16
||
3005 expr
->op
== expr_encode_int32
||
3006 expr
->op
== expr_host_lookup
||
3007 expr
->op
== expr_binary_to_ascii
||
3008 expr
->op
== expr_filename
||
3009 expr
->op
== expr_sname
||
3010 expr
->op
== expr_reverse
||
3011 expr
->op
== expr_pick_first_value
||
3012 expr
->op
== expr_host_decl_name
||
3013 expr
->op
== expr_leased_address
||
3014 expr
->op
== expr_config_option
||
3015 expr
->op
== expr_null
||
3016 expr
->op
== expr_gethostname
||
3017 expr
->op
== expr_v6relay
);
3020 int is_numeric_expression (expr
)
3021 struct expression
*expr
;
3023 return (expr
-> op
== expr_extract_int8
||
3024 expr
-> op
== expr_extract_int16
||
3025 expr
-> op
== expr_extract_int32
||
3026 expr
-> op
== expr_const_int
||
3027 expr
-> op
== expr_lease_time
||
3028 expr
-> op
== expr_add
||
3029 expr
-> op
== expr_subtract
||
3030 expr
-> op
== expr_multiply
||
3031 expr
-> op
== expr_divide
||
3032 expr
-> op
== expr_remainder
||
3033 expr
-> op
== expr_binary_and
||
3034 expr
-> op
== expr_binary_or
||
3035 expr
-> op
== expr_binary_xor
||
3036 expr
-> op
== expr_client_state
);
3039 int is_compound_expression (expr
)
3040 struct expression
*expr
;
3042 return (expr
-> op
== expr_substring
||
3043 expr
-> op
== expr_suffix
||
3044 expr
-> op
== expr_option
||
3045 expr
-> op
== expr_concat
||
3046 expr
-> op
== expr_encode_int8
||
3047 expr
-> op
== expr_encode_int16
||
3048 expr
-> op
== expr_encode_int32
||
3049 expr
-> op
== expr_binary_to_ascii
||
3050 expr
-> op
== expr_reverse
||
3051 expr
-> op
== expr_pick_first_value
||
3052 expr
-> op
== expr_config_option
||
3053 expr
-> op
== expr_extract_int8
||
3054 expr
-> op
== expr_extract_int16
||
3055 expr
-> op
== expr_extract_int32
||
3056 expr
-> op
== expr_v6relay
);
3059 static int op_val (enum expr_op
);
3061 static int op_val (op
)
3069 case expr_substring
:
3074 case expr_encapsulate
:
3075 case expr_host_lookup
:
3080 case expr_const_data
:
3081 case expr_extract_int8
:
3082 case expr_extract_int16
:
3083 case expr_extract_int32
:
3084 case expr_encode_int8
:
3085 case expr_encode_int16
:
3086 case expr_encode_int32
:
3087 case expr_const_int
:
3089 case expr_variable_exists
:
3091 case expr_binary_to_ascii
:
3095 case expr_pick_first_value
:
3096 case expr_host_decl_name
:
3097 case expr_config_option
:
3098 case expr_leased_address
:
3099 case expr_lease_time
:
3100 case expr_dns_transaction
:
3102 case expr_variable_reference
:
3104 case expr_ns_delete
:
3105 case expr_ns_exists
:
3106 case expr_ns_not_exists
:
3110 /* XXXDPN: Need to assign sane precedences to these. */
3111 case expr_binary_and
:
3112 case expr_binary_or
:
3113 case expr_binary_xor
:
3114 case expr_client_state
:
3115 case expr_gethostname
:
3120 case expr_not_equal
:
3121 case expr_regex_match
:
3122 case expr_iregex_match
:
3135 case expr_remainder
:
3141 int op_precedence (op1
, op2
)
3142 enum expr_op op1
, op2
;
3144 return op_val (op1
) - op_val (op2
);
3147 enum expression_context
expression_context (struct expression
*expr
)
3149 if (is_data_expression (expr
))
3150 return context_data
;
3151 if (is_numeric_expression (expr
))
3152 return context_numeric
;
3153 if (is_boolean_expression (expr
))
3154 return context_boolean
;
3158 enum expression_context
op_context (op
)
3162 /* XXX Why aren't these specific? */
3167 case expr_substring
:
3172 case expr_encapsulate
:
3173 case expr_host_lookup
:
3178 case expr_const_data
:
3179 case expr_extract_int8
:
3180 case expr_extract_int16
:
3181 case expr_extract_int32
:
3182 case expr_encode_int8
:
3183 case expr_encode_int16
:
3184 case expr_encode_int32
:
3185 case expr_const_int
:
3187 case expr_variable_exists
:
3189 case expr_binary_to_ascii
:
3193 case expr_pick_first_value
:
3194 case expr_host_decl_name
:
3195 case expr_config_option
:
3196 case expr_leased_address
:
3197 case expr_lease_time
:
3199 case expr_variable_reference
:
3201 case expr_ns_delete
:
3202 case expr_ns_exists
:
3203 case expr_ns_not_exists
:
3204 case expr_dns_transaction
:
3208 case expr_gethostname
:
3213 case expr_not_equal
:
3214 case expr_regex_match
:
3215 case expr_iregex_match
:
3216 return context_data
;
3219 return context_boolean
;
3222 return context_boolean
;
3228 case expr_remainder
:
3229 case expr_binary_and
:
3230 case expr_binary_or
:
3231 case expr_binary_xor
:
3232 case expr_client_state
:
3233 return context_numeric
;
3238 int write_expression (file
, expr
, col
, indent
, firstp
)
3240 struct expression
*expr
;
3245 struct expression
*e
;
3251 /* If this promises to be a fat expression, start a new line. */
3252 if (!firstp
&& is_compound_expression (expr
)) {
3253 indent_spaces (file
, indent
);
3257 switch (expr
-> op
) {
3259 col
= token_print_indent (file
, col
, indent
, "", "", "null");
3263 col
= token_print_indent (file
, col
, indent
, "", "", "check");
3264 col
= token_print_indent_concat (file
, col
, indent
,
3266 expr
-> data
.check
-> name
,
3270 case expr_regex_match
:
3274 case expr_iregex_match
:
3278 case expr_not_equal
:
3285 col
= write_expression (file
, expr
-> data
.equal
[0],
3287 col
= token_print_indent (file
, col
, indent
, " ", " ", s
);
3288 col
= write_expression (file
, expr
-> data
.equal
[1],
3289 col
, indent
+ 2, 0);
3292 case expr_substring
:
3293 col
= token_print_indent (file
, col
, indent
, "", "",
3295 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3297 col
= write_expression (file
, expr
-> data
.substring
.expr
,
3299 col
= token_print_indent (file
, col
, indent
, "", " ", ",");
3300 col
= write_expression (file
, expr
-> data
.substring
.offset
,
3302 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3303 col
= write_expression (file
, expr
-> data
.substring
.len
,
3305 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3309 col
= token_print_indent (file
, col
, indent
, "", "", "suffix");
3310 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3312 col
= write_expression (file
, expr
-> data
.suffix
.expr
,
3314 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3315 col
= write_expression (file
, expr
-> data
.suffix
.len
,
3317 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3321 col
= token_print_indent(file
, col
, indent
, "", "", "lcase");
3322 col
= token_print_indent(file
, col
, indent
, " ", "", "(");
3324 col
= write_expression(file
, expr
->data
.lcase
, col
, scol
, 1);
3325 col
= token_print_indent(file
, col
, indent
, "", "", ")");
3329 col
= token_print_indent(file
, col
, indent
, "", "", "ucase");
3330 col
= token_print_indent(file
, col
, indent
, " ", "", "(");
3332 col
= write_expression(file
, expr
->data
.ucase
, col
, scol
, 1);
3333 col
= token_print_indent(file
, col
, indent
, "", "", ")");
3338 col
= token_print_indent (file
, col
, indent
, "", "",
3340 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3344 col
= write_expression (file
, e
-> data
.concat
[0],
3347 if (!e
-> data
.concat
[1])
3349 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3350 if (e
-> data
.concat
[1] -> op
== expr_concat
) {
3351 e
= e
-> data
.concat
[1];
3354 col
= write_expression (file
, e
-> data
.concat
[1],
3357 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3360 case expr_host_lookup
:
3361 col
= token_print_indent (file
, col
, indent
, "", "",
3363 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3364 col
= token_print_indent_concat
3365 (file
, col
, indent
, "", "",
3366 "\"", expr
-> data
.host_lookup
-> hostname
, "\"",
3368 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3387 case expr_remainder
:
3391 case expr_binary_and
:
3395 case expr_binary_or
:
3399 case expr_binary_xor
:
3412 col
= token_print_indent (file
, col
, indent
, "", " ", "not");
3413 col
= write_expression (file
,
3414 expr
-> data
.not, col
, indent
+ 2, 1);
3421 col
= token_print_indent (file
, col
, indent
, "", "", s
);
3423 if (expr
-> data
.option
-> universe
!= &dhcp_universe
) {
3424 col
= token_print_indent (file
, col
, indent
,
3426 (expr
-> data
.option
->
3428 col
= token_print_indent (file
, col
, indent
, "", "",
3430 col
= token_print_indent (file
, col
, indent
, "", "",
3431 expr
-> data
.option
-> name
);
3433 col
= token_print_indent (file
, col
, indent
, " ", "",
3434 expr
-> data
.option
-> name
);
3439 col
= token_print_indent (file
, col
, indent
, "", "",
3444 col
= token_print_indent (file
, col
, indent
, "", "",
3446 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3448 col
= write_expression (file
, expr
-> data
.packet
.offset
,
3450 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3451 col
= write_expression (file
, expr
-> data
.packet
.len
,
3453 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3456 case expr_const_data
:
3457 col
= token_indent_data_string (file
, col
, indent
, "", "",
3458 &expr
-> data
.const_data
);
3461 case expr_extract_int8
:
3464 col
= token_print_indent (file
, col
, indent
, "", "",
3466 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3468 col
= write_expression (file
, expr
-> data
.extract_int
,
3470 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3471 sprintf (obuf
, "%d", width
);
3472 col
= token_print_indent (file
, col
, scol
, " ", "", obuf
);
3473 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3476 case expr_extract_int16
:
3480 case expr_extract_int32
:
3484 case expr_encode_int8
:
3487 col
= token_print_indent (file
, col
, indent
, "", "",
3489 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3491 col
= write_expression (file
, expr
-> data
.extract_int
,
3493 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3494 sprintf (obuf
, "%d", width
);
3495 col
= token_print_indent (file
, col
, scol
, " ", "", obuf
);
3496 col
= token_print_indent (file
, col
, indent
, "", "",
3500 case expr_encode_int16
:
3504 case expr_encode_int32
:
3508 case expr_const_int
:
3509 sprintf (obuf
, "%lu", expr
-> data
.const_int
);
3510 col
= token_print_indent (file
, col
, indent
, "", "", obuf
);
3515 goto print_option_name
;
3517 case expr_encapsulate
:
3518 col
= token_print_indent (file
, col
, indent
, "", "",
3520 col
= token_indent_data_string (file
, col
, indent
, " ", "",
3521 &expr
-> data
.encapsulate
);
3525 col
= token_print_indent (file
, col
, indent
, "", "", "known");
3529 col
= token_print_indent (file
, col
, indent
, "", "",
3531 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3533 col
= write_expression (file
, expr
-> data
.reverse
.width
,
3535 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3536 col
= write_expression (file
, expr
-> data
.reverse
.buffer
,
3538 col
= token_print_indent (file
, col
, indent
, "", "",
3542 case expr_leased_address
:
3543 col
= token_print_indent (file
, col
, indent
, "", "",
3547 case expr_client_state
:
3548 col
= token_print_indent (file
, col
, indent
, "", "",
3552 case expr_binary_to_ascii
:
3553 col
= token_print_indent (file
, col
, indent
, "", "",
3555 col
= token_print_indent (file
, col
, indent
, " ", "",
3558 col
= write_expression (file
, expr
-> data
.b2a
.base
,
3560 col
= token_print_indent (file
, col
, scol
, "", " ",
3562 col
= write_expression (file
, expr
-> data
.b2a
.width
,
3564 col
= token_print_indent (file
, col
, scol
, "", " ",
3566 col
= write_expression (file
, expr
-> data
.b2a
.separator
,
3568 col
= token_print_indent (file
, col
, scol
, "", " ",
3570 col
= write_expression (file
, expr
-> data
.b2a
.buffer
,
3572 col
= token_print_indent (file
, col
, indent
, "", "",
3576 case expr_config_option
:
3577 s
= "config-option";
3578 goto print_option_name
;
3580 case expr_host_decl_name
:
3581 col
= token_print_indent (file
, col
, indent
, "", "",
3585 case expr_pick_first_value
:
3587 col
= token_print_indent (file
, col
, indent
, "", "",
3589 col
= token_print_indent (file
, col
, indent
, " ", "",
3594 col
= write_expression (file
,
3595 e
-> data
.pick_first_value
.car
,
3598 /* We're being very lisp-like right now - instead of
3599 representing this expression as (first middle . last) we're
3600 representing it as (first middle last), which means that the
3601 tail cdr is always nil. Apologies to non-wisp-lizards - may
3602 this obscure way of describing the problem motivate you to
3603 learn more about the one true computing language. */
3604 if (!e
-> data
.pick_first_value
.cdr
)
3606 col
= token_print_indent (file
, col
, scol
, "", " ",
3608 if (e
-> data
.pick_first_value
.cdr
-> op
==
3609 expr_pick_first_value
) {
3610 e
= e
-> data
.pick_first_value
.cdr
;
3613 col
= write_expression (file
,
3614 e
-> data
.pick_first_value
.cdr
,
3617 col
= token_print_indent (file
, col
, indent
, "", "",
3621 case expr_lease_time
:
3622 col
= token_print_indent (file
, col
, indent
, "", "",
3627 col
= token_print_indent (file
, col
, indent
, "", "",
3632 col
= token_print_indent (file
, col
, indent
, "", "", "null");
3635 case expr_variable_reference
:
3636 col
= token_print_indent (file
, indent
, indent
, "", "",
3637 expr
-> data
.variable
);
3640 case expr_variable_exists
:
3641 col
= token_print_indent (file
, indent
, indent
, "", "",
3643 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3644 col
= token_print_indent (file
, col
, indent
, "", "",
3645 expr
-> data
.variable
);
3646 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3649 case expr_gethostname
:
3650 col
= token_print_indent(file
, col
, indent
, "", "",
3655 col
= token_print_indent(file
, indent
, indent
, "", "",
3656 expr
->data
.funcall
.name
);
3657 col
= token_print_indent(file
, col
, indent
, " ", "", "(");
3660 e
= expr
->data
.funcall
.arglist
;
3663 col
= token_print_indent(file
, col
, indent
,
3666 col
= write_expression(file
, e
->data
.arg
.val
, col
,
3669 e
= e
->data
.arg
.next
;
3672 col
= token_print_indent(file
, col
, indent
, "", "", ")");
3676 col
= token_print_indent(file
, col
, indent
, "", "",
3678 col
= token_print_indent(file
, col
, indent
, " ", "", "(");
3680 col
= write_expression(file
, expr
->data
.v6relay
.relay
,
3682 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3683 col
= write_expression(file
, expr
->data
.v6relay
.roption
,
3685 col
= token_print_indent(file
, col
, indent
, "", "", ")");
3689 log_fatal ("invalid expression type in print_expression: %d",
3695 struct binding
*find_binding (struct binding_scope
*scope
, const char *name
)
3698 struct binding_scope
*s
;
3700 for (s
= scope
; s
; s
= s
-> outer
) {
3701 for (bp
= s
-> bindings
; bp
; bp
= bp
-> next
) {
3702 if (!strcasecmp (name
, bp
-> name
)) {
3707 return (struct binding
*)0;
3710 int free_bindings (struct binding_scope
*scope
, const char *file
, int line
)
3712 struct binding
*bp
, *next
;
3714 for (bp
= scope
-> bindings
; bp
; bp
= next
) {
3717 dfree (bp
-> name
, file
, line
);
3719 binding_value_dereference (&bp
-> value
, file
, line
);
3720 dfree (bp
, file
, line
);
3722 scope
-> bindings
= (struct binding
*)0;
3726 int binding_scope_dereference (ptr
, file
, line
)
3727 struct binding_scope
**ptr
;
3731 struct binding_scope
*binding_scope
;
3733 if (!ptr
|| !*ptr
) {
3734 log_error ("%s(%d): null pointer", file
, line
);
3735 #if defined (POINTER_DEBUG)
3742 binding_scope
= *ptr
;
3743 *ptr
= (struct binding_scope
*)0;
3744 --binding_scope
-> refcnt
;
3745 rc_register (file
, line
, ptr
,
3746 binding_scope
, binding_scope
-> refcnt
, 1, RC_MISC
);
3747 if (binding_scope
-> refcnt
> 0)
3750 if (binding_scope
-> refcnt
< 0) {
3751 log_error ("%s(%d): negative refcnt!", file
, line
);
3752 #if defined (DEBUG_RC_HISTORY)
3753 dump_rc_history (binding_scope
);
3755 #if defined (POINTER_DEBUG)
3762 free_bindings (binding_scope
, file
, line
);
3763 if (binding_scope
-> outer
)
3764 binding_scope_dereference (&binding_scope
-> outer
, MDL
);
3765 dfree (binding_scope
, file
, line
);
3769 int fundef_dereference (ptr
, file
, line
)
3770 struct fundef
**ptr
;
3775 struct string_list
*sp
, *next
;
3777 if ((ptr
== NULL
) || (*ptr
== NULL
)) {
3778 log_error ("%s(%d): null pointer", file
, line
);
3779 #if defined (POINTER_DEBUG)
3788 rc_register (file
, line
, ptr
, bp
, bp
-> refcnt
, 1, RC_MISC
);
3789 if (bp
-> refcnt
< 0) {
3790 log_error ("%s(%d): negative refcnt!", file
, line
);
3791 #if defined (DEBUG_RC_HISTORY)
3792 dump_rc_history (bp
);
3794 #if defined (POINTER_DEBUG)
3800 if (!bp
-> refcnt
) {
3801 for (sp
= bp
-> args
; sp
; sp
= next
) {
3803 dfree (sp
, file
, line
);
3805 if (bp
-> statements
)
3806 executable_statement_dereference (&bp
-> statements
,
3808 dfree (bp
, file
, line
);
3810 *ptr
= (struct fundef
*)0;
3814 #if defined (NOTYET) /* Post 3.0 final. */
3815 int data_subexpression_length (int *rv
,
3816 struct expression
*expr
)
3818 int crhs
, clhs
, llhs
, lrhs
;
3819 switch (expr
-> op
) {
3820 case expr_substring
:
3821 if (expr
-> data
.substring
.len
&&
3822 expr
-> data
.substring
.len
-> op
== expr_const_int
) {
3824 (int)expr
-> data
.substring
.len
-> data
.const_int
);
3831 if (expr
-> data
.suffix
.len
&&
3832 expr
-> data
.suffix
.len
-> op
== expr_const_int
) {
3834 (int)expr
-> data
.suffix
.len
-> data
.const_int
);
3840 return data_subexpression_length(rv
, expr
->data
.lcase
);
3843 return data_subexpression_length(rv
, expr
->data
.ucase
);
3846 clhs
= data_subexpression_length (&llhs
,
3847 expr
-> data
.concat
[0]);
3848 crhs
= data_subexpression_length (&lrhs
,
3849 expr
-> data
.concat
[1]);
3850 if (crhs
== 0 || clhs
== 0)
3859 case expr_const_data
:
3860 *rv
= expr
-> data
.const_data
.len
;
3864 return data_subexpression_length (rv
,
3865 expr
-> data
.reverse
.buffer
);
3867 case expr_leased_address
:
3868 case expr_lease_time
:
3872 case expr_pick_first_value
:
3873 clhs
= data_subexpression_length (&llhs
,
3874 expr
-> data
.concat
[0]);
3875 crhs
= data_subexpression_length (&lrhs
,
3876 expr
-> data
.concat
[1]);
3877 if (crhs
== 0 || clhs
== 0)
3886 clhs
= data_subexpression_length (&llhs
,
3887 expr
-> data
.v6relay
.relay
);
3888 crhs
= data_subexpression_length (&lrhs
,
3889 expr
-> data
.v6relay
.roption
);
3890 if (crhs
== 0 || clhs
== 0)
3896 case expr_binary_to_ascii
:
3897 case expr_config_option
:
3898 case expr_host_decl_name
:
3899 case expr_encapsulate
:
3902 case expr_host_lookup
:
3908 case expr_regex_match
:
3909 case expr_iregex_match
:
3913 case expr_extract_int8
:
3914 case expr_extract_int16
:
3915 case expr_extract_int32
:
3916 case expr_encode_int8
:
3917 case expr_encode_int16
:
3918 case expr_encode_int32
:
3919 case expr_const_int
:
3923 case expr_not_equal
:
3925 case expr_variable_exists
:
3926 case expr_variable_reference
:
3934 case expr_remainder
:
3935 case expr_binary_and
:
3936 case expr_binary_or
:
3937 case expr_binary_xor
:
3938 case expr_client_state
:
3939 case expr_gethostname
:
3945 int expr_valid_for_context (struct expression
*expr
,
3946 enum expression_context context
)
3948 /* We don't know at parse time what type of value a function may
3949 return, so we can't flag an error on it. */
3950 if (expr
-> op
== expr_funcall
||
3951 expr
-> op
== expr_variable_reference
)
3958 case context_boolean
:
3959 if (is_boolean_expression (expr
))
3964 if (is_data_expression (expr
))
3968 case context_numeric
:
3969 if (is_numeric_expression (expr
))
3973 case context_data_or_numeric
:
3974 if (is_numeric_expression (expr
) ||
3975 is_data_expression (expr
)) {
3980 case context_function
:
3981 if (expr
-> op
== expr_function
)
3989 struct binding
*create_binding (struct binding_scope
**scope
, const char *name
)
3991 struct binding
*binding
;
3994 if (!binding_scope_allocate (scope
, MDL
))
3995 return (struct binding
*)0;
3998 binding
= find_binding (*scope
, name
);
4000 binding
= dmalloc (sizeof *binding
, MDL
);
4002 return (struct binding
*)0;
4004 memset (binding
, 0, sizeof *binding
);
4005 binding
-> name
= dmalloc (strlen (name
) + 1, MDL
);
4006 if (!binding
-> name
) {
4007 dfree (binding
, MDL
);
4008 return (struct binding
*)0;
4010 strcpy (binding
-> name
, name
);
4012 binding
-> next
= (*scope
) -> bindings
;
4013 (*scope
) -> bindings
= binding
;
4020 int bind_ds_value (struct binding_scope
**scope
,
4022 struct data_string
*value
)
4024 struct binding
*binding
;
4026 binding
= create_binding (scope
, name
);
4030 if (binding
-> value
)
4031 binding_value_dereference (&binding
-> value
, MDL
);
4033 if (!binding_value_allocate (&binding
-> value
, MDL
))
4036 data_string_copy (&binding
-> value
-> value
.data
, value
, MDL
);
4037 binding
-> value
-> type
= binding_data
;
4043 int find_bound_string (struct data_string
*value
,
4044 struct binding_scope
*scope
,
4047 struct binding
*binding
;
4049 binding
= find_binding (scope
, name
);
4051 !binding
-> value
||
4052 binding
-> value
-> type
!= binding_data
)
4055 if (binding
-> value
-> value
.data
.terminated
) {
4056 data_string_copy (value
, &binding
-> value
-> value
.data
, MDL
);
4058 if (buffer_allocate (&value
->buffer
,
4059 binding
->value
->value
.data
.len
,
4064 memcpy (value
-> buffer
-> data
,
4065 binding
-> value
-> value
.data
.data
,
4066 binding
-> value
-> value
.data
.len
);
4067 value
-> data
= value
-> buffer
-> data
;
4068 value
-> len
= binding
-> value
-> value
.data
.len
;
4074 int unset (struct binding_scope
*scope
, const char *name
)
4076 struct binding
*binding
;
4078 binding
= find_binding (scope
, name
);
4080 if (binding
-> value
)
4081 binding_value_dereference
4082 (&binding
-> value
, MDL
);
4088 /* vim: set tabstop=8: */