ISC DHCP  4.3.3
A reference DHCPv4 and DHCPv6 implementation
tree.c
Go to the documentation of this file.
1 /* tree.c
2 
3  Routines for manipulating parse trees... */
4 
5 /*
6  * Copyright (c) 2011-2014 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
8  * Copyright (c) 1995-2003 by Internet Software Consortium
9  *
10  * Permission to use, copy, modify, and distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  *
22  * Internet Systems Consortium, Inc.
23  * 950 Charter Street
24  * Redwood City, CA 94063
25  * <info@isc.org>
26  * https://www.isc.org/
27  *
28  */
29 
30 #include "dhcpd.h"
31 #include <omapip/omapip_p.h>
32 #include <ctype.h>
33 #include <sys/wait.h>
34 
35 #ifdef HAVE_REGEX_H
36 # include <regex.h>
37 #endif
38 
40 
41 static int do_host_lookup (struct data_string *, struct dns_host_entry *);
42 
43 #define DS_SPRINTF_SIZE 128
44 
45 /*
46  * If we are using a data_string structure to hold a NUL-terminated
47  * ASCII string, this function can be used to append a printf-formatted
48  * string to the end of it. The data_string structure will be resized to
49  * be big enough to hold the new string.
50  *
51  * If the append works, then 1 is returned.
52  *
53  * If it is not possible to allocate a buffer big enough to hold the
54  * new value, then the old data_string is unchanged, and 0 is returned.
55  */
56 int
57 data_string_sprintfa(struct data_string *ds, const char *fmt, ...) {
58  va_list args;
59  int cur_strlen;
60  int max;
61  int vsnprintf_ret;
62  int new_len;
63  struct buffer *tmp_buffer;
64 
65  /*
66  * If the data_string is empty, then initialize it.
67  */
68  if (ds->data == NULL) {
69  /* INSIST(ds.buffer == NULL); */
71  return 0;
72  }
73  ds->data = ds->buffer->data;
74  ds->len = DS_SPRINTF_SIZE;
75  *((char *)ds->data) = '\0';
76  }
77 
78  /*
79  * Get the length of the string, and figure out how much space
80  * is left.
81  */
82  cur_strlen = strlen((char *)ds->data);
83  max = ds->len - cur_strlen;
84 
85  /*
86  * Use vsnprintf(), which won't write past our space, but will
87  * tell us how much space it wants.
88  */
89  va_start(args, fmt);
90  vsnprintf_ret = vsnprintf((char *)ds->data+cur_strlen, max, fmt, args);
91  va_end(args);
92  /* INSIST(vsnprintf_ret >= 0); */
93 
94  /*
95  * If our buffer is not big enough, we need a new buffer.
96  */
97  if (vsnprintf_ret >= max) {
98  /*
99  * Figure out a size big enough.
100  */
101  new_len = ds->len * 2;
102  while (new_len <= cur_strlen + vsnprintf_ret) {
103  new_len *= 2;
104  }
105 
106  /*
107  * Create a new buffer and fill it.
108  */
109  tmp_buffer = NULL;
110  if (!buffer_allocate(&tmp_buffer, new_len, MDL)) {
111  /*
112  * If we can't create a big enough buffer,
113  * we should remove any truncated output that we had.
114  */
115  *((char *)ds->data+cur_strlen) = '\0';
116  va_end(args);
117  return 0;
118  }
119  memcpy(tmp_buffer->data, ds->data, cur_strlen);
120 
121  /* Rerun the vsprintf. */
122  va_start(args, fmt);
123  vsprintf((char *)tmp_buffer->data + cur_strlen, fmt, args);
124  va_end(args);
125 
126  /*
127  * Replace our old buffer with the new buffer.
128  */
130  buffer_reference(&ds->buffer, tmp_buffer, MDL);
131  buffer_dereference(&tmp_buffer, MDL);
132  ds->data = ds->buffer->data;
133  ds->len = new_len;
134  }
135  return 1;
136 }
137 
138 pair cons (car, cdr)
139  caddr_t car;
140  pair cdr;
141 {
142  pair foo = (pair)dmalloc (sizeof *foo, MDL);
143  if (!foo)
144  log_fatal ("no memory for cons.");
145  foo -> car = car;
146  foo -> cdr = cdr;
147  return foo;
148 }
149 
151  struct option_cache **oc;
152  struct buffer **buffer;
153  u_int8_t *data;
154  unsigned len;
155  struct option *option;
156  const char *file;
157  int line;
158 {
159  struct buffer *bp;
160 
161  if (buffer) {
162  bp = *buffer;
163  *buffer = 0;
164  } else {
165  bp = (struct buffer *)0;
166  if (!buffer_allocate (&bp, len, file, line)) {
167  log_error ("%s(%d): can't allocate buffer.",
168  file, line);
169  return 0;
170  }
171  }
172 
173  if (!option_cache_allocate (oc, file, line)) {
174  log_error ("%s(%d): can't allocate option cache.", file, line);
175  buffer_dereference (&bp, file, line);
176  return 0;
177  }
178 
179  (*oc) -> data.len = len;
180  (*oc) -> data.buffer = bp;
181  (*oc) -> data.data = &bp -> data [0];
182  (*oc) -> data.terminated = 0;
183  if (data)
184  memcpy (&bp -> data [0], data, len);
185  option_reference(&((*oc)->option), option, MDL);
186  return 1;
187 }
188 
189 int make_host_lookup (expr, name)
190  struct expression **expr;
191  const char *name;
192 {
193  if (!expression_allocate (expr, MDL)) {
194  log_error ("No memory for host lookup tree node.");
195  return 0;
196  }
197  (*expr) -> op = expr_host_lookup;
198  if (!enter_dns_host (&((*expr) -> data.host_lookup), name)) {
199  expression_dereference (expr, MDL);
200  return 0;
201  }
202  return 1;
203 }
204 
205 int enter_dns_host (dh, name)
206  struct dns_host_entry **dh;
207  const char *name;
208 {
209  /* XXX This should really keep a hash table of hostnames
210  XXX and just add a new reference to a hostname that
211  XXX already exists, if possible, rather than creating
212  XXX a new structure. */
213  if (!dns_host_entry_allocate (dh, name, MDL)) {
214  log_error ("Can't allocate space for new host.");
215  return 0;
216  }
217  return 1;
218 }
219 
220 int make_const_data (struct expression **expr, const unsigned char *data,
221  unsigned len, int terminated, int allocate,
222  const char *file, int line)
223 {
224  struct expression *nt;
225 
226  if (!expression_allocate (expr, file, line)) {
227  log_error ("No memory for make_const_data tree node.");
228  return 0;
229  }
230  nt = *expr;
231 
232  if (len) {
233  if (allocate) {
234  if (!buffer_allocate (&nt -> data.const_data.buffer,
235  len + terminated, file, line)) {
236  log_error ("Can't allocate const_data buffer");
237  expression_dereference (expr, file, line);
238  return 0;
239  }
240  nt -> data.const_data.data =
241  &nt -> data.const_data.buffer -> data [0];
242  memcpy (nt -> data.const_data.buffer -> data,
243  data, len + terminated);
244  } else
245  nt -> data.const_data.data = data;
246  nt -> data.const_data.terminated = terminated;
247  } else
248  nt -> data.const_data.data = 0;
249 
250  nt -> op = expr_const_data;
251  nt -> data.const_data.len = len;
252  return 1;
253 }
254 
255 int make_const_int (expr, val)
256  struct expression **expr;
257  unsigned long val;
258 {
259  if (!expression_allocate (expr, MDL)) {
260  log_error ("No memory for make_const_int tree node.");
261  return 0;
262  }
263 
264  (*expr) -> op = expr_const_int;
265  (*expr) -> data.const_int = val;
266  return 1;
267 }
268 
269 int make_concat (expr, left, right)
270  struct expression **expr;
271  struct expression *left, *right;
272 {
273  /* If we're concatenating a null tree to a non-null tree, just
274  return the non-null tree; if both trees are null, return
275  a null tree. */
276  if (!left) {
277  if (!right)
278  return 0;
279  expression_reference (expr, right, MDL);
280  return 1;
281  }
282  if (!right) {
283  expression_reference (expr, left, MDL);
284  return 1;
285  }
286 
287  /* Otherwise, allocate a new node to concatenate the two. */
288  if (!expression_allocate (expr, MDL)) {
289  log_error ("No memory for concatenation expression node.");
290  return 0;
291  }
292 
293  (*expr) -> op = expr_concat;
294  expression_reference (&(*expr) -> data.concat [0], left, MDL);
295  expression_reference (&(*expr) -> data.concat [1], right, MDL);
296  return 1;
297 }
298 
299 int make_encapsulation (expr, name)
300  struct expression **expr;
301  struct data_string *name;
302 {
303  /* Allocate a new node to store the encapsulation. */
304  if (!expression_allocate (expr, MDL)) {
305  log_error ("No memory for encapsulation expression node.");
306  return 0;
307  }
308 
309  (*expr) -> op = expr_encapsulate;
310  data_string_copy (&(*expr) -> data.encapsulate, name, MDL);
311  return 1;
312 }
313 
314 int make_substring (new, expr, offset, length)
315  struct expression **new;
316  struct expression *expr;
317  struct expression *offset;
318  struct expression *length;
319 {
320  /* Allocate an expression node to compute the substring. */
321  if (!expression_allocate (new, MDL)) {
322  log_error ("no memory for substring expression.");
323  return 0;
324  }
325  (*new) -> op = expr_substring;
326  expression_reference (&(*new) -> data.substring.expr, expr, MDL);
327  expression_reference (&(*new) -> data.substring.offset, offset, MDL);
328  expression_reference (&(*new) -> data.substring.len, length, MDL);
329  return 1;
330 }
331 
332 int make_limit (new, expr, limit)
333  struct expression **new;
334  struct expression *expr;
335  int limit;
336 {
337  /* Allocate a node to enforce a limit on evaluation. */
338  if (!expression_allocate (new, MDL))
339  log_error ("no memory for limit expression");
340  (*new) -> op = expr_substring;
341  expression_reference (&(*new) -> data.substring.expr, expr, MDL);
342 
343  /* Offset is a constant 0. */
344  if (!expression_allocate (&(*new) -> data.substring.offset, MDL)) {
345  log_error ("no memory for limit offset expression");
347  return 0;
348  }
349  (*new) -> data.substring.offset -> op = expr_const_int;
350  (*new) -> data.substring.offset -> data.const_int = 0;
351 
352  /* Length is a constant: the specified limit. */
353  if (!expression_allocate (&(*new) -> data.substring.len, MDL)) {
354  log_error ("no memory for limit length expression");
356  return 0;
357  }
358  (*new) -> data.substring.len -> op = expr_const_int;
359  (*new) -> data.substring.len -> data.const_int = limit;
360 
361  return 1;
362 }
363 
364 int option_cache (struct option_cache **oc, struct data_string *dp,
365  struct expression *expr, struct option *option,
366  const char *file, int line)
367 {
368  if (!option_cache_allocate (oc, file, line))
369  return 0;
370  if (dp)
371  data_string_copy (&(*oc) -> data, dp, file, line);
372  if (expr)
373  expression_reference (&(*oc) -> expression, expr, file, line);
374  option_reference(&(*oc)->option, option, MDL);
375  return 1;
376 }
377 
378 int make_let (result, name)
379  struct executable_statement **result;
380  const char *name;
381 {
382  if (!(executable_statement_allocate (result, MDL)))
383  return 0;
384 
385  (*result) -> op = let_statement;
386  (*result) -> data.let.name = dmalloc (strlen (name) + 1, MDL);
387  if (!(*result) -> data.let.name) {
389  return 0;
390  }
391  strcpy ((*result) -> data.let.name, name);
392  return 1;
393 }
394 
395 static int do_host_lookup (result, dns)
396  struct data_string *result;
397  struct dns_host_entry *dns;
398 {
399  struct hostent *h;
400  unsigned i, count;
401  unsigned new_len;
402 
403 #ifdef DEBUG_EVAL
404  log_debug ("time: now = %d dns = %d diff = %d",
405  cur_time, dns -> timeout, cur_time - dns -> timeout);
406 #endif
407 
408  /* If the record hasn't timed out, just copy the data and return. */
409  if (cur_time <= dns -> timeout) {
410 #ifdef DEBUG_EVAL
411  log_debug ("easy copy: %d %s",
412  dns -> data.len,
413  (dns -> data.len > 4
414  ? inet_ntoa (*(struct in_addr *)(dns -> data.data))
415  : 0));
416 #endif
417  data_string_copy (result, &dns -> data, MDL);
418  return 1;
419  }
420 #ifdef DEBUG_EVAL
421  log_debug ("Looking up %s", dns -> hostname);
422 #endif
423 
424  /* Otherwise, look it up... */
425  h = gethostbyname (dns -> hostname);
426  if (!h) {
427 #ifndef NO_H_ERRNO
428  switch (h_errno) {
429  case HOST_NOT_FOUND:
430 #endif
431  log_error ("%s: host unknown.", dns -> hostname);
432 #ifndef NO_H_ERRNO
433  break;
434  case TRY_AGAIN:
435  log_error ("%s: temporary name server failure",
436  dns -> hostname);
437  break;
438  case NO_RECOVERY:
439  log_error ("%s: name server failed", dns -> hostname);
440  break;
441  case NO_DATA:
442  log_error ("%s: no A record associated with address",
443  dns -> hostname);
444  }
445 #endif /* !NO_H_ERRNO */
446 
447  /* Okay to try again after a minute. */
448  dns -> timeout = cur_time + 60;
449  data_string_forget (&dns -> data, MDL);
450  return 0;
451  }
452 
453 #ifdef DEBUG_EVAL
454  log_debug ("Lookup succeeded; first address is %s",
455  inet_ntoa (h -> h_addr_list [0]));
456 #endif
457 
458  /* Count the number of addresses we got... */
459  for (count = 0; h -> h_addr_list [count]; count++)
460  ;
461 
462  /* Dereference the old data, if any. */
463  data_string_forget (&dns -> data, MDL);
464 
465  /* Do we need to allocate more memory? */
466  new_len = count * h -> h_length;
467  if (!buffer_allocate (&dns -> data.buffer, new_len, MDL))
468  {
469  log_error ("No memory for %s.", dns -> hostname);
470  return 0;
471  }
472 
473  dns -> data.data = &dns -> data.buffer -> data [0];
474  dns -> data.len = new_len;
475  dns -> data.terminated = 0;
476 
477  /* Addresses are conveniently stored one to the buffer, so we
478  have to copy them out one at a time... :'( */
479  for (i = 0; i < count; i++) {
480  memcpy (&dns -> data.buffer -> data [h -> h_length * i],
481  h -> h_addr_list [i], (unsigned)(h -> h_length));
482  }
483 #ifdef DEBUG_EVAL
484  log_debug ("dns -> data: %x h -> h_addr_list [0]: %x",
485  *(int *)(dns -> buffer), h -> h_addr_list [0]);
486 #endif
487 
488  /* XXX Set the timeout for an hour from now.
489  XXX This should really use the time on the DNS reply. */
490  dns -> timeout = cur_time + 3600;
491 
492 #ifdef DEBUG_EVAL
493  log_debug ("hard copy: %d %s", dns -> data.len,
494  (dns -> data.len > 4
495  ? inet_ntoa (*(struct in_addr *)(dns -> data.data)) : 0));
496 #endif
497  data_string_copy (result, &dns -> data, MDL);
498  return 1;
499 }
500 
502  in_options, cfg_options, scope, expr, file, line)
503  struct binding_value **result;
504  struct packet *packet;
505  struct lease *lease;
506  struct client_state *client_state;
507  struct option_state *in_options;
508  struct option_state *cfg_options;
509  struct binding_scope **scope;
510  struct expression *expr;
511  const char *file;
512  int line;
513 {
514  struct binding_value *bv;
515  int status;
516  struct binding *binding;
517 
518  bv = (struct binding_value *)0;
519 
520  if (expr -> op == expr_variable_reference) {
521  if (!scope || !*scope)
522  return 0;
523 
524  binding = find_binding (*scope, expr -> data.variable);
525 
526  if (binding && binding -> value) {
527  if (result)
528  binding_value_reference (result,
529  binding -> value,
530  file, line);
531  return 1;
532  } else
533  return 0;
534  } else if (expr -> op == expr_funcall) {
535  struct string_list *s;
536  struct expression *arg;
537  struct binding_scope *ns;
538  struct binding *nb;
539 
540  if (!scope || !*scope) {
541  log_error ("%s: no such function.",
542  expr -> data.funcall.name);
543  return 0;
544  }
545 
546  binding = find_binding (*scope, expr -> data.funcall.name);
547 
548  if (!binding || !binding -> value) {
549  log_error ("%s: no such function.",
550  expr -> data.funcall.name);
551  return 0;
552  }
553  if (binding -> value -> type != binding_function) {
554  log_error ("%s: not a function.",
555  expr -> data.funcall.name);
556  return 0;
557  }
558 
559  /* Create a new binding scope in which to define
560  the arguments to the function. */
561  ns = (struct binding_scope *)0;
562  if (!binding_scope_allocate (&ns, MDL)) {
563  log_error ("%s: can't allocate argument scope.",
564  expr -> data.funcall.name);
565  return 0;
566  }
567 
568  arg = expr -> data.funcall.arglist;
569  s = binding -> value -> value.fundef -> args;
570  while (arg && s) {
571  nb = dmalloc (sizeof *nb, MDL);
572  if (!nb) {
573  blb:
575  return 0;
576  } else {
577  memset (nb, 0, sizeof *nb);
578  nb -> name = dmalloc (strlen (s -> string) + 1,
579  MDL);
580  if (nb -> name)
581  strcpy (nb -> name, s -> string);
582  else {
583  dfree (nb, MDL);
584  goto blb;
585  }
586  }
587  evaluate_expression (&nb -> value, packet, lease,
588  client_state,
589  in_options, cfg_options, scope,
590  arg -> data.arg.val, file, line);
591  nb -> next = ns -> bindings;
592  ns -> bindings = nb;
593  arg = arg -> data.arg.next;
594  s = s -> next;
595  }
596  if (arg) {
597  log_error ("%s: too many arguments.",
598  expr -> data.funcall.name);
600  return 0;
601  }
602  if (s) {
603  log_error ("%s: too few arguments.",
604  expr -> data.funcall.name);
606  return 0;
607  }
608 
609  if (scope && *scope)
610  binding_scope_reference (&ns -> outer, *scope, MDL);
611 
612  status = (execute_statements
613  (&bv, packet,
614  lease, client_state, in_options, cfg_options, &ns,
615  binding->value->value.fundef->statements, NULL));
617 
618  if (!bv)
619  return 1;
620  } else if (is_boolean_expression (expr)) {
621  if (!binding_value_allocate (&bv, MDL))
622  return 0;
623  bv -> type = binding_boolean;
625  (&bv -> value.boolean, packet, lease, client_state,
626  in_options, cfg_options, scope, expr));
627  } else if (is_numeric_expression (expr)) {
628  if (!binding_value_allocate (&bv, MDL))
629  return 0;
630  bv -> type = binding_numeric;
632  (&bv -> value.intval, packet, lease, client_state,
633  in_options, cfg_options, scope, expr));
634  } else if (is_data_expression (expr)) {
635  if (!binding_value_allocate (&bv, MDL))
636  return 0;
637  bv -> type = binding_data;
638  status = (evaluate_data_expression
639  (&bv -> value.data, packet, lease, client_state,
640  in_options, cfg_options, scope, expr, MDL));
641  } else {
642  log_error ("%s: invalid expression type: %d",
643  "evaluate_expression", expr -> op);
644  return 0;
645  }
646  if (result && status)
647  binding_value_reference (result, bv, file, line);
649 
650  return status;
651 }
652 
654  const char *file, int line)
655 {
656  struct binding_value *bv = *v;
657 
658  *v = (struct binding_value *)0;
659 
660  /* Decrement the reference count. If it's nonzero, we're
661  done. */
662  --(bv -> refcnt);
663  rc_register (file, line, v, bv, bv -> refcnt, 1, RC_MISC);
664  if (bv -> refcnt > 0)
665  return 1;
666  if (bv -> refcnt < 0) {
667  log_error ("%s(%d): negative refcnt!", file, line);
668 #if defined (DEBUG_RC_HISTORY)
669  dump_rc_history (bv);
670 #endif
671 #if defined (POINTER_DEBUG)
672  abort ();
673 #else
674  return 0;
675 #endif
676  }
677 
678  switch (bv -> type) {
679  case binding_boolean:
680  case binding_numeric:
681  break;
682  case binding_data:
683  if (bv -> value.data.buffer)
684  data_string_forget (&bv -> value.data, file, line);
685  break;
686  default:
687  log_error ("%s(%d): invalid binding type: %d",
688  file, line, bv -> type);
689  return 0;
690  }
691  free_binding_value(bv, file, line);
692  return 1;
693 }
694 
696  in_options, cfg_options, scope, expr)
697  int *result;
698  struct packet *packet;
699  struct lease *lease;
700  struct client_state *client_state;
701  struct option_state *in_options;
702  struct option_state *cfg_options;
703  struct binding_scope **scope;
704  struct expression *expr;
705 {
706  struct data_string left, right;
707  int bleft, bright;
708  int sleft, sright;
709  struct binding *binding;
710  struct binding_value *bv, *obv;
711 #ifdef HAVE_REGEX_H
712  int regflags = REG_EXTENDED | REG_NOSUB;
713  regex_t re;
714 #endif
715 
716  switch (expr -> op) {
717  case expr_check:
718  *result = check_collection (packet, lease,
719  expr -> data.check);
720 #if defined (DEBUG_EXPRESSIONS)
721  log_debug ("bool: check (%s) returns %s",
722  expr -> data.check -> name,
723  *result ? "true" : "false");
724 #endif
725  return 1;
726 
727  case expr_equal:
728  case expr_not_equal:
729  bv = obv = (struct binding_value *)0;
730  sleft = evaluate_expression (&bv, packet, lease, client_state,
731  in_options, cfg_options, scope,
732  expr -> data.equal [0], MDL);
733  sright = evaluate_expression (&obv, packet, lease,
734  client_state, in_options,
735  cfg_options, scope,
736  expr -> data.equal [1], MDL);
737  if (sleft && sright) {
738  if (bv -> type != obv -> type)
739  *result = expr -> op == expr_not_equal;
740  else {
741  switch (obv -> type) {
742  case binding_boolean:
743  if (bv -> value.boolean == obv -> value.boolean)
744  *result = expr -> op == expr_equal;
745  else
746  *result = expr -> op == expr_not_equal;
747  break;
748 
749  case binding_data:
750  if ((bv -> value.data.len ==
751  obv -> value.data.len) &&
752  !memcmp (bv -> value.data.data,
753  obv -> value.data.data,
754  obv -> value.data.len))
755  *result = expr -> op == expr_equal;
756  else
757  *result = expr -> op == expr_not_equal;
758  break;
759 
760  case binding_numeric:
761  if (bv -> value.intval == obv -> value.intval)
762  *result = expr -> op == expr_equal;
763  else
764  *result = expr -> op == expr_not_equal;
765  break;
766 
767  case binding_function:
768  if (bv -> value.fundef == obv -> value.fundef)
769  *result = expr -> op == expr_equal;
770  else
771  *result = expr -> op == expr_not_equal;
772  break;
773  default:
774  *result = expr -> op == expr_not_equal;
775  break;
776  }
777  }
778  } else if (!sleft && !sright)
779  *result = expr -> op == expr_equal;
780  else
781  *result = expr -> op == expr_not_equal;
782 
783 #if defined (DEBUG_EXPRESSIONS)
784  log_debug ("bool: %sequal = %s",
785  expr -> op == expr_not_equal ? "not" : "",
786  (*result ? "true" : "false"));
787 #endif
788  if (sleft)
790  if (sright)
792  return 1;
793 
794  case expr_iregex_match:
795 #ifdef HAVE_REGEX_H
796  regflags |= REG_ICASE;
797 #endif
798  /* FALL THROUGH */
799  case expr_regex_match:
800 #ifdef HAVE_REGEX_H
801  memset(&left, 0, sizeof left);
802  bleft = evaluate_data_expression(&left, packet, lease,
803  client_state,
804  in_options, cfg_options,
805  scope,
806  expr->data.equal[0], MDL);
807  memset(&right, 0, sizeof right);
808  bright = evaluate_data_expression(&right, packet, lease,
809  client_state,
810  in_options, cfg_options,
811  scope,
812  expr->data.equal[1], MDL);
813 
814  *result = 0;
815  memset(&re, 0, sizeof(re));
816  if (bleft && bright &&
817  (left.data != NULL) && (right.data != NULL) &&
818  (regcomp(&re, (char *)right.data, regflags) == 0) &&
819  (regexec(&re, (char *)left.data, (size_t)0, NULL, 0) == 0))
820  *result = 1;
821 
822 #if defined (DEBUG_EXPRESSIONS)
823  log_debug("bool: %s ~= %s yields %s",
824  bleft ? print_hex_1(left.len, left.data, 20)
825  : "NULL",
826  bright ? print_hex_2 (right.len, right.data, 20)
827  : "NULL",
828  *result ? "true" : "false");
829 #endif
830 
831  if (bleft)
832  data_string_forget(&left, MDL);
833  if (bright)
834  data_string_forget(&right, MDL);
835 
836  regfree(&re);
837 
838  /*
839  * If we have bleft and bright then we have a good
840  * syntax, otherwise not.
841  *
842  * XXX: we don't warn on invalid regular expression
843  * syntax, should we?
844  */
845  return bleft && bright;
846 #else
847  /* It shouldn't be possible to configure a regex operator
848  * when there's no support.
849  */
850  log_fatal("Impossible condition at %s:%d.", MDL);
851  break;
852 #endif
853 
854  case expr_and:
855  sleft = evaluate_boolean_expression (&bleft, packet, lease,
856  client_state,
857  in_options, cfg_options,
858  scope,
859  expr -> data.and [0]);
860  if (sleft && bleft)
862  (&bright, packet, lease, client_state,
863  in_options, cfg_options,
864  scope, expr -> data.and [1]);
865  else
866  sright = bright = 0;
867 
868 #if defined (DEBUG_EXPRESSIONS)
869  log_debug ("bool: and (%s, %s) = %s",
870  sleft ? (bleft ? "true" : "false") : "NULL",
871  sright ? (bright ? "true" : "false") : "NULL",
872  ((sleft && sright)
873  ? (bleft && bright ? "true" : "false") : "NULL"));
874 #endif
875  if (sleft && sright) {
876  *result = bleft && bright;
877  return 1;
878  }
879  return 0;
880 
881  case expr_or:
882  bleft = bright = 0;
883  sleft = evaluate_boolean_expression (&bleft, packet, lease,
884  client_state,
885  in_options, cfg_options,
886  scope,
887  expr -> data.or [0]);
888  if (!sleft || !bleft)
890  (&bright, packet, lease, client_state,
891  in_options, cfg_options,
892  scope, expr -> data.or [1]);
893  else
894  sright = 0;
895 #if defined (DEBUG_EXPRESSIONS)
896  log_debug ("bool: or (%s, %s) = %s",
897  sleft ? (bleft ? "true" : "false") : "NULL",
898  sright ? (bright ? "true" : "false") : "NULL",
899  ((sleft || sright)
900  ? (bleft || bright ? "true" : "false") : "NULL"));
901 #endif
902  if (sleft || sright) {
903  *result = bleft || bright;
904  return 1;
905  }
906  return 0;
907 
908  case expr_not:
909  sleft = evaluate_boolean_expression(&bleft, packet, lease,
910  client_state,
911  in_options, cfg_options,
912  scope,
913  expr->data.not);
914 #if defined (DEBUG_EXPRESSIONS)
915  log_debug("bool: not (%s) = %s",
916  sleft ? (bleft ? "true" : "false") : "NULL",
917  sleft ? (!bleft ? "true" : "false") : "NULL");
918 #endif
919  if (sleft) {
920  *result = !bleft;
921  return 1;
922  }
923  return 0;
924 
925  case expr_exists:
926  memset (&left, 0, sizeof left);
927  if (!in_options ||
928  !get_option (&left, expr -> data.exists -> universe,
929  packet, lease, client_state,
930  in_options, cfg_options, in_options,
931  scope, expr -> data.exists -> code, MDL))
932  *result = 0;
933  else {
934  *result = 1;
935  data_string_forget (&left, MDL);
936  }
937 #if defined (DEBUG_EXPRESSIONS)
938  log_debug ("bool: exists %s.%s = %s",
939  expr -> data.option -> universe -> name,
940  expr -> data.option -> name,
941  *result ? "true" : "false");
942 #endif
943  return 1;
944 
945  case expr_known:
946  if (!packet) {
947 #if defined (DEBUG_EXPRESSIONS)
948  log_debug ("bool: known = NULL");
949 #endif
950  return 0;
951  }
952 #if defined (DEBUG_EXPRESSIONS)
953  log_debug ("bool: known = %s",
954  packet -> known ? "true" : "false");
955 #endif
956  *result = packet -> known;
957  return 1;
958 
959  case expr_static:
960  if (!lease || !(lease -> flags & STATIC_LEASE)) {
961 #if defined (DEBUG_EXPRESSIONS)
962  log_debug ("bool: static = false (%s %s %s %d)",
963  lease ? "y" : "n",
964  (lease && (lease -> flags & STATIC_LEASE)
965  ? "y" : "n"),
966  piaddr (lease -> ip_addr),
967  lease ? lease -> flags : 0);
968 #endif
969  *result = 0;
970  return 1;
971  }
972 #if defined (DEBUG_EXPRESSIONS)
973  log_debug ("bool: static = true");
974 #endif
975  *result = 1;
976  return 1;
977 
979  if (scope && *scope) {
980  binding = find_binding (*scope, expr -> data.variable);
981 
982  if (binding) {
983  if (binding -> value)
984  *result = 1;
985  else
986  *result = 0;
987  } else
988  *result = 0;
989  } else
990  *result = 0;
991 #if defined (DEBUG_EXPRESSIONS)
992  log_debug ("boolean: %s? = %s", expr -> data.variable,
993  *result ? "true" : "false");
994 #endif
995  return 1;
996 
998  if (scope && *scope) {
999  binding = find_binding (*scope, expr -> data.variable);
1000 
1001  if (binding && binding -> value) {
1002  if (binding -> value -> type ==
1003  binding_boolean) {
1004  *result = binding -> value -> value.boolean;
1005  sleft = 1;
1006  } else {
1007  log_error ("binding type %d in %s.",
1008  binding -> value -> type,
1009  "evaluate_boolean_expression");
1010  sleft = 0;
1011  }
1012  } else
1013  sleft = 0;
1014  } else
1015  sleft = 0;
1016 #if defined (DEBUG_EXPRESSIONS)
1017  log_debug ("boolean: %s = %s", expr -> data.variable,
1018  sleft ? (*result ? "true" : "false") : "NULL");
1019 #endif
1020  return sleft;
1021 
1022  case expr_funcall:
1023  bv = (struct binding_value *)0;
1024  sleft = evaluate_expression (&bv, packet, lease, client_state,
1025  in_options, cfg_options,
1026  scope, expr, MDL);
1027  if (sleft) {
1028  if (bv -> type != binding_boolean)
1029  log_error ("%s() returned type %d in %s.",
1030  expr -> data.funcall.name,
1031  bv -> type,
1032  "evaluate_boolean_expression");
1033  else
1034  *result = bv -> value.boolean;
1036  }
1037 #if defined (DEBUG_EXPRESSIONS)
1038  log_debug ("boolean: %s() = %s", expr -> data.funcall.name,
1039  sleft ? (*result ? "true" : "false") : "NULL");
1040 #endif
1041  break;
1042 
1043  case expr_none:
1044  case expr_match:
1045  case expr_substring:
1046  case expr_suffix:
1047  case expr_lcase:
1048  case expr_ucase:
1049  case expr_option:
1050  case expr_hardware:
1051  case expr_const_data:
1052  case expr_packet:
1053  case expr_concat:
1054  case expr_encapsulate:
1055  case expr_host_lookup:
1056  case expr_encode_int8:
1057  case expr_encode_int16:
1058  case expr_encode_int32:
1059  case expr_binary_to_ascii:
1060  case expr_reverse:
1061  case expr_pick_first_value:
1062  case expr_host_decl_name:
1063  case expr_config_option:
1064  case expr_leased_address:
1065  case expr_null:
1066  case expr_filename:
1067  case expr_sname:
1068  case expr_gethostname:
1069  case expr_v6relay:
1070  case expr_concat_dclist:
1071  log_error ("Data opcode in evaluate_boolean_expression: %d",
1072  expr -> op);
1073  return 0;
1074 
1075  case expr_extract_int8:
1076  case expr_extract_int16:
1077  case expr_extract_int32:
1078  case expr_const_int:
1079  case expr_lease_time:
1080  case expr_dns_transaction:
1081  case expr_add:
1082  case expr_subtract:
1083  case expr_multiply:
1084  case expr_divide:
1085  case expr_remainder:
1086  case expr_binary_and:
1087  case expr_binary_or:
1088  case expr_binary_xor:
1089  case expr_client_state:
1090  log_error ("Numeric opcode in evaluate_boolean_expression: %d",
1091  expr -> op);
1092  return 0;
1093 
1094  case expr_ns_add:
1095  case expr_ns_delete:
1096  case expr_ns_exists:
1097  case expr_ns_not_exists:
1098  log_error ("dns opcode in evaluate_boolean_expression: %d",
1099  expr -> op);
1100  return 0;
1101 
1102  case expr_function:
1103  log_error ("function definition in evaluate_boolean_expr");
1104  return 0;
1105 
1106  case expr_arg:
1107  break;
1108  }
1109 
1110  log_error ("Bogus opcode in evaluate_boolean_expression: %d",
1111  expr -> op);
1112  return 0;
1113 }
1114 
1116  in_options, cfg_options, scope, expr, file, line)
1117  struct data_string *result;
1118  struct packet *packet;
1119  struct lease *lease;
1120  struct client_state *client_state;
1121  struct option_state *in_options;
1122  struct option_state *cfg_options;
1123  struct binding_scope **scope;
1124  struct expression *expr;
1125  const char *file;
1126  int line;
1127 {
1128  struct data_string data, other;
1129  unsigned long offset, len, i;
1130  int s0, s1, s2, s3;
1131  int status;
1132  struct binding *binding;
1133  unsigned char *s;
1134  struct binding_value *bv;
1135  struct packet *relay_packet;
1136  struct option_state *relay_options;
1137 
1138  switch (expr -> op) {
1139  /* Extract N bytes starting at byte M of a data string. */
1140  case expr_substring:
1141  memset (&data, 0, sizeof data);
1142  s0 = evaluate_data_expression (&data, packet, lease,
1143  client_state,
1144  in_options, cfg_options, scope,
1145  expr -> data.substring.expr,
1146  MDL);
1147 
1148  /* Evaluate the offset and length. */
1150  (&offset, packet, lease, client_state, in_options,
1151  cfg_options, scope, expr -> data.substring.offset);
1152  s2 = evaluate_numeric_expression (&len, packet, lease,
1153  client_state,
1154  in_options, cfg_options,
1155  scope,
1156  expr -> data.substring.len);
1157 
1158  if (s0 && s1 && s2) {
1159  /* If the offset is after end of the string,
1160  return an empty string. Otherwise, do the
1161  adjustments and return what's left. */
1162  if (data.len > offset) {
1163  data_string_copy (result, &data, file, line);
1164  result -> len -= offset;
1165  if (result -> len > len) {
1166  result -> len = len;
1167  result -> terminated = 0;
1168  }
1169  result -> data += offset;
1170  }
1171  s3 = 1;
1172  } else
1173  s3 = 0;
1174 
1175 #if defined (DEBUG_EXPRESSIONS)
1176  log_debug ("data: substring (%s, %s, %s) = %s",
1177  s0 ? print_hex_1 (data.len, data.data, 30) : "NULL",
1178  s1 ? print_dec_1 (offset) : "NULL",
1179  s2 ? print_dec_2 (len) : "NULL",
1180  (s3 ? print_hex_2 (result -> len, result -> data, 30)
1181  : "NULL"));
1182 #endif
1183  if (s0)
1184  data_string_forget (&data, MDL);
1185  if (s3)
1186  return 1;
1187  return 0;
1188 
1189  /* Extract the last N bytes of a data string. */
1190  case expr_suffix:
1191  memset (&data, 0, sizeof data);
1192  s0 = evaluate_data_expression (&data, packet, lease,
1193  client_state,
1194  in_options, cfg_options, scope,
1195  expr -> data.suffix.expr, MDL);
1196  /* Evaluate the length. */
1197  s1 = evaluate_numeric_expression (&len, packet, lease,
1198  client_state,
1199  in_options, cfg_options,
1200  scope,
1201  expr -> data.suffix.len);
1202  if (s0 && s1) {
1203  data_string_copy (result, &data, file, line);
1204 
1205  /* If we are returning the last N bytes of a
1206  string whose length is <= N, just return
1207  the string - otherwise, compute a new
1208  starting address and decrease the
1209  length. */
1210  if (data.len > len) {
1211  result -> data += data.len - len;
1212  result -> len = len;
1213  }
1214 
1215  data_string_forget (&data, MDL);
1216  }
1217 
1218 #if defined (DEBUG_EXPRESSIONS)
1219  log_debug ("data: suffix (%s, %s) = %s",
1220  s0 ? print_hex_1 (data.len, data.data, 30) : "NULL",
1221  s1 ? print_dec_1 (len) : "NULL",
1222  ((s0 && s1)
1223  ? print_hex_2 (result -> len, result -> data, 30)
1224  : "NULL"));
1225 #endif
1226 
1227  return s0 && s1;
1228 
1229  /* Convert string to lowercase. */
1230  case expr_lcase:
1231  memset(&data, 0, sizeof data);
1232  s0 = evaluate_data_expression(&data, packet, lease,
1233  client_state,
1234  in_options, cfg_options, scope,
1235  expr->data.lcase, MDL);
1236  s1 = 0;
1237  if (s0) {
1238  result->len = data.len;
1239  if (buffer_allocate(&result->buffer,
1240  result->len + data.terminated,
1241  MDL)) {
1242  result->data = &result->buffer->data[0];
1243  memcpy(result->buffer->data, data.data,
1244  data.len + data.terminated);
1245  result->terminated = data.terminated;
1246  s = (unsigned char *)result->data;
1247  for (i = 0; i < result->len; i++, s++)
1248  *s = tolower(*s);
1249  s1 = 1;
1250  } else {
1251  log_error("data: lcase: no buffer memory.");
1252  }
1253  }
1254 
1255 #if defined (DEBUG_EXPRESSIONS)
1256  log_debug("data: lcase (%s) = %s",
1257  s0 ? print_hex_1(data.len, data.data, 30) : "NULL",
1258  s1 ? print_hex_2(result->len, result->data, 30)
1259  : "NULL");
1260 #endif
1261  if (s0)
1262  data_string_forget(&data, MDL);
1263  return s1;
1264 
1265  /* Convert string to uppercase. */
1266  case expr_ucase:
1267  memset(&data, 0, sizeof data);
1268  s0 = evaluate_data_expression(&data, packet, lease,
1269  client_state,
1270  in_options, cfg_options, scope,
1271  expr->data.lcase, MDL);
1272  s1 = 0;
1273  if (s0) {
1274  result->len = data.len;
1275  if (buffer_allocate(&result->buffer,
1276  result->len + data.terminated,
1277  file, line)) {
1278  result->data = &result->buffer->data[0];
1279  memcpy(result->buffer->data, data.data,
1280  data.len + data.terminated);
1281  result->terminated = data.terminated;
1282  s = (unsigned char *)result->data;
1283  for (i = 0; i < result->len; i++, s++)
1284  *s = toupper(*s);
1285  s1 = 1;
1286  } else {
1287  log_error("data: lcase: no buffer memory.");
1288  }
1289  }
1290 
1291 #if defined (DEBUG_EXPRESSIONS)
1292  log_debug("data: ucase (%s) = %s",
1293  s0 ? print_hex_1(data.len, data.data, 30) : "NULL",
1294  s1 ? print_hex_2(result->len, result->data, 30)
1295  : "NULL");
1296 #endif
1297  if (s0)
1298  data_string_forget(&data, MDL);
1299 
1300  return s1;
1301 
1302  /* Extract an option. */
1303  case expr_option:
1304  if (in_options)
1305  s0 = get_option (result,
1306  expr -> data.option -> universe,
1307  packet, lease, client_state,
1308  in_options, cfg_options, in_options,
1309  scope, expr -> data.option -> code,
1310  file, line);
1311  else
1312  s0 = 0;
1313 
1314 #if defined (DEBUG_EXPRESSIONS)
1315  log_debug ("data: option %s.%s = %s",
1316  expr -> data.option -> universe -> name,
1317  expr -> data.option -> name,
1318  s0 ? print_hex_1 (result -> len, result -> data, 60)
1319  : "NULL");
1320 #endif
1321  return s0;
1322 
1323  case expr_config_option:
1324  if (cfg_options)
1325  s0 = get_option (result,
1326  expr -> data.option -> universe,
1327  packet, lease, client_state,
1328  in_options, cfg_options, cfg_options,
1329  scope, expr -> data.option -> code,
1330  file, line);
1331  else
1332  s0 = 0;
1333 
1334 #if defined (DEBUG_EXPRESSIONS)
1335  log_debug ("data: config-option %s.%s = %s",
1336  expr -> data.option -> universe -> name,
1337  expr -> data.option -> name,
1338  s0 ? print_hex_1 (result -> len, result -> data, 60)
1339  : "NULL");
1340 #endif
1341  return s0;
1342 
1343  /* Combine the hardware type and address. */
1344  case expr_hardware:
1345  /* On the client, hardware is our hardware. */
1346  if (client_state) {
1347  memset(result, 0, sizeof(*result));
1348  result->data = client_state->interface->hw_address.hbuf;
1349  result->len = client_state->interface->hw_address.hlen;
1350 #if defined (DEBUG_EXPRESSIONS)
1351  log_debug("data: hardware = %s",
1352  print_hex_1(result->len, result->data, 60));
1353 #endif
1354  return (1);
1355  }
1356 
1357  /* The server cares about the client's hardware address,
1358  so only in the case where we are examining a packet or have
1359  a lease with a hardware address can we return anything. */
1360 
1361  if (packet != NULL && packet->raw != NULL) {
1362  if (packet->raw->hlen > sizeof(packet->raw->chaddr)) {
1363  log_error("data: hardware: invalid hlen (%d)\n",
1364  packet->raw->hlen);
1365  return (0);
1366  }
1367  result->len = packet->raw->hlen + 1;
1368  if (buffer_allocate(&result->buffer, result->len, MDL)){
1369  result->data = &result->buffer->data[0];
1370  result->buffer->data[0] = packet->raw->htype;
1371  memcpy(&result->buffer->data[1],
1372  packet->raw->chaddr, packet->raw->hlen);
1373  result->terminated = 0;
1374  } else {
1375  log_error("data: hardware: "
1376  "no memory for buffer.");
1377  return (0);
1378  }
1379  } else if (lease != NULL) {
1380  result->len = lease->hardware_addr.hlen;
1381  if (buffer_allocate(&result->buffer, result->len, MDL)){
1382  result->data = &result->buffer->data[0];
1383  memcpy(result->buffer->data,
1384  lease->hardware_addr.hbuf, result->len);
1385  result->terminated = 0;
1386  } else {
1387  log_error("data: hardware: "
1388  "no memory for buffer.");
1389  return (0);
1390  }
1391  } else {
1392  log_error("data: hardware: no raw packet or lease "
1393  "is available");
1394  return (0);
1395  }
1396 
1397 #if defined (DEBUG_EXPRESSIONS)
1398  log_debug("data: hardware = %s",
1399  print_hex_1(result->len, result->data, 60));
1400 #endif
1401  return (1);
1402 
1403  /* Extract part of the raw packet. */
1404  case expr_packet:
1405  if (!packet || !packet -> raw) {
1406  log_error ("data: packet: raw packet not available");
1407  return 0;
1408  }
1409 
1410  s0 = evaluate_numeric_expression (&offset, packet, lease,
1411  client_state,
1412  in_options, cfg_options,
1413  scope,
1414  expr -> data.packet.offset);
1415  s1 = evaluate_numeric_expression (&len,
1416  packet, lease, client_state,
1417  in_options, cfg_options,
1418  scope,
1419  expr -> data.packet.len);
1420  if (s0 && s1 && offset < packet -> packet_length) {
1421  if (offset + len > packet -> packet_length)
1422  result -> len =
1423  packet -> packet_length - offset;
1424  else
1425  result -> len = len;
1426  if (buffer_allocate (&result -> buffer,
1427  result -> len, file, line)) {
1428  result -> data = &result -> buffer -> data [0];
1429  memcpy (result -> buffer -> data,
1430  (((unsigned char *)(packet -> raw))
1431  + offset), result -> len);
1432  result -> terminated = 0;
1433  } else {
1434  log_error ("data: packet: no buffer memory.");
1435  return 0;
1436  }
1437  s2 = 1;
1438  } else
1439  s2 = 0;
1440 #if defined (DEBUG_EXPRESSIONS)
1441  log_debug ("data: packet (%ld, %ld) = %s",
1442  offset, len,
1443  s2 ? print_hex_1 (result -> len,
1444  result -> data, 60) : NULL);
1445 #endif
1446  return s2;
1447 
1448  /* The encapsulation of all defined options in an
1449  option space... */
1450  case expr_encapsulate:
1451  if (cfg_options)
1453  (result, packet, lease, client_state,
1454  in_options, cfg_options, scope,
1455  &expr -> data.encapsulate);
1456  else
1457  s0 = 0;
1458 
1459 #if defined (DEBUG_EXPRESSIONS)
1460  log_debug ("data: encapsulate (%s) = %s",
1461  expr -> data.encapsulate.data,
1462  s0 ? print_hex_1 (result -> len,
1463  result -> data, 60) : "NULL");
1464 #endif
1465  return s0;
1466 
1467  /* Some constant data... */
1468  case expr_const_data:
1469 #if defined (DEBUG_EXPRESSIONS)
1470  log_debug ("data: const = %s",
1471  print_hex_1 (expr -> data.const_data.len,
1472  expr -> data.const_data.data, 60));
1473 #endif
1474  data_string_copy (result,
1475  &expr -> data.const_data, file, line);
1476  return 1;
1477 
1478  /* Hostname lookup... */
1479  case expr_host_lookup:
1480  s0 = do_host_lookup (result, expr -> data.host_lookup);
1481 #if defined (DEBUG_EXPRESSIONS)
1482  log_debug ("data: DNS lookup (%s) = %s",
1483  expr -> data.host_lookup -> hostname,
1484  (s0
1485  ? print_dotted_quads (result -> len, result -> data)
1486  : "NULL"));
1487 #endif
1488  return s0;
1489 
1490  /* Concatenation... */
1491  case expr_concat:
1492  memset (&data, 0, sizeof data);
1493  s0 = evaluate_data_expression (&data, packet, lease,
1494  client_state,
1495  in_options, cfg_options, scope,
1496  expr -> data.concat [0], MDL);
1497  memset (&other, 0, sizeof other);
1498  s1 = evaluate_data_expression (&other, packet, lease,
1499  client_state,
1500  in_options, cfg_options, scope,
1501  expr -> data.concat [1], MDL);
1502 
1503  if (s0 && s1) {
1504  result -> len = data.len + other.len;
1505  if (!buffer_allocate (&result -> buffer,
1506  (result -> len + other.terminated),
1507  file, line)) {
1508  log_error ("data: concat: no memory");
1509  result -> len = 0;
1510  data_string_forget (&data, MDL);
1511  data_string_forget (&other, MDL);
1512  return 0;
1513  }
1514  result -> data = &result -> buffer -> data [0];
1515  memcpy (result -> buffer -> data, data.data, data.len);
1516  memcpy (&result -> buffer -> data [data.len],
1517  other.data, other.len + other.terminated);
1518  }
1519 
1520  if (s0)
1521  data_string_forget (&data, MDL);
1522  if (s1)
1523  data_string_forget (&other, MDL);
1524 #if defined (DEBUG_EXPRESSIONS)
1525  log_debug ("data: concat (%s, %s) = %s",
1526  s0 ? print_hex_1 (data.len, data.data, 20) : "NULL",
1527  s1 ? print_hex_2 (other.len, other.data, 20) : "NULL",
1528  ((s0 && s1)
1529  ? print_hex_3 (result -> len, result -> data, 30)
1530  : "NULL"));
1531 #endif
1532  return s0 && s1;
1533 
1534  case expr_encode_int8:
1535  s0 = evaluate_numeric_expression (&len, packet, lease,
1536  client_state,
1537  in_options, cfg_options,
1538  scope,
1539  expr -> data.encode_int);
1540  if (s0) {
1541  result -> len = 1;
1542  if (!buffer_allocate (&result -> buffer,
1543  1, file, line)) {
1544  log_error ("data: encode_int8: no memory");
1545  result -> len = 0;
1546  s0 = 0;
1547  } else {
1548  result -> data = &result -> buffer -> data [0];
1549  result -> buffer -> data [0] = len;
1550  }
1551  } else
1552  result -> len = 0;
1553 
1554 #if defined (DEBUG_EXPRESSIONS)
1555  if (!s0)
1556  log_debug ("data: encode_int8 (NULL) = NULL");
1557  else
1558  log_debug ("data: encode_int8 (%ld) = %s", len,
1559  print_hex_2 (result -> len,
1560  result -> data, 20));
1561 #endif
1562  return s0;
1563 
1564 
1565  case expr_encode_int16:
1566  s0 = evaluate_numeric_expression (&len, packet, lease,
1567  client_state,
1568  in_options, cfg_options,
1569  scope,
1570  expr -> data.encode_int);
1571  if (s0) {
1572  result -> len = 2;
1573  if (!buffer_allocate (&result -> buffer, 2,
1574  file, line)) {
1575  log_error ("data: encode_int16: no memory");
1576  result -> len = 0;
1577  s0 = 0;
1578  } else {
1579  result -> data = &result -> buffer -> data [0];
1580  putUShort (result -> buffer -> data, len);
1581  }
1582  } else
1583  result -> len = 0;
1584 
1585 #if defined (DEBUG_EXPRESSIONS)
1586  if (!s0)
1587  log_debug ("data: encode_int16 (NULL) = NULL");
1588  else
1589  log_debug ("data: encode_int16 (%ld) = %s", len,
1590  print_hex_2 (result -> len,
1591  result -> data, 20));
1592 #endif
1593  return s0;
1594 
1595  case expr_encode_int32:
1596  s0 = evaluate_numeric_expression (&len, packet, lease,
1597  client_state,
1598  in_options, cfg_options,
1599  scope,
1600  expr -> data.encode_int);
1601  if (s0) {
1602  result -> len = 4;
1603  if (!buffer_allocate (&result -> buffer, 4,
1604  file, line)) {
1605  log_error ("data: encode_int32: no memory");
1606  result -> len = 0;
1607  s0 = 0;
1608  } else {
1609  result -> data = &result -> buffer -> data [0];
1610  putULong (result -> buffer -> data, len);
1611  }
1612  } else
1613  result -> len = 0;
1614 
1615 #if defined (DEBUG_EXPRESSIONS)
1616  if (!s0)
1617  log_debug ("data: encode_int32 (NULL) = NULL");
1618  else
1619  log_debug ("data: encode_int32 (%ld) = %s", len,
1620  print_hex_2 (result -> len,
1621  result -> data, 20));
1622 #endif
1623  return s0;
1624 
1625  case expr_binary_to_ascii:
1626  /* Evaluate the base (offset) and width (len): */
1628  (&offset, packet, lease, client_state, in_options,
1629  cfg_options, scope, expr -> data.b2a.base);
1630  s1 = evaluate_numeric_expression (&len, packet, lease,
1631  client_state,
1632  in_options, cfg_options,
1633  scope,
1634  expr -> data.b2a.width);
1635 
1636  /* Evaluate the separator string. */
1637  memset (&data, 0, sizeof data);
1638  s2 = evaluate_data_expression (&data, packet, lease,
1639  client_state,
1640  in_options, cfg_options, scope,
1641  expr -> data.b2a.separator,
1642  MDL);
1643 
1644  /* Evaluate the data to be converted. */
1645  memset (&other, 0, sizeof other);
1646  s3 = evaluate_data_expression (&other, packet, lease,
1647  client_state,
1648  in_options, cfg_options, scope,
1649  expr -> data.b2a.buffer, MDL);
1650 
1651  if (s0 && s1 && s2 && s3) {
1652  unsigned buflen, i;
1653 
1654  if (len != 8 && len != 16 && len != 32) {
1655  log_info ("binary_to_ascii: %s %ld!",
1656  "invalid width", len);
1657  status = 0;
1658  goto b2a_out;
1659  }
1660  len /= 8;
1661 
1662  /* The buffer must be a multiple of the number's
1663  width. */
1664  if (other.len % len) {
1665  log_info ("binary-to-ascii: %s %d %s %ld!",
1666  "length of buffer", other.len,
1667  "not a multiple of width", len);
1668  status = 0;
1669  goto b2a_out;
1670  }
1671 
1672  /* Count the width of the output. */
1673  buflen = 0;
1674  for (i = 0; i < other.len; i += len) {
1675  if (len == 1) {
1676  if (offset == 8) {
1677  if (other.data [i] < 8)
1678  buflen++;
1679  else if (other.data [i] < 64)
1680  buflen += 2;
1681  else
1682  buflen += 3;
1683  } else if (offset == 10) {
1684  if (other.data [i] < 10)
1685  buflen++;
1686  else if (other.data [i] < 100)
1687  buflen += 2;
1688  else
1689  buflen += 3;
1690  } else if (offset == 16) {
1691  if (other.data [i] < 16)
1692  buflen++;
1693  else
1694  buflen += 2;
1695  } else
1696  buflen += (converted_length
1697  (&other.data [i],
1698  offset, 1));
1699  } else
1700  buflen += (converted_length
1701  (&other.data [i],
1702  offset, len));
1703  if (i + len != other.len)
1704  buflen += data.len;
1705  }
1706 
1707  if (!buffer_allocate (&result -> buffer,
1708  buflen + 1, file, line)) {
1709  log_error ("data: binary-to-ascii: no memory");
1710  status = 0;
1711  goto b2a_out;
1712  }
1713  result -> data = &result -> buffer -> data [0];
1714  result -> len = buflen;
1715  result -> terminated = 1;
1716 
1717  buflen = 0;
1718  for (i = 0; i < other.len; i += len) {
1719  buflen += (binary_to_ascii
1720  (&result -> buffer -> data [buflen],
1721  &other.data [i], offset, len));
1722  if (i + len != other.len) {
1723  memcpy (&result ->
1724  buffer -> data [buflen],
1725  data.data, data.len);
1726  buflen += data.len;
1727  }
1728  }
1729  /* NUL terminate. */
1730  result -> buffer -> data [buflen] = 0;
1731  status = 1;
1732  } else
1733  status = 0;
1734 
1735  b2a_out:
1736 #if defined (DEBUG_EXPRESSIONS)
1737  log_debug ("data: binary-to-ascii (%s, %s, %s, %s) = %s",
1738  s0 ? print_dec_1 (offset) : "NULL",
1739  s1 ? print_dec_2 (len) : "NULL",
1740  s2 ? print_hex_1 (data.len, data.data, 30) : "NULL",
1741  s3 ? print_hex_2 (other.len, other.data, 30) : "NULL",
1742  (status ? print_hex_3 (result -> len, result -> data, 30)
1743  : "NULL"));
1744 #endif
1745  if (s2)
1746  data_string_forget (&data, MDL);
1747  if (s3)
1748  data_string_forget (&other, MDL);
1749  if (status)
1750  return 1;
1751  return 0;
1752 
1753  case expr_reverse:
1754  /* Evaluate the width (len): */
1756  (&len, packet, lease, client_state, in_options,
1757  cfg_options, scope, expr -> data.reverse.width);
1758 
1759  /* Evaluate the data. */
1760  memset (&data, 0, sizeof data);
1761  s1 = evaluate_data_expression (&data, packet, lease,
1762  client_state,
1763  in_options, cfg_options, scope,
1764  expr -> data.reverse.buffer,
1765  MDL);
1766 
1767  if (s0 && s1) {
1768  int i;
1769 
1770  /* The buffer must be a multiple of the number's
1771  width. */
1772  if (data.len % len) {
1773  log_info ("reverse: %s %d %s %ld!",
1774  "length of buffer", data.len,
1775  "not a multiple of width", len);
1776  status = 0;
1777  goto reverse_out;
1778  }
1779 
1780  /* XXX reverse in place? I don't think we can. */
1781  if (!buffer_allocate (&result -> buffer,
1782  data.len, file, line)) {
1783  log_error ("data: reverse: no memory");
1784  status = 0;
1785  goto reverse_out;
1786  }
1787  result -> data = &result -> buffer -> data [0];
1788  result -> len = data.len;
1789  result -> terminated = 0;
1790 
1791  for (i = 0; i < data.len; i += len) {
1792  memcpy (&result -> buffer -> data [i],
1793  &data.data [data.len - i - len], len);
1794  }
1795  status = 1;
1796  } else
1797  status = 0;
1798 
1799  reverse_out:
1800 #if defined (DEBUG_EXPRESSIONS)
1801  log_debug ("data: reverse (%s, %s) = %s",
1802  s0 ? print_dec_1 (len) : "NULL",
1803  s1 ? print_hex_1 (data.len, data.data, 30) : "NULL",
1804  (status ? print_hex_3 (result -> len, result -> data, 30)
1805  : "NULL"));
1806 #endif
1807  if (s0)
1808  data_string_forget (&data, MDL);
1809  if (status)
1810  return 1;
1811  return 0;
1812 
1813  case expr_leased_address:
1814  if (!lease) {
1815  log_debug("data: \"leased-address\" configuration "
1816  "directive: there is no lease associated "
1817  "with this client.");
1818  return 0;
1819  }
1820  result -> len = lease -> ip_addr.len;
1821  if (buffer_allocate (&result -> buffer, result -> len,
1822  file, line)) {
1823  result -> data = &result -> buffer -> data [0];
1824  memcpy (&result -> buffer -> data [0],
1825  lease -> ip_addr.iabuf, lease -> ip_addr.len);
1826  result -> terminated = 0;
1827  } else {
1828  log_error ("data: leased-address: no memory.");
1829  return 0;
1830  }
1831 #if defined (DEBUG_EXPRESSIONS)
1832  log_debug ("data: leased-address = %s",
1833  print_hex_1 (result -> len, result -> data, 60));
1834 #endif
1835  return 1;
1836 
1837  case expr_pick_first_value:
1838  memset (&data, 0, sizeof data);
1840  (result, packet,
1841  lease, client_state, in_options, cfg_options,
1842  scope, expr -> data.pick_first_value.car, MDL))) {
1843 #if defined (DEBUG_EXPRESSIONS)
1844  log_debug ("data: pick_first_value (%s, xxx)",
1845  print_hex_1 (result -> len,
1846  result -> data, 40));
1847 #endif
1848  return 1;
1849  }
1850 
1851  if (expr -> data.pick_first_value.cdr &&
1853  (result, packet,
1854  lease, client_state, in_options, cfg_options,
1855  scope, expr -> data.pick_first_value.cdr, MDL))) {
1856 #if defined (DEBUG_EXPRESSIONS)
1857  log_debug ("data: pick_first_value (NULL, %s)",
1858  print_hex_1 (result -> len,
1859  result -> data, 40));
1860 #endif
1861  return 1;
1862  }
1863 
1864 #if defined (DEBUG_EXPRESSIONS)
1865  log_debug ("data: pick_first_value (NULL, NULL) = NULL");
1866 #endif
1867  return 0;
1868 
1869  case expr_host_decl_name:
1870  if (!lease || !lease -> host) {
1871  log_error ("data: host_decl_name: not available");
1872  return 0;
1873  }
1874  result -> len = strlen (lease -> host -> name);
1875  if (buffer_allocate (&result -> buffer,
1876  result -> len + 1, file, line)) {
1877  result -> data = &result -> buffer -> data [0];
1878  strcpy ((char *)&result -> buffer -> data [0],
1879  lease -> host -> name);
1880  result -> terminated = 1;
1881  } else {
1882  log_error ("data: host-decl-name: no memory.");
1883  return 0;
1884  }
1885 #if defined (DEBUG_EXPRESSIONS)
1886  log_debug ("data: host-decl-name = %s", lease -> host -> name);
1887 #endif
1888  return 1;
1889 
1890  case expr_null:
1891 #if defined (DEBUG_EXPRESSIONS)
1892  log_debug ("data: null = NULL");
1893 #endif
1894  return 0;
1895 
1897  if (scope && *scope) {
1898  binding = find_binding (*scope, expr -> data.variable);
1899 
1900  if (binding && binding -> value) {
1901  if (binding -> value -> type == binding_data) {
1902  data_string_copy (result,
1903  &binding -> value -> value.data,
1904  file, line);
1905  s0 = 1;
1906  } else if (binding -> value -> type != binding_data) {
1907  log_error ("binding type %d in %s.",
1908  binding -> value -> type,
1909  "evaluate_data_expression");
1910  s0 = 0;
1911  } else
1912  s0 = 0;
1913  } else
1914  s0 = 0;
1915  } else
1916  s0 = 0;
1917 #if defined (DEBUG_EXPRESSIONS)
1918  log_debug ("data: %s = %s", expr -> data.variable,
1919  s0 ? print_hex_1 (result -> len,
1920  result -> data, 50) : "NULL");
1921 #endif
1922  return s0;
1923 
1924  case expr_funcall:
1925  bv = (struct binding_value *)0;
1926  s0 = evaluate_expression (&bv, packet, lease, client_state,
1927  in_options, cfg_options,
1928  scope, expr, MDL);
1929  if (s0) {
1930  if (bv -> type != binding_data)
1931  log_error ("%s() returned type %d in %s.",
1932  expr -> data.funcall.name,
1933  bv -> type,
1934  "evaluate_data_expression");
1935  else
1936  data_string_copy (result, &bv -> value.data,
1937  file, line);
1939  }
1940 #if defined (DEBUG_EXPRESSIONS)
1941  log_debug ("data: %s = %s", expr -> data.funcall.name,
1942  s0 ? print_hex_1 (result -> len,
1943  result -> data, 50) : "NULL");
1944 #endif
1945  break;
1946 
1947  /* Extract the filename. */
1948  case expr_filename:
1949  if (packet && packet -> raw -> file [0]) {
1950  char *fn =
1951  memchr (packet -> raw -> file, 0,
1952  sizeof packet -> raw -> file);
1953  if (!fn)
1954  fn = ((char *)packet -> raw -> file +
1955  sizeof packet -> raw -> file);
1956  result -> len = fn - &(packet -> raw -> file [0]);
1957  if (buffer_allocate (&result -> buffer,
1958  result -> len + 1, file, line)) {
1959  result -> data = &result -> buffer -> data [0];
1960  memcpy (&result -> buffer -> data [0],
1961  packet -> raw -> file,
1962  result -> len);
1963  result -> buffer -> data [result -> len] = 0;
1964  result -> terminated = 1;
1965  s0 = 1;
1966  } else {
1967  log_error ("data: filename: no memory.");
1968  s0 = 0;
1969  }
1970  } else
1971  s0 = 0;
1972 
1973 #if defined (DEBUG_EXPRESSIONS)
1974  log_info ("data: filename = \"%s\"",
1975  s0 ? (const char *)(result -> data) : "NULL");
1976 #endif
1977  return s0;
1978 
1979  /* Extract the server name. */
1980  case expr_sname:
1981  if (packet && packet -> raw -> sname [0]) {
1982  char *fn =
1983  memchr (packet -> raw -> sname, 0,
1984  sizeof packet -> raw -> sname);
1985  if (!fn)
1986  fn = ((char *)packet -> raw -> sname +
1987  sizeof packet -> raw -> sname);
1988  result -> len = fn - &packet -> raw -> sname [0];
1989  if (buffer_allocate (&result -> buffer,
1990  result -> len + 1, file, line)) {
1991  result -> data = &result -> buffer -> data [0];
1992  memcpy (&result -> buffer -> data [0],
1993  packet -> raw -> sname,
1994  result -> len);
1995  result -> buffer -> data [result -> len] = 0;
1996  result -> terminated = 1;
1997  s0 = 1;
1998  } else {
1999  log_error ("data: sname: no memory.");
2000  s0 = 0;
2001  }
2002  } else
2003  s0 = 0;
2004 
2005 #if defined (DEBUG_EXPRESSIONS)
2006  log_info ("data: sname = \"%s\"",
2007  s0 ? (const char *)(result -> data) : "NULL");
2008 #endif
2009  return s0;
2010 
2011  /* Provide the system's local hostname as a return value. */
2012  case expr_gethostname:
2013  /*
2014  * Allocate a buffer to return.
2015  *
2016  * The largest valid hostname is maybe 64 octets at a single
2017  * label, or 255 octets if you think a hostname is allowed
2018  * to contain labels (plus termination).
2019  */
2020  memset(result, 0, sizeof(*result));
2021  if (!buffer_allocate(&result->buffer, 255, file, line)) {
2022  log_error("data: gethostname(): no memory for buffer");
2023  return 0;
2024  }
2025  result->data = result->buffer->data;
2026 
2027  /*
2028  * On successful completion, gethostname() resturns 0. It may
2029  * not null-terminate the string if there was insufficient
2030  * space.
2031  */
2032  if (!gethostname((char *)result->buffer->data, 255)) {
2033  if (result->buffer->data[255] == '\0')
2034  result->len =
2035  strlen((char *)result->buffer->data);
2036  else
2037  result->len = 255;
2038  return 1;
2039  }
2040 
2041  data_string_forget(result, MDL);
2042  return 0;
2043 
2044  /* Find an option within a v6relay context
2045  *
2046  * The numeric expression in relay indicates which relay
2047  * to try and use as the context. The relays are numbered
2048  * 1 to 32 with 1 being the one closest to the client and
2049  * 32 closest to the server. A value of greater than 33
2050  * indicates using the one closest to the server whatever
2051  * the count. A value of 0 indicates not using the relay
2052  * options, this is included for completeness and consistency
2053  * with the host-identier code.
2054  *
2055  * The data expression in roption is evaluated in that
2056  * context and the result returned.
2057  */
2058  case expr_v6relay:
2059  len = 0;
2060  s1 = 0;
2061  memset (&data, 0, sizeof data);
2062 
2063  /* Evaluate the relay count */
2064  s0 = evaluate_numeric_expression(&len, packet, lease,
2065  client_state,
2066  in_options, cfg_options,
2067  scope,
2068  expr->data.v6relay.relay);
2069 
2070  /* no number or an obviously invalid number */
2071  if ((s0 == 0) ||
2072  ((len > 0) &&
2073  ((packet == NULL) ||
2074  (packet->dhcpv6_container_packet == NULL)))) {
2075 #if defined (DEBUG_EXPRESSIONS)
2076  log_debug("data: v6relay(%lu) = NULL", len);
2077 #endif
2078  return (0);
2079  }
2080 
2081  /* Find the correct packet for the requested relay */
2082  i = len;
2083  relay_packet = packet;
2084  relay_options = in_options;
2085  while ((i != 0) &&
2086  (relay_packet->dhcpv6_container_packet != NULL)) {
2087  relay_packet = relay_packet->dhcpv6_container_packet;
2088  relay_options = relay_packet->options;
2089  i--;
2090  }
2091  /* We wanted a specific relay but were unable to find it */
2092  if ((len <= MAX_V6RELAY_HOPS) && (i != 0)) {
2093 #if defined (DEBUG_EXPRESSIONS)
2094  log_debug("data: v6relay(%lu) = NULL", len);
2095 #endif
2096  return (0);
2097  }
2098 
2099  s1 = evaluate_data_expression(&data, relay_packet, lease,
2100  client_state, relay_options,
2101  cfg_options, scope,
2102  expr->data.v6relay.roption,
2103  MDL);
2104 
2105  if (s1) {
2106  data_string_copy(result, &data, file, line);
2107  data_string_forget(&data, MDL);
2108  }
2109 
2110 #if defined (DEBUG_EXPRESSIONS)
2111  log_debug("data: v6relay(%lu) = %s", len,
2112  s1 ? print_hex_3(result->len, result->data, 30)
2113  : "NULL");
2114 #endif
2115  return (s1);
2116 
2117  case expr_concat_dclist: {
2118  /* Operands are compressed domain-name lists ("Dc" format)
2119  * Fetch both compressed lists then call concat_dclists which
2120  * combines them into a single compressed list. */
2121  memset(&data, 0, sizeof data);
2122  int outcome = 0;
2123  s0 = evaluate_data_expression(&data, packet, lease,
2124  client_state,
2125  in_options, cfg_options, scope,
2126  expr->data.concat[0], MDL);
2127 
2128  memset (&other, 0, sizeof other);
2129  s1 = evaluate_data_expression (&other, packet, lease,
2130  client_state,
2131  in_options, cfg_options, scope,
2132  expr->data.concat[1], MDL);
2133 
2134  if (s0 && s1) {
2135  outcome = concat_dclists(result, &data, &other);
2136  if (outcome == 0) {
2137  log_error ("data: concat_dclist failed");
2138  }
2139  }
2140 
2141 #if defined (DEBUG_EXPRESSIONS)
2142  log_debug ("data: concat_dclists (%s, %s) = %s",
2143  (s0 ? print_hex_1(data.len, data.data, data.len)
2144  : "NULL"),
2145  (s1 ? print_hex_2(other.len, other.data, other.len)
2146  : "NULL"),
2147  (((s0 && s1) && result->len > 0)
2148  ? print_hex_3 (result->len, result->data, result->len)
2149  : "NULL"));
2150 #endif
2151  if (s0)
2152  data_string_forget (&data, MDL);
2153 
2154  if (s1)
2155  data_string_forget (&other, MDL);
2156 
2157  return (outcome);
2158  } /* expr_concat_dclist */
2159 
2160  case expr_check:
2161  case expr_equal:
2162  case expr_not_equal:
2163  case expr_regex_match:
2164  case expr_iregex_match:
2165  case expr_and:
2166  case expr_or:
2167  case expr_not:
2168  case expr_match:
2169  case expr_static:
2170  case expr_known:
2171  case expr_none:
2172  case expr_exists:
2173  case expr_variable_exists:
2174  log_error ("Boolean opcode in evaluate_data_expression: %d",
2175  expr -> op);
2176  return 0;
2177 
2178  case expr_extract_int8:
2179  case expr_extract_int16:
2180  case expr_extract_int32:
2181  case expr_const_int:
2182  case expr_lease_time:
2183  case expr_dns_transaction:
2184  case expr_add:
2185  case expr_subtract:
2186  case expr_multiply:
2187  case expr_divide:
2188  case expr_remainder:
2189  case expr_binary_and:
2190  case expr_binary_or:
2191  case expr_binary_xor:
2192  case expr_client_state:
2193  log_error ("Numeric opcode in evaluate_data_expression: %d",
2194  expr -> op);
2195  return 0;
2196 
2197  case expr_ns_add:
2198  case expr_ns_delete:
2199  case expr_ns_exists:
2200  case expr_ns_not_exists:
2201  log_error ("dns opcode in evaluate_boolean_expression: %d",
2202  expr -> op);
2203  return 0;
2204 
2205  case expr_function:
2206  log_error ("function definition in evaluate_data_expression");
2207  return 0;
2208 
2209  case expr_arg:
2210  break;
2211 
2212  }
2213 
2214  log_error ("Bogus opcode in evaluate_data_expression: %d", expr -> op);
2215  return 0;
2216 }
2217 
2219  in_options, cfg_options, scope, expr)
2220  unsigned long *result;
2221  struct packet *packet;
2222  struct lease *lease;
2223  struct client_state *client_state;
2224  struct option_state *in_options;
2225  struct option_state *cfg_options;
2226  struct binding_scope **scope;
2227  struct expression *expr;
2228 {
2229  struct data_string data;
2230  int status, sleft, sright;
2231 
2232  struct binding *binding;
2233  struct binding_value *bv;
2234  unsigned long ileft, iright;
2235  int rc = 0;
2236 
2237  switch (expr -> op) {
2238  case expr_check:
2239  case expr_equal:
2240  case expr_not_equal:
2241  case expr_regex_match:
2242  case expr_iregex_match:
2243  case expr_and:
2244  case expr_or:
2245  case expr_not:
2246  case expr_match:
2247  case expr_static:
2248  case expr_known:
2249  case expr_none:
2250  case expr_exists:
2251  case expr_variable_exists:
2252  log_error ("Boolean opcode in evaluate_numeric_expression: %d",
2253  expr -> op);
2254  return 0;
2255 
2256  case expr_substring:
2257  case expr_suffix:
2258  case expr_lcase:
2259  case expr_ucase:
2260  case expr_option:
2261  case expr_hardware:
2262  case expr_const_data:
2263  case expr_packet:
2264  case expr_concat:
2265  case expr_encapsulate:
2266  case expr_host_lookup:
2267  case expr_encode_int8:
2268  case expr_encode_int16:
2269  case expr_encode_int32:
2270  case expr_binary_to_ascii:
2271  case expr_reverse:
2272  case expr_filename:
2273  case expr_sname:
2274  case expr_pick_first_value:
2275  case expr_host_decl_name:
2276  case expr_config_option:
2277  case expr_leased_address:
2278  case expr_null:
2279  case expr_gethostname:
2280  case expr_v6relay:
2281  log_error ("Data opcode in evaluate_numeric_expression: %d",
2282  expr -> op);
2283  return 0;
2284 
2285  case expr_extract_int8:
2286  memset (&data, 0, sizeof data);
2287  status = evaluate_data_expression
2288  (&data, packet, lease, client_state, in_options,
2289  cfg_options, scope, expr -> data.extract_int, MDL);
2290  if (status)
2291  *result = data.data [0];
2292 #if defined (DEBUG_EXPRESSIONS)
2293  log_debug ("num: extract_int8 (%s) = %s",
2294  status ? print_hex_1 (data.len, data.data, 60) : "NULL",
2295  status ? print_dec_1 (*result) : "NULL" );
2296 #endif
2297  if (status) data_string_forget (&data, MDL);
2298  return status;
2299 
2300  case expr_extract_int16:
2301  memset(&data, 0, sizeof(data));
2302  status = (evaluate_data_expression
2303  (&data, packet, lease, client_state, in_options,
2304  cfg_options, scope, expr->data.extract_int, MDL));
2305  if (status && data.len >= 2) {
2306  *result = getUShort(data.data);
2307  rc = 1;
2308  }
2309 #if defined (DEBUG_EXPRESSIONS)
2310  if (rc == 1) {
2311  log_debug("num: extract_int16 (%s) = %ld",
2312  print_hex_1(data.len, data.data, 60),
2313  *result);
2314  } else {
2315  log_debug("num: extract_int16 (NULL) = NULL");
2316  }
2317 #endif
2318  if (status)
2319  data_string_forget(&data, MDL);
2320 
2321  return (rc);
2322 
2323  case expr_extract_int32:
2324  memset (&data, 0, sizeof data);
2325  status = (evaluate_data_expression
2326  (&data, packet, lease, client_state, in_options,
2327  cfg_options, scope, expr -> data.extract_int, MDL));
2328  if (status && data.len >= 4) {
2329  *result = getULong (data.data);
2330  rc = 1;
2331  }
2332 #if defined (DEBUG_EXPRESSIONS)
2333  if (rc == 1) {
2334  log_debug ("num: extract_int32 (%s) = %ld",
2335  print_hex_1 (data.len, data.data, 60),
2336  *result);
2337  } else {
2338  log_debug ("num: extract_int32 (NULL) = NULL");
2339  }
2340 #endif
2341  if (status) data_string_forget (&data, MDL);
2342  return (rc);
2343 
2344  case expr_const_int:
2345  *result = expr -> data.const_int;
2346 #if defined (DEBUG_EXPRESSIONS)
2347  log_debug ("number: CONSTANT = %ld", *result);
2348 #endif
2349  return 1;
2350 
2351  case expr_lease_time:
2352  if (!lease) {
2353  log_error("data: leased_lease: not available");
2354  return (0);
2355  }
2356  if (lease->ends < cur_time) {
2357  log_error("%s %lu when it is now %lu",
2358  "data: lease_time: lease ends at",
2359  (long)(lease->ends), (long)cur_time);
2360  return (0);
2361  }
2362  *result = lease->ends - cur_time;
2363 #if defined (DEBUG_EXPRESSIONS)
2364  log_debug("number: lease-time = (%lu - %lu) = %ld",
2365  (long unsigned)lease->ends,
2366  (long unsigned)cur_time, *result);
2367 #endif
2368  return (1);
2369 
2371  if (scope && *scope) {
2372  binding = find_binding (*scope, expr -> data.variable);
2373 
2374  if (binding && binding -> value) {
2375  if (binding -> value -> type == binding_numeric) {
2376  *result = binding -> value -> value.intval;
2377  status = 1;
2378  } else {
2379  log_error ("binding type %d in %s.",
2380  binding -> value -> type,
2381  "evaluate_numeric_expression");
2382  status = 0;
2383  }
2384  } else
2385  status = 0;
2386  } else
2387  status = 0;
2388 #if defined (DEBUG_EXPRESSIONS)
2389  if (status)
2390  log_debug ("numeric: %s = %ld",
2391  expr -> data.variable, *result);
2392  else
2393  log_debug ("numeric: %s = NULL",
2394  expr -> data.variable);
2395 #endif
2396  return status;
2397 
2398  case expr_funcall:
2399  bv = (struct binding_value *)0;
2400  status = evaluate_expression (&bv, packet, lease,
2401  client_state,
2402  in_options, cfg_options,
2403  scope, expr, MDL);
2404  if (status) {
2405  if (bv -> type != binding_numeric)
2406  log_error ("%s() returned type %d in %s.",
2407  expr -> data.funcall.name,
2408  bv -> type,
2409  "evaluate_numeric_expression");
2410  else
2411  *result = bv -> value.intval;
2413  }
2414 #if defined (DEBUG_EXPRESSIONS)
2415  log_debug ("data: %s = %ld", expr -> data.funcall.name,
2416  status ? *result : 0);
2417 #endif
2418  break;
2419 
2420  case expr_add:
2421  sleft = evaluate_numeric_expression (&ileft, packet, lease,
2422  client_state,
2423  in_options, cfg_options,
2424  scope,
2425  expr -> data.and [0]);
2426  sright = evaluate_numeric_expression (&iright, packet, lease,
2427  client_state,
2428  in_options, cfg_options,
2429  scope,
2430  expr -> data.and [1]);
2431 
2432 #if defined (DEBUG_EXPRESSIONS)
2433  if (sleft && sright)
2434  log_debug ("num: %ld + %ld = %ld",
2435  ileft, iright, ileft + iright);
2436  else if (sleft)
2437  log_debug ("num: %ld + NULL = NULL", ileft);
2438  else
2439  log_debug ("num: NULL + %ld = NULL", iright);
2440 #endif
2441  if (sleft && sright) {
2442  *result = ileft + iright;
2443  return 1;
2444  }
2445  return 0;
2446 
2447  case expr_subtract:
2448  sleft = evaluate_numeric_expression (&ileft, packet, lease,
2449  client_state,
2450  in_options, cfg_options,
2451  scope,
2452  expr -> data.and [0]);
2453  sright = evaluate_numeric_expression (&iright, packet, lease,
2454  client_state,
2455  in_options, cfg_options,
2456  scope,
2457  expr -> data.and [1]);
2458 
2459 #if defined (DEBUG_EXPRESSIONS)
2460  if (sleft && sright)
2461  log_debug ("num: %ld - %ld = %ld",
2462  ileft, iright, ileft - iright);
2463  else if (sleft)
2464  log_debug ("num: %ld - NULL = NULL", ileft);
2465  else
2466  log_debug ("num: NULL - %ld = NULL", iright);
2467 #endif
2468  if (sleft && sright) {
2469  *result = ileft - iright;
2470  return 1;
2471  }
2472  return 0;
2473 
2474  case expr_multiply:
2475  sleft = evaluate_numeric_expression (&ileft, packet, lease,
2476  client_state,
2477  in_options, cfg_options,
2478  scope,
2479  expr -> data.and [0]);
2480  sright = evaluate_numeric_expression (&iright, packet, lease,
2481  client_state,
2482  in_options, cfg_options,
2483  scope,
2484  expr -> data.and [1]);
2485 
2486 #if defined (DEBUG_EXPRESSIONS)
2487  if (sleft && sright)
2488  log_debug ("num: %ld * %ld = %ld",
2489  ileft, iright, ileft * iright);
2490  else if (sleft)
2491  log_debug ("num: %ld * NULL = NULL", ileft);
2492  else
2493  log_debug ("num: NULL * %ld = NULL", iright);
2494 #endif
2495  if (sleft && sright) {
2496  *result = ileft * iright;
2497  return 1;
2498  }
2499  return 0;
2500 
2501  case expr_divide:
2502  sleft = evaluate_numeric_expression (&ileft, packet, lease,
2503  client_state,
2504  in_options, cfg_options,
2505  scope,
2506  expr -> data.and [0]);
2507  sright = evaluate_numeric_expression (&iright, packet, lease,
2508  client_state,
2509  in_options, cfg_options,
2510  scope,
2511  expr -> data.and [1]);
2512 
2513 #if defined (DEBUG_EXPRESSIONS)
2514  if (sleft && sright) {
2515  if (iright != 0)
2516  log_debug ("num: %ld / %ld = %ld",
2517  ileft, iright, ileft / iright);
2518  else
2519  log_debug ("num: %ld / %ld = NULL",
2520  ileft, iright);
2521  } else if (sleft)
2522  log_debug ("num: %ld / NULL = NULL", ileft);
2523  else
2524  log_debug ("num: NULL / %ld = NULL", iright);
2525 #endif
2526  if (sleft && sright && iright) {
2527  *result = ileft / iright;
2528  return 1;
2529  }
2530  return 0;
2531 
2532  case expr_remainder:
2533  sleft = evaluate_numeric_expression (&ileft, packet, lease,
2534  client_state,
2535  in_options, cfg_options,
2536  scope,
2537  expr -> data.and [0]);
2538  sright = evaluate_numeric_expression (&iright, packet, lease,
2539  client_state,
2540  in_options, cfg_options,
2541  scope,
2542  expr -> data.and [1]);
2543 
2544 #if defined (DEBUG_EXPRESSIONS)
2545  if (sleft && sright) {
2546  if (iright != 0)
2547  log_debug ("num: %ld %% %ld = %ld",
2548  ileft, iright, ileft % iright);
2549  else
2550  log_debug ("num: %ld %% %ld = NULL",
2551  ileft, iright);
2552  } else if (sleft)
2553  log_debug ("num: %ld %% NULL = NULL", ileft);
2554  else
2555  log_debug ("num: NULL %% %ld = NULL", iright);
2556 #endif
2557  if (sleft && sright && iright) {
2558  *result = ileft % iright;
2559  return 1;
2560  }
2561  return 0;
2562 
2563  case expr_binary_and:
2564  sleft = evaluate_numeric_expression (&ileft, packet, lease,
2565  client_state,
2566  in_options, cfg_options,
2567  scope,
2568  expr -> data.and [0]);
2569  sright = evaluate_numeric_expression (&iright, packet, lease,
2570  client_state,
2571  in_options, cfg_options,
2572  scope,
2573  expr -> data.and [1]);
2574 
2575 #if defined (DEBUG_EXPRESSIONS)
2576  if (sleft && sright)
2577  log_debug ("num: %ld | %ld = %ld",
2578  ileft, iright, ileft & iright);
2579  else if (sleft)
2580  log_debug ("num: %ld & NULL = NULL", ileft);
2581  else
2582  log_debug ("num: NULL & %ld = NULL", iright);
2583 #endif
2584  if (sleft && sright) {
2585  *result = ileft & iright;
2586  return 1;
2587  }
2588  return 0;
2589 
2590  case expr_binary_or:
2591  sleft = evaluate_numeric_expression (&ileft, packet, lease,
2592  client_state,
2593  in_options, cfg_options,
2594  scope,
2595  expr -> data.and [0]);
2596  sright = evaluate_numeric_expression (&iright, packet, lease,
2597  client_state,
2598  in_options, cfg_options,
2599  scope,
2600  expr -> data.and [1]);
2601 
2602 #if defined (DEBUG_EXPRESSIONS)
2603  if (sleft && sright)
2604  log_debug ("num: %ld | %ld = %ld",
2605  ileft, iright, ileft | iright);
2606  else if (sleft)
2607  log_debug ("num: %ld | NULL = NULL", ileft);
2608  else
2609  log_debug ("num: NULL | %ld = NULL", iright);
2610 #endif
2611  if (sleft && sright) {
2612  *result = ileft | iright;
2613  return 1;
2614  }
2615  return 0;
2616 
2617  case expr_binary_xor:
2618  sleft = evaluate_numeric_expression (&ileft, packet, lease,
2619  client_state,
2620  in_options, cfg_options,
2621  scope,
2622  expr -> data.and [0]);
2623  sright = evaluate_numeric_expression (&iright, packet, lease,
2624  client_state,
2625  in_options, cfg_options,
2626  scope,
2627  expr -> data.and [1]);
2628 
2629 #if defined (DEBUG_EXPRESSIONS)
2630  if (sleft && sright)
2631  log_debug ("num: %ld ^ %ld = %ld",
2632  ileft, iright, ileft ^ iright);
2633  else if (sleft)
2634  log_debug ("num: %ld ^ NULL = NULL", ileft);
2635  else
2636  log_debug ("num: NULL ^ %ld = NULL", iright);
2637 #endif
2638  if (sleft && sright) {
2639  *result = ileft ^ iright;
2640  return 1;
2641  }
2642  return 0;
2643 
2644  case expr_client_state:
2645  if (client_state) {
2646 #if defined (DEBUG_EXPRESSIONS)
2647  log_debug ("num: client-state = %d",
2648  client_state -> state);
2649 #endif
2650  *result = client_state -> state;
2651  return 1;
2652  } else {
2653 #if defined (DEBUG_EXPRESSIONS)
2654  log_debug ("num: client-state = NULL");
2655 #endif
2656  return 0;
2657  }
2658 
2659  case expr_function:
2660  log_error ("function definition in evaluate_numeric_expr");
2661  return 0;
2662 
2663  case expr_arg:
2664  break;
2665 
2666  default:
2667  log_fatal("Impossible case at %s:%d. Undefined operator "
2668  "%d.", MDL, expr->op);
2669  break;
2670  }
2671 
2672  log_error ("evaluate_numeric_expression: bogus opcode %d", expr -> op);
2673  return 0;
2674 }
2675 
2676 /*
2677  * Return data hanging off of an option cache structure, or if there
2678  * isn't any, evaluate the expression hanging off of it and return the
2679  * result of that evaluation. There should never be both an expression
2680  * and a valid data_string.
2681  *
2682  * returns 0 if there wasn't an expression or it couldn't be evaluated
2683  * returns non-zero if there was an expression or string that was evaluated
2684  * When it returns zero the arguements, in particualr resutl, should not
2685  * be modified
2686  */
2687 
2689  in_options, cfg_options, scope, oc, file, line)
2690  struct data_string *result;
2691  struct packet *packet;
2692  struct lease *lease;
2693  struct client_state *client_state;
2694  struct option_state *in_options;
2695  struct option_state *cfg_options;
2696  struct binding_scope **scope;
2697  struct option_cache *oc;
2698  const char *file;
2699  int line;
2700 {
2701  if (oc->data.data != NULL) {
2702  data_string_copy (result, &oc -> data, file, line);
2703  return 1;
2704  }
2705  if (!oc -> expression)
2706  return 0;
2707  return evaluate_data_expression (result, packet, lease, client_state,
2708  in_options, cfg_options, scope,
2709  oc -> expression, file, line);
2710 }
2711 
2712 /* Evaluate an option cache and extract a boolean from the result.
2713  * The boolean option cache is actually a trinary value where:
2714  *
2715  * 0 = return 0, ignore parameter 0 (also the case for no data)
2716  * 1 = return 1, ignore parameter 0
2717  * 2 = return 0, ignore parameter 1
2718  *
2719  * This supports both classic boolean flags on/off as well as the
2720  * allow/deny/ignore keywords
2721 */
2723  lease, client_state, in_options,
2724  cfg_options, scope, oc, file, line)
2725  int *ignorep;
2726  struct packet *packet;
2727  struct lease *lease;
2728  struct client_state *client_state;
2729  struct option_state *in_options;
2730  struct option_state *cfg_options;
2731  struct binding_scope **scope;
2732  struct option_cache *oc;
2733  const char *file;
2734  int line;
2735 {
2736  int result = 0;
2737  if (ignorep)
2738  *ignorep = 0;
2739 
2740  /* Only attempt to evaluate if option_cache is not null. This permits
2741  * us to be called with option_lookup() as an argument. */
2742  if (oc && in_options) {
2743  struct data_string ds;
2744 
2745  memset(&ds, 0, sizeof ds);
2746  if (evaluate_option_cache(&ds, packet,
2747  lease, client_state, in_options,
2748  cfg_options, scope, oc, file,
2749  line)) {
2750  /* We have a value for the option set result and
2751  * ignore parameter accordingly. */
2752  if (ds.len) {
2753  if (ds.data[0] == 1)
2754  result = 1;
2755  else if ((ds.data[0] == 2) && (ignorep != NULL))
2756  *ignorep = 1;
2757  }
2758 
2759  data_string_forget(&ds, MDL);
2760  }
2761  }
2762 
2763  return (result);
2764 }
2765 
2766 /* Evaluate a boolean expression and return the result of the evaluation,
2767  or FALSE if it failed. */
2768 
2770  in_options, cfg_options, scope, expr)
2771  int *ignorep;
2772  struct packet *packet;
2773  struct lease *lease;
2774  struct client_state *client_state;
2775  struct option_state *in_options;
2776  struct option_state *cfg_options;
2777  struct binding_scope **scope;
2778  struct expression *expr;
2779 {
2780  int result;
2781 
2782  /* So that we can be called with option_lookup as an argument. */
2783  if (!expr)
2784  return 0;
2785 
2786  if (!evaluate_boolean_expression (&result, packet, lease, client_state,
2787  in_options, cfg_options,
2788  scope, expr))
2789  return 0;
2790 
2791  if (result == 2) {
2792  *ignorep = 1;
2793  result = 0;
2794  } else
2795  *ignorep = 0;
2796  return result;
2797 }
2798 
2799 
2800 /* Dereference an expression node, and if the reference count goes to zero,
2801  dereference any data it refers to, and then free it. */
2803  struct expression **eptr;
2804  const char *file;
2805  int line;
2806 {
2807  struct expression *expr = *eptr;
2808 
2809  /* Zero the pointer. */
2810  *eptr = (struct expression *)0;
2811 
2812  /* Decrement the reference count. If it's nonzero, we're
2813  done. */
2814  --(expr -> refcnt);
2815  rc_register (file, line, eptr, expr, expr -> refcnt, 1, RC_MISC);
2816  if (expr -> refcnt > 0)
2817  return;
2818  if (expr -> refcnt < 0) {
2819  log_error ("%s(%d): negative refcnt!", file, line);
2820 #if defined (DEBUG_RC_HISTORY)
2821  dump_rc_history (expr);
2822 #endif
2823 #if defined (POINTER_DEBUG)
2824  abort ();
2825 #else
2826  return;
2827 #endif
2828  }
2829 
2830  /* Dereference subexpressions. */
2831  switch (expr -> op) {
2832  /* All the binary operators can be handled the same way. */
2833  case expr_equal:
2834  case expr_not_equal:
2835  case expr_regex_match:
2836  case expr_iregex_match:
2837  case expr_concat:
2838  case expr_and:
2839  case expr_or:
2840  case expr_add:
2841  case expr_subtract:
2842  case expr_multiply:
2843  case expr_divide:
2844  case expr_remainder:
2845  case expr_binary_and:
2846  case expr_binary_or:
2847  case expr_binary_xor:
2848  case expr_client_state:
2849  if (expr -> data.equal [0])
2850  expression_dereference (&expr -> data.equal [0],
2851  file, line);
2852  if (expr -> data.equal [1])
2853  expression_dereference (&expr -> data.equal [1],
2854  file, line);
2855  break;
2856 
2857  case expr_substring:
2858  if (expr -> data.substring.expr)
2860  file, line);
2861  if (expr -> data.substring.offset)
2863  file, line);
2864  if (expr -> data.substring.len)
2866  file, line);
2867  break;
2868 
2869  case expr_suffix:
2870  if (expr -> data.suffix.expr)
2872  file, line);
2873  if (expr -> data.suffix.len)
2875  file, line);
2876  break;
2877 
2878  case expr_lcase:
2879  if (expr->data.lcase)
2881  break;
2882 
2883  case expr_ucase:
2884  if (expr->data.ucase)
2886  break;
2887 
2888  case expr_not:
2889  if (expr -> data.not)
2890  expression_dereference (&expr -> data.not, file, line);
2891  break;
2892 
2893  case expr_packet:
2894  if (expr -> data.packet.offset)
2896  file, line);
2897  if (expr -> data.packet.len)
2899  file, line);
2900  break;
2901 
2902  case expr_extract_int8:
2903  case expr_extract_int16:
2904  case expr_extract_int32:
2905  if (expr -> data.extract_int)
2907  file, line);
2908  break;
2909 
2910  case expr_encode_int8:
2911  case expr_encode_int16:
2912  case expr_encode_int32:
2913  if (expr -> data.encode_int)
2915  file, line);
2916  break;
2917 
2918  case expr_encapsulate:
2919  case expr_const_data:
2920  data_string_forget (&expr -> data.const_data, file, line);
2921  break;
2922 
2923  case expr_host_lookup:
2924  if (expr -> data.host_lookup)
2926  file, line);
2927  break;
2928 
2929  case expr_binary_to_ascii:
2930  if (expr -> data.b2a.base)
2931  expression_dereference (&expr -> data.b2a.base,
2932  file, line);
2933  if (expr -> data.b2a.width)
2935  file, line);
2936  if (expr -> data.b2a.separator)
2938  file, line);
2939  if (expr -> data.b2a.buffer)
2941  file, line);
2942  break;
2943 
2944  case expr_pick_first_value:
2945  if (expr -> data.pick_first_value.car)
2947  file, line);
2948  if (expr -> data.pick_first_value.cdr)
2950  file, line);
2951  break;
2952 
2953  case expr_reverse:
2954  if (expr -> data.reverse.width)
2956  file, line);
2957  if (expr -> data.reverse.buffer)
2959  (&expr -> data.reverse.buffer, file, line);
2960  break;
2961 
2963  case expr_variable_exists:
2964  if (expr -> data.variable)
2965  dfree (expr -> data.variable, file, line);
2966  break;
2967 
2968  case expr_funcall:
2969  if (expr -> data.funcall.name)
2970  dfree (expr -> data.funcall.name, file, line);
2971  if (expr -> data.funcall.arglist)
2973  file, line);
2974  break;
2975 
2976  case expr_arg:
2977  if (expr -> data.arg.val)
2978  expression_dereference (&expr -> data.arg.val,
2979  file, line);
2980  if (expr -> data.arg.next)
2981  expression_dereference (&expr -> data.arg.next,
2982  file, line);
2983  break;
2984 
2985  case expr_function:
2986  fundef_dereference (&expr -> data.func, file, line);
2987  break;
2988 
2989  case expr_v6relay:
2990  if (expr->data.v6relay.relay)
2992  file, line);
2993 
2994  if (expr->data.v6relay.roption)
2996  file, line);
2997  break;
2998 
2999  /* No subexpressions. */
3000  case expr_leased_address:
3001  case expr_lease_time:
3002  case expr_filename:
3003  case expr_sname:
3004  case expr_const_int:
3005  case expr_check:
3006  case expr_option:
3007  case expr_hardware:
3008  case expr_exists:
3009  case expr_known:
3010  case expr_null:
3011  case expr_gethostname:
3012  break;
3013 
3014  default:
3015  break;
3016  }
3017  free_expression (expr, MDL);
3018 }
3019 
3021  struct expression *expr;
3022 {
3023  return (expr -> op == expr_check ||
3024  expr -> op == expr_exists ||
3025  expr -> op == expr_variable_exists ||
3026  expr -> op == expr_equal ||
3027  expr -> op == expr_not_equal ||
3028  expr->op == expr_regex_match ||
3029  expr->op == expr_iregex_match ||
3030  expr -> op == expr_and ||
3031  expr -> op == expr_or ||
3032  expr -> op == expr_not ||
3033  expr -> op == expr_known ||
3034  expr -> op == expr_static);
3035 }
3036 
3038  struct expression *expr;
3039 {
3040  return (expr->op == expr_substring ||
3041  expr->op == expr_suffix ||
3042  expr->op == expr_lcase ||
3043  expr->op == expr_ucase ||
3044  expr->op == expr_option ||
3045  expr->op == expr_hardware ||
3046  expr->op == expr_const_data ||
3047  expr->op == expr_packet ||
3048  expr->op == expr_concat ||
3049  expr->op == expr_encapsulate ||
3050  expr->op == expr_encode_int8 ||
3051  expr->op == expr_encode_int16 ||
3052  expr->op == expr_encode_int32 ||
3053  expr->op == expr_host_lookup ||
3054  expr->op == expr_binary_to_ascii ||
3055  expr->op == expr_filename ||
3056  expr->op == expr_sname ||
3057  expr->op == expr_reverse ||
3058  expr->op == expr_pick_first_value ||
3059  expr->op == expr_host_decl_name ||
3060  expr->op == expr_leased_address ||
3061  expr->op == expr_config_option ||
3062  expr->op == expr_null ||
3063  expr->op == expr_gethostname ||
3064  expr->op == expr_v6relay);
3065 }
3066 
3068  struct expression *expr;
3069 {
3070  return (expr -> op == expr_extract_int8 ||
3071  expr -> op == expr_extract_int16 ||
3072  expr -> op == expr_extract_int32 ||
3073  expr -> op == expr_const_int ||
3074  expr -> op == expr_lease_time ||
3075  expr -> op == expr_add ||
3076  expr -> op == expr_subtract ||
3077  expr -> op == expr_multiply ||
3078  expr -> op == expr_divide ||
3079  expr -> op == expr_remainder ||
3080  expr -> op == expr_binary_and ||
3081  expr -> op == expr_binary_or ||
3082  expr -> op == expr_binary_xor ||
3083  expr -> op == expr_client_state);
3084 }
3085 
3087  struct expression *expr;
3088 {
3089  return (expr -> op == expr_substring ||
3090  expr -> op == expr_suffix ||
3091  expr -> op == expr_option ||
3092  expr -> op == expr_concat ||
3093  expr -> op == expr_encode_int8 ||
3094  expr -> op == expr_encode_int16 ||
3095  expr -> op == expr_encode_int32 ||
3096  expr -> op == expr_binary_to_ascii ||
3097  expr -> op == expr_reverse ||
3098  expr -> op == expr_pick_first_value ||
3099  expr -> op == expr_config_option ||
3100  expr -> op == expr_extract_int8 ||
3101  expr -> op == expr_extract_int16 ||
3102  expr -> op == expr_extract_int32 ||
3103  expr -> op == expr_v6relay);
3104 }
3105 
3106 static int op_val (enum expr_op);
3107 
3108 static int op_val (op)
3109  enum expr_op op;
3110 {
3111  switch (op) {
3112  case expr_none:
3113  case expr_match:
3114  case expr_static:
3115  case expr_check:
3116  case expr_substring:
3117  case expr_suffix:
3118  case expr_lcase:
3119  case expr_ucase:
3120  case expr_concat:
3121  case expr_encapsulate:
3122  case expr_host_lookup:
3123  case expr_not:
3124  case expr_option:
3125  case expr_hardware:
3126  case expr_packet:
3127  case expr_const_data:
3128  case expr_extract_int8:
3129  case expr_extract_int16:
3130  case expr_extract_int32:
3131  case expr_encode_int8:
3132  case expr_encode_int16:
3133  case expr_encode_int32:
3134  case expr_const_int:
3135  case expr_exists:
3136  case expr_variable_exists:
3137  case expr_known:
3138  case expr_binary_to_ascii:
3139  case expr_reverse:
3140  case expr_filename:
3141  case expr_sname:
3142  case expr_pick_first_value:
3143  case expr_host_decl_name:
3144  case expr_config_option:
3145  case expr_leased_address:
3146  case expr_lease_time:
3147  case expr_dns_transaction:
3148  case expr_null:
3150  case expr_ns_add:
3151  case expr_ns_delete:
3152  case expr_ns_exists:
3153  case expr_ns_not_exists:
3154  case expr_arg:
3155  case expr_funcall:
3156  case expr_function:
3157  /* XXXDPN: Need to assign sane precedences to these. */
3158  case expr_binary_and:
3159  case expr_binary_or:
3160  case expr_binary_xor:
3161  case expr_client_state:
3162  case expr_gethostname:
3163  case expr_v6relay:
3164  case expr_concat_dclist:
3165  return 100;
3166 
3167  case expr_equal:
3168  case expr_not_equal:
3169  case expr_regex_match:
3170  case expr_iregex_match:
3171  return 4;
3172 
3173  case expr_or:
3174  case expr_and:
3175  return 3;
3176 
3177  case expr_add:
3178  case expr_subtract:
3179  return 2;
3180 
3181  case expr_multiply:
3182  case expr_divide:
3183  case expr_remainder:
3184  return 1;
3185  }
3186  return 100;
3187 }
3188 
3189 int op_precedence (op1, op2)
3190  enum expr_op op1, op2;
3191 {
3192  return op_val (op1) - op_val (op2);
3193 }
3194 
3196 {
3197  if (is_data_expression (expr))
3198  return context_data;
3199  if (is_numeric_expression (expr))
3200  return context_numeric;
3201  if (is_boolean_expression (expr))
3202  return context_boolean;
3203  return context_any;
3204 }
3205 
3207  enum expr_op op;
3208 {
3209  switch (op) {
3210 /* XXX Why aren't these specific? */
3211  case expr_none:
3212  case expr_match:
3213  case expr_static:
3214  case expr_check:
3215  case expr_substring:
3216  case expr_suffix:
3217  case expr_lcase:
3218  case expr_ucase:
3219  case expr_concat:
3220  case expr_encapsulate:
3221  case expr_host_lookup:
3222  case expr_not:
3223  case expr_option:
3224  case expr_hardware:
3225  case expr_packet:
3226  case expr_const_data:
3227  case expr_extract_int8:
3228  case expr_extract_int16:
3229  case expr_extract_int32:
3230  case expr_encode_int8:
3231  case expr_encode_int16:
3232  case expr_encode_int32:
3233  case expr_const_int:
3234  case expr_exists:
3235  case expr_variable_exists:
3236  case expr_known:
3237  case expr_binary_to_ascii:
3238  case expr_reverse:
3239  case expr_filename:
3240  case expr_sname:
3241  case expr_pick_first_value:
3242  case expr_host_decl_name:
3243  case expr_config_option:
3244  case expr_leased_address:
3245  case expr_lease_time:
3246  case expr_null:
3248  case expr_ns_add:
3249  case expr_ns_delete:
3250  case expr_ns_exists:
3251  case expr_ns_not_exists:
3252  case expr_dns_transaction:
3253  case expr_arg:
3254  case expr_funcall:
3255  case expr_function:
3256  case expr_gethostname:
3257  case expr_v6relay:
3258  case expr_concat_dclist:
3259  return context_any;
3260 
3261  case expr_equal:
3262  case expr_not_equal:
3263  case expr_regex_match:
3264  case expr_iregex_match:
3265  return context_data;
3266 
3267  case expr_and:
3268  return context_boolean;
3269 
3270  case expr_or:
3271  return context_boolean;
3272 
3273  case expr_add:
3274  case expr_subtract:
3275  case expr_multiply:
3276  case expr_divide:
3277  case expr_remainder:
3278  case expr_binary_and:
3279  case expr_binary_or:
3280  case expr_binary_xor:
3281  case expr_client_state:
3282  return context_numeric;
3283  }
3284  return context_any;
3285 }
3286 
3287 int write_expression (file, expr, col, indent, firstp)
3288  FILE *file;
3289  struct expression *expr;
3290  int col;
3291  int indent;
3292  int firstp;
3293 {
3294  struct expression *e;
3295  const char *s;
3296  char obuf [65];
3297  int scol;
3298  int width;
3299 
3300  /* If this promises to be a fat expression, start a new line. */
3301  if (!firstp && is_compound_expression (expr)) {
3302  indent_spaces (file, indent);
3303  col = indent;
3304  }
3305 
3306  switch (expr -> op) {
3307  case expr_none:
3308  col = token_print_indent (file, col, indent, "", "", "null");
3309  break;
3310 
3311  case expr_check:
3312  col = token_print_indent (file, col, indent, "", "", "check");
3313  col = token_print_indent_concat (file, col, indent,
3314  " ", "", "\"",
3315  expr -> data.check -> name,
3316  "\"", (char *)0);
3317  break;
3318 
3319  case expr_regex_match:
3320  s = "~=";
3321  goto binary;
3322 
3323  case expr_iregex_match:
3324  s = "~~";
3325  goto binary;
3326 
3327  case expr_not_equal:
3328  s = "!=";
3329  goto binary;
3330 
3331  case expr_equal:
3332  s = "=";
3333  binary:
3334  col = write_expression (file, expr -> data.equal [0],
3335  col, indent, 1);
3336  col = token_print_indent (file, col, indent, " ", " ", s);
3337  col = write_expression (file, expr -> data.equal [1],
3338  col, indent + 2, 0);
3339  break;
3340 
3341  case expr_substring:
3342  col = token_print_indent (file, col, indent, "", "",
3343  "substring");
3344  col = token_print_indent (file, col, indent, " ", "", "(");
3345  scol = col;
3346  col = write_expression (file, expr -> data.substring.expr,
3347  col, scol, 1);
3348  col = token_print_indent (file, col, indent, "", " ", ",");
3349  col = write_expression (file, expr -> data.substring.offset,
3350  col, indent, 0);
3351  col = token_print_indent (file, col, scol, "", " ", ",");
3352  col = write_expression (file, expr -> data.substring.len,
3353  col, scol, 0);
3354  col = token_print_indent (file, col, indent, "", "", ")");
3355  break;
3356 
3357  case expr_suffix:
3358  col = token_print_indent (file, col, indent, "", "", "suffix");
3359  col = token_print_indent (file, col, indent, " ", "", "(");
3360  scol = col;
3361  col = write_expression (file, expr -> data.suffix.expr,
3362  col, scol, 1);
3363  col = token_print_indent (file, col, scol, "", " ", ",");
3364  col = write_expression (file, expr -> data.suffix.len,
3365  col, scol, 0);
3366  col = token_print_indent (file, col, indent, "", "", ")");
3367  break;
3368 
3369  case expr_lcase:
3370  col = token_print_indent(file, col, indent, "", "", "lcase");
3371  col = token_print_indent(file, col, indent, " ", "", "(");
3372  scol = col;
3373  col = write_expression(file, expr->data.lcase, col, scol, 1);
3374  col = token_print_indent(file, col, indent, "", "", ")");
3375  break;
3376 
3377  case expr_ucase:
3378  col = token_print_indent(file, col, indent, "", "", "ucase");
3379  col = token_print_indent(file, col, indent, " ", "", "(");
3380  scol = col;
3381  col = write_expression(file, expr->data.ucase, col, scol, 1);
3382  col = token_print_indent(file, col, indent, "", "", ")");
3383  break;
3384 
3385  case expr_concat:
3386  e = expr;
3387  col = token_print_indent (file, col, indent, "", "",
3388  "concat");
3389  col = token_print_indent (file, col, indent, " ", "", "(");
3390  scol = col;
3391  firstp = 1;
3392  concat_again:
3393  col = write_expression (file, e -> data.concat [0],
3394  col, scol, firstp);
3395  firstp = 0;
3396  if (!e -> data.concat [1])
3397  goto no_concat_cdr;
3398  col = token_print_indent (file, col, scol, "", " ", ",");
3399  if (e -> data.concat [1] -> op == expr_concat) {
3400  e = e -> data.concat [1];
3401  goto concat_again;
3402  }
3403  col = write_expression (file, e -> data.concat [1],
3404  col, scol, 0);
3405  no_concat_cdr:
3406  col = token_print_indent (file, col, indent, "", "", ")");
3407  break;
3408 
3409  case expr_host_lookup:
3410  col = token_print_indent (file, col, indent, "", "",
3411  "gethostbyname");
3412  col = token_print_indent (file, col, indent, " ", "", "(");
3414  (file, col, indent, "", "",
3415  "\"", expr -> data.host_lookup -> hostname, "\"",
3416  (char *)0);
3417  col = token_print_indent (file, col, indent, "", "", ")");
3418  break;
3419 
3420  case expr_add:
3421  s = "+";
3422  goto binary;
3423 
3424  case expr_subtract:
3425  s = "-";
3426  goto binary;
3427 
3428  case expr_multiply:
3429  s = "*";
3430  goto binary;
3431 
3432  case expr_divide:
3433  s = "/";
3434  goto binary;
3435 
3436  case expr_remainder:
3437  s = "%";
3438  goto binary;
3439 
3440  case expr_binary_and:
3441  s = "&";
3442  goto binary;
3443 
3444  case expr_binary_or:
3445  s = "|";
3446  goto binary;
3447 
3448  case expr_binary_xor:
3449  s = "^";
3450  goto binary;
3451 
3452  case expr_and:
3453  s = "and";
3454  goto binary;
3455 
3456  case expr_or:
3457  s = "or";
3458  goto binary;
3459 
3460  case expr_not:
3461  col = token_print_indent (file, col, indent, "", " ", "not");
3462  col = write_expression (file,
3463  expr -> data.not, col, indent + 2, 1);
3464  break;
3465 
3466  case expr_option:
3467  s = "option";
3468 
3469  print_option_name:
3470  col = token_print_indent (file, col, indent, "", "", s);
3471 
3472  if (expr -> data.option -> universe != &dhcp_universe) {
3473  col = token_print_indent (file, col, indent,
3474  " ", "",
3475  (expr -> data.option ->
3476  universe -> name));
3477  col = token_print_indent (file, col, indent, "", "",
3478  ".");
3479  col = token_print_indent (file, col, indent, "", "",
3480  expr -> data.option -> name);
3481  } else {
3482  col = token_print_indent (file, col, indent, " ", "",
3483  expr -> data.option -> name);
3484  }
3485  break;
3486 
3487  case expr_hardware:
3488  col = token_print_indent (file, col, indent, "", "",
3489  "hardware");
3490  break;
3491 
3492  case expr_packet:
3493  col = token_print_indent (file, col, indent, "", "",
3494  "packet");
3495  col = token_print_indent (file, col, indent, " ", "", "(");
3496  scol = col;
3497  col = write_expression (file, expr -> data.packet.offset,
3498  col, indent, 1);
3499  col = token_print_indent (file, col, scol, "", " ", ",");
3500  col = write_expression (file, expr -> data.packet.len,
3501  col, scol, 0);
3502  col = token_print_indent (file, col, indent, "", "", ")");
3503  break;
3504 
3505  case expr_const_data:
3506  col = token_indent_data_string (file, col, indent, "", "",
3507  &expr -> data.const_data);
3508  break;
3509 
3510  case expr_extract_int8:
3511  width = 8;
3512  extract_int:
3513  col = token_print_indent (file, col, indent, "", "",
3514  "extract-int");
3515  col = token_print_indent (file, col, indent, " ", "", "(");
3516  scol = col;
3517  col = write_expression (file, expr -> data.extract_int,
3518  col, indent, 1);
3519  col = token_print_indent (file, col, scol, "", " ", ",");
3520  sprintf (obuf, "%d", width);
3521  col = token_print_indent (file, col, scol, " ", "", obuf);
3522  col = token_print_indent (file, col, indent, "", "", ")");
3523  break;
3524 
3525  case expr_extract_int16:
3526  width = 16;
3527  goto extract_int;
3528 
3529  case expr_extract_int32:
3530  width = 32;
3531  goto extract_int;
3532 
3533  case expr_encode_int8:
3534  width = 8;
3535  encode_int:
3536  col = token_print_indent (file, col, indent, "", "",
3537  "encode-int");
3538  col = token_print_indent (file, col, indent, " ", "", "(");
3539  scol = col;
3540  col = write_expression (file, expr -> data.extract_int,
3541  col, indent, 1);
3542  col = token_print_indent (file, col, scol, "", " ", ",");
3543  sprintf (obuf, "%d", width);
3544  col = token_print_indent (file, col, scol, " ", "", obuf);
3545  col = token_print_indent (file, col, indent, "", "",
3546  ")");
3547  break;
3548 
3549  case expr_encode_int16:
3550  width = 16;
3551  goto encode_int;
3552 
3553  case expr_encode_int32:
3554  width = 32;
3555  goto encode_int;
3556 
3557  case expr_const_int:
3558  sprintf (obuf, "%lu", expr -> data.const_int);
3559  col = token_print_indent (file, col, indent, "", "", obuf);
3560  break;
3561 
3562  case expr_exists:
3563  s = "exists";
3564  goto print_option_name;
3565 
3566  case expr_encapsulate:
3567  col = token_print_indent (file, col, indent, "", "",
3568  "encapsulate");
3569  col = token_indent_data_string (file, col, indent, " ", "",
3570  &expr -> data.encapsulate);
3571  break;
3572 
3573  case expr_known:
3574  col = token_print_indent (file, col, indent, "", "", "known");
3575  break;
3576 
3577  case expr_reverse:
3578  col = token_print_indent (file, col, indent, "", "",
3579  "reverse");
3580  col = token_print_indent (file, col, indent, " ", "", "(");
3581  scol = col;
3582  col = write_expression (file, expr -> data.reverse.width,
3583  col, scol, 1);
3584  col = token_print_indent (file, col, scol, "", " ", ",");
3585  col = write_expression (file, expr -> data.reverse.buffer,
3586  col, scol, 0);
3587  col = token_print_indent (file, col, indent, "", "",
3588  ")");
3589  break;
3590 
3591  case expr_leased_address:
3592  col = token_print_indent (file, col, indent, "", "",
3593  "leased-address");
3594  break;
3595 
3596  case expr_client_state:
3597  col = token_print_indent (file, col, indent, "", "",
3598  "client-state");
3599  break;
3600 
3601  case expr_binary_to_ascii:
3602  col = token_print_indent (file, col, indent, "", "",
3603  "binary-to-ascii");
3604  col = token_print_indent (file, col, indent, " ", "",
3605  "(");
3606  scol = col;
3607  col = write_expression (file, expr -> data.b2a.base,
3608  col, scol, 1);
3609  col = token_print_indent (file, col, scol, "", " ",
3610  ",");
3611  col = write_expression (file, expr -> data.b2a.width,
3612  col, scol, 0);
3613  col = token_print_indent (file, col, scol, "", " ",
3614  ",");
3615  col = write_expression (file, expr -> data.b2a.separator,
3616  col, scol, 0);
3617  col = token_print_indent (file, col, scol, "", " ",
3618  ",");
3619  col = write_expression (file, expr -> data.b2a.buffer,
3620  col, scol, 0);
3621  col = token_print_indent (file, col, indent, "", "",
3622  ")");
3623  break;
3624 
3625  case expr_config_option:
3626  s = "config-option";
3627  goto print_option_name;
3628 
3629  case expr_host_decl_name:
3630  col = token_print_indent (file, col, indent, "", "",
3631  "host-decl-name");
3632  break;
3633 
3634  case expr_pick_first_value:
3635  e = expr;
3636  col = token_print_indent (file, col, indent, "", "",
3637  "concat");
3638  col = token_print_indent (file, col, indent, " ", "",
3639  "(");
3640  scol = col;
3641  firstp = 1;
3642  pick_again:
3643  col = write_expression (file,
3644  e -> data.pick_first_value.car,
3645  col, scol, firstp);
3646  firstp = 0;
3647  /* We're being very lisp-like right now - instead of
3648  representing this expression as (first middle . last) we're
3649  representing it as (first middle last), which means that the
3650  tail cdr is always nil. Apologies to non-wisp-lizards - may
3651  this obscure way of describing the problem motivate you to
3652  learn more about the one true computing language. */
3653  if (!e -> data.pick_first_value.cdr)
3654  goto no_pick_cdr;
3655  col = token_print_indent (file, col, scol, "", " ",
3656  ",");
3657  if (e -> data.pick_first_value.cdr -> op ==
3659  e = e -> data.pick_first_value.cdr;
3660  goto pick_again;
3661  }
3662  col = write_expression (file,
3663  e -> data.pick_first_value.cdr,
3664  col, scol, 0);
3665  no_pick_cdr:
3666  col = token_print_indent (file, col, indent, "", "",
3667  ")");
3668  break;
3669 
3670  case expr_lease_time:
3671  col = token_print_indent (file, col, indent, "", "",
3672  "lease-time");
3673  break;
3674 
3675  case expr_static:
3676  col = token_print_indent (file, col, indent, "", "",
3677  "static");
3678  break;
3679 
3680  case expr_null:
3681  col = token_print_indent (file, col, indent, "", "", "null");
3682  break;
3683 
3685  col = token_print_indent (file, indent, indent, "", "",
3686  expr -> data.variable);
3687  break;
3688 
3689  case expr_variable_exists:
3690  col = token_print_indent (file, indent, indent, "", "",
3691  "defined");
3692  col = token_print_indent (file, col, indent, " ", "", "(");
3693  col = token_print_indent (file, col, indent, "", "",
3694  expr -> data.variable);
3695  col = token_print_indent (file, col, indent, "", "", ")");
3696  break;
3697 
3698  case expr_gethostname:
3699  col = token_print_indent(file, col, indent, "", "",
3700  "gethostname()");
3701  break;
3702 
3703  case expr_funcall:
3704  col = token_print_indent(file, indent, indent, "", "",
3705  expr->data.funcall.name);
3706  col = token_print_indent(file, col, indent, " ", "", "(");
3707 
3708  firstp = 1;
3709  e = expr->data.funcall.arglist;
3710  while (e != NULL) {
3711  if (!firstp)
3712  col = token_print_indent(file, col, indent,
3713  "", " ", ",");
3714 
3715  col = write_expression(file, e->data.arg.val, col,
3716  indent, firstp);
3717  firstp = 0;
3718  e = e->data.arg.next;
3719  }
3720 
3721  col = token_print_indent(file, col, indent, "", "", ")");
3722  break;
3723 
3724  case expr_v6relay:
3725  col = token_print_indent(file, col, indent, "", "",
3726  "v6relay");
3727  col = token_print_indent(file, col, indent, " ", "", "(");
3728  scol = col;
3729  col = write_expression(file, expr->data.v6relay.relay,
3730  col, scol, 1);
3731  col = token_print_indent (file, col, scol, "", " ", ",");
3732  col = write_expression(file, expr->data.v6relay.roption,
3733  col, scol, 0);
3734  col = token_print_indent(file, col, indent, "", "", ")");
3735  break;
3736 
3737  default:
3738  log_fatal ("invalid expression type in print_expression: %d",
3739  expr -> op);
3740  }
3741  return col;
3742 }
3743 
3744 struct binding *find_binding (struct binding_scope *scope, const char *name)
3745 {
3746  struct binding *bp;
3747  struct binding_scope *s;
3748 
3749  for (s = scope; s; s = s -> outer) {
3750  for (bp = s -> bindings; bp; bp = bp -> next) {
3751  if (!strcasecmp (name, bp -> name)) {
3752  return bp;
3753  }
3754  }
3755  }
3756  return (struct binding *)0;
3757 }
3758 
3759 int free_bindings (struct binding_scope *scope, const char *file, int line)
3760 {
3761  struct binding *bp, *next;
3762 
3763  for (bp = scope -> bindings; bp; bp = next) {
3764  next = bp -> next;
3765  if (bp -> name)
3766  dfree (bp -> name, file, line);
3767  if (bp -> value)
3768  binding_value_dereference (&bp -> value, file, line);
3769  dfree (bp, file, line);
3770  }
3771  scope -> bindings = (struct binding *)0;
3772  return 1;
3773 }
3774 
3776  struct binding_scope **ptr;
3777  const char *file;
3778  int line;
3779 {
3780  struct binding_scope *binding_scope;
3781 
3782  if (!ptr || !*ptr) {
3783  log_error ("%s(%d): null pointer", file, line);
3784 #if defined (POINTER_DEBUG)
3785  abort ();
3786 #else
3787  return 0;
3788 #endif
3789  }
3790 
3791  binding_scope = *ptr;
3792  *ptr = (struct binding_scope *)0;
3793  --binding_scope -> refcnt;
3794  rc_register (file, line, ptr,
3795  binding_scope, binding_scope -> refcnt, 1, RC_MISC);
3796  if (binding_scope -> refcnt > 0)
3797  return 1;
3798 
3799  if (binding_scope -> refcnt < 0) {
3800  log_error ("%s(%d): negative refcnt!", file, line);
3801 #if defined (DEBUG_RC_HISTORY)
3802  dump_rc_history (binding_scope);
3803 #endif
3804 #if defined (POINTER_DEBUG)
3805  abort ();
3806 #else
3807  return 0;
3808 #endif
3809  }
3810 
3811  free_bindings (binding_scope, file, line);
3812  if (binding_scope -> outer)
3813  binding_scope_dereference (&binding_scope -> outer, MDL);
3814  dfree (binding_scope, file, line);
3815  return 1;
3816 }
3817 
3819  struct fundef **ptr;
3820  const char *file;
3821  int line;
3822 {
3823  struct fundef *bp;
3824  struct string_list *sp, *next;
3825 
3826  if ((ptr == NULL) || (*ptr == NULL)) {
3827  log_error ("%s(%d): null pointer", file, line);
3828 #if defined (POINTER_DEBUG)
3829  abort ();
3830 #else
3831  return 0;
3832 #endif
3833  }
3834 
3835  bp = *ptr;
3836  bp -> refcnt--;
3837  rc_register (file, line, ptr, bp, bp -> refcnt, 1, RC_MISC);
3838  if (bp -> refcnt < 0) {
3839  log_error ("%s(%d): negative refcnt!", file, line);
3840 #if defined (DEBUG_RC_HISTORY)
3841  dump_rc_history (bp);
3842 #endif
3843 #if defined (POINTER_DEBUG)
3844  abort ();
3845 #else
3846  return 0;
3847 #endif
3848  }
3849  if (!bp -> refcnt) {
3850  for (sp = bp -> args; sp; sp = next) {
3851  next = sp -> next;
3852  dfree (sp, file, line);
3853  }
3854  if (bp -> statements)
3855  executable_statement_dereference (&bp -> statements,
3856  file, line);
3857  dfree (bp, file, line);
3858  }
3859  *ptr = (struct fundef *)0;
3860  return 1;
3861 }
3862 
3863 #if defined (NOTYET) /* Post 3.0 final. */
3864 int data_subexpression_length (int *rv,
3865  struct expression *expr)
3866 {
3867  int crhs, clhs, llhs, lrhs;
3868  switch (expr -> op) {
3869  case expr_substring:
3870  if (expr -> data.substring.len &&
3871  expr -> data.substring.len -> op == expr_const_int) {
3872  (*rv =
3873  (int)expr -> data.substring.len -> data.const_int);
3874  return 1;
3875  }
3876  return 0;
3877 
3878  case expr_packet:
3879  case expr_suffix:
3880  if (expr -> data.suffix.len &&
3881  expr -> data.suffix.len -> op == expr_const_int) {
3882  (*rv =
3883  (int)expr -> data.suffix.len -> data.const_int);
3884  return 1;
3885  }
3886  return 0;
3887 
3888  case expr_lcase:
3889  return data_subexpression_length(rv, expr->data.lcase);
3890 
3891  case expr_ucase:
3892  return data_subexpression_length(rv, expr->data.ucase);
3893 
3894  case expr_concat:
3895  clhs = data_subexpression_length (&llhs,
3896  expr -> data.concat [0]);
3897  crhs = data_subexpression_length (&lrhs,
3898  expr -> data.concat [1]);
3899  if (crhs == 0 || clhs == 0)
3900  return 0;
3901  *rv = llhs + lrhs;
3902  return 1;
3903  break;
3904 
3905  case expr_hardware:
3906  return 0;
3907 
3908  case expr_const_data:
3909  *rv = expr -> data.const_data.len;
3910  return 2;
3911 
3912  case expr_reverse:
3913  return data_subexpression_length (rv,
3914  expr -> data.reverse.buffer);
3915 
3916  case expr_leased_address:
3917  case expr_lease_time:
3918  *rv = 4;
3919  return 2;
3920 
3921  case expr_pick_first_value:
3922  clhs = data_subexpression_length (&llhs,
3923  expr -> data.concat [0]);
3924  crhs = data_subexpression_length (&lrhs,
3925  expr -> data.concat [1]);
3926  if (crhs == 0 || clhs == 0)
3927  return 0;
3928  if (llhs > lrhs)
3929  *rv = llhs;
3930  else
3931  *rv = lrhs;
3932  return 1;
3933 
3934  case expr_v6relay:
3935  clhs = data_subexpression_length (&llhs,
3936  expr -> data.v6relay.relay);
3937  crhs = data_subexpression_length (&lrhs,
3938  expr -> data.v6relay.roption);
3939  if (crhs == 0 || clhs == 0)
3940  return 0;
3941  *rv = llhs + lrhs;
3942  return 1;
3943  break;
3944 
3945  case expr_binary_to_ascii:
3946  case expr_config_option:
3947  case expr_host_decl_name:
3948  case expr_encapsulate:
3949  case expr_filename:
3950  case expr_sname:
3951  case expr_host_lookup:
3952  case expr_option:
3953  case expr_none:
3954  case expr_match:
3955  case expr_check:
3956  case expr_equal:
3957  case expr_regex_match:
3958  case expr_iregex_match:
3959  case expr_and:
3960  case expr_or:
3961  case expr_not:
3962  case expr_extract_int8:
3963  case expr_extract_int16:
3964  case expr_extract_int32:
3965  case expr_encode_int8:
3966  case expr_encode_int16:
3967  case expr_encode_int32:
3968  case expr_const_int:
3969  case expr_exists:
3970  case expr_known:
3971  case expr_static:
3972  case expr_not_equal:
3973  case expr_null:
3974  case expr_variable_exists:
3976  case expr_arg:
3977  case expr_funcall:
3978  case expr_function:
3979  case expr_add:
3980  case expr_subtract:
3981  case expr_multiply:
3982  case expr_divide:
3983  case expr_remainder:
3984  case expr_binary_and:
3985  case expr_binary_or:
3986  case expr_binary_xor:
3987  case expr_client_state:
3988  case expr_gethostname:
3989  return 0;
3990  }
3991  return 0;
3992 }
3993 
3994 int expr_valid_for_context (struct expression *expr,
3995  enum expression_context context)
3996 {
3997  /* We don't know at parse time what type of value a function may
3998  return, so we can't flag an error on it. */
3999  if (expr -> op == expr_funcall ||
4000  expr -> op == expr_variable_reference)
4001  return 1;
4002 
4003  switch (context) {
4004  case context_any:
4005  return 1;
4006 
4007  case context_boolean:
4008  if (is_boolean_expression (expr))
4009  return 1;
4010  return 0;
4011 
4012  case context_data:
4013  if (is_data_expression (expr))
4014  return 1;
4015  return 0;
4016 
4017  case context_numeric:
4018  if (is_numeric_expression (expr))
4019  return 1;
4020  return 0;
4021 
4023  if (is_numeric_expression (expr) ||
4024  is_data_expression (expr)) {
4025  return 1;
4026  }
4027  return 0;
4028 
4029  case context_function:
4030  if (expr -> op == expr_function)
4031  return 1;
4032  return 0;
4033  }
4034  return 0;
4035 }
4036 #endif /* NOTYET */
4037 
4038 struct binding *create_binding (struct binding_scope **scope, const char *name)
4039 {
4040  struct binding *binding;
4041 
4042  if (!*scope) {
4043  if (!binding_scope_allocate (scope, MDL))
4044  return (struct binding *)0;
4045  }
4046 
4047  binding = find_binding (*scope, name);
4048  if (!binding) {
4049  binding = dmalloc (sizeof *binding, MDL);
4050  if (!binding)
4051  return (struct binding *)0;
4052 
4053  memset (binding, 0, sizeof *binding);
4054  binding -> name = dmalloc (strlen (name) + 1, MDL);
4055  if (!binding -> name) {
4056  dfree (binding, MDL);
4057  return (struct binding *)0;
4058  }
4059  strcpy (binding -> name, name);
4060 
4061  binding -> next = (*scope) -> bindings;
4062  (*scope) -> bindings = binding;
4063  }
4064 
4065  return binding;
4066 }
4067 
4068 
4069 int bind_ds_value (struct binding_scope **scope,
4070  const char *name,
4071  struct data_string *value)
4072 {
4073  struct binding *binding;
4074 
4075  binding = create_binding (scope, name);
4076  if (!binding)
4077  return 0;
4078 
4079  if (binding -> value)
4080  binding_value_dereference (&binding -> value, MDL);
4081 
4082  if (!binding_value_allocate (&binding -> value, MDL))
4083  return 0;
4084 
4085  data_string_copy (&binding -> value -> value.data, value, MDL);
4086  binding -> value -> type = binding_data;
4087 
4088  return 1;
4089 }
4090 
4091 
4093  struct binding_scope *scope,
4094  const char *name)
4095 {
4096  struct binding *binding;
4097 
4098  binding = find_binding (scope, name);
4099  if (!binding ||
4100  !binding -> value ||
4101  binding -> value -> type != binding_data)
4102  return 0;
4103 
4104  if (binding -> value -> value.data.terminated) {
4105  data_string_copy (value, &binding -> value -> value.data, MDL);
4106  } else {
4107  if (buffer_allocate (&value->buffer,
4108  binding->value->value.data.len,
4109  MDL) == 0) {
4110  return 0;
4111  }
4112 
4113  memcpy (value -> buffer -> data,
4114  binding -> value -> value.data.data,
4115  binding -> value -> value.data.len);
4116  value -> data = value -> buffer -> data;
4117  value -> len = binding -> value -> value.data.len;
4118  }
4119 
4120  return 1;
4121 }
4122 
4123 int unset (struct binding_scope *scope, const char *name)
4124 {
4125  struct binding *binding;
4126 
4127  binding = find_binding (scope, name);
4128  if (binding) {
4129  if (binding -> value)
4131  (&binding -> value, MDL);
4132  return 1;
4133  }
4134  return 0;
4135 }
4136 
4166 int concat_dclists (struct data_string* result,
4167  struct data_string* list1,
4168  struct data_string* list2)
4169 {
4170  char uncompbuf[32*NS_MAXCDNAME];
4171  char *uncomp = uncompbuf;
4172  int uncomp_len = 0;
4173  int compbuf_max = 0;
4174  int list_len = 0;
4175  int i;
4176 
4177  /* If not empty, uncompress first list into the uncompressed buffer */
4178  if (list1 && (list1->data) && (list1->len)) {
4179  list_len = MRns_name_uncompress_list(list1->data,
4180  list1->len, uncomp,
4181  sizeof(uncompbuf));
4182  if (list_len < 0) {
4183  log_error ("concat_dclists:"
4184  " error decompressing domain list 1");
4185  return (0);
4186  }
4187 
4188  uncomp_len = list_len;
4189  uncomp += list_len;
4190  }
4191 
4192  /* If not empty, uncompress second list into the uncompressed buffer */
4193  if (list2 && (list2->data) && (list2->len)) {
4194  /* If first list wasn't empty, add a comma */
4195  if (uncomp_len > 0) {
4196  *uncomp++ = ',';
4197  uncomp_len++;
4198  }
4199 
4200  list_len = MRns_name_uncompress_list(list2->data, list2->len,
4201  uncomp, (sizeof(uncompbuf)
4202  - uncomp_len));
4203  if (list_len < 0) {
4204  log_error ("concat_dclists:"
4205  " error decompressing domain list 2");
4206  return (0);
4207  }
4208 
4209  uncomp_len += list_len;
4210  uncomp += list_len;
4211  }
4212 
4213  /* If both lists were empty, return an "empty" result */
4214  if (uncomp_len == 0) {
4215  if (!buffer_allocate (&result->buffer, 1, MDL)) {
4216  log_error ("concat_dclists: empty list allocate fail");
4217  result->len = 0;
4218  return (0);
4219  }
4220 
4221  result->len = 1;
4222  result->data = result->buffer->data;
4223  return (1);
4224  }
4225 
4226  /* Estimate the buffer size needed for decompression. The largest
4227  * decompression would if one where there are no repeated portions,
4228  * (i.e. no compressions). Therefore that size should be the
4229  * decompressed string length + 2 for each comma + a final null. Each
4230  * dot gets replaced with a length byte and is accounted for in string
4231  * length. Mininum length is * uncomp_len + 3. */
4232  compbuf_max = uncomp_len + 3;
4233  uncomp = uncompbuf;
4234  for (i = 0; i < uncomp_len; i++)
4235  if (*uncomp++ == ',')
4236  compbuf_max += 2;
4237 
4238  /* Allocate compression buffer based on estimated max */
4239  if (!buffer_allocate (&result->buffer, compbuf_max, MDL)) {
4240  log_error ("concat_dclists: No memory for result");
4241  result->len = 0;
4242  return (0);
4243  }
4244 
4245  /* Compress the combined list into result */
4246  list_len = MRns_name_compress_list(uncompbuf, uncomp_len,
4247  result->buffer->data, compbuf_max);
4248 
4249  if (list_len <= 0) {
4250  log_error ("concat_dlists: error compressing result");
4251  data_string_forget(result, MDL);
4252  result->len = 0;
4253  return (0);
4254  }
4255 
4256  /* Update result length to actual size */
4257  result->len = list_len;
4258  result->data = result->buffer->data;
4259  return (list_len);
4260 }
4261 
4262 /* vim: set tabstop=8: */
enum expr_op op
Definition: tree.h:200
#define rc_register(file, line, reference, addr, refcnt, d, f)
Definition: alloc.h:88
int executable_statement_allocate(struct executable_statement **ptr, const char *file, int line)
Definition: alloc.c:959
Definition: tree.h:31
#define NS_MAXCDNAME
Definition: nameser.h:75
const char int line
Definition: dhcpd.h:3676
struct binding_scope * global_scope
Definition: tree.c:39
Definition: tree.h:142
int binding_value_dereference(struct binding_value **v, const char *file, int line)
Definition: tree.c:653
Definition: dhcpd.h:550
unsigned len
Definition: tree.h:80
int executable_statement_dereference(struct executable_statement **ptr, const char *file, int line)
Definition: execute.c:623
Definition: tree.h:94
int free_bindings(struct binding_scope *scope, const char *file, int line)
Definition: tree.c:3759
struct expression * val
Definition: tree.h:270
const char * piaddr(const struct iaddr addr)
Definition: inet.c:581
u_int8_t hlen
Definition: dhcpd.h:483
int make_const_option_cache(struct option_cache **oc, struct buffer **buffer, u_int8_t *data, unsigned len, struct option *option, const char *file, int line)
Definition: tree.c:150
struct expression::expr_union::@25 arg
struct expression * equal[2]
Definition: tree.h:207
struct binding_scope * outer
Definition: tree.h:126
struct data_string encapsulate
Definition: tree.h:236
void * dmalloc(unsigned, const char *, int)
Definition: alloc.c:56
struct expression::expr_union::@21 pick_first_value
int expression_allocate(struct expression **cptr, const char *file, int line)
Definition: alloc.c:427
int data_string_sprintfa(struct data_string *ds, const char *fmt,...)
Definition: tree.c:57
int execute_statements(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct executable_statement *statements, struct on_star *on_star)
Definition: execute.c:35
int refcnt
Definition: tree.h:125
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
Definition: inet.c:65
int binding_value_reference(struct binding_value **ptr, struct binding_value *src, const char *file, int line)
Definition: alloc.c:521
#define MDL
Definition: omapip.h:568
unsigned char iabuf[16]
Definition: inet.h:33
#define print_hex_1(len, data, limit)
Definition: dhcpd.h:2533
int refcnt
Definition: tree.h:199
u_int8_t hlen
Definition: dhcp.h:51
struct executable_statement * statements
Definition: tree.h:97
enum expression_context expression_context(struct expression *expr)
Definition: tree.c:3195
unsigned long const_int
Definition: tree.h:232
struct expression * lcase
Definition: tree.h:221
struct data_string data
Definition: tree.h:110
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
struct binding * next
Definition: tree.h:119
struct expression * arglist
Definition: tree.h:275
struct expression::expr_union::@16 substring
int is_numeric_expression(struct expression *expr)
Definition: tree.c:3067
int option_reference(struct option **dest, struct option *src, const char *file, int line)
Definition: tables.c:935
int find_bound_string(struct data_string *value, struct binding_scope *scope, const char *name)
Definition: tree.c:4092
struct universe dhcp_universe
void data_string_forget(struct data_string *data, const char *file, int line)
Definition: alloc.c:1340
struct expression * concat[2]
Definition: tree.h:233
Definition: tree.h:141
int evaluate_numeric_expression(unsigned long *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct expression *expr)
Definition: tree.c:2218
enum binding_value::@15 type
int log_error(const char *,...) __attribute__((__format__(__printf__
int is_compound_expression(struct expression *expr)
Definition: tree.c:3086
struct expression * offset
Definition: tree.h:204
int binding_scope_dereference(struct binding_scope **ptr, const char *file, int line)
Definition: tree.c:3775
enum expression_context op_context(enum expr_op op)
Definition: tree.c:3206
Definition: tree.h:177
int evaluate_expression(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct expression *expr, const char *file, int line)
Definition: tree.c:501
struct fundef * func
Definition: tree.h:277
unsigned len
Definition: inet.h:32
struct _pair * pair
int option_space_encapsulate(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct data_string *name)
Definition: options.c:3006
struct expression * not
Definition: tree.h:210
int terminated
Definition: tree.h:81
int make_substring(struct expression **new, struct expression *expr, struct expression *offset, struct expression *length)
Definition: tree.c:314
struct option_state * options
Definition: dhcpd.h:443
Definition: tree.h:302
struct expression::expr_union::@17 suffix
int is_boolean_expression(struct expression *expr)
Definition: tree.c:3020
void expression_dereference(struct expression **eptr, const char *file, int line)
Definition: tree.c:2802
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int evaluate_boolean_expression_result(int *ignorep, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct expression *expr)
Definition: tree.c:2769
int binding_value_allocate(struct binding_value **cptr, const char *file, int line)
Definition: alloc.c:501
int buffer_reference(struct buffer **ptr, struct buffer *bp, const char *file, int line)
Definition: alloc.c:699
int option_cache_allocate(struct option_cache **cptr, const char *file, int line)
Definition: alloc.c:631
struct fundef * fundef
Definition: tree.h:113
struct dhcp_packet * raw
Definition: dhcpd.h:406
union expression::expr_union data
struct hardware hardware_addr
Definition: dhcpd.h:579
int unset(struct binding_scope *scope, const char *name)
Definition: tree.c:4123
struct expression * encode_int
Definition: tree.h:231
int make_host_lookup(struct expression **expr, const char *name)
Definition: tree.c:189
u_int8_t htype
Definition: dhcp.h:50
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
Definition: tree.c:2688
Definition: tree.h:346
unsigned char chaddr[16]
Definition: dhcp.h:60
char * name
Definition: tree.h:120
#define MAX_V6RELAY_HOPS
Definition: dhcp6.h:197
struct expression::expr_union::@20 reverse
struct expression * width
Definition: tree.h:239
struct expression * roption
Definition: tree.h:280
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
Definition: alloc.c:680
int binding_scope_allocate(struct binding_scope **ptr, const char *file, int line)
Definition: alloc.c:1195
void putULong(unsigned char *, u_int32_t)
Definition: convert.c:70
int binary_to_ascii(unsigned char *, const unsigned char *, unsigned int, unsigned int)
Definition: convert.c:150
Definition: dhcpd.h:405
struct expression * next
Definition: tree.h:271
struct expression * expr
Definition: tree.h:203
#define cur_time
Definition: dhcpd.h:2041
int make_concat(struct expression **expr, struct expression *left, struct expression *right)
Definition: tree.c:269
int MRns_name_compress_list(const char *buf, int buflen, unsigned char *compbuf, size_t compbuf_size)
Creates a compressed list from a string of comma-separated domain-names.
Definition: ns_name.c:747
u_int32_t getUShort(const unsigned char *)
void dfree(void *, const char *, int)
Definition: alloc.c:131
struct expression * buffer
Definition: tree.h:241
int concat_dclists(struct data_string *result, struct data_string *list1, struct data_string *list2)
Adds two Dc-formatted lists into a single Dc-formatted list.
Definition: tree.c:4166
int make_let(struct executable_statement **result, const char *name)
Definition: tree.c:378
struct hardware hw_address
Definition: dhcpd.h:1329
struct expression * base
Definition: tree.h:238
#define print_hex_3(len, data, limit)
Definition: dhcpd.h:2535
int int log_info(const char *,...) __attribute__((__format__(__printf__
struct expression * relay
Definition: tree.h:279
int fundef_dereference(struct fundef **ptr, const char *file, int line)
Definition: tree.c:3818
struct expression::expr_union::@19 b2a
int evaluate_data_expression(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct expression *expr, const char *file, int line)
Definition: tree.c:1115
int option_cache(struct option_cache **oc, struct data_string *dp, struct expression *expr, struct option *option, const char *file, int line)
Definition: tree.c:364
struct expression * extract_int
Definition: tree.h:230
Definition: tree.h:288
struct option * option
Definition: tree.h:223
u_int32_t getULong(const unsigned char *)
Definition: tree.h:143
int get_option(struct data_string *result, struct universe *universe, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct option_state *options, struct binding_scope **scope, unsigned code, const char *file, int line)
Definition: options.c:2168
int check_collection(struct packet *packet, struct lease *lease, struct collection *collection)
Definition: dhclient.c:1262
union binding_value::value value
int MRns_name_uncompress_list(const unsigned char *buf, int buflen, char *dst_buf, size_t dst_size)
Creates a string of comma-separated domain-names from a compressed list.
Definition: ns_name.c:678
struct data_string const_data
Definition: tree.h:229
struct binding * bindings
Definition: tree.h:127
expr_op
Definition: tree.h:132
void indent(int)
int binding_scope_reference(struct binding_scope **ptr, struct binding_scope *bp, const char *file, int line)
Definition: alloc.c:1228
struct expression * len
Definition: tree.h:205
int evaluate_boolean_option_cache(int *ignorep, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
Definition: tree.c:2722
#define print_hex_2(len, data, limit)
Definition: dhcpd.h:2534
int make_const_data(struct expression **expr, const unsigned char *data, unsigned len, int terminated, int allocate, const char *file, int line)
Definition: tree.c:220
int enter_dns_host(struct dns_host_entry **dh, const char *name)
Definition: tree.c:205
struct data_string data
Definition: tree.h:291
struct string_list * next
Definition: dhcpd.h:348
const char int
Definition: omapip.h:443
int is_data_expression(struct expression *expr)
Definition: tree.c:3037
struct binding_value * value
Definition: tree.h:121
int make_limit(struct expression **new, struct expression *expr, int limit)
Definition: tree.c:332
struct binding * create_binding(struct binding_scope **scope, const char *name)
Definition: tree.c:4038
struct expression * ucase
Definition: tree.h:222
void free_expression(struct expression *expr, const char *file, int line)
Definition: alloc.c:475
unsigned char data[1]
Definition: tree.h:63
Definition: tree.h:61
struct collection * check
Definition: tree.h:216
int make_encapsulation(struct expression **expr, struct data_string *name)
Definition: tree.c:299
int expression_reference(struct expression **ptr, struct expression *src, const char *file, int line)
Definition: alloc.c:447
int refcnt
Definition: tree.h:101
#define STATIC_LEASE
Definition: dhcpd.h:582
int dns_host_entry_allocate(struct dns_host_entry **ptr, const char *hostname, const char *file, int line)
Definition: alloc.c:769
int converted_length(const unsigned char *, unsigned int, unsigned int)
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
Definition: dhcpd.h:484
expression_context
Definition: tree.h:84
int evaluate_boolean_expression(int *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct expression *expr)
Definition: tree.c:695
int op_precedence(enum expr_op op1, enum expr_op op2)
Definition: tree.c:3189
struct data_string data
Definition: dhcpd.h:390
Definition: tree.h:118
struct expression * cdr
Definition: tree.h:249
int dns_host_entry_dereference(struct dns_host_entry **ptr, const char *file, int line)
Definition: alloc.c:814
int make_const_int(struct expression **expr, unsigned long val)
Definition: tree.c:255
struct expression::expr_union::@27 v6relay
struct dns_host_entry * host_lookup
Definition: tree.h:234
pair cons(caddr_t car, pair cdr)
Definition: tree.c:138
int write_expression(FILE *file, struct expression *expr, int col, int indent, int firstp)
Definition: tree.c:3287
struct binding * find_binding(struct binding_scope *scope, const char *name)
Definition: tree.c:3744
const char * file
Definition: dhcpd.h:3676
void putUShort(unsigned char *, u_int32_t)
Definition: convert.c:86
struct expression * car
Definition: tree.h:248
unsigned long intval
Definition: tree.h:111
const unsigned char * data
Definition: tree.h:79
struct interface_info * interface
Definition: dhcpd.h:1244
int bind_ds_value(struct binding_scope **scope, const char *name, struct data_string *value)
Definition: tree.c:4069
TIME ends
Definition: dhcpd.h:560
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
Definition: alloc.c:1324
void free_binding_value(struct binding_value *bv, const char *file, int line)
Definition: alloc.c:549
struct expression::expr_union::@26 funcall
int data_subexpression_length(int *, struct expression *)
#define DS_SPRINTF_SIZE
Definition: tree.c:43
#define RC_MISC
Definition: alloc.h:56
int expr_valid_for_context(struct expression *, enum expression_context)
struct expression::expr_union::@18 packet
struct buffer * buffer
Definition: tree.h:78
struct expression * separator
Definition: tree.h:240
int buffer_dereference(struct buffer **ptr, const char *file, int line)
Definition: alloc.c:727
struct packet * dhcpv6_container_packet
Definition: dhcpd.h:422
Definition: tree.h:180