3 Routines for manipulating parse trees... */
6 * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
36 static char copyright
[] =
37 "$Id: tree.c,v 1.113 2007/05/08 23:05:20 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
41 #include <omapip/omapip_p.h>
44 struct binding_scope
*global_scope
;
46 static int do_host_lookup
PROTO ((struct data_string
*,
47 struct dns_host_entry
*));
50 struct __res_state resolver_state
;
51 int resolver_inited
= 0;
55 append_to_ary(char **ary_ptr
, int *ary_size
, int ary_capacity
,
58 /* INSIST(ary_ptr != NULL); */
59 /* INSIST(ary_size != NULL); */
60 /* INSIST(ary_capacity > 1); */
62 if (new_element
== NULL
)
65 if (*ary_size
>= ary_capacity
) {
66 log_fatal("Improbable error at %s:%d.", MDL
);
70 ary_ptr
[(*ary_size
)++] = new_element
;
74 data_string_to_char_string(struct data_string
*d
)
76 char *str
, *start
, *end
;
77 const unsigned char *pos
;
88 /* Per byte could be "\777" at worst, plus null terminator. */
89 len
= (d
->len
* 4) + 1;
90 str
= dmalloc(len
, MDL
);
97 if (pretty_escape(&start
, end
, &pos
, pos
+ d
->len
) < 0) {
102 /* dmalloc() sets the buffer to zero - there is no need to null
109 #define DS_SPRINTF_SIZE 128
112 * If we are using a data_string structure to hold a NUL-terminated
113 * ASCII string, this function can be used to append a printf-formatted
114 * string to the end of it. The data_string structure will be resized to
115 * be big enough to hold the new string.
117 * If the append works, then 1 is returned.
119 * If it is not possible to allocate a buffer big enough to hold the
120 * new value, then the old data_string is unchanged, and 0 is returned.
123 data_string_sprintfa(struct data_string
*ds
, const char *fmt
, ...) {
129 struct buffer
*tmp_buffer
;
132 * If the data_string is empty, then initialize it.
134 if (ds
->data
== NULL
) {
135 /* INSIST(ds.buffer == NULL); */
136 if (!buffer_allocate(&ds
->buffer
, DS_SPRINTF_SIZE
, MDL
)) {
139 ds
->data
= ds
->buffer
->data
;
140 ds
->len
= DS_SPRINTF_SIZE
;
141 *((char *)ds
->data
) = '\0';
145 * Get the length of the string, and figure out how much space
148 cur_strlen
= strlen(ds
->data
);
149 max
= ds
->len
- cur_strlen
;
152 * Use vsnprintf(), which won't write past our space, but will
153 * tell us how much space it wants.
156 vsnprintf_ret
= vsnprintf((char *)ds
->data
+cur_strlen
, max
, fmt
, args
);
157 /* INSIST(vsnprintf_ret >= 0); */
160 * If our buffer is not big enough, we need a new buffer.
162 if (vsnprintf_ret
>= max
) {
164 * Figure out a size big enough.
166 new_len
= ds
->len
* 2;
167 while (new_len
<= cur_strlen
+ vsnprintf_ret
) {
172 * Create a new buffer and fill it.
175 if (!buffer_allocate(&tmp_buffer
, new_len
, MDL
)) {
177 * If we can't create a big enough buffer,
178 * we should remove any truncated output that we had.
180 *((char *)ds
->data
+cur_strlen
) = '\0';
184 memcpy(tmp_buffer
->data
, ds
->data
, cur_strlen
);
185 vsprintf(tmp_buffer
->data
+ cur_strlen
, fmt
, args
);
188 * Replace our old buffer with the new buffer.
190 buffer_dereference(&ds
->buffer
, MDL
);
191 buffer_reference(&ds
->buffer
, tmp_buffer
, MDL
);
192 buffer_dereference(&tmp_buffer
, MDL
);
193 ds
->data
= ds
->buffer
->data
;
204 pair foo
= (pair
)dmalloc (sizeof *foo
, MDL
);
206 log_fatal ("no memory for cons.");
212 int make_const_option_cache (oc
, buffer
, data
, len
, option
, file
, line
)
213 struct option_cache
**oc
;
214 struct buffer
**buffer
;
217 struct option
*option
;
227 bp
= (struct buffer
*)0;
228 if (!buffer_allocate (&bp
, len
, file
, line
)) {
229 log_error ("%s(%d): can't allocate buffer.",
235 if (!option_cache_allocate (oc
, file
, line
)) {
236 log_error ("%s(%d): can't allocate option cache.", file
, line
);
237 buffer_dereference (&bp
, file
, line
);
241 (*oc
) -> data
.len
= len
;
242 (*oc
) -> data
.buffer
= bp
;
243 (*oc
) -> data
.data
= &bp
-> data
[0];
244 (*oc
) -> data
.terminated
= 0;
246 memcpy (&bp
-> data
[0], data
, len
);
247 option_reference(&((*oc
)->option
), option
, MDL
);
251 int make_host_lookup (expr
, name
)
252 struct expression
**expr
;
255 if (!expression_allocate (expr
, MDL
)) {
256 log_error ("No memory for host lookup tree node.");
259 (*expr
) -> op
= expr_host_lookup
;
260 if (!enter_dns_host (&((*expr
) -> data
.host_lookup
), name
)) {
261 expression_dereference (expr
, MDL
);
267 int enter_dns_host (dh
, name
)
268 struct dns_host_entry
**dh
;
271 /* XXX This should really keep a hash table of hostnames
272 XXX and just add a new reference to a hostname that
273 XXX already exists, if possible, rather than creating
274 XXX a new structure. */
275 if (!dns_host_entry_allocate (dh
, name
, MDL
)) {
276 log_error ("Can't allocate space for new host.");
282 int make_const_data (struct expression
**expr
, const unsigned char *data
,
283 unsigned len
, int terminated
, int allocate
,
284 const char *file
, int line
)
286 struct expression
*nt
;
288 if (!expression_allocate (expr
, file
, line
)) {
289 log_error ("No memory for make_const_data tree node.");
296 if (!buffer_allocate (&nt
-> data
.const_data
.buffer
,
297 len
+ terminated
, file
, line
)) {
298 log_error ("Can't allocate const_data buffer");
299 expression_dereference (expr
, file
, line
);
302 nt
-> data
.const_data
.data
=
303 &nt
-> data
.const_data
.buffer
-> data
[0];
304 memcpy (nt
-> data
.const_data
.buffer
-> data
,
305 data
, len
+ terminated
);
307 nt
-> data
.const_data
.data
= data
;
308 nt
-> data
.const_data
.terminated
= terminated
;
310 nt
-> data
.const_data
.data
= 0;
312 nt
-> op
= expr_const_data
;
313 nt
-> data
.const_data
.len
= len
;
317 int make_const_int (expr
, val
)
318 struct expression
**expr
;
321 if (!expression_allocate (expr
, MDL
)) {
322 log_error ("No memory for make_const_int tree node.");
326 (*expr
) -> op
= expr_const_int
;
327 (*expr
) -> data
.const_int
= val
;
331 int make_concat (expr
, left
, right
)
332 struct expression
**expr
;
333 struct expression
*left
, *right
;
335 /* If we're concatenating a null tree to a non-null tree, just
336 return the non-null tree; if both trees are null, return
341 expression_reference (expr
, right
, MDL
);
345 expression_reference (expr
, left
, MDL
);
349 /* Otherwise, allocate a new node to concatenate the two. */
350 if (!expression_allocate (expr
, MDL
)) {
351 log_error ("No memory for concatenation expression node.");
355 (*expr
) -> op
= expr_concat
;
356 expression_reference (&(*expr
) -> data
.concat
[0], left
, MDL
);
357 expression_reference (&(*expr
) -> data
.concat
[1], right
, MDL
);
361 int make_encapsulation (expr
, name
)
362 struct expression
**expr
;
363 struct data_string
*name
;
365 /* Allocate a new node to store the encapsulation. */
366 if (!expression_allocate (expr
, MDL
)) {
367 log_error ("No memory for encapsulation expression node.");
371 (*expr
) -> op
= expr_encapsulate
;
372 data_string_copy (&(*expr
) -> data
.encapsulate
, name
, MDL
);
376 int make_substring (new, expr
, offset
, length
)
377 struct expression
**new;
378 struct expression
*expr
;
379 struct expression
*offset
;
380 struct expression
*length
;
382 /* Allocate an expression node to compute the substring. */
383 if (!expression_allocate (new, MDL
)) {
384 log_error ("no memory for substring expression.");
387 (*new) -> op
= expr_substring
;
388 expression_reference (&(*new) -> data
.substring
.expr
, expr
, MDL
);
389 expression_reference (&(*new) -> data
.substring
.offset
, offset
, MDL
);
390 expression_reference (&(*new) -> data
.substring
.len
, length
, MDL
);
394 int make_limit (new, expr
, limit
)
395 struct expression
**new;
396 struct expression
*expr
;
399 struct expression
*rv
;
401 /* Allocate a node to enforce a limit on evaluation. */
402 if (!expression_allocate (new, MDL
))
403 log_error ("no memory for limit expression");
404 (*new) -> op
= expr_substring
;
405 expression_reference (&(*new) -> data
.substring
.expr
, expr
, MDL
);
407 /* Offset is a constant 0. */
408 if (!expression_allocate (&(*new) -> data
.substring
.offset
, MDL
)) {
409 log_error ("no memory for limit offset expression");
410 expression_dereference (new, MDL
);
413 (*new) -> data
.substring
.offset
-> op
= expr_const_int
;
414 (*new) -> data
.substring
.offset
-> data
.const_int
= 0;
416 /* Length is a constant: the specified limit. */
417 if (!expression_allocate (&(*new) -> data
.substring
.len
, MDL
)) {
418 log_error ("no memory for limit length expression");
419 expression_dereference (new, MDL
);
422 (*new) -> data
.substring
.len
-> op
= expr_const_int
;
423 (*new) -> data
.substring
.len
-> data
.const_int
= limit
;
428 int option_cache (struct option_cache
**oc
, struct data_string
*dp
,
429 struct expression
*expr
, struct option
*option
,
430 const char *file
, int line
)
432 if (!option_cache_allocate (oc
, file
, line
))
435 data_string_copy (&(*oc
) -> data
, dp
, file
, line
);
437 expression_reference (&(*oc
) -> expression
, expr
, file
, line
);
438 option_reference(&(*oc
)->option
, option
, MDL
);
442 int make_let (result
, name
)
443 struct executable_statement
**result
;
446 if (!(executable_statement_allocate (result
, MDL
)))
449 (*result
) -> op
= let_statement
;
450 (*result
) -> data
.let
.name
= dmalloc (strlen (name
) + 1, MDL
);
451 if (!(*result
) -> data
.let
.name
) {
452 executable_statement_dereference (result
, MDL
);
455 strcpy ((*result
) -> data
.let
.name
, name
);
459 static int do_host_lookup (result
, dns
)
460 struct data_string
*result
;
461 struct dns_host_entry
*dns
;
468 log_debug ("time: now = %d dns = %d diff = %d",
469 cur_time
, dns
-> timeout
, cur_time
- dns
-> timeout
);
472 /* If the record hasn't timed out, just copy the data and return. */
473 if (cur_time
<= dns
-> timeout
) {
475 log_debug ("easy copy: %d %s",
478 ? inet_ntoa (*(struct in_addr
*)(dns
-> data
.data
))
481 data_string_copy (result
, &dns
-> data
, MDL
);
485 log_debug ("Looking up %s", dns
-> hostname
);
488 /* Otherwise, look it up... */
489 h
= gethostbyname (dns
-> hostname
);
495 log_error ("%s: host unknown.", dns
-> hostname
);
499 log_error ("%s: temporary name server failure",
503 log_error ("%s: name server failed", dns
-> hostname
);
506 log_error ("%s: no A record associated with address",
509 #endif /* !NO_H_ERRNO */
511 /* Okay to try again after a minute. */
512 dns
-> timeout
= cur_time
+ 60;
513 data_string_forget (&dns
-> data
, MDL
);
518 log_debug ("Lookup succeeded; first address is %s",
519 inet_ntoa (h
-> h_addr_list
[0]));
522 /* Count the number of addresses we got... */
523 for (count
= 0; h
-> h_addr_list
[count
]; count
++)
526 /* Dereference the old data, if any. */
527 data_string_forget (&dns
-> data
, MDL
);
529 /* Do we need to allocate more memory? */
530 new_len
= count
* h
-> h_length
;
531 if (!buffer_allocate (&dns
-> data
.buffer
, new_len
, MDL
))
533 log_error ("No memory for %s.", dns
-> hostname
);
537 dns
-> data
.data
= &dns
-> data
.buffer
-> data
[0];
538 dns
-> data
.len
= new_len
;
539 dns
-> data
.terminated
= 0;
541 /* Addresses are conveniently stored one to the buffer, so we
542 have to copy them out one at a time... :'( */
543 for (i
= 0; i
< count
; i
++) {
544 memcpy (&dns
-> data
.buffer
-> data
[h
-> h_length
* i
],
545 h
-> h_addr_list
[i
], (unsigned)(h
-> h_length
));
548 log_debug ("dns -> data: %x h -> h_addr_list [0]: %x",
549 *(int *)(dns
-> buffer
), h
-> h_addr_list
[0]);
552 /* XXX Set the timeout for an hour from now.
553 XXX This should really use the time on the DNS reply. */
554 dns
-> timeout
= cur_time
+ 3600;
557 log_debug ("hard copy: %d %s", dns
-> data
.len
,
559 ? inet_ntoa (*(struct in_addr
*)(dns
-> data
.data
)) : 0));
561 data_string_copy (result
, &dns
-> data
, MDL
);
565 int evaluate_expression (result
, packet
, lease
, client_state
,
566 in_options
, cfg_options
, scope
, expr
, file
, line
)
567 struct binding_value
**result
;
568 struct packet
*packet
;
570 struct client_state
*client_state
;
571 struct option_state
*in_options
;
572 struct option_state
*cfg_options
;
573 struct binding_scope
**scope
;
574 struct expression
*expr
;
578 struct binding_value
*bv
;
580 struct binding
*binding
;
582 bv
= (struct binding_value
*)0;
584 if (expr
-> op
== expr_variable_reference
) {
585 if (!scope
|| !*scope
)
588 binding
= find_binding (*scope
, expr
-> data
.variable
);
590 if (binding
&& binding
-> value
) {
592 binding_value_reference (result
,
598 } else if (expr
-> op
== expr_funcall
) {
599 struct string_list
*s
;
600 struct expression
*arg
;
601 struct binding_scope
*ns
;
604 if (!scope
|| !*scope
) {
605 log_error ("%s: no such function.",
606 expr
-> data
.funcall
.name
);
610 binding
= find_binding (*scope
, expr
-> data
.funcall
.name
);
612 if (!binding
|| !binding
-> value
) {
613 log_error ("%s: no such function.",
614 expr
-> data
.funcall
.name
);
617 if (binding
-> value
-> type
!= binding_function
) {
618 log_error ("%s: not a function.",
619 expr
-> data
.funcall
.name
);
623 /* Create a new binding scope in which to define
624 the arguments to the function. */
625 ns
= (struct binding_scope
*)0;
626 if (!binding_scope_allocate (&ns
, MDL
)) {
627 log_error ("%s: can't allocate argument scope.",
628 expr
-> data
.funcall
.name
);
632 arg
= expr
-> data
.funcall
.arglist
;
633 s
= binding
-> value
-> value
.fundef
-> args
;
635 nb
= dmalloc (sizeof *nb
, MDL
);
638 binding_scope_dereference (&ns
, MDL
);
641 memset (nb
, 0, sizeof *nb
);
642 nb
-> name
= dmalloc (strlen (s
-> string
) + 1,
645 strcpy (nb
-> name
, s
-> string
);
648 nb
= (struct binding
*)0;
652 evaluate_expression (&nb
-> value
, packet
, lease
,
654 in_options
, cfg_options
, scope
,
655 arg
-> data
.arg
.val
, file
, line
);
656 nb
-> next
= ns
-> bindings
;
658 arg
= arg
-> data
.arg
.next
;
662 log_error ("%s: too many arguments.",
663 expr
-> data
.funcall
.name
);
664 binding_scope_dereference (&ns
, MDL
);
668 log_error ("%s: too few arguments.",
669 expr
-> data
.funcall
.name
);
670 binding_scope_dereference (&ns
, MDL
);
675 binding_scope_reference (&ns
-> outer
, *scope
, MDL
);
677 status
= (execute_statements
679 lease
, client_state
, in_options
, cfg_options
, &ns
,
680 binding
-> value
-> value
.fundef
-> statements
));
681 binding_scope_dereference (&ns
, MDL
);
685 } else if (is_boolean_expression (expr
)) {
686 if (!binding_value_allocate (&bv
, MDL
))
688 bv
-> type
= binding_boolean
;
689 status
= (evaluate_boolean_expression
690 (&bv
-> value
.boolean
, packet
, lease
, client_state
,
691 in_options
, cfg_options
, scope
, expr
));
692 } else if (is_numeric_expression (expr
)) {
693 if (!binding_value_allocate (&bv
, MDL
))
695 bv
-> type
= binding_numeric
;
696 status
= (evaluate_numeric_expression
697 (&bv
-> value
.intval
, packet
, lease
, client_state
,
698 in_options
, cfg_options
, scope
, expr
));
699 } else if (is_data_expression (expr
)) {
700 if (!binding_value_allocate (&bv
, MDL
))
702 bv
-> type
= binding_data
;
703 status
= (evaluate_data_expression
704 (&bv
-> value
.data
, packet
, lease
, client_state
,
705 in_options
, cfg_options
, scope
, expr
, MDL
));
706 } else if (is_dns_expression (expr
)) {
707 #if defined (NSUPDATE)
708 if (!binding_value_allocate (&bv
, MDL
))
710 bv
-> type
= binding_dns
;
711 status
= (evaluate_dns_expression
712 (&bv
-> value
.dns
, packet
, lease
, client_state
,
713 in_options
, cfg_options
, scope
, expr
));
716 log_error ("%s: invalid expression type: %d",
717 "evaluate_expression", expr
-> op
);
720 if (result
&& status
)
721 binding_value_reference (result
, bv
, file
, line
);
722 binding_value_dereference (&bv
, MDL
);
727 int binding_value_dereference (struct binding_value
**v
,
728 const char *file
, int line
)
730 struct binding_value
*bv
= *v
;
732 *v
= (struct binding_value
*)0;
734 /* Decrement the reference count. If it's nonzero, we're
737 rc_register (file
, line
, v
, bv
, bv
-> refcnt
, 1, RC_MISC
);
738 if (bv
-> refcnt
> 0)
740 if (bv
-> refcnt
< 0) {
741 log_error ("%s(%d): negative refcnt!", file
, line
);
742 #if defined (DEBUG_RC_HISTORY)
743 dump_rc_history (bv
);
745 #if defined (POINTER_DEBUG)
752 switch (bv
-> type
) {
753 case binding_boolean
:
754 case binding_numeric
:
757 if (bv
-> value
.data
.buffer
)
758 data_string_forget (&bv
-> value
.data
, file
, line
);
761 #if defined (NSUPDATE)
762 if (bv
-> value
.dns
) {
763 if (bv
-> value
.dns
-> r_data
) {
764 dfree (bv
-> value
.dns
-> r_data_ephem
, MDL
);
765 bv
-> value
.dns
-> r_data
= (unsigned char *)0;
766 bv
-> value
.dns
-> r_data_ephem
=
769 minires_freeupdrec (bv
-> value
.dns
);
774 log_error ("%s(%d): invalid binding type: %d",
775 file
, line
, bv
-> type
);
778 free_binding_value(bv
, file
, line
);
782 #if defined (NSUPDATE)
783 int evaluate_dns_expression (result
, packet
, lease
, client_state
, in_options
,
784 cfg_options
, scope
, expr
)
786 struct packet
*packet
;
788 struct client_state
*client_state
;
789 struct option_state
*in_options
;
790 struct option_state
*cfg_options
;
791 struct binding_scope
**scope
;
792 struct expression
*expr
;
795 unsigned long ttl
= 0;
797 struct data_string name
, data
;
800 if (!result
|| *result
) {
801 log_error ("evaluate_dns_expression called with non-null %s",
803 #if defined (POINTER_DEBUG)
810 switch (expr
-> op
) {
811 #if defined (NSUPDATE)
813 r0
= evaluate_numeric_expression (&ttl
, packet
, lease
,
815 in_options
, cfg_options
,
817 expr
-> data
.ns_add
.ttl
);
824 case expr_ns_not_exists
:
827 memset (&name
, 0, sizeof name
);
828 r1
= evaluate_data_expression (&name
, packet
, lease
,
830 in_options
, cfg_options
, scope
,
831 expr
-> data
.ns_add
.rrname
,
834 /* The result of the evaluation may or may not
835 be NUL-terminated, but we need it
836 terminated for sure, so we have to allocate
837 a buffer and terminate it. */
838 tname
= dmalloc (name
.len
+ 1, MDL
);
842 data_string_forget (&name
, MDL
);
844 memcpy (tname
, name
.data
, name
.len
);
845 tname
[name
.len
] = 0;
846 memset (&data
, 0, sizeof data
);
847 r2
= evaluate_data_expression
848 (&data
, packet
, lease
, client_state
,
849 in_options
, cfg_options
, scope
,
850 expr
-> data
.ns_add
.rrdata
, MDL
);
856 if (r0
&& r1
&& (r2
|| expr
-> op
!= expr_ns_add
)) {
857 *result
= minires_mkupdrec (((expr
-> op
== expr_ns_add
||
858 expr
-> op
== expr_ns_delete
)
859 ? S_UPDATE
: S_PREREQ
),
861 expr
-> data
.ns_add
.rrclass
,
862 expr
-> data
.ns_add
.rrtype
,
867 data_string_forget (&data
, MDL
);
872 /* As a special case, if we get exactly
873 four bytes of data, it's an IP address
874 represented as a 32-bit quantity, which
875 is actually what we *should* be getting
876 here. Because res_mkupdrec is currently
877 broken and expects a dotted quad, convert
878 it. This should be fixed when the new
879 resolver is merged. */
881 (*result
) -> r_data_ephem
=
883 if (!(*result
) -> r_data_ephem
)
885 (*result
) -> r_data
=
886 (*result
) -> r_data_ephem
;
887 /*%Audit% 16 bytes max. %2004.06.17,Safe%*/
888 sprintf ((char *)(*result
) -> r_data_ephem
,
890 data
.data
[0] & 0xff,
891 data
.data
[1] & 0xff,
892 data
.data
[2] & 0xff,
893 data
.data
[3] & 0xff);
894 (*result
) -> r_size
=
895 strlen ((const char *)
896 (*result
) -> r_data
);
898 (*result
) -> r_size
= data
.len
;
899 (*result
) -> r_data_ephem
=
900 dmalloc (data
.len
, MDL
);
901 if (!(*result
) -> r_data_ephem
) {
902 dpngood
: /* double plus ungood. */
903 minires_freeupdrec (*result
);
907 (*result
) -> r_data
=
908 (*result
) -> r_data_ephem
;
909 memcpy ((*result
) -> r_data_ephem
,
910 data
.data
, data
.len
);
913 (*result
) -> r_data
= 0;
914 (*result
) -> r_size
= 0;
916 switch (expr
-> op
) {
918 (*result
) -> r_opcode
= ADD
;
921 (*result
) -> r_opcode
= DELETE
;
924 (*result
) -> r_opcode
= YXRRSET
;
926 case expr_ns_not_exists
:
927 (*result
) -> r_opcode
= NXRRSET
;
930 /* Can't happen, but satisfy gcc. */
937 data_string_forget (&name
, MDL
);
941 data_string_forget (&data
, MDL
);
942 /* One flaw in the thinking here: an IP address and an
943 ASCII string both look like data expressions, but
944 for A records, we want an ASCII string, not a
945 binary IP address. Do I need to turn binary IP
946 addresses into a separate type? */
948 (r2
|| expr
-> op
!= expr_ns_add
) && *result
);
954 case expr_ns_not_exists
:
958 log_error ("%s: dns values for functions not supported.",
959 expr
-> data
.funcall
.name
);
962 case expr_variable_reference
:
963 log_error ("%s: dns values for variables not supported.",
964 expr
-> data
.variable
);
977 case expr_variable_exists
:
978 log_error ("Boolean opcode in evaluate_dns_expression: %d",
989 case expr_const_data
:
992 case expr_encapsulate
:
993 case expr_host_lookup
:
994 case expr_encode_int8
:
995 case expr_encode_int16
:
996 case expr_encode_int32
:
997 case expr_binary_to_ascii
:
1001 case expr_pick_first_value
:
1002 case expr_host_decl_name
:
1003 case expr_config_option
:
1004 case expr_leased_address
:
1006 log_error ("Data opcode in evaluate_dns_expression: %d",
1010 case expr_extract_int8
:
1011 case expr_extract_int16
:
1012 case expr_extract_int32
:
1013 case expr_const_int
:
1014 case expr_lease_time
:
1015 case expr_dns_transaction
:
1020 case expr_remainder
:
1021 case expr_binary_and
:
1022 case expr_binary_or
:
1023 case expr_binary_xor
:
1024 case expr_client_state
:
1025 log_error ("Numeric opcode in evaluate_dns_expression: %d",
1030 log_error ("Function opcode in evaluate_dns_expression: %d",
1038 log_error ("Bogus opcode in evaluate_dns_expression: %d",
1042 #endif /* defined (NSUPDATE) */
1044 int evaluate_boolean_expression (result
, packet
, lease
, client_state
,
1045 in_options
, cfg_options
, scope
, expr
)
1047 struct packet
*packet
;
1048 struct lease
*lease
;
1049 struct client_state
*client_state
;
1050 struct option_state
*in_options
;
1051 struct option_state
*cfg_options
;
1052 struct binding_scope
**scope
;
1053 struct expression
*expr
;
1055 struct data_string left
, right
;
1056 struct data_string rrtype
, rrname
, rrdata
;
1058 int srrtype
, srrname
, srrdata
, sttl
;
1061 struct binding
*binding
;
1062 struct binding_value
*bv
, *obv
;
1064 switch (expr
-> op
) {
1066 *result
= check_collection (packet
, lease
,
1067 expr
-> data
.check
);
1068 #if defined (DEBUG_EXPRESSIONS)
1069 log_debug ("bool: check (%s) returns %s",
1070 expr
-> data
.check
-> name
,
1071 *result
? "true" : "false");
1076 case expr_not_equal
:
1077 bv
= obv
= (struct binding_value
*)0;
1078 sleft
= evaluate_expression (&bv
, packet
, lease
, client_state
,
1079 in_options
, cfg_options
, scope
,
1080 expr
-> data
.equal
[0], MDL
);
1081 sright
= evaluate_expression (&obv
, packet
, lease
,
1082 client_state
, in_options
,
1084 expr
-> data
.equal
[1], MDL
);
1085 if (sleft
&& sright
) {
1086 if (bv
-> type
!= obv
-> type
)
1087 *result
= expr
-> op
== expr_not_equal
;
1089 switch (obv
-> type
) {
1090 case binding_boolean
:
1091 if (bv
-> value
.boolean
== obv
-> value
.boolean
)
1092 *result
= expr
-> op
== expr_equal
;
1094 *result
= expr
-> op
== expr_not_equal
;
1098 if ((bv
-> value
.data
.len
==
1099 obv
-> value
.data
.len
) &&
1100 !memcmp (bv
-> value
.data
.data
,
1101 obv
-> value
.data
.data
,
1102 obv
-> value
.data
.len
))
1103 *result
= expr
-> op
== expr_equal
;
1105 *result
= expr
-> op
== expr_not_equal
;
1108 case binding_numeric
:
1109 if (bv
-> value
.intval
== obv
-> value
.intval
)
1110 *result
= expr
-> op
== expr_equal
;
1112 *result
= expr
-> op
== expr_not_equal
;
1116 #if defined (NSUPDATE)
1117 /* XXX This should be a comparison for equal
1118 XXX values, not for identity. */
1119 if (bv
-> value
.dns
== obv
-> value
.dns
)
1120 *result
= expr
-> op
== expr_equal
;
1122 *result
= expr
-> op
== expr_not_equal
;
1124 *result
= expr
-> op
== expr_not_equal
;
1128 case binding_function
:
1129 if (bv
-> value
.fundef
== obv
-> value
.fundef
)
1130 *result
= expr
-> op
== expr_equal
;
1132 *result
= expr
-> op
== expr_not_equal
;
1135 *result
= expr
-> op
== expr_not_equal
;
1139 } else if (!sleft
&& !sright
)
1140 *result
= expr
-> op
== expr_equal
;
1142 *result
= expr
-> op
== expr_not_equal
;
1144 #if defined (DEBUG_EXPRESSIONS)
1145 log_debug ("bool: %sequal = %s",
1146 expr
-> op
== expr_not_equal
? "not" : "",
1147 (*result
? "true" : "false"));
1150 binding_value_dereference (&bv
, MDL
);
1152 binding_value_dereference (&obv
, MDL
);
1156 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1158 in_options
, cfg_options
,
1160 expr
-> data
.and [0]);
1162 sright
= evaluate_boolean_expression
1163 (&bright
, packet
, lease
, client_state
,
1164 in_options
, cfg_options
,
1165 scope
, expr
-> data
.and [1]);
1167 sright
= bright
= 0;
1169 #if defined (DEBUG_EXPRESSIONS)
1170 log_debug ("bool: and (%s, %s) = %s",
1171 sleft
? (bleft
? "true" : "false") : "NULL",
1172 sright
? (bright
? "true" : "false") : "NULL",
1174 ? (bleft
&& bright
? "true" : "false") : "NULL"));
1176 if (sleft
&& sright
) {
1177 *result
= bleft
&& bright
;
1184 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1186 in_options
, cfg_options
,
1188 expr
-> data
.or [0]);
1189 if (!sleft
|| !bleft
)
1190 sright
= evaluate_boolean_expression
1191 (&bright
, packet
, lease
, client_state
,
1192 in_options
, cfg_options
,
1193 scope
, expr
-> data
.or [1]);
1196 #if defined (DEBUG_EXPRESSIONS)
1197 log_debug ("bool: or (%s, %s) = %s",
1198 sleft
? (bleft
? "true" : "false") : "NULL",
1199 sright
? (bright
? "true" : "false") : "NULL",
1201 ? (bleft
|| bright
? "true" : "false") : "NULL"));
1203 if (sleft
|| sright
) {
1204 *result
= bleft
|| bright
;
1210 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1212 in_options
, cfg_options
,
1215 #if defined (DEBUG_EXPRESSIONS)
1216 log_debug ("bool: not (%s) = %s",
1217 sleft
? (bleft
? "true" : "false") : "NULL",
1219 ? (!bleft
? "true" : "false") : "NULL"));
1229 memset (&left
, 0, sizeof left
);
1231 !get_option (&left
, expr
-> data
.exists
-> universe
,
1232 packet
, lease
, client_state
,
1233 in_options
, cfg_options
, in_options
,
1234 scope
, expr
-> data
.exists
-> code
, MDL
))
1238 data_string_forget (&left
, MDL
);
1240 #if defined (DEBUG_EXPRESSIONS)
1241 log_debug ("bool: exists %s.%s = %s",
1242 expr
-> data
.option
-> universe
-> name
,
1243 expr
-> data
.option
-> name
,
1244 *result
? "true" : "false");
1250 #if defined (DEBUG_EXPRESSIONS)
1251 log_debug ("bool: known = NULL");
1255 #if defined (DEBUG_EXPRESSIONS)
1256 log_debug ("bool: known = %s",
1257 packet
-> known
? "true" : "false");
1259 *result
= packet
-> known
;
1263 if (!lease
|| !(lease
-> flags
& STATIC_LEASE
)) {
1264 #if defined (DEBUG_EXPRESSIONS)
1265 log_debug ("bool: static = false (%s %s %s %d)",
1267 (lease
&& (lease
-> flags
& STATIC_LEASE
)
1269 piaddr (lease
-> ip_addr
),
1270 lease
? lease
-> flags
: 0);
1275 #if defined (DEBUG_EXPRESSIONS)
1276 log_debug ("bool: static = true");
1281 case expr_variable_exists
:
1282 if (scope
&& *scope
) {
1283 binding
= find_binding (*scope
, expr
-> data
.variable
);
1286 if (binding
-> value
)
1294 #if defined (DEBUG_EXPRESSIONS)
1295 log_debug ("boolean: %s? = %s", expr
-> data
.variable
,
1296 *result
? "true" : "false");
1300 case expr_variable_reference
:
1301 if (scope
&& *scope
) {
1302 binding
= find_binding (*scope
, expr
-> data
.variable
);
1304 if (binding
&& binding
-> value
) {
1305 if (binding
-> value
-> type
==
1307 *result
= binding
-> value
-> value
.boolean
;
1310 log_error ("binding type %d in %s.",
1311 binding
-> value
-> type
,
1312 "evaluate_boolean_expression");
1319 #if defined (DEBUG_EXPRESSIONS)
1320 log_debug ("boolean: %s = %s", expr
-> data
.variable
,
1321 sleft
? (*result
? "true" : "false") : "NULL");
1326 bv
= (struct binding_value
*)0;
1327 sleft
= evaluate_expression (&bv
, packet
, lease
, client_state
,
1328 in_options
, cfg_options
,
1331 if (bv
-> type
!= binding_boolean
)
1332 log_error ("%s() returned type %d in %s.",
1333 expr
-> data
.funcall
.name
,
1335 "evaluate_boolean_expression");
1337 *result
= bv
-> value
.boolean
;
1338 binding_value_dereference (&bv
, MDL
);
1340 #if defined (DEBUG_EXPRESSIONS)
1341 log_debug ("boolean: %s() = %s", expr
-> data
.funcall
.name
,
1342 sleft
? (*result
? "true" : "false") : "NULL");
1348 case expr_substring
:
1354 case expr_const_data
:
1357 case expr_encapsulate
:
1358 case expr_host_lookup
:
1359 case expr_encode_int8
:
1360 case expr_encode_int16
:
1361 case expr_encode_int32
:
1362 case expr_binary_to_ascii
:
1364 case expr_pick_first_value
:
1365 case expr_host_decl_name
:
1366 case expr_config_option
:
1367 case expr_leased_address
:
1371 log_error ("Data opcode in evaluate_boolean_expression: %d",
1375 case expr_extract_int8
:
1376 case expr_extract_int16
:
1377 case expr_extract_int32
:
1378 case expr_const_int
:
1379 case expr_lease_time
:
1380 case expr_dns_transaction
:
1385 case expr_remainder
:
1386 case expr_binary_and
:
1387 case expr_binary_or
:
1388 case expr_binary_xor
:
1389 case expr_client_state
:
1390 log_error ("Numeric opcode in evaluate_boolean_expression: %d",
1395 case expr_ns_delete
:
1396 case expr_ns_exists
:
1397 case expr_ns_not_exists
:
1398 log_error ("dns opcode in evaluate_boolean_expression: %d",
1403 log_error ("function definition in evaluate_boolean_expr");
1410 log_error ("Bogus opcode in evaluate_boolean_expression: %d",
1415 int evaluate_data_expression (result
, packet
, lease
, client_state
,
1416 in_options
, cfg_options
, scope
, expr
, file
, line
)
1417 struct data_string
*result
;
1418 struct packet
*packet
;
1419 struct lease
*lease
;
1420 struct client_state
*client_state
;
1421 struct option_state
*in_options
;
1422 struct option_state
*cfg_options
;
1423 struct binding_scope
**scope
;
1424 struct expression
*expr
;
1428 struct data_string data
, other
;
1429 unsigned long offset
, len
, i
;
1432 struct binding
*binding
;
1434 struct binding_value
*bv
;
1436 switch (expr
-> op
) {
1437 /* Extract N bytes starting at byte M of a data string. */
1438 case expr_substring
:
1439 memset (&data
, 0, sizeof data
);
1440 s0
= evaluate_data_expression (&data
, packet
, lease
,
1442 in_options
, cfg_options
, scope
,
1443 expr
-> data
.substring
.expr
,
1446 /* Evaluate the offset and length. */
1447 s1
= evaluate_numeric_expression
1448 (&offset
, packet
, lease
, client_state
, in_options
,
1449 cfg_options
, scope
, expr
-> data
.substring
.offset
);
1450 s2
= evaluate_numeric_expression (&len
, packet
, lease
,
1452 in_options
, cfg_options
,
1454 expr
-> data
.substring
.len
);
1456 if (s0
&& s1
&& s2
) {
1457 /* If the offset is after end of the string,
1458 return an empty string. Otherwise, do the
1459 adjustments and return what's left. */
1460 if (data
.len
> offset
) {
1461 data_string_copy (result
, &data
, file
, line
);
1462 result
-> len
-= offset
;
1463 if (result
-> len
> len
) {
1464 result
-> len
= len
;
1465 result
-> terminated
= 0;
1467 result
-> data
+= offset
;
1473 #if defined (DEBUG_EXPRESSIONS)
1474 log_debug ("data: substring (%s, %s, %s) = %s",
1475 s0
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1476 s1
? print_dec_1 (offset
) : "NULL",
1477 s2
? print_dec_2 (len
) : "NULL",
1478 (s3
? print_hex_2 (result
-> len
, result
-> data
, 30)
1482 data_string_forget (&data
, MDL
);
1487 /* Extract the last N bytes of a data string. */
1489 memset (&data
, 0, sizeof data
);
1490 s0
= evaluate_data_expression (&data
, packet
, lease
,
1492 in_options
, cfg_options
, scope
,
1493 expr
-> data
.suffix
.expr
, MDL
);
1494 /* Evaluate the length. */
1495 s1
= evaluate_numeric_expression (&len
, packet
, lease
,
1497 in_options
, cfg_options
,
1499 expr
-> data
.suffix
.len
);
1501 data_string_copy (result
, &data
, file
, line
);
1503 /* If we are returning the last N bytes of a
1504 string whose length is <= N, just return
1505 the string - otherwise, compute a new
1506 starting address and decrease the
1508 if (data
.len
> len
) {
1509 result
-> data
+= data
.len
- len
;
1510 result
-> len
= len
;
1512 data_string_forget (&data
, MDL
);
1515 #if defined (DEBUG_EXPRESSIONS)
1516 log_debug ("data: suffix (%s, %s) = %s",
1517 s0
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1518 s1
? print_dec_1 (len
) : "NULL",
1520 ? print_hex_2 (result
-> len
, result
-> data
, 30)
1525 /* Convert string to lowercase. */
1527 memset(&data
, 0, sizeof data
);
1528 s0
= evaluate_data_expression(&data
, packet
, lease
,
1530 in_options
, cfg_options
, scope
,
1531 expr
->data
.lcase
, MDL
);
1534 result
->len
= data
.len
;
1535 if (buffer_allocate(&result
->buffer
,
1536 result
->len
+ data
.terminated
,
1538 result
->data
= &result
->buffer
->data
[0];
1539 memcpy(result
->buffer
->data
, data
.data
,
1540 data
.len
+ data
.terminated
);
1541 result
->terminated
= data
.terminated
;
1542 s
= (unsigned char *)result
->data
;
1543 for (i
= 0; i
< result
->len
; i
++, s
++)
1547 log_error("data: lcase: no buffer memory.");
1551 #if defined (DEBUG_EXPRESSIONS)
1552 log_debug("data: lcase (%s) = %s",
1553 s0
? print_hex_1(data
.len
, data
.data
, 30) : "NULL",
1554 s1
? print_hex_2(result
->len
, result
->data
, 30)
1558 data_string_forget(&data
, MDL
);
1561 /* Convert string to uppercase. */
1563 memset(&data
, 0, sizeof data
);
1564 s0
= evaluate_data_expression(&data
, packet
, lease
,
1566 in_options
, cfg_options
, scope
,
1567 expr
->data
.lcase
, MDL
);
1570 result
->len
= data
.len
;
1571 if (buffer_allocate(&result
->buffer
,
1572 result
->len
+ data
.terminated
,
1574 result
->data
= &result
->buffer
->data
[0];
1575 memcpy(result
->buffer
->data
, data
.data
,
1576 data
.len
+ data
.terminated
);
1577 result
->terminated
= data
.terminated
;
1578 s
= (unsigned char *)result
->data
;
1579 for (i
= 0; i
< result
->len
; i
++, s
++)
1583 log_error("data: lcase: no buffer memory.");
1587 #if defined (DEBUG_EXPRESSIONS)
1588 log_debug("data: ucase (%s) = %s",
1589 s0
? print_hex_1(data
.len
, data
.data
, 30) : "NULL",
1590 s1
? print_hex_2(result
->len
, result
->data
, 30)
1594 data_string_forget(&data
, MDL
);
1597 /* Extract an option. */
1600 s0
= get_option (result
,
1601 expr
-> data
.option
-> universe
,
1602 packet
, lease
, client_state
,
1603 in_options
, cfg_options
, in_options
,
1604 scope
, expr
-> data
.option
-> code
,
1609 #if defined (DEBUG_EXPRESSIONS)
1610 log_debug ("data: option %s.%s = %s",
1611 expr
-> data
.option
-> universe
-> name
,
1612 expr
-> data
.option
-> name
,
1613 s0
? print_hex_1 (result
-> len
, result
-> data
, 60)
1618 case expr_config_option
:
1620 s0
= get_option (result
,
1621 expr
-> data
.option
-> universe
,
1622 packet
, lease
, client_state
,
1623 in_options
, cfg_options
, cfg_options
,
1624 scope
, expr
-> data
.option
-> code
,
1629 #if defined (DEBUG_EXPRESSIONS)
1630 log_debug ("data: config-option %s.%s = %s",
1631 expr
-> data
.option
-> universe
-> name
,
1632 expr
-> data
.option
-> name
,
1633 s0
? print_hex_1 (result
-> len
, result
-> data
, 60)
1638 /* Combine the hardware type and address. */
1640 /* On the client, hardware is our hardware. */
1642 memset (result
, 0, sizeof *result
);
1644 client_state
-> interface
-> hw_address
.hbuf
;
1646 client_state
-> interface
-> hw_address
.hlen
;
1647 #if defined (DEBUG_EXPRESSIONS)
1648 log_debug ("data: hardware = %s",
1649 print_hex_1 (result
-> len
,
1650 result
-> data
, 60));
1655 /* The server cares about the client's hardware address,
1656 so only in the case where we are examining a packet can
1657 we return anything. */
1658 if (!packet
|| !packet
-> raw
) {
1659 log_error ("data: hardware: raw packet not available");
1662 if (packet
-> raw
-> hlen
> sizeof packet
-> raw
-> chaddr
) {
1663 log_error ("data: hardware: invalid hlen (%d)\n",
1664 packet
-> raw
-> hlen
);
1667 result
-> len
= packet
-> raw
-> hlen
+ 1;
1668 if (buffer_allocate (&result
-> buffer
, result
-> len
,
1670 result
-> data
= &result
-> buffer
-> data
[0];
1671 result
-> buffer
-> data
[0] = packet
-> raw
-> htype
;
1672 memcpy (&result
-> buffer
-> data
[1],
1673 packet
-> raw
-> chaddr
,
1674 packet
-> raw
-> hlen
);
1675 result
-> terminated
= 0;
1677 log_error ("data: hardware: no memory for buffer.");
1680 #if defined (DEBUG_EXPRESSIONS)
1681 log_debug ("data: hardware = %s",
1682 print_hex_1 (result
-> len
, result
-> data
, 60));
1686 /* Extract part of the raw packet. */
1688 if (!packet
|| !packet
-> raw
) {
1689 log_error ("data: packet: raw packet not available");
1693 s0
= evaluate_numeric_expression (&offset
, packet
, lease
,
1695 in_options
, cfg_options
,
1697 expr
-> data
.packet
.offset
);
1698 s1
= evaluate_numeric_expression (&len
,
1699 packet
, lease
, client_state
,
1700 in_options
, cfg_options
,
1702 expr
-> data
.packet
.len
);
1703 if (s0
&& s1
&& offset
< packet
-> packet_length
) {
1704 if (offset
+ len
> packet
-> packet_length
)
1706 packet
-> packet_length
- offset
;
1708 result
-> len
= len
;
1709 if (buffer_allocate (&result
-> buffer
,
1710 result
-> len
, file
, line
)) {
1711 result
-> data
= &result
-> buffer
-> data
[0];
1712 memcpy (result
-> buffer
-> data
,
1713 (((unsigned char *)(packet
-> raw
))
1714 + offset
), result
-> len
);
1715 result
-> terminated
= 0;
1717 log_error ("data: packet: no buffer memory.");
1723 #if defined (DEBUG_EXPRESSIONS)
1724 log_debug ("data: packet (%ld, %ld) = %s",
1726 s2
? print_hex_1 (result
-> len
,
1727 result
-> data
, 60) : NULL
);
1731 /* The encapsulation of all defined options in an
1733 case expr_encapsulate
:
1735 s0
= option_space_encapsulate
1736 (result
, packet
, lease
, client_state
,
1737 in_options
, cfg_options
, scope
,
1738 &expr
-> data
.encapsulate
);
1742 #if defined (DEBUG_EXPRESSIONS)
1743 log_debug ("data: encapsulate (%s) = %s",
1744 expr
-> data
.encapsulate
.data
,
1745 s0
? print_hex_1 (result
-> len
,
1746 result
-> data
, 60) : "NULL");
1750 /* Some constant data... */
1751 case expr_const_data
:
1752 #if defined (DEBUG_EXPRESSIONS)
1753 log_debug ("data: const = %s",
1754 print_hex_1 (expr
-> data
.const_data
.len
,
1755 expr
-> data
.const_data
.data
, 60));
1757 data_string_copy (result
,
1758 &expr
-> data
.const_data
, file
, line
);
1761 /* Hostname lookup... */
1762 case expr_host_lookup
:
1763 s0
= do_host_lookup (result
, expr
-> data
.host_lookup
);
1764 #if defined (DEBUG_EXPRESSIONS)
1765 log_debug ("data: DNS lookup (%s) = %s",
1766 expr
-> data
.host_lookup
-> hostname
,
1768 ? print_dotted_quads (result
-> len
, result
-> data
)
1773 /* Concatenation... */
1775 memset (&data
, 0, sizeof data
);
1776 s0
= evaluate_data_expression (&data
, packet
, lease
,
1778 in_options
, cfg_options
, scope
,
1779 expr
-> data
.concat
[0], MDL
);
1780 memset (&other
, 0, sizeof other
);
1781 s1
= evaluate_data_expression (&other
, packet
, lease
,
1783 in_options
, cfg_options
, scope
,
1784 expr
-> data
.concat
[1], MDL
);
1787 result
-> len
= data
.len
+ other
.len
;
1788 if (!buffer_allocate (&result
-> buffer
,
1789 (result
-> len
+ other
.terminated
),
1791 log_error ("data: concat: no memory");
1793 data_string_forget (&data
, MDL
);
1794 data_string_forget (&other
, MDL
);
1797 result
-> data
= &result
-> buffer
-> data
[0];
1798 memcpy (result
-> buffer
-> data
, data
.data
, data
.len
);
1799 memcpy (&result
-> buffer
-> data
[data
.len
],
1800 other
.data
, other
.len
+ other
.terminated
);
1804 data_string_forget (&data
, MDL
);
1806 data_string_forget (&other
, MDL
);
1807 #if defined (DEBUG_EXPRESSIONS)
1808 log_debug ("data: concat (%s, %s) = %s",
1809 s0
? print_hex_1 (data
.len
, data
.data
, 20) : "NULL",
1810 s1
? print_hex_2 (other
.len
, other
.data
, 20) : "NULL",
1812 ? print_hex_3 (result
-> len
, result
-> data
, 30)
1817 case expr_encode_int8
:
1818 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1820 in_options
, cfg_options
,
1822 expr
-> data
.encode_int
);
1825 if (!buffer_allocate (&result
-> buffer
,
1827 log_error ("data: encode_int8: no memory");
1831 result
-> data
= &result
-> buffer
-> data
[0];
1832 result
-> buffer
-> data
[0] = len
;
1837 #if defined (DEBUG_EXPRESSIONS)
1839 log_debug ("data: encode_int8 (NULL) = NULL");
1841 log_debug ("data: encode_int8 (%ld) = %s", len
,
1842 print_hex_2 (result
-> len
,
1843 result
-> data
, 20));
1848 case expr_encode_int16
:
1849 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1851 in_options
, cfg_options
,
1853 expr
-> data
.encode_int
);
1856 if (!buffer_allocate (&result
-> buffer
, 2,
1858 log_error ("data: encode_int16: no memory");
1862 result
-> data
= &result
-> buffer
-> data
[0];
1863 putUShort (result
-> buffer
-> data
, len
);
1868 #if defined (DEBUG_EXPRESSIONS)
1870 log_debug ("data: encode_int16 (NULL) = NULL");
1872 log_debug ("data: encode_int16 (%ld) = %s", len
,
1873 print_hex_2 (result
-> len
,
1874 result
-> data
, 20));
1878 case expr_encode_int32
:
1879 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1881 in_options
, cfg_options
,
1883 expr
-> data
.encode_int
);
1886 if (!buffer_allocate (&result
-> buffer
, 4,
1888 log_error ("data: encode_int32: no memory");
1892 result
-> data
= &result
-> buffer
-> data
[0];
1893 putULong (result
-> buffer
-> data
, len
);
1898 #if defined (DEBUG_EXPRESSIONS)
1900 log_debug ("data: encode_int32 (NULL) = NULL");
1902 log_debug ("data: encode_int32 (%ld) = %s", len
,
1903 print_hex_2 (result
-> len
,
1904 result
-> data
, 20));
1908 case expr_binary_to_ascii
:
1909 /* Evaluate the base (offset) and width (len): */
1910 s0
= evaluate_numeric_expression
1911 (&offset
, packet
, lease
, client_state
, in_options
,
1912 cfg_options
, scope
, expr
-> data
.b2a
.base
);
1913 s1
= evaluate_numeric_expression (&len
, packet
, lease
,
1915 in_options
, cfg_options
,
1917 expr
-> data
.b2a
.width
);
1919 /* Evaluate the separator string. */
1920 memset (&data
, 0, sizeof data
);
1921 s2
= evaluate_data_expression (&data
, packet
, lease
,
1923 in_options
, cfg_options
, scope
,
1924 expr
-> data
.b2a
.separator
,
1927 /* Evaluate the data to be converted. */
1928 memset (&other
, 0, sizeof other
);
1929 s3
= evaluate_data_expression (&other
, packet
, lease
,
1931 in_options
, cfg_options
, scope
,
1932 expr
-> data
.b2a
.buffer
, MDL
);
1934 if (s0
&& s1
&& s2
&& s3
) {
1937 if (len
!= 8 && len
!= 16 && len
!= 32) {
1938 log_info ("binary_to_ascii: %s %ld!",
1939 "invalid width", len
);
1945 /* The buffer must be a multiple of the number's
1947 if (other
.len
% len
) {
1948 log_info ("binary-to-ascii: %s %d %s %ld!",
1949 "length of buffer", other
.len
,
1950 "not a multiple of width", len
);
1955 /* Count the width of the output. */
1957 for (i
= 0; i
< other
.len
; i
+= len
) {
1960 if (other
.data
[i
] < 8)
1962 else if (other
.data
[i
] < 64)
1966 } else if (offset
== 10) {
1967 if (other
.data
[i
] < 10)
1969 else if (other
.data
[i
] < 100)
1973 } else if (offset
== 16) {
1974 if (other
.data
[i
] < 16)
1979 buflen
+= (converted_length
1983 buflen
+= (converted_length
1986 if (i
+ len
!= other
.len
)
1990 if (!buffer_allocate (&result
-> buffer
,
1991 buflen
+ 1, file
, line
)) {
1992 log_error ("data: binary-to-ascii: no memory");
1996 result
-> data
= &result
-> buffer
-> data
[0];
1997 result
-> len
= buflen
;
1998 result
-> terminated
= 1;
2001 for (i
= 0; i
< other
.len
; i
+= len
) {
2002 buflen
+= (binary_to_ascii
2003 (&result
-> buffer
-> data
[buflen
],
2004 &other
.data
[i
], offset
, len
));
2005 if (i
+ len
!= other
.len
) {
2007 buffer
-> data
[buflen
],
2008 data
.data
, data
.len
);
2012 /* NUL terminate. */
2013 result
-> buffer
-> data
[buflen
] = 0;
2019 #if defined (DEBUG_EXPRESSIONS)
2020 log_debug ("data: binary-to-ascii (%s, %s, %s, %s) = %s",
2021 s0
? print_dec_1 (offset
) : "NULL",
2022 s1
? print_dec_2 (len
) : "NULL",
2023 s2
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
2024 s3
? print_hex_2 (other
.len
, other
.data
, 30) : "NULL",
2025 (status
? print_hex_3 (result
-> len
, result
-> data
, 30)
2029 data_string_forget (&data
, MDL
);
2031 data_string_forget (&other
, MDL
);
2037 /* Evaluate the width (len): */
2038 s0
= evaluate_numeric_expression
2039 (&len
, packet
, lease
, client_state
, in_options
,
2040 cfg_options
, scope
, expr
-> data
.reverse
.width
);
2042 /* Evaluate the data. */
2043 memset (&data
, 0, sizeof data
);
2044 s1
= evaluate_data_expression (&data
, packet
, lease
,
2046 in_options
, cfg_options
, scope
,
2047 expr
-> data
.reverse
.buffer
,
2054 /* The buffer must be a multiple of the number's
2056 if (data
.len
% len
) {
2057 log_info ("reverse: %s %d %s %ld!",
2058 "length of buffer", data
.len
,
2059 "not a multiple of width", len
);
2064 /* XXX reverse in place? I don't think we can. */
2065 if (!buffer_allocate (&result
-> buffer
,
2066 data
.len
, file
, line
)) {
2067 log_error ("data: reverse: no memory");
2071 result
-> data
= &result
-> buffer
-> data
[0];
2072 result
-> len
= data
.len
;
2073 result
-> terminated
= 0;
2075 for (i
= 0; i
< data
.len
; i
+= len
) {
2076 memcpy (&result
-> buffer
-> data
[i
],
2077 &data
.data
[data
.len
- i
- len
], len
);
2084 #if defined (DEBUG_EXPRESSIONS)
2085 log_debug ("data: reverse (%s, %s) = %s",
2086 s0
? print_dec_1 (len
) : "NULL",
2087 s1
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
2088 (status
? print_hex_3 (result
-> len
, result
-> data
, 30)
2092 data_string_forget (&data
, MDL
);
2097 case expr_leased_address
:
2099 log_debug("data: \"leased-address\" configuration "
2100 "directive: there is no lease associated "
2101 "with this client.");
2104 result
-> len
= lease
-> ip_addr
.len
;
2105 if (buffer_allocate (&result
-> buffer
, result
-> len
,
2107 result
-> data
= &result
-> buffer
-> data
[0];
2108 memcpy (&result
-> buffer
-> data
[0],
2109 lease
-> ip_addr
.iabuf
, lease
-> ip_addr
.len
);
2110 result
-> terminated
= 0;
2112 log_error ("data: leased-address: no memory.");
2115 #if defined (DEBUG_EXPRESSIONS)
2116 log_debug ("data: leased-address = %s",
2117 print_hex_1 (result
-> len
, result
-> data
, 60));
2121 case expr_pick_first_value
:
2122 memset (&data
, 0, sizeof data
);
2123 if ((evaluate_data_expression
2125 lease
, client_state
, in_options
, cfg_options
,
2126 scope
, expr
-> data
.pick_first_value
.car
, MDL
))) {
2127 #if defined (DEBUG_EXPRESSIONS)
2128 log_debug ("data: pick_first_value (%s, xxx)",
2129 print_hex_1 (result
-> len
,
2130 result
-> data
, 40));
2135 if (expr
-> data
.pick_first_value
.cdr
&&
2136 (evaluate_data_expression
2138 lease
, client_state
, in_options
, cfg_options
,
2139 scope
, expr
-> data
.pick_first_value
.cdr
, MDL
))) {
2140 #if defined (DEBUG_EXPRESSIONS)
2141 log_debug ("data: pick_first_value (NULL, %s)",
2142 print_hex_1 (result
-> len
,
2143 result
-> data
, 40));
2148 #if defined (DEBUG_EXPRESSIONS)
2149 log_debug ("data: pick_first_value (NULL, NULL) = NULL");
2153 case expr_host_decl_name
:
2154 if (!lease
|| !lease
-> host
) {
2155 log_error ("data: host_decl_name: not available");
2158 result
-> len
= strlen (lease
-> host
-> name
);
2159 if (buffer_allocate (&result
-> buffer
,
2160 result
-> len
+ 1, file
, line
)) {
2161 result
-> data
= &result
-> buffer
-> data
[0];
2162 strcpy ((char *)&result
-> buffer
-> data
[0],
2163 lease
-> host
-> name
);
2164 result
-> terminated
= 1;
2166 log_error ("data: host-decl-name: no memory.");
2169 #if defined (DEBUG_EXPRESSIONS)
2170 log_debug ("data: host-decl-name = %s", lease
-> host
-> name
);
2175 #if defined (DEBUG_EXPRESSIONS)
2176 log_debug ("data: null = NULL");
2180 case expr_variable_reference
:
2181 if (scope
&& *scope
) {
2182 binding
= find_binding (*scope
, expr
-> data
.variable
);
2184 if (binding
&& binding
-> value
) {
2185 if (binding
-> value
-> type
== binding_data
) {
2186 data_string_copy (result
,
2187 &binding
-> value
-> value
.data
,
2190 } else if (binding
-> value
-> type
!= binding_data
) {
2191 log_error ("binding type %d in %s.",
2192 binding
-> value
-> type
,
2193 "evaluate_data_expression");
2201 #if defined (DEBUG_EXPRESSIONS)
2202 log_debug ("data: %s = %s", expr
-> data
.variable
,
2203 s0
? print_hex_1 (result
-> len
,
2204 result
-> data
, 50) : "NULL");
2209 bv
= (struct binding_value
*)0;
2210 s0
= evaluate_expression (&bv
, packet
, lease
, client_state
,
2211 in_options
, cfg_options
,
2214 if (bv
-> type
!= binding_data
)
2215 log_error ("%s() returned type %d in %s.",
2216 expr
-> data
.funcall
.name
,
2218 "evaluate_data_expression");
2220 data_string_copy (result
, &bv
-> value
.data
,
2222 binding_value_dereference (&bv
, MDL
);
2224 #if defined (DEBUG_EXPRESSIONS)
2225 log_debug ("data: %s = %s", expr
-> data
.funcall
.name
,
2226 s0
? print_hex_1 (result
-> len
,
2227 result
-> data
, 50) : "NULL");
2231 /* Extract the filename. */
2233 if (packet
&& packet
-> raw
-> file
[0]) {
2235 memchr (packet
-> raw
-> file
, 0,
2236 sizeof packet
-> raw
-> file
);
2238 fn
= ((char *)packet
-> raw
-> file
+
2239 sizeof packet
-> raw
-> file
);
2240 result
-> len
= fn
- &(packet
-> raw
-> file
[0]);
2241 if (buffer_allocate (&result
-> buffer
,
2242 result
-> len
+ 1, file
, line
)) {
2243 result
-> data
= &result
-> buffer
-> data
[0];
2244 memcpy (&result
-> buffer
-> data
[0],
2245 packet
-> raw
-> file
,
2247 result
-> buffer
-> data
[result
-> len
] = 0;
2248 result
-> terminated
= 1;
2251 log_error ("data: filename: no memory.");
2257 #if defined (DEBUG_EXPRESSIONS)
2258 log_info ("data: filename = \"%s\"",
2259 s0
? (const char *)(result
-> data
) : "NULL");
2263 /* Extract the server name. */
2265 if (packet
&& packet
-> raw
-> sname
[0]) {
2267 memchr (packet
-> raw
-> sname
, 0,
2268 sizeof packet
-> raw
-> sname
);
2270 fn
= ((char *)packet
-> raw
-> sname
+
2271 sizeof packet
-> raw
-> sname
);
2272 result
-> len
= fn
- &packet
-> raw
-> sname
[0];
2273 if (buffer_allocate (&result
-> buffer
,
2274 result
-> len
+ 1, file
, line
)) {
2275 result
-> data
= &result
-> buffer
-> data
[0];
2276 memcpy (&result
-> buffer
-> data
[0],
2277 packet
-> raw
-> sname
,
2279 result
-> buffer
-> data
[result
-> len
] = 0;
2280 result
-> terminated
= 1;
2283 log_error ("data: sname: no memory.");
2289 #if defined (DEBUG_EXPRESSIONS)
2290 log_info ("data: sname = \"%s\"",
2291 s0
? (const char *)(result
-> data
) : "NULL");
2297 case expr_not_equal
:
2306 case expr_variable_exists
:
2307 log_error ("Boolean opcode in evaluate_data_expression: %d",
2311 case expr_extract_int8
:
2312 case expr_extract_int16
:
2313 case expr_extract_int32
:
2314 case expr_const_int
:
2315 case expr_lease_time
:
2316 case expr_dns_transaction
:
2321 case expr_remainder
:
2322 case expr_binary_and
:
2323 case expr_binary_or
:
2324 case expr_binary_xor
:
2325 case expr_client_state
:
2326 log_error ("Numeric opcode in evaluate_data_expression: %d",
2331 case expr_ns_delete
:
2332 case expr_ns_exists
:
2333 case expr_ns_not_exists
:
2334 log_error ("dns update opcode in evaluate_data_expression: %d",
2339 log_error ("function definition in evaluate_data_expression");
2346 log_error ("Bogus opcode in evaluate_data_expression: %d", expr
-> op
);
2350 int evaluate_numeric_expression (result
, packet
, lease
, client_state
,
2351 in_options
, cfg_options
, scope
, expr
)
2352 unsigned long *result
;
2353 struct packet
*packet
;
2354 struct lease
*lease
;
2355 struct client_state
*client_state
;
2356 struct option_state
*in_options
;
2357 struct option_state
*cfg_options
;
2358 struct binding_scope
**scope
;
2359 struct expression
*expr
;
2361 struct data_string data
;
2362 int status
, sleft
, sright
;
2363 #if defined (NSUPDATE)
2367 struct expression
*cur
, *next
;
2368 struct binding
*binding
;
2369 struct binding_value
*bv
;
2370 unsigned long ileft
, iright
;
2372 switch (expr
-> op
) {
2375 case expr_not_equal
:
2384 case expr_variable_exists
:
2385 log_error ("Boolean opcode in evaluate_numeric_expression: %d",
2389 case expr_substring
:
2395 case expr_const_data
:
2398 case expr_encapsulate
:
2399 case expr_host_lookup
:
2400 case expr_encode_int8
:
2401 case expr_encode_int16
:
2402 case expr_encode_int32
:
2403 case expr_binary_to_ascii
:
2407 case expr_pick_first_value
:
2408 case expr_host_decl_name
:
2409 case expr_config_option
:
2410 case expr_leased_address
:
2412 log_error ("Data opcode in evaluate_numeric_expression: %d",
2416 case expr_extract_int8
:
2417 memset (&data
, 0, sizeof data
);
2418 status
= evaluate_data_expression
2419 (&data
, packet
, lease
, client_state
, in_options
,
2420 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
);
2422 *result
= data
.data
[0];
2423 #if defined (DEBUG_EXPRESSIONS)
2424 log_debug ("num: extract_int8 (%s) = %s",
2425 status
? print_hex_1 (data
.len
, data
.data
, 60) : "NULL",
2426 status
? print_dec_1 (*result
) : "NULL" );
2428 if (status
) data_string_forget (&data
, MDL
);
2431 case expr_extract_int16
:
2432 memset (&data
, 0, sizeof data
);
2433 status
= (evaluate_data_expression
2434 (&data
, packet
, lease
, client_state
, in_options
,
2435 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
));
2436 if (status
&& data
.len
>= 2)
2437 *result
= getUShort (data
.data
);
2438 #if defined (DEBUG_EXPRESSIONS)
2439 log_debug ("num: extract_int16 (%s) = %ld",
2440 ((status
&& data
.len
>= 2) ?
2441 print_hex_1 (data
.len
, data
.data
, 60) : "NULL"),
2444 if (status
) data_string_forget (&data
, MDL
);
2445 return (status
&& data
.len
>= 2);
2447 case expr_extract_int32
:
2448 memset (&data
, 0, sizeof data
);
2449 status
= (evaluate_data_expression
2450 (&data
, packet
, lease
, client_state
, in_options
,
2451 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
));
2452 if (status
&& data
.len
>= 4)
2453 *result
= getULong (data
.data
);
2454 #if defined (DEBUG_EXPRESSIONS)
2455 log_debug ("num: extract_int32 (%s) = %ld",
2456 ((status
&& data
.len
>= 4) ?
2457 print_hex_1 (data
.len
, data
.data
, 60) : "NULL"),
2460 if (status
) data_string_forget (&data
, MDL
);
2461 return (status
&& data
.len
>= 4);
2463 case expr_const_int
:
2464 *result
= expr
-> data
.const_int
;
2465 #if defined (DEBUG_EXPRESSIONS)
2466 log_debug ("number: CONSTANT = %ld", *result
);
2470 case expr_lease_time
:
2472 log_error ("data: leased_lease: not available");
2475 if (lease
-> ends
< cur_time
) {
2476 log_error ("%s %lu when it is now %lu",
2477 "data: lease_time: lease ends at",
2478 (long)(lease
-> ends
), (long)cur_time
);
2481 *result
= lease
-> ends
- cur_time
;
2482 #if defined (DEBUG_EXPRESSIONS)
2483 log_debug ("number: lease-time = (%lu - %lu) = %ld",
2489 case expr_dns_transaction
:
2490 #if !defined (NSUPDATE)
2493 if (!resolver_inited
) {
2494 minires_ninit (&resolver_state
);
2495 resolver_inited
= 1;
2496 resolver_state
.retrans
= 1;
2497 resolver_state
.retry
= 1;
2502 next
= cur
-> data
.dns_transaction
.cdr
;
2504 status
= (evaluate_dns_expression
2506 lease
, client_state
, in_options
, cfg_options
,
2507 scope
, cur
-> data
.dns_transaction
.car
));
2510 ISC_LIST_APPEND (uq
, nut
, r_link
);
2514 /* Do the update and record the error code, if there was
2515 an error; otherwise set it to NOERROR. */
2516 *result
= minires_nupdate (&resolver_state
,
2517 ISC_LIST_HEAD (uq
));
2520 print_dns_status ((int)*result
, &uq
);
2523 while (!ISC_LIST_EMPTY (uq
)) {
2524 ns_updrec
*tmp
= ISC_LIST_HEAD (uq
);
2525 ISC_LIST_UNLINK (uq
, tmp
, r_link
);
2526 if (tmp
-> r_data_ephem
) {
2527 dfree (tmp
-> r_data_ephem
, MDL
);
2528 tmp
-> r_data
= (unsigned char *)0;
2529 tmp
-> r_data_ephem
= (unsigned char *)0;
2531 minires_freeupdrec (tmp
);
2534 #endif /* NSUPDATE */
2536 case expr_variable_reference
:
2537 if (scope
&& *scope
) {
2538 binding
= find_binding (*scope
, expr
-> data
.variable
);
2540 if (binding
&& binding
-> value
) {
2541 if (binding
-> value
-> type
== binding_numeric
) {
2542 *result
= binding
-> value
-> value
.intval
;
2545 log_error ("binding type %d in %s.",
2546 binding
-> value
-> type
,
2547 "evaluate_numeric_expression");
2554 #if defined (DEBUG_EXPRESSIONS)
2556 log_debug ("numeric: %s = %ld",
2557 expr
-> data
.variable
, *result
);
2559 log_debug ("numeric: %s = NULL",
2560 expr
-> data
.variable
);
2565 bv
= (struct binding_value
*)0;
2566 status
= evaluate_expression (&bv
, packet
, lease
,
2568 in_options
, cfg_options
,
2571 if (bv
-> type
!= binding_numeric
)
2572 log_error ("%s() returned type %d in %s.",
2573 expr
-> data
.funcall
.name
,
2575 "evaluate_numeric_expression");
2577 *result
= bv
-> value
.intval
;
2578 binding_value_dereference (&bv
, MDL
);
2580 #if defined (DEBUG_EXPRESSIONS)
2581 log_debug ("data: %s = %ld", expr
-> data
.funcall
.name
,
2582 status
? *result
: 0);
2587 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2589 in_options
, cfg_options
,
2591 expr
-> data
.and [0]);
2592 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2594 in_options
, cfg_options
,
2596 expr
-> data
.and [1]);
2598 #if defined (DEBUG_EXPRESSIONS)
2599 if (sleft
&& sright
)
2600 log_debug ("num: %ld + %ld = %ld",
2601 ileft
, iright
, ileft
+ iright
);
2603 log_debug ("num: %ld + NULL = NULL", ileft
);
2605 log_debug ("num: NULL + %ld = NULL", iright
);
2607 if (sleft
&& sright
) {
2608 *result
= ileft
+ iright
;
2614 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2616 in_options
, cfg_options
,
2618 expr
-> data
.and [0]);
2619 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2621 in_options
, cfg_options
,
2623 expr
-> data
.and [1]);
2625 #if defined (DEBUG_EXPRESSIONS)
2626 if (sleft
&& sright
)
2627 log_debug ("num: %ld - %ld = %ld",
2628 ileft
, iright
, ileft
- iright
);
2630 log_debug ("num: %ld - NULL = NULL", ileft
);
2632 log_debug ("num: NULL - %ld = NULL", iright
);
2634 if (sleft
&& sright
) {
2635 *result
= ileft
- iright
;
2641 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2643 in_options
, cfg_options
,
2645 expr
-> data
.and [0]);
2646 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2648 in_options
, cfg_options
,
2650 expr
-> data
.and [1]);
2652 #if defined (DEBUG_EXPRESSIONS)
2653 if (sleft
&& sright
)
2654 log_debug ("num: %ld * %ld = %ld",
2655 ileft
, iright
, ileft
* iright
);
2657 log_debug ("num: %ld * NULL = NULL", ileft
);
2659 log_debug ("num: NULL * %ld = NULL", iright
);
2661 if (sleft
&& sright
) {
2662 *result
= ileft
* iright
;
2668 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2670 in_options
, cfg_options
,
2672 expr
-> data
.and [0]);
2673 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2675 in_options
, cfg_options
,
2677 expr
-> data
.and [1]);
2679 #if defined (DEBUG_EXPRESSIONS)
2680 if (sleft
&& sright
) {
2682 log_debug ("num: %ld / %ld = %ld",
2683 ileft
, iright
, ileft
/ iright
);
2685 log_debug ("num: %ld / %ld = NULL",
2688 log_debug ("num: %ld / NULL = NULL", ileft
);
2690 log_debug ("num: NULL / %ld = NULL", iright
);
2692 if (sleft
&& sright
&& iright
) {
2693 *result
= ileft
/ iright
;
2698 case expr_remainder
:
2699 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2701 in_options
, cfg_options
,
2703 expr
-> data
.and [0]);
2704 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2706 in_options
, cfg_options
,
2708 expr
-> data
.and [1]);
2710 #if defined (DEBUG_EXPRESSIONS)
2711 if (sleft
&& sright
) {
2713 log_debug ("num: %ld %% %ld = %ld",
2714 ileft
, iright
, ileft
% iright
);
2716 log_debug ("num: %ld %% %ld = NULL",
2719 log_debug ("num: %ld %% NULL = NULL", ileft
);
2721 log_debug ("num: NULL %% %ld = NULL", iright
);
2723 if (sleft
&& sright
&& iright
) {
2724 *result
= ileft
% iright
;
2729 case expr_binary_and
:
2730 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2732 in_options
, cfg_options
,
2734 expr
-> data
.and [0]);
2735 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2737 in_options
, cfg_options
,
2739 expr
-> data
.and [1]);
2741 #if defined (DEBUG_EXPRESSIONS)
2742 if (sleft
&& sright
)
2743 log_debug ("num: %ld | %ld = %ld",
2744 ileft
, iright
, ileft
& iright
);
2746 log_debug ("num: %ld & NULL = NULL", ileft
);
2748 log_debug ("num: NULL & %ld = NULL", iright
);
2750 if (sleft
&& sright
) {
2751 *result
= ileft
& iright
;
2756 case expr_binary_or
:
2757 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2759 in_options
, cfg_options
,
2761 expr
-> data
.and [0]);
2762 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2764 in_options
, cfg_options
,
2766 expr
-> data
.and [1]);
2768 #if defined (DEBUG_EXPRESSIONS)
2769 if (sleft
&& sright
)
2770 log_debug ("num: %ld | %ld = %ld",
2771 ileft
, iright
, ileft
| iright
);
2773 log_debug ("num: %ld | NULL = NULL", ileft
);
2775 log_debug ("num: NULL | %ld = NULL", iright
);
2777 if (sleft
&& sright
) {
2778 *result
= ileft
| iright
;
2783 case expr_binary_xor
:
2784 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2786 in_options
, cfg_options
,
2788 expr
-> data
.and [0]);
2789 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2791 in_options
, cfg_options
,
2793 expr
-> data
.and [1]);
2795 #if defined (DEBUG_EXPRESSIONS)
2796 if (sleft
&& sright
)
2797 log_debug ("num: %ld ^ %ld = %ld",
2798 ileft
, iright
, ileft
^ iright
);
2800 log_debug ("num: %ld ^ NULL = NULL", ileft
);
2802 log_debug ("num: NULL ^ %ld = NULL", iright
);
2804 if (sleft
&& sright
) {
2805 *result
= ileft
^ iright
;
2810 case expr_client_state
:
2812 #if defined (DEBUG_EXPRESSIONS)
2813 log_debug ("num: client-state = %d",
2814 client_state
-> state
);
2816 *result
= client_state
-> state
;
2819 #if defined (DEBUG_EXPRESSIONS)
2820 log_debug ("num: client-state = NULL");
2826 case expr_ns_delete
:
2827 case expr_ns_exists
:
2828 case expr_ns_not_exists
:
2829 log_error ("dns opcode in evaluate_numeric_expression: %d",
2834 log_error ("function definition in evaluate_numeric_expr");
2841 log_fatal("Impossible case at %s:%d. Undefined operator "
2842 "%d.", MDL
, expr
->op
);
2846 log_error ("evaluate_numeric_expression: bogus opcode %d", expr
-> op
);
2850 /* Return data hanging off of an option cache structure, or if there
2851 isn't any, evaluate the expression hanging off of it and return the
2852 result of that evaluation. There should never be both an expression
2853 and a valid data_string. */
2855 int evaluate_option_cache (result
, packet
, lease
, client_state
,
2856 in_options
, cfg_options
, scope
, oc
, file
, line
)
2857 struct data_string
*result
;
2858 struct packet
*packet
;
2859 struct lease
*lease
;
2860 struct client_state
*client_state
;
2861 struct option_state
*in_options
;
2862 struct option_state
*cfg_options
;
2863 struct binding_scope
**scope
;
2864 struct option_cache
*oc
;
2868 if (oc
->data
.data
!= NULL
) {
2869 data_string_copy (result
, &oc
-> data
, file
, line
);
2872 if (!oc
-> expression
)
2874 return evaluate_data_expression (result
, packet
, lease
, client_state
,
2875 in_options
, cfg_options
, scope
,
2876 oc
-> expression
, file
, line
);
2879 /* Evaluate an option cache and extract a boolean from the result,
2880 returning the boolean. Return false if there is no data. */
2882 int evaluate_boolean_option_cache (ignorep
, packet
,
2883 lease
, client_state
, in_options
,
2884 cfg_options
, scope
, oc
, file
, line
)
2886 struct packet
*packet
;
2887 struct lease
*lease
;
2888 struct client_state
*client_state
;
2889 struct option_state
*in_options
;
2890 struct option_state
*cfg_options
;
2891 struct binding_scope
**scope
;
2892 struct option_cache
*oc
;
2896 struct data_string ds
;
2899 /* So that we can be called with option_lookup as an argument. */
2900 if (!oc
|| !in_options
)
2903 memset (&ds
, 0, sizeof ds
);
2904 if (!evaluate_option_cache (&ds
, packet
,
2905 lease
, client_state
, in_options
,
2906 cfg_options
, scope
, oc
, file
, line
))
2910 result
= ds
.data
[0];
2918 data_string_forget (&ds
, MDL
);
2923 /* Evaluate a boolean expression and return the result of the evaluation,
2924 or FALSE if it failed. */
2926 int evaluate_boolean_expression_result (ignorep
, packet
, lease
, client_state
,
2927 in_options
, cfg_options
, scope
, expr
)
2929 struct packet
*packet
;
2930 struct lease
*lease
;
2931 struct client_state
*client_state
;
2932 struct option_state
*in_options
;
2933 struct option_state
*cfg_options
;
2934 struct binding_scope
**scope
;
2935 struct expression
*expr
;
2939 /* So that we can be called with option_lookup as an argument. */
2943 if (!evaluate_boolean_expression (&result
, packet
, lease
, client_state
,
2944 in_options
, cfg_options
,
2957 /* Dereference an expression node, and if the reference count goes to zero,
2958 dereference any data it refers to, and then free it. */
2959 void expression_dereference (eptr
, file
, line
)
2960 struct expression
**eptr
;
2964 struct expression
*expr
= *eptr
;
2966 /* Zero the pointer. */
2967 *eptr
= (struct expression
*)0;
2969 /* Decrement the reference count. If it's nonzero, we're
2972 rc_register (file
, line
, eptr
, expr
, expr
-> refcnt
, 1, RC_MISC
);
2973 if (expr
-> refcnt
> 0)
2975 if (expr
-> refcnt
< 0) {
2976 log_error ("%s(%d): negative refcnt!", file
, line
);
2977 #if defined (DEBUG_RC_HISTORY)
2978 dump_rc_history (expr
);
2980 #if defined (POINTER_DEBUG)
2987 /* Dereference subexpressions. */
2988 switch (expr
-> op
) {
2989 /* All the binary operators can be handled the same way. */
2991 case expr_not_equal
:
2999 case expr_remainder
:
3000 case expr_binary_and
:
3001 case expr_binary_or
:
3002 case expr_binary_xor
:
3003 case expr_client_state
:
3004 if (expr
-> data
.equal
[0])
3005 expression_dereference (&expr
-> data
.equal
[0],
3007 if (expr
-> data
.equal
[1])
3008 expression_dereference (&expr
-> data
.equal
[1],
3012 case expr_substring
:
3013 if (expr
-> data
.substring
.expr
)
3014 expression_dereference (&expr
-> data
.substring
.expr
,
3016 if (expr
-> data
.substring
.offset
)
3017 expression_dereference (&expr
-> data
.substring
.offset
,
3019 if (expr
-> data
.substring
.len
)
3020 expression_dereference (&expr
-> data
.substring
.len
,
3025 if (expr
-> data
.suffix
.expr
)
3026 expression_dereference (&expr
-> data
.suffix
.expr
,
3028 if (expr
-> data
.suffix
.len
)
3029 expression_dereference (&expr
-> data
.suffix
.len
,
3034 if (expr
->data
.lcase
)
3035 expression_dereference(&expr
->data
.lcase
, MDL
);
3039 if (expr
->data
.ucase
)
3040 expression_dereference(&expr
->data
.ucase
, MDL
);
3044 if (expr
-> data
.not)
3045 expression_dereference (&expr
-> data
.not, file
, line
);
3049 if (expr
-> data
.packet
.offset
)
3050 expression_dereference (&expr
-> data
.packet
.offset
,
3052 if (expr
-> data
.packet
.len
)
3053 expression_dereference (&expr
-> data
.packet
.len
,
3057 case expr_extract_int8
:
3058 case expr_extract_int16
:
3059 case expr_extract_int32
:
3060 if (expr
-> data
.extract_int
)
3061 expression_dereference (&expr
-> data
.extract_int
,
3065 case expr_encode_int8
:
3066 case expr_encode_int16
:
3067 case expr_encode_int32
:
3068 if (expr
-> data
.encode_int
)
3069 expression_dereference (&expr
-> data
.encode_int
,
3073 case expr_encapsulate
:
3074 case expr_const_data
:
3075 data_string_forget (&expr
-> data
.const_data
, file
, line
);
3078 case expr_host_lookup
:
3079 if (expr
-> data
.host_lookup
)
3080 dns_host_entry_dereference (&expr
-> data
.host_lookup
,
3084 case expr_binary_to_ascii
:
3085 if (expr
-> data
.b2a
.base
)
3086 expression_dereference (&expr
-> data
.b2a
.base
,
3088 if (expr
-> data
.b2a
.width
)
3089 expression_dereference (&expr
-> data
.b2a
.width
,
3091 if (expr
-> data
.b2a
.separator
)
3092 expression_dereference (&expr
-> data
.b2a
.separator
,
3094 if (expr
-> data
.b2a
.buffer
)
3095 expression_dereference (&expr
-> data
.b2a
.buffer
,
3099 case expr_pick_first_value
:
3100 if (expr
-> data
.pick_first_value
.car
)
3101 expression_dereference (&expr
-> data
.pick_first_value
.car
,
3103 if (expr
-> data
.pick_first_value
.cdr
)
3104 expression_dereference (&expr
-> data
.pick_first_value
.cdr
,
3109 if (expr
-> data
.reverse
.width
)
3110 expression_dereference (&expr
-> data
.reverse
.width
,
3112 if (expr
-> data
.reverse
.buffer
)
3113 expression_dereference
3114 (&expr
-> data
.reverse
.buffer
, file
, line
);
3117 case expr_dns_transaction
:
3118 if (expr
-> data
.dns_transaction
.car
)
3119 expression_dereference (&expr
-> data
.dns_transaction
.car
,
3121 if (expr
-> data
.dns_transaction
.cdr
)
3122 expression_dereference (&expr
-> data
.dns_transaction
.cdr
,
3127 if (expr
-> data
.ns_add
.rrname
)
3128 expression_dereference (&expr
-> data
.ns_add
.rrname
,
3130 if (expr
-> data
.ns_add
.rrdata
)
3131 expression_dereference (&expr
-> data
.ns_add
.rrdata
,
3133 if (expr
-> data
.ns_add
.ttl
)
3134 expression_dereference (&expr
-> data
.ns_add
.ttl
,
3138 case expr_ns_delete
:
3139 case expr_ns_exists
:
3140 case expr_ns_not_exists
:
3141 if (expr
-> data
.ns_delete
.rrname
)
3142 expression_dereference (&expr
-> data
.ns_delete
.rrname
,
3144 if (expr
-> data
.ns_delete
.rrdata
)
3145 expression_dereference (&expr
-> data
.ns_delete
.rrdata
,
3149 case expr_variable_reference
:
3150 case expr_variable_exists
:
3151 if (expr
-> data
.variable
)
3152 dfree (expr
-> data
.variable
, file
, line
);
3156 if (expr
-> data
.funcall
.name
)
3157 dfree (expr
-> data
.funcall
.name
, file
, line
);
3158 if (expr
-> data
.funcall
.arglist
)
3159 expression_dereference (&expr
-> data
.funcall
.arglist
,
3164 if (expr
-> data
.arg
.val
)
3165 expression_dereference (&expr
-> data
.arg
.val
,
3167 if (expr
-> data
.arg
.next
)
3168 expression_dereference (&expr
-> data
.arg
.next
,
3173 fundef_dereference (&expr
-> data
.func
, file
, line
);
3176 /* No subexpressions. */
3177 case expr_leased_address
:
3178 case expr_lease_time
:
3181 case expr_const_int
:
3193 free_expression (expr
, MDL
);
3196 int is_dns_expression (expr
)
3197 struct expression
*expr
;
3199 return (expr
-> op
== expr_ns_add
||
3200 expr
-> op
== expr_ns_delete
||
3201 expr
-> op
== expr_ns_exists
||
3202 expr
-> op
== expr_ns_not_exists
);
3205 int is_boolean_expression (expr
)
3206 struct expression
*expr
;
3208 return (expr
-> op
== expr_check
||
3209 expr
-> op
== expr_exists
||
3210 expr
-> op
== expr_variable_exists
||
3211 expr
-> op
== expr_equal
||
3212 expr
-> op
== expr_not_equal
||
3213 expr
-> op
== expr_and
||
3214 expr
-> op
== expr_or
||
3215 expr
-> op
== expr_not
||
3216 expr
-> op
== expr_known
||
3217 expr
-> op
== expr_static
);
3220 int is_data_expression (expr
)
3221 struct expression
*expr
;
3223 return (expr
->op
== expr_substring
||
3224 expr
->op
== expr_suffix
||
3225 expr
->op
== expr_lcase
||
3226 expr
->op
== expr_ucase
||
3227 expr
->op
== expr_option
||
3228 expr
->op
== expr_hardware
||
3229 expr
->op
== expr_const_data
||
3230 expr
->op
== expr_packet
||
3231 expr
->op
== expr_concat
||
3232 expr
->op
== expr_encapsulate
||
3233 expr
->op
== expr_encode_int8
||
3234 expr
->op
== expr_encode_int16
||
3235 expr
->op
== expr_encode_int32
||
3236 expr
->op
== expr_host_lookup
||
3237 expr
->op
== expr_binary_to_ascii
||
3238 expr
->op
== expr_filename
||
3239 expr
->op
== expr_sname
||
3240 expr
->op
== expr_reverse
||
3241 expr
->op
== expr_pick_first_value
||
3242 expr
->op
== expr_host_decl_name
||
3243 expr
->op
== expr_leased_address
||
3244 expr
->op
== expr_config_option
||
3245 expr
->op
== expr_null
);
3248 int is_numeric_expression (expr
)
3249 struct expression
*expr
;
3251 return (expr
-> op
== expr_extract_int8
||
3252 expr
-> op
== expr_extract_int16
||
3253 expr
-> op
== expr_extract_int32
||
3254 expr
-> op
== expr_const_int
||
3255 expr
-> op
== expr_lease_time
||
3256 expr
-> op
== expr_dns_transaction
||
3257 expr
-> op
== expr_add
||
3258 expr
-> op
== expr_subtract
||
3259 expr
-> op
== expr_multiply
||
3260 expr
-> op
== expr_divide
||
3261 expr
-> op
== expr_remainder
||
3262 expr
-> op
== expr_binary_and
||
3263 expr
-> op
== expr_binary_or
||
3264 expr
-> op
== expr_binary_xor
||
3265 expr
-> op
== expr_client_state
);
3268 int is_compound_expression (expr
)
3269 struct expression
*expr
;
3271 return (expr
-> op
== expr_ns_add
||
3272 expr
-> op
== expr_ns_delete
||
3273 expr
-> op
== expr_ns_exists
||
3274 expr
-> op
== expr_ns_not_exists
||
3275 expr
-> op
== expr_substring
||
3276 expr
-> op
== expr_suffix
||
3277 expr
-> op
== expr_option
||
3278 expr
-> op
== expr_concat
||
3279 expr
-> op
== expr_encode_int8
||
3280 expr
-> op
== expr_encode_int16
||
3281 expr
-> op
== expr_encode_int32
||
3282 expr
-> op
== expr_binary_to_ascii
||
3283 expr
-> op
== expr_reverse
||
3284 expr
-> op
== expr_pick_first_value
||
3285 expr
-> op
== expr_config_option
||
3286 expr
-> op
== expr_extract_int8
||
3287 expr
-> op
== expr_extract_int16
||
3288 expr
-> op
== expr_extract_int32
||
3289 expr
-> op
== expr_dns_transaction
);
3292 static int op_val
PROTO ((enum expr_op
));
3294 static int op_val (op
)
3302 case expr_substring
:
3307 case expr_encapsulate
:
3308 case expr_host_lookup
:
3313 case expr_const_data
:
3314 case expr_extract_int8
:
3315 case expr_extract_int16
:
3316 case expr_extract_int32
:
3317 case expr_encode_int8
:
3318 case expr_encode_int16
:
3319 case expr_encode_int32
:
3320 case expr_const_int
:
3322 case expr_variable_exists
:
3324 case expr_binary_to_ascii
:
3328 case expr_pick_first_value
:
3329 case expr_host_decl_name
:
3330 case expr_config_option
:
3331 case expr_leased_address
:
3332 case expr_lease_time
:
3333 case expr_dns_transaction
:
3335 case expr_variable_reference
:
3337 case expr_ns_delete
:
3338 case expr_ns_exists
:
3339 case expr_ns_not_exists
:
3343 /* XXXDPN: Need to assign sane precedences to these. */
3344 case expr_binary_and
:
3345 case expr_binary_or
:
3346 case expr_binary_xor
:
3347 case expr_client_state
:
3351 case expr_not_equal
:
3364 case expr_remainder
:
3370 int op_precedence (op1
, op2
)
3371 enum expr_op op1
, op2
;
3375 return op_val (op1
) - op_val (op2
);
3378 enum expression_context
expression_context (struct expression
*expr
)
3380 if (is_data_expression (expr
))
3381 return context_data
;
3382 if (is_numeric_expression (expr
))
3383 return context_numeric
;
3384 if (is_boolean_expression (expr
))
3385 return context_boolean
;
3386 if (is_dns_expression (expr
))
3391 enum expression_context
op_context (op
)
3395 /* XXX Why aren't these specific? */
3400 case expr_substring
:
3405 case expr_encapsulate
:
3406 case expr_host_lookup
:
3411 case expr_const_data
:
3412 case expr_extract_int8
:
3413 case expr_extract_int16
:
3414 case expr_extract_int32
:
3415 case expr_encode_int8
:
3416 case expr_encode_int16
:
3417 case expr_encode_int32
:
3418 case expr_const_int
:
3420 case expr_variable_exists
:
3422 case expr_binary_to_ascii
:
3426 case expr_pick_first_value
:
3427 case expr_host_decl_name
:
3428 case expr_config_option
:
3429 case expr_leased_address
:
3430 case expr_lease_time
:
3432 case expr_variable_reference
:
3434 case expr_ns_delete
:
3435 case expr_ns_exists
:
3436 case expr_ns_not_exists
:
3437 case expr_dns_transaction
:
3444 case expr_not_equal
:
3445 return context_data
;
3448 return context_boolean
;
3451 return context_boolean
;
3457 case expr_remainder
:
3458 case expr_binary_and
:
3459 case expr_binary_or
:
3460 case expr_binary_xor
:
3461 case expr_client_state
:
3462 return context_numeric
;
3467 int write_expression (file
, expr
, col
, indent
, firstp
)
3469 struct expression
*expr
;
3474 struct expression
*e
;
3475 struct expression
*next_arg
;
3481 /* If this promises to be a fat expression, start a new line. */
3482 if (!firstp
&& is_compound_expression (expr
)) {
3483 indent_spaces (file
, indent
);
3487 switch (expr
-> op
) {
3489 col
= token_print_indent (file
, col
, indent
, "", "", "null");
3493 col
= token_print_indent (file
, col
, indent
, "", "", "check");
3494 col
= token_print_indent_concat (file
, col
, indent
,
3496 expr
-> data
.check
-> name
,
3500 case expr_not_equal
:
3507 col
= write_expression (file
, expr
-> data
.equal
[0],
3509 col
= token_print_indent (file
, col
, indent
, " ", " ", s
);
3510 col
= write_expression (file
, expr
-> data
.equal
[1],
3511 col
, indent
+ 2, 0);
3514 case expr_substring
:
3515 col
= token_print_indent (file
, col
, indent
, "", "",
3517 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3519 col
= write_expression (file
, expr
-> data
.substring
.expr
,
3521 col
= token_print_indent (file
, col
, indent
, "", " ", ",");
3522 col
= write_expression (file
, expr
-> data
.substring
.offset
,
3524 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3525 col
= write_expression (file
, expr
-> data
.substring
.len
,
3527 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3531 col
= token_print_indent (file
, col
, indent
, "", "", "suffix");
3532 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3534 col
= write_expression (file
, expr
-> data
.suffix
.expr
,
3536 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3537 col
= write_expression (file
, expr
-> data
.suffix
.len
,
3539 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3542 col
= token_print_indent(file
, col
, indent
, "", "", "lcase");
3543 col
= token_print_indent(file
, col
, indent
, " ", "", "(");
3545 col
= write_expression(file
, expr
->data
.lcase
, col
, scol
, 1);
3546 col
= token_print_indent(file
, col
, indent
, "", "", ")");
3550 col
= token_print_indent(file
, col
, indent
, "", "", "ucase");
3551 col
= token_print_indent(file
, col
, indent
, " ", "", "(");
3553 col
= write_expression(file
, expr
->data
.ucase
, col
, scol
, 1);
3554 col
= token_print_indent(file
, col
, indent
, "", "", ")");
3559 col
= token_print_indent (file
, col
, indent
, "", "",
3561 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3565 col
= write_expression (file
, e
-> data
.concat
[0],
3568 if (!e
-> data
.concat
[1])
3570 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3571 if (e
-> data
.concat
[1] -> op
== expr_concat
) {
3572 e
= e
-> data
.concat
[1];
3575 col
= write_expression (file
, e
-> data
.concat
[1],
3578 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3581 case expr_host_lookup
:
3582 col
= token_print_indent (file
, col
, indent
, "", "",
3584 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3585 col
= token_print_indent_concat
3586 (file
, col
, indent
, "", "",
3587 "\"", expr
-> data
.host_lookup
-> hostname
, "\"",
3589 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3608 case expr_remainder
:
3612 case expr_binary_and
:
3616 case expr_binary_or
:
3620 case expr_binary_xor
:
3633 col
= token_print_indent (file
, col
, indent
, "", " ", "not");
3634 col
= write_expression (file
,
3635 expr
-> data
.not, col
, indent
+ 2, 1);
3642 col
= token_print_indent (file
, col
, indent
, "", "", s
);
3644 if (expr
-> data
.option
-> universe
!= &dhcp_universe
) {
3645 col
= token_print_indent (file
, col
, indent
,
3647 (expr
-> data
.option
->
3649 col
= token_print_indent (file
, col
, indent
, "", "",
3651 col
= token_print_indent (file
, col
, indent
, "", "",
3652 expr
-> data
.option
-> name
);
3654 col
= token_print_indent (file
, col
, indent
, " ", "",
3655 expr
-> data
.option
-> name
);
3660 col
= token_print_indent (file
, col
, indent
, "", "",
3665 col
= token_print_indent (file
, col
, indent
, "", "",
3667 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3669 col
= write_expression (file
, expr
-> data
.packet
.offset
,
3671 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3672 col
= write_expression (file
, expr
-> data
.packet
.len
,
3674 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3677 case expr_const_data
:
3678 col
= token_indent_data_string (file
, col
, indent
, "", "",
3679 &expr
-> data
.const_data
);
3682 case expr_extract_int8
:
3685 col
= token_print_indent (file
, col
, indent
, "", "",
3687 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3689 col
= write_expression (file
, expr
-> data
.extract_int
,
3691 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3692 sprintf (obuf
, "%d", width
);
3693 col
= token_print_indent (file
, col
, scol
, " ", "", obuf
);
3694 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3697 case expr_extract_int16
:
3701 case expr_extract_int32
:
3705 case expr_encode_int8
:
3708 col
= token_print_indent (file
, col
, indent
, "", "",
3710 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3712 col
= write_expression (file
, expr
-> data
.extract_int
,
3714 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3715 sprintf (obuf
, "%d", width
);
3716 col
= token_print_indent (file
, col
, scol
, " ", "", obuf
);
3717 col
= token_print_indent (file
, col
, indent
, "", "",
3721 case expr_encode_int16
:
3725 case expr_encode_int32
:
3729 case expr_const_int
:
3730 sprintf (obuf
, "%lu", expr
-> data
.const_int
);
3731 col
= token_print_indent (file
, col
, indent
, "", "", obuf
);
3736 goto print_option_name
;
3738 case expr_encapsulate
:
3739 col
= token_print_indent (file
, col
, indent
, "", "",
3741 col
= token_indent_data_string (file
, col
, indent
, " ", "",
3742 &expr
-> data
.encapsulate
);
3746 col
= token_print_indent (file
, col
, indent
, "", "", "known");
3750 col
= token_print_indent (file
, col
, indent
, "", "",
3752 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3754 col
= write_expression (file
, expr
-> data
.reverse
.width
,
3756 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3757 col
= write_expression (file
, expr
-> data
.reverse
.buffer
,
3759 col
= token_print_indent (file
, col
, indent
, "", "",
3763 case expr_leased_address
:
3764 col
= token_print_indent (file
, col
, indent
, "", "",
3768 case expr_client_state
:
3769 col
= token_print_indent (file
, col
, indent
, "", "",
3773 case expr_binary_to_ascii
:
3774 col
= token_print_indent (file
, col
, indent
, "", "",
3776 col
= token_print_indent (file
, col
, indent
, " ", "",
3779 col
= write_expression (file
, expr
-> data
.b2a
.base
,
3781 col
= token_print_indent (file
, col
, scol
, "", " ",
3783 col
= write_expression (file
, expr
-> data
.b2a
.width
,
3785 col
= token_print_indent (file
, col
, scol
, "", " ",
3787 col
= write_expression (file
, expr
-> data
.b2a
.separator
,
3789 col
= token_print_indent (file
, col
, scol
, "", " ",
3791 col
= write_expression (file
, expr
-> data
.b2a
.buffer
,
3793 col
= token_print_indent (file
, col
, indent
, "", "",
3797 case expr_config_option
:
3798 s
= "config-option";
3799 goto print_option_name
;
3801 case expr_host_decl_name
:
3802 col
= token_print_indent (file
, col
, indent
, "", "",
3806 case expr_pick_first_value
:
3808 col
= token_print_indent (file
, col
, indent
, "", "",
3810 col
= token_print_indent (file
, col
, indent
, " ", "",
3815 col
= write_expression (file
,
3816 e
-> data
.pick_first_value
.car
,
3819 /* We're being very lisp-like right now - instead of
3820 representing this expression as (first middle . last) we're
3821 representing it as (first middle last), which means that the
3822 tail cdr is always nil. Apologies to non-wisp-lizards - may
3823 this obscure way of describing the problem motivate you to
3824 learn more about the one true computing language. */
3825 if (!e
-> data
.pick_first_value
.cdr
)
3827 col
= token_print_indent (file
, col
, scol
, "", " ",
3829 if (e
-> data
.pick_first_value
.cdr
-> op
==
3830 expr_pick_first_value
) {
3831 e
= e
-> data
.pick_first_value
.cdr
;
3834 col
= write_expression (file
,
3835 e
-> data
.pick_first_value
.cdr
,
3838 col
= token_print_indent (file
, col
, indent
, "", "",
3842 case expr_lease_time
:
3843 col
= token_print_indent (file
, col
, indent
, "", "",
3847 case expr_dns_transaction
:
3848 col
= token_print_indent (file
, col
, indent
, "", "",
3850 col
= token_print_indent (file
, col
, indent
, " ", "",
3854 e
&& e
-> op
== expr_dns_transaction
;
3855 e
= e
-> data
.dns_transaction
.cdr
) {
3861 col
= write_expression (file
,
3862 e
-> data
.dns_transaction
.car
,
3864 if (e
-> data
.dns_transaction
.cdr
)
3865 col
= token_print_indent (file
, col
, scol
,
3869 col
= write_expression (file
, e
, col
, scol
, 0);
3870 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3874 col
= token_print_indent (file
, col
, indent
, "", "",
3876 col
= token_print_indent (file
, col
, indent
, " ", "",
3879 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrclass
);
3880 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3881 col
= token_print_indent (file
, col
, scol
, "", " ",
3883 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrtype
);
3884 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3885 col
= token_print_indent (file
, col
, scol
, "", " ",
3887 col
= write_expression (file
, expr
-> data
.ns_add
.rrname
,
3889 col
= token_print_indent (file
, col
, scol
, "", " ",
3891 col
= write_expression (file
, expr
-> data
.ns_add
.rrdata
,
3893 col
= token_print_indent (file
, col
, scol
, "", " ",
3895 col
= write_expression (file
, expr
-> data
.ns_add
.ttl
,
3897 col
= token_print_indent (file
, col
, indent
, "", "",
3901 case expr_ns_delete
:
3902 col
= token_print_indent (file
, col
, indent
, "", "",
3904 col
= token_print_indent (file
, col
, indent
, " ", "",
3908 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrclass
);
3909 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3910 col
= token_print_indent (file
, col
, scol
, "", " ",
3912 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrtype
);
3913 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3914 col
= token_print_indent (file
, col
, scol
, "", " ",
3916 col
= write_expression (file
, expr
-> data
.ns_add
.rrname
,
3918 col
= token_print_indent (file
, col
, scol
, "", " ",
3920 col
= write_expression (file
, expr
-> data
.ns_add
.rrdata
,
3922 col
= token_print_indent (file
, col
, indent
, "", "",
3926 case expr_ns_exists
:
3927 col
= token_print_indent (file
, col
, indent
, "", "",
3929 col
= token_print_indent (file
, col
, indent
, " ", "",
3931 goto finish_ns_small
;
3933 case expr_ns_not_exists
:
3934 col
= token_print_indent (file
, col
, indent
, "", "",
3936 col
= token_print_indent (file
, col
, indent
, " ", "",
3938 goto finish_ns_small
;
3941 col
= token_print_indent (file
, col
, indent
, "", "",
3946 col
= token_print_indent (file
, col
, indent
, "", "", "null");
3949 case expr_variable_reference
:
3950 col
= token_print_indent (file
, indent
, indent
, "", "",
3951 expr
-> data
.variable
);
3954 case expr_variable_exists
:
3955 col
= token_print_indent (file
, indent
, indent
, "", "",
3957 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3958 col
= token_print_indent (file
, col
, indent
, "", "",
3959 expr
-> data
.variable
);
3960 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3964 log_fatal ("invalid expression type in print_expression: %d",
3970 struct binding
*find_binding (struct binding_scope
*scope
, const char *name
)
3973 struct binding_scope
*s
;
3975 for (s
= scope
; s
; s
= s
-> outer
) {
3976 for (bp
= s
-> bindings
; bp
; bp
= bp
-> next
) {
3977 if (!strcasecmp (name
, bp
-> name
)) {
3982 return (struct binding
*)0;
3985 int free_bindings (struct binding_scope
*scope
, const char *file
, int line
)
3987 struct binding
*bp
, *next
;
3989 for (bp
= scope
-> bindings
; bp
; bp
= next
) {
3992 dfree (bp
-> name
, file
, line
);
3994 binding_value_dereference (&bp
-> value
, file
, line
);
3995 dfree (bp
, file
, line
);
3997 scope
-> bindings
= (struct binding
*)0;
4001 int binding_scope_dereference (ptr
, file
, line
)
4002 struct binding_scope
**ptr
;
4007 struct binding_scope
*binding_scope
;
4009 if (!ptr
|| !*ptr
) {
4010 log_error ("%s(%d): null pointer", file
, line
);
4011 #if defined (POINTER_DEBUG)
4018 binding_scope
= *ptr
;
4019 *ptr
= (struct binding_scope
*)0;
4020 --binding_scope
-> refcnt
;
4021 rc_register (file
, line
, ptr
,
4022 binding_scope
, binding_scope
-> refcnt
, 1, RC_MISC
);
4023 if (binding_scope
-> refcnt
> 0)
4026 if (binding_scope
-> refcnt
< 0) {
4027 log_error ("%s(%d): negative refcnt!", file
, line
);
4028 #if defined (DEBUG_RC_HISTORY)
4029 dump_rc_history (binding_scope
);
4031 #if defined (POINTER_DEBUG)
4038 free_bindings (binding_scope
, file
, line
);
4039 if (binding_scope
-> outer
)
4040 binding_scope_dereference (&binding_scope
-> outer
, MDL
);
4041 dfree (binding_scope
, file
, line
);
4045 int fundef_dereference (ptr
, file
, line
)
4046 struct fundef
**ptr
;
4050 struct fundef
*bp
= *ptr
;
4051 struct string_list
*sp
, *next
;
4054 log_error ("%s(%d): null pointer", file
, line
);
4055 #if defined (POINTER_DEBUG)
4063 log_error ("%s(%d): null pointer", file
, line
);
4064 #if defined (POINTER_DEBUG)
4072 rc_register (file
, line
, ptr
, bp
, bp
-> refcnt
, 1, RC_MISC
);
4073 if (bp
-> refcnt
< 0) {
4074 log_error ("%s(%d): negative refcnt!", file
, line
);
4075 #if defined (DEBUG_RC_HISTORY)
4076 dump_rc_history (bp
);
4078 #if defined (POINTER_DEBUG)
4084 if (!bp
-> refcnt
) {
4085 for (sp
= bp
-> args
; sp
; sp
= next
) {
4087 dfree (sp
, file
, line
);
4089 if (bp
-> statements
)
4090 executable_statement_dereference (&bp
-> statements
,
4092 dfree (bp
, file
, line
);
4094 *ptr
= (struct fundef
*)0;
4098 #if defined (NOTYET) /* Post 3.0 final. */
4099 int data_subexpression_length (int *rv
,
4100 struct expression
*expr
)
4102 int crhs
, clhs
, llhs
, lrhs
;
4103 switch (expr
-> op
) {
4104 case expr_substring
:
4105 if (expr
-> data
.substring
.len
&&
4106 expr
-> data
.substring
.len
-> op
== expr_const_int
) {
4108 (int)expr
-> data
.substring
.len
-> data
.const_int
);
4115 if (expr
-> data
.suffix
.len
&&
4116 expr
-> data
.suffix
.len
-> op
== expr_const_int
) {
4118 (int)expr
-> data
.suffix
.len
-> data
.const_int
);
4124 return data_subexpression_length(rv
, expr
->data
.lcase
);
4127 return data_subexpression_length(rv
, expr
->data
.ucase
);
4130 clhs
= data_subexpression_length (&llhs
,
4131 expr
-> data
.concat
[0]);
4132 crhs
= data_subexpression_length (&lrhs
,
4133 expr
-> data
.concat
[1]);
4134 if (crhs
== 0 || clhs
== 0)
4143 case expr_const_data
:
4144 *rv
= expr
-> data
.const_data
.len
;
4148 return data_subexpression_length (rv
,
4149 expr
-> data
.reverse
.buffer
);
4151 case expr_leased_address
:
4152 case expr_lease_time
:
4156 case expr_pick_first_value
:
4157 clhs
= data_subexpression_length (&llhs
,
4158 expr
-> data
.concat
[0]);
4159 crhs
= data_subexpression_length (&lrhs
,
4160 expr
-> data
.concat
[1]);
4161 if (crhs
== 0 || clhs
== 0)
4169 case expr_binary_to_ascii
:
4170 case expr_config_option
:
4171 case expr_host_decl_name
:
4172 case expr_encapsulate
:
4175 case expr_host_lookup
:
4184 case expr_extract_int8
:
4185 case expr_extract_int16
:
4186 case expr_extract_int32
:
4187 case expr_encode_int8
:
4188 case expr_encode_int16
:
4189 case expr_encode_int32
:
4190 case expr_const_int
:
4193 case expr_dns_transaction
:
4196 case expr_ns_delete
:
4197 case expr_ns_exists
:
4198 case expr_ns_not_exists
:
4199 case expr_not_equal
:
4201 case expr_variable_exists
:
4202 case expr_variable_reference
:
4210 case expr_remainder
:
4211 case expr_binary_and
:
4212 case expr_binary_or
:
4213 case expr_binary_xor
:
4214 case expr_client_state
:
4220 int expr_valid_for_context (struct expression
*expr
,
4221 enum expression_context context
)
4223 /* We don't know at parse time what type of value a function may
4224 return, so we can't flag an error on it. */
4225 if (expr
-> op
== expr_funcall
||
4226 expr
-> op
== expr_variable_reference
)
4233 case context_boolean
:
4234 if (is_boolean_expression (expr
))
4239 if (is_data_expression (expr
))
4243 case context_numeric
:
4244 if (is_numeric_expression (expr
))
4249 if (is_dns_expression (expr
)) {
4254 case context_data_or_numeric
:
4255 if (is_numeric_expression (expr
) ||
4256 is_data_expression (expr
)) {
4261 case context_function
:
4262 if (expr
-> op
== expr_function
)
4270 struct binding
*create_binding (struct binding_scope
**scope
, const char *name
)
4272 struct binding
*binding
;
4275 if (!binding_scope_allocate (scope
, MDL
))
4276 return (struct binding
*)0;
4279 binding
= find_binding (*scope
, name
);
4281 binding
= dmalloc (sizeof *binding
, MDL
);
4283 return (struct binding
*)0;
4285 memset (binding
, 0, sizeof *binding
);
4286 binding
-> name
= dmalloc (strlen (name
) + 1, MDL
);
4287 if (!binding
-> name
) {
4288 dfree (binding
, MDL
);
4289 return (struct binding
*)0;
4291 strcpy (binding
-> name
, name
);
4293 binding
-> next
= (*scope
) -> bindings
;
4294 (*scope
) -> bindings
= binding
;
4301 int bind_ds_value (struct binding_scope
**scope
,
4303 struct data_string
*value
)
4305 struct binding
*binding
;
4307 binding
= create_binding (scope
, name
);
4311 if (binding
-> value
)
4312 binding_value_dereference (&binding
-> value
, MDL
);
4314 if (!binding_value_allocate (&binding
-> value
, MDL
))
4317 data_string_copy (&binding
-> value
-> value
.data
, value
, MDL
);
4318 binding
-> value
-> type
= binding_data
;
4324 int find_bound_string (struct data_string
*value
,
4325 struct binding_scope
*scope
,
4328 struct binding
*binding
;
4330 binding
= find_binding (scope
, name
);
4332 !binding
-> value
||
4333 binding
-> value
-> type
!= binding_data
)
4336 if (binding
-> value
-> value
.data
.terminated
) {
4337 data_string_copy (value
, &binding
-> value
-> value
.data
, MDL
);
4339 buffer_allocate (&value
-> buffer
,
4340 binding
-> value
-> value
.data
.len
,
4342 if (!value
-> buffer
)
4345 memcpy (value
-> buffer
-> data
,
4346 binding
-> value
-> value
.data
.data
,
4347 binding
-> value
-> value
.data
.len
);
4348 value
-> data
= value
-> buffer
-> data
;
4349 value
-> len
= binding
-> value
-> value
.data
.len
;
4355 int unset (struct binding_scope
*scope
, const char *name
)
4357 struct binding
*binding
;
4359 binding
= find_binding (scope
, name
);
4361 if (binding
-> value
)
4362 binding_value_dereference
4363 (&binding
-> value
, MDL
);
4369 /* vim: set tabstop=8: */