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