1 /* $NetBSD: print.c,v 1.3 2022/04/03 01:10:59 christos Exp $ */
2
3 /*
4 * Copyright (C) 2017-2022 Internet Systems Consortium, Inc. ("ISC")
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * Internet Systems Consortium, Inc.
19 * PO Box 360
20 * Newmarket, NH 03857 USA
21 * <info@isc.org>
22 * https://www.isc.org/
23 *
24 */
25
26 #include <sys/cdefs.h>
27 __RCSID("$NetBSD: print.c,v 1.3 2022/04/03 01:10:59 christos Exp $");
28
29 #include "keama.h"
30
31 #include <sys/errno.h>
32 #include <sys/types.h>
33 #include <arpa/inet.h>
34 #include <ctype.h>
35 #include <netdb.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <unistd.h>
40
41 static void debug(const char* fmt, ...);
42
43 const char *
print_expression(struct element * expr,isc_boolean_t * lose)44 print_expression(struct element *expr, isc_boolean_t *lose)
45 {
46 if (expr->type == ELEMENT_BOOLEAN)
47 return print_boolean_expression(expr, lose);
48 if (expr->type == ELEMENT_INTEGER)
49 return print_numeric_expression(expr, lose);
50 if (expr->type == ELEMENT_STRING)
51 return print_data_expression(expr, lose);
52
53 if (is_boolean_expression(expr))
54 return print_boolean_expression(expr, lose);
55 if (is_numeric_expression(expr))
56 return print_numeric_expression(expr, lose);
57 if (is_data_expression(expr))
58 return print_data_expression(expr, lose);
59 *lose = ISC_TRUE;
60 return "???";
61 }
62
63 const char *
print_boolean_expression(struct element * expr,isc_boolean_t * lose)64 print_boolean_expression(struct element *expr, isc_boolean_t *lose)
65 {
66 struct string *result;
67
68 if (expr->type == ELEMENT_BOOLEAN) {
69 if (boolValue(expr))
70 return "true";
71 else
72 return "false";
73 }
74
75 /*
76 * From is_boolean_expression
77 */
78 if (expr->type != ELEMENT_MAP) {
79 *lose = ISC_TRUE;
80 return "???";
81 }
82 result = allocString();
83
84 /* check */
85 if (mapContains(expr, "check")) {
86 struct element *name;
87
88 appendString(result, "check ");
89 name = mapGet(expr, "check");
90 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
91 *lose = ISC_TRUE;
92 appendString(result, "???");
93 } else
94 concatString(result, stringValue(name));
95 return result->content;
96 }
97
98 /* exists */
99 if (mapContains(expr, "exists")) {
100 struct element *arg;
101 struct element *universe;
102 struct element *name;
103
104 appendString(result, "exists ");
105 arg = mapGet(expr, "exists");
106 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
107 *lose = ISC_TRUE;
108 appendString(result, "???");
109 return result->content;
110 }
111 universe = mapGet(arg, "universe");
112 if ((universe == NULL) || (universe->type != ELEMENT_STRING)) {
113 *lose = ISC_TRUE;
114 appendString(result, "???");
115 return result->content;
116 }
117 concatString(result, stringValue(universe));
118 appendString(result, ".");
119 name = mapGet(arg, "name");
120 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
121 *lose = ISC_TRUE;
122 appendString(result, "???");
123 return result->content;
124 }
125 concatString(result, stringValue(name));
126 return result->content;
127 }
128
129 /* variable-exists */
130 if (mapContains(expr, "variable-exists")) {
131 struct element *name;
132
133 appendString(result, "variable-exists ");
134 name = mapGet(expr, "variable-exists");
135 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
136 *lose = ISC_TRUE;
137 appendString(result, "???");
138 } else
139 concatString(result, stringValue(name));
140 return result->content;
141 }
142
143 /* equal */
144 if (mapContains(expr, "equal")) {
145 struct element *arg;
146 struct element *left;
147 struct element *right;
148 isc_boolean_t add_parenthesis;
149
150 appendString(result, "equal ");
151 arg = mapGet(expr, "equal");
152 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
153 *lose = ISC_TRUE;
154 appendString(result, "???");
155 return result->content;
156 }
157 left = mapGet(arg, "left");
158 if (left == NULL) {
159 *lose = ISC_TRUE;
160 appendString(result, "???");
161 return result->content;
162 }
163 result = allocString();
164 add_parenthesis = ISC_TF(expr_precedence(expr_equal,
165 left) < 0);
166 if (add_parenthesis)
167 appendString(result, "(");
168 appendString(result, print_expression(left, lose));
169 if (add_parenthesis)
170 appendString(result, ")");
171 appendString(result, " = ");
172 right = mapGet(arg, "right");
173 if (right == NULL) {
174 *lose = ISC_TRUE;
175 appendString(result, "???");
176 return result->content;
177 }
178 add_parenthesis = ISC_TF(expr_precedence(expr_equal,
179 right) < 0);
180 if (add_parenthesis)
181 appendString(result, "(");
182 appendString(result, print_expression(right, lose));
183 if (add_parenthesis)
184 appendString(result, ")");
185 return result->content;
186 }
187
188 /* not-equal */
189 if (mapContains(expr, "not-equal")) {
190 struct element *arg;
191 struct element *left;
192 struct element *right;
193 isc_boolean_t add_parenthesis;
194
195 appendString(result, "not-equal ");
196 arg = mapGet(expr, "not-equal");
197 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
198 *lose = ISC_TRUE;
199 appendString(result, "???");
200 return result->content;
201 }
202 left = mapGet(arg, "left");
203 if (left == NULL) {
204 *lose = ISC_TRUE;
205 appendString(result, "???");
206 return result->content;
207 }
208 result = allocString();
209 add_parenthesis = ISC_TF(expr_precedence(expr_not_equal,
210 left) < 0);
211 if (add_parenthesis)
212 appendString(result, "(");
213 appendString(result, print_expression(left, lose));
214 if (add_parenthesis)
215 appendString(result, ")");
216 appendString(result, " != ");
217 right = mapGet(arg, "right");
218 if (right == NULL) {
219 *lose = ISC_TRUE;
220 appendString(result, "???");
221 return result->content;
222 }
223 add_parenthesis = ISC_TF(expr_precedence(expr_not_equal,
224 right) < 0);
225 if (add_parenthesis)
226 appendString(result, "(");
227 appendString(result, print_expression(right, lose));
228 if (add_parenthesis)
229 appendString(result, ")");
230 return result->content;
231 }
232
233 /* regex-match */
234 if (mapContains(expr, "regex-match")) {
235 struct element *arg;
236 struct element *left;
237 struct element *right;
238 isc_boolean_t add_parenthesis;
239
240 appendString(result, "regex-match ");
241 arg = mapGet(expr, "regex-match");
242 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
243 *lose = ISC_TRUE;
244 appendString(result, "???");
245 return result->content;
246 }
247 left = mapGet(arg, "left");
248 if (left == NULL) {
249 *lose = ISC_TRUE;
250 appendString(result, "???");
251 return result->content;
252 }
253 result = allocString();
254 add_parenthesis = ISC_TF(expr_precedence(expr_regex_match,
255 left) < 0);
256 if (add_parenthesis)
257 appendString(result, "(");
258 appendString(result, print_expression(left, lose));
259 if (add_parenthesis)
260 appendString(result, ")");
261 appendString(result, " ~= ");
262 right = mapGet(arg, "right");
263 if (right == NULL) {
264 *lose = ISC_TRUE;
265 appendString(result, "???");
266 return result->content;
267 }
268 appendString(result, print_expression(right, lose));
269 return result->content;
270 }
271
272 /* iregex-match */
273 if (mapContains(expr, "iregex-match")) {
274 struct element *arg;
275 struct element *left;
276 struct element *right;
277 isc_boolean_t add_parenthesis;
278
279 appendString(result, "iregex-match ");
280 arg = mapGet(expr, "iregex-match");
281 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
282 *lose = ISC_TRUE;
283 appendString(result, "???");
284 return result->content;
285 }
286 left = mapGet(arg, "left");
287 if (left == NULL) {
288 *lose = ISC_TRUE;
289 appendString(result, "???");
290 return result->content;
291 }
292 result = allocString();
293 add_parenthesis = ISC_TF(expr_precedence(expr_iregex_match,
294 left) < 0);
295 if (add_parenthesis)
296 appendString(result, "(");
297 appendString(result, print_expression(left, lose));
298 if (add_parenthesis)
299 appendString(result, ")");
300 appendString(result, " ~~ ");
301 right = mapGet(arg, "right");
302 if (right == NULL) {
303 *lose = ISC_TRUE;
304 appendString(result, "???");
305 return result->content;
306 }
307 appendString(result, print_expression(right, lose));
308 return result->content;
309 }
310
311 /* and */
312 if (mapContains(expr, "and")) {
313 struct element *arg;
314 struct element *left;
315 struct element *right;
316 isc_boolean_t add_parenthesis;
317
318 appendString(result, "and ");
319 arg = mapGet(expr, "and");
320 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
321 *lose = ISC_TRUE;
322 appendString(result, "???");
323 return result->content;
324 }
325 left = mapGet(arg, "left");
326 if (left == NULL) {
327 *lose = ISC_TRUE;
328 appendString(result, "???");
329 return result->content;
330 }
331 result = allocString();
332 add_parenthesis = ISC_TF(expr_precedence(expr_and,
333 left) < 0);
334 if (add_parenthesis)
335 appendString(result, "(");
336 appendString(result, print_expression(left, lose));
337 if (add_parenthesis)
338 appendString(result, ")");
339 appendString(result, " and ");
340 right = mapGet(arg, "right");
341 if (right == NULL) {
342 *lose = ISC_TRUE;
343 appendString(result, "???");
344 return result->content;
345 }
346 add_parenthesis = ISC_TF(expr_precedence(expr_and,
347 right) < 0);
348 if (add_parenthesis)
349 appendString(result, "(");
350 appendString(result, print_expression(right, lose));
351 if (add_parenthesis)
352 appendString(result, ")");
353 return result->content;
354 }
355
356 /* or */
357 if (mapContains(expr, "or")) {
358 struct element *arg;
359 struct element *left;
360 struct element *right;
361 isc_boolean_t add_parenthesis;
362
363 appendString(result, "or ");
364 arg = mapGet(expr, "or");
365 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
366 *lose = ISC_TRUE;
367 appendString(result, "???");
368 return result->content;
369 }
370 left = mapGet(arg, "left");
371 if (left == NULL) {
372 *lose = ISC_TRUE;
373 appendString(result, "???");
374 return result->content;
375 }
376 result = allocString();
377 add_parenthesis = ISC_TF(expr_precedence(expr_or,
378 left) < 0);
379 if (add_parenthesis)
380 appendString(result, "(");
381 appendString(result, print_expression(left, lose));
382 if (add_parenthesis)
383 appendString(result, ")");
384 appendString(result, " or ");
385 right = mapGet(arg, "right");
386 if (right == NULL) {
387 *lose = ISC_TRUE;
388 appendString(result, "???");
389 return result->content;
390 }
391 add_parenthesis = ISC_TF(expr_precedence(expr_or,
392 right) < 0);
393 if (add_parenthesis)
394 appendString(result, "(");
395 appendString(result, print_expression(right, lose));
396 if (add_parenthesis)
397 appendString(result, ")");
398 return result->content;
399 }
400
401 /* not */
402 if (mapContains(expr, "not")) {
403 struct element *arg;
404 isc_boolean_t add_parenthesis;
405
406 appendString(result, "not ");
407 arg = mapGet(expr, "not");
408 if (arg == NULL) {
409 *lose = ISC_TRUE;
410 appendString(result, "???");
411 return result->content;
412 }
413 add_parenthesis = ISC_TF(expr_precedence(expr_not,
414 arg) < 0);
415 if (add_parenthesis)
416 appendString(result, "(");
417 appendString(result, print_expression(arg, lose));
418 if (add_parenthesis)
419 appendString(result, ")");
420 return result->content;
421 }
422
423 /* known */
424 if (mapContains(expr, "known")) {
425 return "known";
426 }
427
428 /* static */
429 if (mapContains(expr, "static")) {
430 return "static";
431 }
432
433 /* variable-reference */
434 if (mapContains(expr, "variable-reference")) {
435 struct element *name;
436
437 appendString(result, "variable-reference ");
438 name = mapGet(expr, "variable-reference");
439 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
440 *lose = ISC_TRUE;
441 appendString(result, "???");
442 return result->content;
443 }
444 return stringValue(name)->content;
445 }
446
447 /* funcall */
448 if (mapContains(expr, "funcall")) {
449 struct element *arg;
450 struct element *name;
451 struct element *args;
452 size_t i;
453
454 appendString(result, "funcall ");
455 arg = mapGet(expr, "funcall");
456 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
457 *lose = ISC_TRUE;
458 appendString(result, "???");
459 return result->content;
460 }
461 name = mapGet(arg, "name");
462 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
463 *lose = ISC_TRUE;
464 appendString(result, "???");
465 return result->content;
466 }
467 result = allocString();
468 concatString(result, stringValue(name));
469 appendString(result, "(");
470 args = mapGet(arg, "arguments");
471 if ((args == NULL) || (args->type != ELEMENT_LIST)) {
472 *lose = ISC_TRUE;
473 appendString(result, "???" ")");
474 return result->content;
475 }
476 for (i = 0; i < listSize(args); i++) {
477 struct element *item;
478
479 if (i != 0)
480 appendString(result, ", ");
481 item = listGet(args, i);
482 if (item == NULL) {
483 debug("funcall null argument %u",
484 (unsigned)i);
485 *lose = ISC_TRUE;
486 appendString(result, "???");
487 continue;
488 }
489 appendString(result, print_expression(item, lose));
490 }
491 appendString(result, ")");
492 return result->content;
493 }
494
495 *lose = ISC_TRUE;
496 appendString(result, "???");
497 return result->content;
498 }
499
500 const char *
print_data_expression(struct element * expr,isc_boolean_t * lose)501 print_data_expression(struct element *expr, isc_boolean_t *lose)
502 {
503 struct string *result;
504
505 if (expr->type == ELEMENT_STRING)
506 return quote(stringValue(expr))->content;
507
508 /*
509 * From is_data_expression
510 */
511 if (expr->type != ELEMENT_MAP) {
512 *lose = ISC_TRUE;
513 return "???";
514 }
515 result = allocString();
516
517 /* substring */
518 if (mapContains(expr, "substring")) {
519 struct element *arg;
520 struct element *string;
521 struct element *offset;
522 struct element *length;
523
524 appendString(result, "substring(");
525 arg = mapGet(expr, "substring");
526 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
527 *lose = ISC_TRUE;
528 appendString(result, "???" ")");
529 return result->content;
530 }
531 string = mapGet(arg, "expression");
532 if (string == NULL) {
533 *lose = ISC_TRUE;
534 appendString(result, "???" ")");
535 return result->content;
536 }
537 appendString(result, print_data_expression(string, lose));
538 appendString(result, ", ");
539 offset = mapGet(arg, "offset");
540 if (offset == NULL) {
541 *lose = ISC_TRUE;
542 appendString(result, "???" ")");
543 return result->content;
544 }
545 appendString(result, print_numeric_expression(offset, lose));
546 appendString(result, ", ");
547 length = mapGet(arg, "length");
548 if (length == NULL) {
549 *lose = ISC_TRUE;
550 appendString(result, "???" ")");
551 return result->content;
552 }
553 appendString(result, print_numeric_expression(length, lose));
554 appendString(result, ")");
555 return result->content;
556 }
557
558 /* suffix */
559 if (mapContains(expr, "suffix")) {
560 struct element *arg;
561 struct element *string;
562 struct element *length;
563
564 appendString(result, "suffix(");
565 arg = mapGet(expr, "suffix");
566 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
567 *lose = ISC_TRUE;
568 appendString(result, "???" ")");
569 return result->content;
570 }
571 string = mapGet(arg, "expression");
572 if (string == NULL) {
573 *lose = ISC_TRUE;
574 appendString(result, "???" ")");
575 return result->content;
576 }
577 appendString(result, print_data_expression(string, lose));
578 appendString(result, ", ");
579 length = mapGet(arg, "length");
580 if (length == NULL) {
581 *lose = ISC_TRUE;
582 appendString(result, "???" ")");
583 return result->content;
584 }
585 appendString(result, print_numeric_expression(length, lose));
586 appendString(result, ")");
587 return result->content;
588 }
589
590 /* lowercase */
591 if (mapContains(expr, "lowercase")) {
592 struct element *arg;
593
594 appendString(result, "lowercase(");
595 arg = mapGet(expr, "lowercase");
596 if (arg == NULL) {
597 *lose = ISC_TRUE;
598 appendString(result, "???" ")");
599 return result->content;
600 }
601 appendString(result, print_data_expression(arg, lose));
602 appendString(result, ")");
603 return result->content;
604 }
605
606 /* uppercase */
607 if (mapContains(expr, "uppercase")) {
608 struct element *arg;
609
610 appendString(result, "uppercase(");
611 arg = mapGet(expr, "uppercase");
612 if (arg == NULL) {
613 *lose = ISC_TRUE;
614 appendString(result, "???" ")");
615 return result->content;
616 }
617 appendString(result, print_data_expression(arg, lose));
618 appendString(result, ")");
619 return result->content;
620 }
621
622 /* option */
623 if (mapContains(expr, "option")) {
624 struct element *arg;
625 struct element *universe;
626 struct element *name;
627
628 appendString(result, "option ");
629 arg = mapGet(expr, "option");
630 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
631 *lose = ISC_TRUE;
632 appendString(result, "???");
633 return result->content;
634 }
635 universe = mapGet(arg, "universe");
636 if ((universe == NULL) || (universe->type != ELEMENT_STRING)) {
637 *lose = ISC_TRUE;
638 appendString(result, "???");
639 return result->content;
640 }
641 concatString(result, stringValue(universe));
642 appendString(result, ".");
643 name = mapGet(arg, "name");
644 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
645 *lose = ISC_TRUE;
646 appendString(result, "???");
647 return result->content;
648 }
649 concatString(result, stringValue(name));
650 return result->content;
651 }
652
653 /* hardware */
654 if (mapContains(expr, "hardware"))
655 return "hardware";
656
657 /* hw-type */
658 if (mapContains(expr, "hw-type"))
659 return "hw-type";
660
661 /* hw-address */
662 if (mapContains(expr, "hw-address"))
663 return "hw-address";
664
665 /* const-data */
666 if (mapContains(expr, "const-data")) {
667 struct element *arg;
668
669 arg = mapGet(expr, "const-data");
670 if ((arg == NULL) || (arg->type != ELEMENT_STRING)) {
671 *lose = ISC_TRUE;
672 appendString(result, "???");
673 return result->content;
674 }
675 concatString(result, stringValue(arg));
676 return result->content;
677 }
678
679 /* packet */
680 if (mapContains(expr, "packet")) {
681 struct element *arg;
682 struct element *offset;
683 struct element *length;
684
685 appendString(result, "packet(");
686 arg = mapGet(expr, "packet");
687 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
688 *lose = ISC_TRUE;
689 appendString(result, "???" ")");
690 return result->content;
691 }
692 offset = mapGet(arg, "offset");
693 if (offset == NULL) {
694 *lose = ISC_TRUE;
695 appendString(result, "???" ")");
696 return result->content;
697 }
698 appendString(result, print_numeric_expression(offset, lose));
699 appendString(result, ", ");
700 length = mapGet(arg, "length");
701 if (length == NULL) {
702 *lose = ISC_TRUE;
703 appendString(result, "???" ")");
704 return result->content;
705 }
706 appendString(result, print_numeric_expression(length, lose));
707 appendString(result, ")");
708 return result->content;
709 }
710
711 /* concat */
712 if (mapContains(expr, "concat")) {
713 struct element *arg;
714 struct element *left;
715 struct element *right;
716
717 appendString(result, "concat(");
718 arg = mapGet(expr, "concat");
719 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
720 *lose = ISC_TRUE;
721 appendString(result, "???" ")");
722 return result->content;
723 }
724 left = mapGet(arg, "left");
725 if (left == NULL) {
726 *lose = ISC_TRUE;
727 appendString(result, "???" ")");
728 return result->content;
729 }
730 appendString(result, print_data_expression(left, lose));
731 appendString(result, ", ");
732 right = mapGet(arg, "right");
733 if (right == NULL) {
734 *lose = ISC_TRUE;
735 appendString(result, "???" ")");
736 return result->content;
737 }
738 appendString(result, print_data_expression(right, lose));
739 appendString(result, ")");
740 return result->content;
741 }
742
743 /* encapsulate */
744 if (mapContains(expr, "encapsulate")) {
745 struct element *arg;
746
747 appendString(result, "encapsulate ");
748 arg = mapGet(expr, "encapsulate");
749 if (arg == NULL) {
750 *lose = ISC_TRUE;
751 appendString(result, "???");
752 return result->content;
753 }
754 appendString(result, print_data_expression(arg, lose));
755 return result->content;
756 }
757
758 /* encode-int8 */
759 if (mapContains(expr, "encode-int8")) {
760 struct element *arg;
761
762 appendString(result, "encode-int(");
763 arg = mapGet(expr, "encode-int8");
764 if (arg == NULL) {
765 *lose = ISC_TRUE;
766 appendString(result, "???, 8)");
767 return result->content;
768 }
769 appendString(result, print_numeric_expression(arg, lose));
770 appendString(result, ", 8)");
771 return result->content;
772 }
773
774 /* encode-int16 */
775 if (mapContains(expr, "encode-int16")) {
776 struct element *arg;
777
778 appendString(result, "encode-int(");
779 arg = mapGet(expr, "encode-int16");
780 if (arg == NULL) {
781 *lose = ISC_TRUE;
782 appendString(result, "???, 16)");
783 return result->content;
784 }
785 appendString(result, print_numeric_expression(arg, lose));
786 appendString(result, ", 16)");
787 return result->content;
788 }
789
790 /* encode-int32 */
791 if (mapContains(expr, "encode-int32")) {
792 struct element *arg;
793
794 appendString(result, "encode-int(");
795 arg = mapGet(expr, "encode-int32");
796 if (arg == NULL) {
797 *lose = ISC_TRUE;
798 appendString(result, "???, 32)");
799 return result->content;
800 }
801 appendString(result, print_numeric_expression(arg, lose));
802 appendString(result, ", 32)");
803 return result->content;
804 }
805
806 /* gethostbyname */
807 if (mapContains(expr, "gethostbyname")) {
808 struct element *arg;
809
810 appendString(result, "gethostbyname(");
811 arg = mapGet(expr, "gethostbyname");
812 if (arg == NULL) {
813 *lose = ISC_TRUE;
814 appendString(result, "???");
815 return result->content;
816 }
817 appendString(result, print_data_expression(arg, lose));
818 appendString(result, ")");
819 return result->content;
820 }
821
822 /* binary-to-ascii */
823 if (mapContains(expr, "binary-to-ascii")) {
824 struct element *arg;
825 struct element *base;
826 struct element *width;
827 struct element *separator;
828 struct element *buffer;
829
830 appendString(result, "binary-to-ascii(");
831 arg = mapGet(expr, "binary-to-ascii");
832 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
833 *lose = ISC_TRUE;
834 appendString(result, "???" ")");
835 return result->content;
836 }
837 base = mapGet(arg, "base");
838 if (base == NULL) {
839 *lose = ISC_TRUE;
840 appendString(result, "???" ")");
841 return result->content;
842 }
843 appendString(result, print_numeric_expression(base, lose));
844 appendString(result, ", ");
845 width = mapGet(arg, "width");
846 if (width == NULL) {
847 *lose = ISC_TRUE;
848 appendString(result, "???" ")");
849 return result->content;
850 }
851 appendString(result, print_numeric_expression(width, lose));
852 appendString(result, ", ");
853 separator = mapGet(arg, "separator");
854 if (separator == NULL) {
855 *lose = ISC_TRUE;
856 appendString(result, "???" ")");
857 return result->content;
858 }
859 appendString(result, print_data_expression(separator, lose));
860 appendString(result, ", ");
861 buffer = mapGet(arg, "buffer");
862 if (buffer == NULL) {
863 *lose = ISC_TRUE;
864 appendString(result, "???" ")");
865 return result->content;
866 }
867 appendString(result, print_data_expression(buffer, lose));
868 appendString(result, ")");
869 return result->content;
870 }
871
872 /* filename */
873 if (mapContains(expr, "filename"))
874 return "filename";
875
876 /* server-name */
877 if (mapContains(expr, "server-name"))
878 return "server-name";
879
880 /* reverse */
881 if (mapContains(expr, "reverse")) {
882 struct element *arg;
883 struct element *width;
884 struct element *buffer;
885
886 appendString(result, "reverse(");
887 arg = mapGet(expr, "reverse");
888 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
889 *lose = ISC_TRUE;
890 appendString(result, "???" ")");
891 return result->content;
892 }
893 width = mapGet(arg, "width");
894 if (width == NULL) {
895 *lose = ISC_TRUE;
896 appendString(result, "???" ")");
897 return result->content;
898 }
899 appendString(result, print_numeric_expression(width, lose));
900 appendString(result, ", ");
901 buffer = mapGet(arg, "buffer");
902 if (buffer == NULL) {
903 *lose = ISC_TRUE;
904 appendString(result, "???" ")");
905 return result->content;
906 }
907 appendString(result, print_data_expression(buffer, lose));
908 appendString(result, ")");
909 return result->content;
910 }
911
912 /* pick-first-value */
913 if (mapContains(expr, "pick-first-value")) {
914 struct element *arg;
915 size_t i;
916
917 appendString(result, "pick-first-value(");
918 arg = mapGet(expr, "pick-first-value");
919 if ((arg == NULL) || (arg->type != ELEMENT_LIST)) {
920 *lose = ISC_TRUE;
921 appendString(result, "???" ")");
922 return result->content;
923 }
924 for (i = 0; i < listSize(arg); i++) {
925 struct element *item;
926
927 if (i != 0)
928 appendString(result, ", ");
929 item = listGet(arg, i);
930 if (item == NULL) {
931 *lose = ISC_TRUE;
932 appendString(result, "???");
933 continue;
934 }
935 appendString(result,
936 print_data_expression(item, lose));
937 }
938 appendString(result, ")");
939 return result->content;
940 }
941
942 /* host-decl-name */
943 if (mapContains(expr, "host-decl-name"))
944 return "host-decl-name";
945
946 /* leased-address */
947 if (mapContains(expr, "leased-address"))
948 return "leased-address";
949
950 /* config-option */
951 if (mapContains(expr, "config-option")) {
952 struct element *arg;
953 struct element *universe;
954 struct element *name;
955
956 appendString(result, "config-option ");
957 arg = mapGet(expr, "config-option");
958 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
959 *lose = ISC_TRUE;
960 appendString(result, "???");
961 return result->content;
962 }
963 universe = mapGet(arg, "universe");
964 if ((universe == NULL) || (universe->type != ELEMENT_STRING)) {
965 *lose = ISC_TRUE;
966 appendString(result, "???");
967 return result->content;
968 }
969 concatString(result, stringValue(universe));
970 appendString(result, ".");
971 name = mapGet(arg, "name");
972 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
973 *lose = ISC_TRUE;
974 appendString(result, "???");
975 return result->content;
976 }
977 concatString(result, stringValue(name));
978 return result->content;
979 }
980
981 /* null */
982 if (mapContains(expr, "null"))
983 return "null";
984
985 /* gethostname */
986 if (mapContains(expr, "gethostname"))
987 return "gethostname";
988
989 /* v6relay */
990 if (mapContains(expr, "v6relay")) {
991 struct element *arg;
992 struct element *relay;
993 struct element *option;
994
995
996 appendString(result, "v6relay(");
997 arg = mapGet(expr, "v6relay");
998 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
999 *lose = ISC_TRUE;
1000 appendString(result, "???" ")");
1001 return result->content;
1002 }
1003 relay = mapGet(arg, "relay");
1004 if (relay == NULL) {
1005 *lose = ISC_TRUE;
1006 appendString(result, "???" ")");
1007 return result->content;
1008 }
1009 appendString(result, print_numeric_expression(relay, lose));
1010 appendString(result, ", ");
1011 option = mapGet(arg, "relay-option");
1012 if (option == NULL) {
1013 *lose = ISC_TRUE;
1014 appendString(result, "???" ")");
1015 return result->content;
1016 }
1017 appendString(result, print_data_expression(option, lose));
1018 appendString(result, ")");
1019 return result->content;
1020 }
1021
1022 *lose = ISC_TRUE;
1023 appendString(result, "???");
1024 return result->content;
1025 }
1026
1027 const char *
print_numeric_expression(struct element * expr,isc_boolean_t * lose)1028 print_numeric_expression(struct element *expr, isc_boolean_t *lose)
1029 {
1030 struct string *result;
1031
1032 if (expr->type == ELEMENT_INTEGER) {
1033 char buf[20];
1034
1035 snprintf(buf, sizeof(buf), "%lld", (long long)intValue(expr));
1036 result = makeString(-1, buf);
1037 return result->content;
1038 }
1039
1040 /*
1041 * From is_numeric_expression
1042 */
1043 if (expr->type != ELEMENT_MAP) {
1044 *lose = ISC_TRUE;
1045 return "???";
1046 }
1047 result = allocString();
1048
1049 /* extract-int8 */
1050 if (mapContains(expr, "extract-int8")) {
1051 struct element *arg;
1052
1053 appendString(result, "extract-int(");
1054 arg = mapGet(expr, "extract-int8");
1055 if (arg == NULL) {
1056 *lose = ISC_TRUE;
1057 appendString(result, "???, 8)");
1058 return result->content;
1059 }
1060 appendString(result, print_data_expression(arg, lose));
1061 appendString(result, ", 8)");
1062 return result->content;
1063 }
1064
1065 /* extract-int16 */
1066 if (mapContains(expr, "extract-int16")) {
1067 struct element *arg;
1068
1069 appendString(result, "extract-int(");
1070 arg = mapGet(expr, "extract-int16");
1071 if (arg == NULL) {
1072 *lose = ISC_TRUE;
1073 appendString(result, "???, 16)");
1074 return result->content;
1075 }
1076 appendString(result, print_data_expression(arg, lose));
1077 appendString(result, ", 16)");
1078 return result->content;
1079 }
1080
1081 /* extract-int32 */
1082 if (mapContains(expr, "extract-int32")) {
1083 struct element *arg;
1084
1085 appendString(result, "extract-int(");
1086 arg = mapGet(expr, "extract-int32");
1087 if (arg == NULL) {
1088 *lose = ISC_TRUE;
1089 appendString(result, "???, 32)");
1090 return result->content;
1091 }
1092 appendString(result, print_data_expression(arg, lose));
1093 appendString(result, ", 32)");
1094 return result->content;
1095 }
1096
1097 /* const-int */
1098 if (mapContains(expr, "const-int")) {
1099 struct element *arg;
1100 char buf[20];
1101
1102 arg = mapGet(expr, "const-int");
1103 if ((arg == NULL) || (arg->type != ELEMENT_INTEGER)) {
1104 *lose = ISC_TRUE;
1105 appendString(result, "???");
1106 return result->content;
1107 }
1108 snprintf(buf, sizeof(buf), "%lld", (long long)intValue(arg));
1109 result = makeString(-1, buf);
1110 return result->content;
1111 }
1112
1113 /* lease-time */
1114 if (mapContains(expr, "lease-time"))
1115 return "lease-time";
1116
1117 /* add */
1118 if (mapContains(expr, "add")) {
1119 struct element *arg;
1120 struct element *left;
1121 struct element *right;
1122 isc_boolean_t add_parenthesis;
1123
1124 appendString(result, "add ");
1125 arg = mapGet(expr, "add");
1126 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1127 *lose = ISC_TRUE;
1128 appendString(result, "???");
1129 return result->content;
1130 }
1131 left = mapGet(arg, "left");
1132 if (left == NULL) {
1133 *lose = ISC_TRUE;
1134 appendString(result, "???");
1135 return result->content;
1136 }
1137 result = allocString();
1138 add_parenthesis = ISC_TF(expr_precedence(expr_add,
1139 left) < 0);
1140 if (add_parenthesis)
1141 appendString(result, "(");
1142 appendString(result, print_expression(left, lose));
1143 if (add_parenthesis)
1144 appendString(result, ")");
1145 appendString(result, " + ");
1146 right = mapGet(arg, "right");
1147 if (right == NULL) {
1148 *lose = ISC_TRUE;
1149 appendString(result, "???");
1150 return result->content;
1151 }
1152 add_parenthesis = ISC_TF(expr_precedence(expr_add,
1153 right) < 0);
1154 if (add_parenthesis)
1155 appendString(result, "(");
1156 appendString(result, print_expression(right, lose));
1157 if (add_parenthesis)
1158 appendString(result, ")");
1159 return result->content;
1160 }
1161
1162 /* subtract */
1163 if (mapContains(expr, "subtract")) {
1164 struct element *arg;
1165 struct element *left;
1166 struct element *right;
1167 isc_boolean_t add_parenthesis;
1168
1169 appendString(result, "subtract ");
1170 arg = mapGet(expr, "subtract");
1171 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1172 *lose = ISC_TRUE;
1173 appendString(result, "???");
1174 return result->content;
1175 }
1176 left = mapGet(arg, "left");
1177 if (left == NULL) {
1178 *lose = ISC_TRUE;
1179 appendString(result, "???");
1180 return result->content;
1181 }
1182 result = allocString();
1183 add_parenthesis = ISC_TF(expr_precedence(expr_subtract,
1184 left) < 0);
1185 if (add_parenthesis)
1186 appendString(result, "(");
1187 appendString(result, print_expression(left, lose));
1188 if (add_parenthesis)
1189 appendString(result, ")");
1190 appendString(result, " - ");
1191 right = mapGet(arg, "right");
1192 if (right == NULL) {
1193 *lose = ISC_TRUE;
1194 appendString(result, "???");
1195 return result->content;
1196 }
1197 add_parenthesis = ISC_TF(expr_precedence(expr_subtract,
1198 right) < 0);
1199 if (add_parenthesis)
1200 appendString(result, "(");
1201 appendString(result, print_expression(right, lose));
1202 if (add_parenthesis)
1203 appendString(result, ")");
1204 return result->content;
1205 }
1206
1207 /* multiply */
1208 if (mapContains(expr, "multiply")) {
1209 struct element *arg;
1210 struct element *left;
1211 struct element *right;
1212 isc_boolean_t add_parenthesis;
1213
1214 appendString(result, "multiply ");
1215 arg = mapGet(expr, "multiply");
1216 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1217 *lose = ISC_TRUE;
1218 appendString(result, "???");
1219 return result->content;
1220 }
1221 left = mapGet(arg, "left");
1222 if (left == NULL) {
1223 *lose = ISC_TRUE;
1224 appendString(result, "???");
1225 return result->content;
1226 }
1227 result = allocString();
1228 add_parenthesis = ISC_TF(expr_precedence(expr_multiply,
1229 left) < 0);
1230 if (add_parenthesis)
1231 appendString(result, "(");
1232 appendString(result, print_expression(left, lose));
1233 if (add_parenthesis)
1234 appendString(result, ")");
1235 appendString(result, " * ");
1236 right = mapGet(arg, "right");
1237 if (right == NULL) {
1238 *lose = ISC_TRUE;
1239 appendString(result, "???");
1240 return result->content;
1241 }
1242 add_parenthesis = ISC_TF(expr_precedence(expr_multiply,
1243 right) < 0);
1244 if (add_parenthesis)
1245 appendString(result, "(");
1246 appendString(result, print_expression(right, lose));
1247 if (add_parenthesis)
1248 appendString(result, ")");
1249 return result->content;
1250 }
1251
1252 /* divide */
1253 if (mapContains(expr, "divide")) {
1254 struct element *arg;
1255 struct element *left;
1256 struct element *right;
1257 isc_boolean_t add_parenthesis;
1258
1259 appendString(result, "divide ");
1260 arg = mapGet(expr, "divide");
1261 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1262 *lose = ISC_TRUE;
1263 appendString(result, "???");
1264 return result->content;
1265 }
1266 left = mapGet(arg, "left");
1267 if (left == NULL) {
1268 *lose = ISC_TRUE;
1269 appendString(result, "???");
1270 return result->content;
1271 }
1272 result = allocString();
1273 add_parenthesis = ISC_TF(expr_precedence(expr_divide,
1274 left) < 0);
1275 if (add_parenthesis)
1276 appendString(result, "(");
1277 appendString(result, print_expression(left, lose));
1278 if (add_parenthesis)
1279 appendString(result, ")");
1280 appendString(result, " / ");
1281 right = mapGet(arg, "right");
1282 if (right == NULL) {
1283 *lose = ISC_TRUE;
1284 appendString(result, "???");
1285 return result->content;
1286 }
1287 add_parenthesis = ISC_TF(expr_precedence(expr_divide,
1288 right) < 0);
1289 if (add_parenthesis)
1290 appendString(result, "(");
1291 appendString(result, print_expression(right, lose));
1292 if (add_parenthesis)
1293 appendString(result, ")");
1294 return result->content;
1295 }
1296
1297 /* remainder */
1298 if (mapContains(expr, "remainder")) {
1299 struct element *arg;
1300 struct element *left;
1301 struct element *right;
1302 isc_boolean_t add_parenthesis;
1303
1304 appendString(result, "remainder ");
1305 arg = mapGet(expr, "remainder");
1306 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1307 *lose = ISC_TRUE;
1308 appendString(result, "???");
1309 return result->content;
1310 }
1311 left = mapGet(arg, "left");
1312 if (left == NULL) {
1313 *lose = ISC_TRUE;
1314 appendString(result, "???");
1315 return result->content;
1316 }
1317 result = allocString();
1318 add_parenthesis = ISC_TF(expr_precedence(expr_remainder,
1319 left) < 0);
1320 if (add_parenthesis)
1321 appendString(result, "(");
1322 appendString(result, print_expression(left, lose));
1323 if (add_parenthesis)
1324 appendString(result, ")");
1325 appendString(result, " % ");
1326 right = mapGet(arg, "right");
1327 if (right == NULL) {
1328 *lose = ISC_TRUE;
1329 appendString(result, "???");
1330 return result->content;
1331 }
1332 add_parenthesis = ISC_TF(expr_precedence(expr_remainder,
1333 right) < 0);
1334 if (add_parenthesis)
1335 appendString(result, "(");
1336 appendString(result, print_expression(right, lose));
1337 if (add_parenthesis)
1338 appendString(result, ")");
1339 return result->content;
1340 }
1341
1342 /* binary-and */
1343 if (mapContains(expr, "binary-and")) {
1344 struct element *arg;
1345 struct element *left;
1346 struct element *right;
1347 isc_boolean_t add_parenthesis;
1348
1349 appendString(result, "binary-and ");
1350 arg = mapGet(expr, "binary-and");
1351 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1352 *lose = ISC_TRUE;
1353 appendString(result, "???");
1354 return result->content;
1355 }
1356 left = mapGet(arg, "left");
1357 if (left == NULL) {
1358 *lose = ISC_TRUE;
1359 appendString(result, "???");
1360 return result->content;
1361 }
1362 result = allocString();
1363 add_parenthesis = ISC_TF(expr_precedence(expr_binary_and,
1364 left) < 0);
1365 if (add_parenthesis)
1366 appendString(result, "(");
1367 appendString(result, print_expression(left, lose));
1368 if (add_parenthesis)
1369 appendString(result, ")");
1370 appendString(result, " & ");
1371 right = mapGet(arg, "right");
1372 if (right == NULL) {
1373 *lose = ISC_TRUE;
1374 appendString(result, "???");
1375 return result->content;
1376 }
1377 add_parenthesis = ISC_TF(expr_precedence(expr_binary_and,
1378 right) < 0);
1379 if (add_parenthesis)
1380 appendString(result, "(");
1381 appendString(result, print_expression(right, lose));
1382 if (add_parenthesis)
1383 appendString(result, ")");
1384 return result->content;
1385 }
1386
1387 /* binary-or */
1388 if (mapContains(expr, "binary-or")) {
1389 struct element *arg;
1390 struct element *left;
1391 struct element *right;
1392 isc_boolean_t add_parenthesis;
1393
1394 appendString(result, "binary-or ");
1395 arg = mapGet(expr, "binary-or");
1396 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1397 *lose = ISC_TRUE;
1398 appendString(result, "???");
1399 return result->content;
1400 }
1401 left = mapGet(arg, "left");
1402 if (left == NULL) {
1403 *lose = ISC_TRUE;
1404 appendString(result, "???");
1405 return result->content;
1406 }
1407 result = allocString();
1408 add_parenthesis = ISC_TF(expr_precedence(expr_binary_or,
1409 left) < 0);
1410 if (add_parenthesis)
1411 appendString(result, "(");
1412 appendString(result, print_expression(left, lose));
1413 if (add_parenthesis)
1414 appendString(result, ")");
1415 appendString(result, " | ");
1416 right = mapGet(arg, "right");
1417 if (right == NULL) {
1418 *lose = ISC_TRUE;
1419 appendString(result, "???");
1420 return result->content;
1421 }
1422 add_parenthesis = ISC_TF(expr_precedence(expr_binary_or,
1423 right) < 0);
1424 if (add_parenthesis)
1425 appendString(result, "(");
1426 appendString(result, print_expression(right, lose));
1427 if (add_parenthesis)
1428 appendString(result, ")");
1429 return result->content;
1430 }
1431
1432 /* binary-xor */
1433 if (mapContains(expr, "binary-xor")) {
1434 struct element *arg;
1435 struct element *left;
1436 struct element *right;
1437 isc_boolean_t add_parenthesis;
1438
1439 appendString(result, "binary-xor ");
1440 arg = mapGet(expr, "binary-xor");
1441 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1442 *lose = ISC_TRUE;
1443 appendString(result, "???");
1444 return result->content;
1445 }
1446 left = mapGet(arg, "left");
1447 if (left == NULL) {
1448 *lose = ISC_TRUE;
1449 appendString(result, "???");
1450 return result->content;
1451 }
1452 result = allocString();
1453 add_parenthesis = ISC_TF(expr_precedence(expr_binary_xor,
1454 left) < 0);
1455 if (add_parenthesis)
1456 appendString(result, "(");
1457 appendString(result, print_expression(left, lose));
1458 if (add_parenthesis)
1459 appendString(result, ")");
1460 appendString(result, " ^ ");
1461 right = mapGet(arg, "right");
1462 if (right == NULL) {
1463 *lose = ISC_TRUE;
1464 appendString(result, "???");
1465 return result->content;
1466 }
1467 add_parenthesis = ISC_TF(expr_precedence(expr_binary_xor,
1468 right) < 0);
1469 if (add_parenthesis)
1470 appendString(result, "(");
1471 appendString(result, print_expression(right, lose));
1472 if (add_parenthesis)
1473 appendString(result, ")");
1474 return result->content;
1475 }
1476
1477 /* client-state */
1478 if (mapContains(expr, "client-state"))
1479 return "client-state";
1480
1481 *lose = ISC_TRUE;
1482 appendString(result, "???");
1483 return result->content;
1484 }
1485
1486 static void
debug(const char * fmt,...)1487 debug(const char* fmt, ...)
1488 {
1489 va_list list;
1490
1491 va_start(list, fmt);
1492 vfprintf(stderr, fmt, list);
1493 fprintf(stderr, "\n");
1494 va_end(list);
1495 }
1496