3 Common parser code for dhcpd and dhclient. */
6 * Copyright (c) 1995-2002 Internet Software Consortium.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
38 * To learn more about the Internet Software Consortium, see
39 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
40 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
41 * ``http://www.nominum.com''.
43 * $Id: parse.c,v 1.104.2.14 2003/07/25 19:36:11 dhankins Exp $ Copyright (c) 1995-2002 The Internet Software Consortium. All rights reserved.
44 * $DragonFly: src/contrib/isc-dhcp/common/Attic/parse.c,v 1.2 2003/10/11 21:14:17 dillon Exp $
50 /* Enumerations can be specified in option formats, and are used for
51 parsing, so we define the routines that manage them here. */
53 struct enumeration *enumerations;
55 void add_enumeration (struct enumeration *enumeration)
57 enumeration -> next = enumerations;
58 enumerations = enumeration;
61 struct enumeration *find_enumeration (const char *name, int length)
63 struct enumeration *e;
65 for (e = enumerations; e; e = e -> next)
66 if (strlen (e -> name) == length &&
67 !memcmp (e -> name, name, (unsigned)length))
69 return (struct enumeration *)0;
72 struct enumeration_value *find_enumeration_value (const char *name,
76 struct enumeration *e;
79 e = find_enumeration (name, length);
81 for (i = 0; e -> values [i].name; i++) {
82 if (!strcmp (value, e -> values [i].name))
83 return &e -> values [i];
86 return (struct enumeration_value *)0;
89 /* Skip to the semicolon ending the current statement. If we encounter
90 braces, the matching closing brace terminates the statement. If we
91 encounter a right brace but haven't encountered a left brace, return
92 leaving the brace in the token buffer for the caller. If we see a
93 semicolon and haven't seen a left brace, return. This lets us skip
98 statement foo bar { statement { } }
103 void skip_to_semi (cfile)
106 skip_to_rbrace (cfile, 0);
109 void skip_to_rbrace (cfile, brace_count)
113 enum dhcp_token token;
116 #if defined (DEBUG_TOKEN)
117 log_error ("skip_to_rbrace: %d\n", brace_count);
120 token = peek_token (&val, (unsigned *)0, cfile);
121 if (token == RBRACE) {
122 token = next_token (&val, (unsigned *)0, cfile);
128 } else if (token == LBRACE) {
130 } else if (token == SEMI && !brace_count) {
131 token = next_token (&val, (unsigned *)0, cfile);
133 } else if (token == EOL) {
134 /* EOL only happens when parsing /etc/resolv.conf,
135 and we treat it like a semicolon because the
136 resolv.conf file is line-oriented. */
137 token = next_token (&val, (unsigned *)0, cfile);
140 token = next_token (&val, (unsigned *)0, cfile);
141 } while (token != END_OF_FILE);
144 int parse_semi (cfile)
147 enum dhcp_token token;
150 token = next_token (&val, (unsigned *)0, cfile);
152 parse_warn (cfile, "semicolon expected.");
153 skip_to_semi (cfile);
159 /* string-parameter :== STRING SEMI */
161 int parse_string (cfile, sptr, lptr)
167 enum dhcp_token token;
171 token = next_token (&val, &len, cfile);
172 if (token != STRING) {
173 parse_warn (cfile, "expecting a string");
174 skip_to_semi (cfile);
177 s = (char *)dmalloc (len + 1, MDL);
179 log_fatal ("no memory for string %s.", val);
180 memcpy (s, val, len + 1);
182 if (!parse_semi (cfile)) {
196 * hostname :== IDENTIFIER
198 * | hostname DOT IDENTIFIER
201 char *parse_host_name (cfile)
205 enum dhcp_token token;
212 /* Read a dotted hostname... */
214 /* Read a token, which should be an identifier. */
215 token = peek_token (&val, (unsigned *)0, cfile);
216 if (!is_identifier (token) && token != NUMBER)
218 token = next_token (&val, (unsigned *)0, cfile);
220 /* Store this identifier... */
221 if (!(s = (char *)dmalloc (strlen (val) + 1, MDL)))
222 log_fatal ("can't allocate temp space for hostname.");
224 c = cons ((caddr_t)s, c);
225 len += strlen (s) + 1;
226 /* Look for a dot; if it's there, keep going, otherwise
228 token = peek_token (&val, (unsigned *)0, cfile);
230 token = next_token (&val, (unsigned *)0, cfile);
234 } while (token == DOT);
236 /* Should be at least one token. */
240 /* Assemble the hostname together into a string. */
241 if (!(s = (char *)dmalloc (len + ltid, MDL)))
242 log_fatal ("can't allocate space for hostname.");
249 unsigned l = strlen ((char *)(c -> car));
251 memcpy (t, (char *)(c -> car), l);
252 /* Free up temp space. */
253 dfree (c -> car, MDL);
262 /* ip-addr-or-hostname :== ip-address | hostname
263 ip-address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
265 Parse an ip address or a hostname. If uniform is zero, put in
266 an expr_substring node to limit hostnames that evaluate to more
267 than one IP address. */
269 int parse_ip_addr_or_hostname (expr, cfile, uniform)
270 struct expression **expr;
275 enum dhcp_token token;
276 unsigned char addr [4];
277 unsigned len = sizeof addr;
279 struct expression *x = (struct expression *)0;
281 token = peek_token (&val, (unsigned *)0, cfile);
282 if (is_identifier (token)) {
283 name = parse_host_name (cfile);
286 if (!make_host_lookup (expr, name)) {
292 if (!make_limit (&x, *expr, 4))
294 expression_dereference (expr, MDL);
297 } else if (token == NUMBER) {
298 if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
300 return make_const_data (expr, addr, len, 0, 1, MDL);
302 if (token != RBRACE && token != LBRACE)
303 token = next_token (&val, (unsigned *)0, cfile);
304 parse_warn (cfile, "%s (%d): expecting IP address or hostname",
307 skip_to_semi (cfile);
315 * ip-address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
318 int parse_ip_addr (cfile, addr)
323 enum dhcp_token token;
326 if (parse_numeric_aggregate (cfile, addr -> iabuf,
327 &addr -> len, DOT, 10, 8))
333 * hardware-parameter :== HARDWARE hardware-type colon-seperated-hex-list SEMI
334 * hardware-type :== ETHERNET | TOKEN_RING | FDDI
337 void parse_hardware_param (cfile, hardware)
339 struct hardware *hardware;
342 enum dhcp_token token;
346 token = next_token (&val, (unsigned *)0, cfile);
349 hardware -> hbuf [0] = HTYPE_ETHER;
352 hardware -> hbuf [0] = HTYPE_IEEE802;
355 hardware -> hbuf [0] = HTYPE_FDDI;
358 if (!strncmp (val, "unknown-", 8)) {
359 hardware -> hbuf [0] = atoi (&val [8]);
362 "expecting a network hardware type");
363 skip_to_semi (cfile);
369 /* Parse the hardware address information. Technically,
370 it would make a lot of sense to restrict the length of the
371 data we'll accept here to the length of a particular hardware
372 address type. Unfortunately, there are some broken clients
373 out there that put bogus data in the chaddr buffer, and we accept
374 that data in the lease file rather than simply failing on such
377 token = peek_token (&val, (unsigned *)0, cfile);
379 hardware -> hlen = 1;
382 t = parse_numeric_aggregate (cfile, (unsigned char *)0, &hlen,
385 hardware -> hlen = 1;
388 if (hlen + 1 > sizeof hardware -> hbuf) {
390 parse_warn (cfile, "hardware address too long");
392 hardware -> hlen = hlen + 1;
393 memcpy ((unsigned char *)&hardware -> hbuf [1], t, hlen);
394 if (hlen + 1 < sizeof hardware -> hbuf)
395 memset (&hardware -> hbuf [hlen + 1], 0,
396 (sizeof hardware -> hbuf) - hlen - 1);
401 token = next_token (&val, (unsigned *)0, cfile);
403 parse_warn (cfile, "expecting semicolon.");
404 skip_to_semi (cfile);
408 /* lease-time :== NUMBER SEMI */
410 void parse_lease_time (cfile, timep)
415 enum dhcp_token token;
417 token = next_token (&val, (unsigned *)0, cfile);
418 if (token != NUMBER) {
419 parse_warn (cfile, "Expecting numeric lease time");
420 skip_to_semi (cfile);
423 convert_num (cfile, (unsigned char *)timep, val, 10, 32);
424 /* Unswap the number - convert_num returns stuff in NBO. */
425 *timep = ntohl (*timep); /* XXX */
430 /* No BNF for numeric aggregates - that's defined by the caller. What
431 this function does is to parse a sequence of numbers seperated by
432 the token specified in seperator. If max is zero, any number of
433 numbers will be parsed; otherwise, exactly max numbers are
434 expected. Base and size tell us how to internalize the numbers
435 once they've been tokenized. */
437 unsigned char *parse_numeric_aggregate (cfile, buf,
438 max, seperator, base, size)
447 enum dhcp_token token;
448 unsigned char *bufp = buf, *s, *t;
453 bufp = (unsigned char *)dmalloc (*max * size / 8, MDL);
455 log_fatal ("no space for numeric aggregate");
462 token = peek_token (&val, (unsigned *)0, cfile);
463 if (token != seperator) {
466 if (token != RBRACE && token != LBRACE)
467 token = next_token (&val,
470 parse_warn (cfile, "too few numbers.");
472 skip_to_semi (cfile);
473 return (unsigned char *)0;
475 token = next_token (&val, (unsigned *)0, cfile);
477 token = next_token (&val, (unsigned *)0, cfile);
479 if (token == END_OF_FILE) {
480 parse_warn (cfile, "unexpected end of file");
484 /* Allow NUMBER_OR_NAME if base is 16. */
485 if (token != NUMBER &&
486 (base != 16 || token != NUMBER_OR_NAME)) {
487 parse_warn (cfile, "expecting numeric value.");
488 skip_to_semi (cfile);
489 return (unsigned char *)0;
491 /* If we can, convert the number now; otherwise, build
492 a linked list of all the numbers. */
494 convert_num (cfile, s, val, base, size);
497 t = (unsigned char *)dmalloc (strlen (val) + 1, MDL);
499 log_fatal ("no temp space for number.");
500 strcpy ((char *)t, val);
501 c = cons ((caddr_t)t, c);
503 } while (++count != *max);
505 /* If we had to cons up a list, convert it now. */
507 bufp = (unsigned char *)dmalloc (count * size / 8, MDL);
509 log_fatal ("no space for numeric aggregate.");
510 s = bufp + count - size / 8;
515 convert_num (cfile, s, (char *)(c -> car), base, size);
517 /* Free up temp space. */
518 dfree (c -> car, MDL);
525 void convert_num (cfile, buf, str, base, size)
532 const char *ptr = str;
543 /* If base wasn't specified, figure it out from the data. */
545 if (ptr [0] == '0') {
546 if (ptr [1] == 'x') {
549 } else if (isascii (ptr [1]) && isdigit (ptr [1])) {
562 /* XXX assumes ASCII... */
564 tval = tval - 'a' + 10;
565 else if (tval >= 'A')
566 tval = tval - 'A' + 10;
567 else if (tval >= '0')
570 parse_warn (cfile, "Bogus number: %s.", str);
575 "Bogus number %s: digit %d not in base %d",
579 val = val * base + tval;
583 max = (1 << (size - 1));
585 max = (1 << (size - 1)) + ((1 << (size - 1)) - 1);
590 "%s%lo exceeds max (%d) for precision.",
592 (unsigned long)val, max);
596 "%s%lx exceeds max (%d) for precision.",
598 (unsigned long)val, max);
602 "%s%lu exceeds max (%d) for precision.",
604 (unsigned long)val, max);
612 *buf = -(unsigned long)val;
615 putShort (buf, -(long)val);
618 putLong (buf, -(long)val);
622 "Unexpected integer size: %d\n", size);
628 *buf = (u_int8_t)val;
631 putUShort (buf, (u_int16_t)val);
638 "Unexpected integer size: %d\n", size);
645 * date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER
646 * NUMBER COLON NUMBER COLON NUMBER SEMI |
647 * NUMBER NUMBER SLASH NUMBER SLASH NUMBER
648 * NUMBER COLON NUMBER COLON NUMBER NUMBER SEMI |
651 * Dates are stored in GMT or with a timezone offset; first number is day
652 * of week; next is year/month/day; next is hours:minutes:seconds on a
653 * 24-hour clock, followed by the timezone offset in seconds, which is
657 TIME parse_date (cfile)
662 int tzoff, wday, year, mon, mday, hour, min, sec;
664 enum dhcp_token token;
665 static int months [11] = { 31, 59, 90, 120, 151, 181,
666 212, 243, 273, 304, 334 };
668 /* Day of week, or "never"... */
669 token = next_token (&val, (unsigned *)0, cfile);
670 if (token == NEVER) {
671 if (!parse_semi (cfile))
676 if (token != NUMBER) {
677 parse_warn (cfile, "numeric day of week expected.");
679 skip_to_semi (cfile);
685 token = next_token (&val, (unsigned *)0, cfile);
686 if (token != NUMBER) {
687 parse_warn (cfile, "numeric year expected.");
689 skip_to_semi (cfile);
693 /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
694 somebody invents a time machine, I think we can safely disregard
695 it. This actually works around a stupid Y2K bug that was present
696 in a very early beta release of dhcpd. */
701 /* Slash seperating year from month... */
702 token = next_token (&val, (unsigned *)0, cfile);
703 if (token != SLASH) {
705 "expected slash seperating year from month.");
707 skip_to_semi (cfile);
712 token = next_token (&val, (unsigned *)0, cfile);
713 if (token != NUMBER) {
714 parse_warn (cfile, "numeric month expected.");
716 skip_to_semi (cfile);
719 mon = atoi (val) - 1;
721 /* Slash seperating month from day... */
722 token = next_token (&val, (unsigned *)0, cfile);
723 if (token != SLASH) {
725 "expected slash seperating month from day.");
727 skip_to_semi (cfile);
732 token = next_token (&val, (unsigned *)0, cfile);
733 if (token != NUMBER) {
734 parse_warn (cfile, "numeric day of month expected.");
736 skip_to_semi (cfile);
742 token = next_token (&val, (unsigned *)0, cfile);
743 if (token != NUMBER) {
744 parse_warn (cfile, "numeric hour expected.");
746 skip_to_semi (cfile);
751 /* Colon seperating hour from minute... */
752 token = next_token (&val, (unsigned *)0, cfile);
753 if (token != COLON) {
755 "expected colon seperating hour from minute.");
757 skip_to_semi (cfile);
762 token = next_token (&val, (unsigned *)0, cfile);
763 if (token != NUMBER) {
764 parse_warn (cfile, "numeric minute expected.");
766 skip_to_semi (cfile);
771 /* Colon seperating minute from second... */
772 token = next_token (&val, (unsigned *)0, cfile);
773 if (token != COLON) {
775 "expected colon seperating hour from minute.");
777 skip_to_semi (cfile);
782 token = next_token (&val, (unsigned *)0, cfile);
783 if (token != NUMBER) {
784 parse_warn (cfile, "numeric minute expected.");
786 skip_to_semi (cfile);
791 token = peek_token (&val, (unsigned *)0, cfile);
792 if (token == NUMBER) {
793 token = next_token (&val, (unsigned *)0, cfile);
798 /* Make sure the date ends in a semicolon... */
799 if (!parse_semi (cfile))
802 /* Guess the time value... */
803 guess = ((((((365 * (year - 70) + /* Days in years since '70 */
804 (year - 69) / 4 + /* Leap days since '70 */
805 (mon /* Days in months this year */
808 (mon > 1 && /* Leap day this year */
809 !((year - 72) & 3)) +
810 mday - 1) * 24) + /* Day of month */
812 min) * 60) + sec + tzoff;
814 /* This guess could be wrong because of leap seconds or other
815 weirdness we don't know about that the system does. For
816 now, we're just going to accept the guess, but at some point
817 it might be nice to do a successive approximation here to
818 get an exact value. Even if the error is small, if the
819 server is restarted frequently (and thus the lease database
820 is reread), the error could accumulate into something
827 * option-name :== IDENTIFIER |
828 IDENTIFIER . IDENTIFIER
831 struct option *parse_option_name (cfile, allocate, known)
837 enum dhcp_token token;
839 struct universe *universe;
840 struct option *option;
842 token = next_token (&val, (unsigned *)0, cfile);
843 if (!is_identifier (token)) {
845 "expecting identifier after option keyword.");
847 skip_to_semi (cfile);
848 return (struct option *)0;
850 uname = dmalloc (strlen (val) + 1, MDL);
852 log_fatal ("no memory for uname information.");
854 token = peek_token (&val, (unsigned *)0, cfile);
856 /* Go ahead and take the DOT token... */
857 token = next_token (&val, (unsigned *)0, cfile);
859 /* The next token should be an identifier... */
860 token = next_token (&val, (unsigned *)0, cfile);
861 if (!is_identifier (token)) {
862 parse_warn (cfile, "expecting identifier after '.'");
864 skip_to_semi (cfile);
865 return (struct option *)0;
868 /* Look up the option name hash table for the specified
870 universe = (struct universe *)0;
871 if (!universe_hash_lookup (&universe, universe_hash,
873 parse_warn (cfile, "no option space named %s.", uname);
874 skip_to_semi (cfile);
875 return (struct option *)0;
878 /* Use the default hash table, which contains all the
879 standard dhcp option names. */
881 universe = &dhcp_universe;
884 /* Look up the actual option info... */
885 option = (struct option *)0;
886 option_hash_lookup (&option, universe -> hash, val, 0, MDL);
888 /* If we didn't get an option structure, it's an undefined option. */
893 /* If we've been told to allocate, that means that this
894 (might) be an option code definition, so we'll create
895 an option structure just in case. */
897 option = new_option (MDL);
899 option -> name = val;
903 s = dmalloc (strlen (val) + 1, MDL);
905 log_fatal ("no memory for option %s.%s",
906 universe -> name, val);
910 option -> universe = universe;
915 parse_warn (cfile, "no option named %s", val);
917 parse_warn (cfile, "no option named %s in space %s",
919 skip_to_semi (cfile);
920 return (struct option *)0;
923 /* Free the initial identifier token. */
928 /* IDENTIFIER SEMI */
930 void parse_option_space_decl (cfile)
935 struct universe **ua, *nu;
938 next_token (&val, (unsigned *)0, cfile); /* Discard the SPACE token,
939 which was checked by the
941 token = next_token (&val, (unsigned *)0, cfile);
942 if (!is_identifier (token)) {
943 parse_warn (cfile, "expecting identifier.");
944 skip_to_semi (cfile);
947 nu = new_universe (MDL);
949 log_fatal ("No memory for new option space.");
951 /* Set up the server option universe... */
952 s = dmalloc (strlen (val) + 1, MDL);
954 log_fatal ("No memory for new option space name.");
957 nu -> lookup_func = lookup_hashed_option;
958 nu -> option_state_dereference =
959 hashed_option_state_dereference;
960 nu -> foreach = hashed_option_space_foreach;
961 nu -> save_func = save_hashed_option;
962 nu -> delete_func = delete_hashed_option;
963 nu -> encapsulate = hashed_option_space_encapsulate;
964 nu -> decode = parse_option_buffer;
965 nu -> length_size = 1;
967 nu -> store_tag = putUChar;
968 nu -> store_length = putUChar;
969 nu -> index = universe_count++;
970 if (nu -> index >= universe_max) {
971 ua = dmalloc (universe_max * 2 * sizeof *ua, MDL);
973 log_fatal ("No memory to expand option space array.");
974 memcpy (ua, universes, universe_max * sizeof *ua);
976 dfree (universes, MDL);
979 universes [nu -> index] = nu;
980 option_new_hash (&nu -> hash, 1, MDL);
982 log_fatal ("Can't allocate %s option hash table.", nu -> name);
983 universe_hash_add (universe_hash, nu -> name, 0, nu, MDL);
987 /* This is faked up to look good right now. Ideally, this should do a
988 recursive parse and allow arbitrary data structure definitions, but for
989 now it just allows you to specify a single type, an array of single types,
990 a sequence of types, or an array of sequences of types.
992 ocd :== NUMBER EQUALS ocsd SEMI
996 ARRAY OF ocsd_simple_type_sequence
998 ocsd_type_sequence :== LBRACE ocsd_types RBRACE
1000 ocsd_simple_type_sequence :== LBRACE ocsd_simple_types RBRACE
1002 ocsd_types :== ocsd_type |
1003 ocsd_types ocsd_type
1005 ocsd_type :== ocsd_simple_type |
1006 ARRAY OF ocsd_simple_type
1008 ocsd_simple_types :== ocsd_simple_type |
1009 ocsd_simple_types ocsd_simple_type
1011 ocsd_simple_type :== BOOLEAN |
1013 SIGNED INTEGER NUMBER |
1014 UNSIGNED INTEGER NUMBER |
1018 ENCAPSULATE identifier */
1020 int parse_option_code_definition (cfile, option)
1021 struct parse *cfile;
1022 struct option *option;
1025 enum dhcp_token token;
1026 unsigned arrayp = 0;
1028 int no_more_in_record = 0;
1035 int has_encapsulation = 0;
1037 /* Parse the option code. */
1038 token = next_token (&val, (unsigned *)0, cfile);
1039 if (token != NUMBER) {
1040 parse_warn (cfile, "expecting option code number.");
1041 skip_to_semi (cfile);
1044 option -> code = atoi (val);
1046 token = next_token (&val, (unsigned *)0, cfile);
1047 if (token != EQUAL) {
1048 parse_warn (cfile, "expecting \"=\"");
1049 skip_to_semi (cfile);
1053 /* See if this is an array. */
1054 token = next_token (&val, (unsigned *)0, cfile);
1055 if (token == ARRAY) {
1056 token = next_token (&val, (unsigned *)0, cfile);
1058 parse_warn (cfile, "expecting \"of\".");
1059 skip_to_semi (cfile);
1063 token = next_token (&val, (unsigned *)0, cfile);
1066 if (token == LBRACE) {
1068 token = next_token (&val, (unsigned *)0, cfile);
1071 /* At this point we're expecting a data type. */
1073 if (has_encapsulation) {
1075 "encapsulate must always be the last item.");
1076 skip_to_semi (cfile);
1083 parse_warn (cfile, "no nested arrays.");
1084 skip_to_rbrace (cfile, recordp);
1086 skip_to_semi (cfile);
1089 token = next_token (&val, (unsigned *)0, cfile);
1091 parse_warn (cfile, "expecting \"of\".");
1092 skip_to_semi (cfile);
1095 arrayp = recordp + 1;
1096 token = next_token (&val, (unsigned *)0, cfile);
1097 if ((recordp) && (token == LBRACE)) {
1099 "only uniform array inside record.");
1100 skip_to_rbrace (cfile, recordp + 1);
1101 skip_to_semi (cfile);
1111 token = next_token (&val, (unsigned *)0, cfile);
1112 if (token != NUMBER) {
1113 parse_warn (cfile, "expecting number.");
1114 skip_to_rbrace (cfile, recordp);
1116 skip_to_semi (cfile);
1119 switch (atoi (val)) {
1121 type = is_signed ? 'b' : 'B';
1124 type = is_signed ? 's' : 'S';
1127 type = is_signed ? 'l' : 'L';
1131 "%s bit precision is not supported.", val);
1132 skip_to_rbrace (cfile, recordp);
1134 skip_to_semi (cfile);
1141 token = next_token (&val, (unsigned *)0, cfile);
1142 if (token != INTEGER) {
1143 parse_warn (cfile, "expecting \"integer\" keyword.");
1144 skip_to_rbrace (cfile, recordp);
1146 skip_to_semi (cfile);
1164 parse_warn (cfile, "arrays of text strings not %s",
1166 skip_to_rbrace (cfile, recordp);
1168 skip_to_semi (cfile);
1171 no_more_in_record = 1;
1178 token = next_token (&val, (unsigned *)0, cfile);
1179 if (!is_identifier (token)) {
1181 "expecting option space identifier");
1182 skip_to_semi (cfile);
1185 if (strlen (val) + tokix + 2 > sizeof (tokbuf))
1187 tokbuf [tokix++] = 'E';
1188 strcpy (&tokbuf [tokix], val);
1189 tokix += strlen (val);
1191 has_encapsulation = 1;
1195 parse_warn (cfile, "unknown data type %s", val);
1196 skip_to_rbrace (cfile, recordp);
1198 skip_to_semi (cfile);
1202 if (tokix == sizeof tokbuf) {
1204 parse_warn (cfile, "too many types in record.");
1205 skip_to_rbrace (cfile, recordp);
1207 skip_to_semi (cfile);
1210 tokbuf [tokix++] = type;
1213 token = next_token (&val, (unsigned *)0, cfile);
1214 if (arrayp > recordp) {
1215 if (tokix == sizeof tokbuf) {
1217 "too many types in record.");
1218 skip_to_rbrace (cfile, 1);
1219 skip_to_semi (cfile);
1223 tokbuf[tokix++] = 'a';
1225 if (token == COMMA) {
1226 if (no_more_in_record) {
1228 "%s must be at end of record.",
1229 type == 't' ? "text" : "string");
1230 skip_to_rbrace (cfile, 1);
1232 skip_to_semi (cfile);
1235 token = next_token (&val, (unsigned *)0, cfile);
1238 if (token != RBRACE) {
1239 parse_warn (cfile, "expecting right brace.");
1240 skip_to_rbrace (cfile, 1);
1242 skip_to_semi (cfile);
1246 if (!parse_semi (cfile)) {
1247 parse_warn (cfile, "semicolon expected.");
1248 skip_to_semi (cfile);
1250 skip_to_semi (cfile);
1253 if (has_encapsulation && arrayp) {
1255 "Arrays of encapsulations don't make sense.");
1258 if (has_encapsulation && tokbuf [0] == 'E')
1259 has_encapsulation = 0;
1260 s = dmalloc (tokix +
1262 (has_encapsulation ? 1 : 0) + 1, MDL);
1264 log_fatal ("no memory for option format.");
1265 if (has_encapsulation)
1267 memcpy (s + has_encapsulation, tokbuf, tokix);
1268 tokix += has_encapsulation;
1270 s [tokix++] = (arrayp > recordp) ? 'a' : 'A';
1272 option -> format = s;
1273 if (option -> universe -> options [option -> code]) {
1274 /* XXX Free the option, but we can't do that now because they
1275 XXX may start out static. */
1277 option -> universe -> options [option -> code] = option;
1278 option_hash_add (option -> universe -> hash,
1279 (const char *)option -> name,
1285 * base64 :== NUMBER_OR_STRING
1288 int parse_base64 (data, cfile)
1289 struct data_string *data;
1290 struct parse *cfile;
1292 enum dhcp_token token;
1296 static unsigned char
1297 from64 [] = {64, 64, 64, 64, 64, 64, 64, 64, /* \"#$%&' */
1298 64, 64, 64, 62, 64, 64, 64, 63, /* ()*+,-./ */
1299 52, 53, 54, 55, 56, 57, 58, 59, /* 01234567 */
1300 60, 61, 64, 64, 64, 64, 64, 64, /* 89:;<=>? */
1301 64, 0, 1, 2, 3, 4, 5, 6, /* @ABCDEFG */
1302 7, 8, 9, 10, 11, 12, 13, 14, /* HIJKLMNO */
1303 15, 16, 17, 18, 19, 20, 21, 22, /* PQRSTUVW */
1304 23, 24, 25, 64, 64, 64, 64, 64, /* XYZ[\]^_ */
1305 64, 26, 27, 28, 29, 30, 31, 32, /* 'abcdefg */
1306 33, 34, 35, 36, 37, 38, 39, 40, /* hijklmno */
1307 41, 42, 43, 44, 45, 46, 47, 48, /* pqrstuvw */
1308 49, 50, 51, 64, 64, 64, 64, 64}; /* xyz{|}~ */
1309 struct string_list *bufs = (struct string_list *)0,
1310 *last = (struct string_list *)0,
1315 /* It's possible for a + or a / to cause a base64 quantity to be
1316 tokenized into more than one token, so we have to parse them all
1317 in before decoding. */
1321 token = next_token (&val, &l, cfile);
1322 t = dmalloc (l + sizeof *t, MDL);
1324 log_fatal ("no memory for base64 buffer.");
1325 memset (t, 0, (sizeof *t) - 1);
1326 memcpy (t -> string, val, l + 1);
1333 token = peek_token (&val, (unsigned *)0, cfile);
1334 } while (token == NUMBER_OR_NAME || token == NAME || token == EQUAL ||
1335 token == NUMBER || token == PLUS || token == SLASH ||
1339 data -> len = (data -> len * 3) / 4;
1340 if (!buffer_allocate (&data -> buffer, data -> len, MDL)) {
1341 parse_warn (cfile, "can't allocate buffer for base64 data.");
1343 data -> data = (unsigned char *)0;
1348 for (t = bufs; t; t = t -> next) {
1349 for (i = 0; t -> string [i]; i++) {
1350 unsigned foo = t -> string [i];
1351 if (terminated && foo != '=') {
1353 "stuff after base64 '=' terminator: %s.",
1357 if (foo < ' ' || foo > 'z') {
1360 "invalid base64 character %d.",
1363 data_string_forget (data, MDL);
1369 foo = from64 [foo - ' '];
1372 acc = (acc << 6) + foo;
1377 data -> buffer -> data [j++] = (acc >> 4);
1382 data -> buffer -> data [j++] = (acc >> 2);
1386 data -> buffer -> data [j++] = acc;
1397 "partial base64 value left over: %d.",
1402 data -> data = data -> buffer -> data;
1404 for (t = bufs; t; t = last) {
1416 * colon-seperated-hex-list :== NUMBER |
1417 * NUMBER COLON colon-seperated-hex-list
1420 int parse_cshl (data, cfile)
1421 struct data_string *data;
1422 struct parse *cfile;
1424 u_int8_t ibuf [128];
1427 struct option_tag *sl = (struct option_tag *)0;
1428 struct option_tag *next, **last = &sl;
1429 enum dhcp_token token;
1434 token = next_token (&val, (unsigned *)0, cfile);
1435 if (token != NUMBER && token != NUMBER_OR_NAME) {
1436 parse_warn (cfile, "expecting hexadecimal number.");
1437 skip_to_semi (cfile);
1438 for (; sl; sl = next) {
1444 if (ilen == sizeof ibuf) {
1445 next = (struct option_tag *)
1447 sizeof (struct option_tag), MDL);
1449 log_fatal ("no memory for string list.");
1450 memcpy (next -> data, ibuf, ilen);
1452 last = &next -> next;
1456 convert_num (cfile, &ibuf [ilen++], val, 16, 8);
1458 token = peek_token (&val, (unsigned *)0, cfile);
1461 token = next_token (&val, (unsigned *)0, cfile);
1464 if (!buffer_allocate (&data -> buffer, tlen + ilen, MDL))
1465 log_fatal ("no memory to store octet data.");
1466 data -> data = &data -> buffer -> data [0];
1467 data -> len = tlen + ilen;
1468 data -> terminated = 0;
1470 rvp = &data -> buffer -> data [0];
1473 memcpy (rvp, sl -> data, sizeof ibuf);
1479 memcpy (rvp, ibuf, ilen);
1484 * executable-statements :== executable-statement executable-statements |
1485 * executable-statement
1487 * executable-statement :==
1489 * ADD class-name SEMI |
1491 * OPTION option-parameter SEMI |
1492 * SUPERSEDE option-parameter SEMI |
1493 * PREPEND option-parameter SEMI |
1494 * APPEND option-parameter SEMI
1497 int parse_executable_statements (statements, cfile, lose, case_context)
1498 struct executable_statement **statements;
1499 struct parse *cfile;
1501 enum expression_context case_context;
1503 struct executable_statement **next;
1506 while (parse_executable_statement (next, cfile, lose, case_context))
1507 next = &((*next) -> next);
1513 int parse_executable_statement (result, cfile, lose, case_context)
1514 struct executable_statement **result;
1515 struct parse *cfile;
1517 enum expression_context case_context;
1519 enum dhcp_token token;
1521 struct executable_statement base;
1523 struct option *option;
1524 struct option_cache *cache;
1528 struct dns_zone *zone;
1529 isc_result_t status;
1532 token = peek_token (&val, (unsigned *)0, cfile);
1535 next_token (&val, (unsigned *)0, cfile);
1536 return parse_if_statement (result, cfile, lose);
1539 token = next_token (&val, (unsigned *)0, cfile);
1540 token = next_token (&val, (unsigned *)0, cfile);
1541 if (token != STRING) {
1542 parse_warn (cfile, "expecting class name.");
1543 skip_to_semi (cfile);
1547 cta = (struct class *)0;
1548 status = find_class (&cta, val, MDL);
1549 if (status != ISC_R_SUCCESS) {
1550 parse_warn (cfile, "class %s: %s",
1551 val, isc_result_totext (status));
1552 skip_to_semi (cfile);
1556 if (!parse_semi (cfile)) {
1560 if (!executable_statement_allocate (result, MDL))
1561 log_fatal ("no memory for new statement.");
1562 (*result) -> op = add_statement;
1563 (*result) -> data.add = cta;
1567 token = next_token (&val, (unsigned *)0, cfile);
1568 if (!parse_semi (cfile)) {
1572 if (!executable_statement_allocate (result, MDL))
1573 log_fatal ("no memory for new statement.");
1574 (*result) -> op = break_statement;
1578 token = next_token (&val, (unsigned *)0, cfile);
1580 option = parse_option_name (cfile, 0, &known);
1585 return parse_option_statement (result, cfile, 1, option,
1586 send_option_statement);
1590 token = next_token (&val, (unsigned *)0, cfile);
1592 option = parse_option_name (cfile, 0, &known);
1597 return parse_option_statement (result, cfile, 1, option,
1598 supersede_option_statement);
1609 token = next_token (&val, (unsigned *)0, cfile);
1610 cache = (struct option_cache *)0;
1611 if (!parse_allow_deny (&cache, cfile, flag))
1613 if (!executable_statement_allocate (result, MDL))
1614 log_fatal ("no memory for new statement.");
1615 (*result) -> op = supersede_option_statement;
1616 (*result) -> data.option = cache;
1620 token = next_token (&val, (unsigned *)0, cfile);
1621 token = peek_token (&val, (unsigned *)0, cfile);
1623 goto switch_default;
1625 option = parse_option_name (cfile, 0, &known);
1630 return parse_option_statement (result, cfile, 1, option,
1631 default_option_statement);
1634 token = next_token (&val, (unsigned *)0, cfile);
1636 option = parse_option_name (cfile, 0, &known);
1641 return parse_option_statement (result, cfile, 1, option,
1642 prepend_option_statement);
1645 token = next_token (&val, (unsigned *)0, cfile);
1647 option = parse_option_name (cfile, 0, &known);
1652 return parse_option_statement (result, cfile, 1, option,
1653 append_option_statement);
1656 token = next_token (&val, (unsigned *)0, cfile);
1657 return parse_on_statement (result, cfile, lose);
1660 token = next_token (&val, (unsigned *)0, cfile);
1661 return parse_switch_statement (result, cfile, lose);
1664 token = next_token (&val, (unsigned *)0, cfile);
1665 if (case_context == context_any) {
1667 "case statement in inappropriate scope.");
1669 skip_to_semi (cfile);
1672 return parse_case_statement (result,
1673 cfile, lose, case_context);
1676 token = next_token (&val, (unsigned *)0, cfile);
1677 if (case_context == context_any) {
1678 parse_warn (cfile, "switch default statement in %s",
1679 "inappropriate scope.");
1684 if (!executable_statement_allocate (result, MDL))
1685 log_fatal ("no memory for default statement.");
1686 (*result) -> op = default_statement;
1692 token = next_token (&val, (unsigned *)0, cfile);
1693 if (token == DEFINE)
1698 token = next_token (&val, (unsigned *)0, cfile);
1699 if (token != NAME && token != NUMBER_OR_NAME) {
1701 "%s can't be a variable name", val);
1703 skip_to_semi (cfile);
1708 if (!executable_statement_allocate (result, MDL))
1709 log_fatal ("no memory for set statement.");
1710 (*result) -> op = flag ? define_statement : set_statement;
1711 (*result) -> data.set.name = dmalloc (strlen (val) + 1, MDL);
1712 if (!(*result)->data.set.name)
1713 log_fatal ("can't allocate variable name");
1714 strcpy ((*result) -> data.set.name, val);
1715 token = next_token (&val, (unsigned *)0, cfile);
1717 if (token == LPAREN) {
1718 struct string_list *head, *cur, *new;
1719 struct expression *expr;
1720 head = cur = (struct string_list *)0;
1722 token = next_token (&val,
1723 (unsigned *)0, cfile);
1724 if (token == RPAREN)
1726 if (token != NAME && token != NUMBER_OR_NAME) {
1728 "expecting argument name");
1729 skip_to_rbrace (cfile, 0);
1731 executable_statement_dereference
1735 new = ((struct string_list *)
1736 dmalloc (sizeof (struct string_list) +
1737 strlen (val), MDL));
1739 log_fatal ("can't allocate string.");
1740 memset (new, 0, sizeof *new);
1741 strcpy (new -> string, val);
1748 token = next_token (&val,
1749 (unsigned *)0, cfile);
1750 } while (token == COMMA);
1752 if (token != RPAREN) {
1753 parse_warn (cfile, "expecting right paren.");
1755 skip_to_semi (cfile);
1757 executable_statement_dereference (result, MDL);
1761 token = next_token (&val, (unsigned *)0, cfile);
1762 if (token != LBRACE) {
1763 parse_warn (cfile, "expecting left brace.");
1767 expr = (struct expression *)0;
1768 if (!(expression_allocate (&expr, MDL)))
1769 log_fatal ("can't allocate expression.");
1770 expr -> op = expr_function;
1771 if (!fundef_allocate (&expr -> data.func, MDL))
1772 log_fatal ("can't allocate fundef.");
1773 expr -> data.func -> args = head;
1774 (*result) -> data.set.expr = expr;
1776 if (!(parse_executable_statements
1777 (&expr -> data.func -> statements, cfile, lose,
1783 token = next_token (&val, (unsigned *)0, cfile);
1784 if (token != RBRACE) {
1785 parse_warn (cfile, "expecting rigt brace.");
1789 if (token != EQUAL) {
1791 "expecting '=' in %s statement.",
1792 flag ? "define" : "set");
1796 if (!parse_expression (&(*result) -> data.set.expr,
1797 cfile, lose, context_any,
1798 (struct expression **)0,
1802 "expecting expression.");
1805 skip_to_semi (cfile);
1806 executable_statement_dereference (result, MDL);
1809 if (!parse_semi (cfile)) {
1811 executable_statement_dereference (result, MDL);
1818 token = next_token (&val, (unsigned *)0, cfile);
1820 token = next_token (&val, (unsigned *)0, cfile);
1821 if (token != NAME && token != NUMBER_OR_NAME) {
1823 "%s can't be a variable name", val);
1825 skip_to_semi (cfile);
1830 if (!executable_statement_allocate (result, MDL))
1831 log_fatal ("no memory for set statement.");
1832 (*result) -> op = unset_statement;
1833 (*result) -> data.unset = dmalloc (strlen (val) + 1, MDL);
1834 if (!(*result)->data.unset)
1835 log_fatal ("can't allocate variable name");
1836 strcpy ((*result) -> data.unset, val);
1837 if (!parse_semi (cfile)) {
1839 executable_statement_dereference (result, MDL);
1845 token = next_token (&val, (unsigned *)0, cfile);
1847 if (!executable_statement_allocate (result, MDL))
1848 log_fatal ("no memory for eval statement.");
1849 (*result) -> op = eval_statement;
1851 if (!parse_expression (&(*result) -> data.eval,
1852 cfile, lose, context_data, /* XXX */
1853 (struct expression **)0, expr_none)) {
1856 "expecting data expression.");
1859 skip_to_semi (cfile);
1860 executable_statement_dereference (result, MDL);
1863 if (!parse_semi (cfile)) {
1865 executable_statement_dereference (result, MDL);
1870 token = next_token (&val, (unsigned *)0, cfile);
1872 if (!executable_statement_allocate (result, MDL))
1873 log_fatal ("no memory for return statement.");
1874 (*result) -> op = return_statement;
1876 if (!parse_expression (&(*result) -> data.retval,
1877 cfile, lose, context_data,
1878 (struct expression **)0, expr_none)) {
1881 "expecting data expression.");
1884 skip_to_semi (cfile);
1885 executable_statement_dereference (result, MDL);
1888 if (!parse_semi (cfile)) {
1890 executable_statement_dereference (result, MDL);
1896 token = next_token (&val, (unsigned *)0, cfile);
1898 if (!executable_statement_allocate (result, MDL))
1899 log_fatal ("no memory for log statement.");
1900 (*result) -> op = log_statement;
1902 token = next_token (&val, (unsigned *)0, cfile);
1903 if (token != LPAREN) {
1904 parse_warn (cfile, "left parenthesis expected.");
1905 skip_to_semi (cfile);
1910 token = peek_token (&val, (unsigned *)0, cfile);
1912 if (token == FATAL) {
1913 (*result) -> data.log.priority = log_priority_fatal;
1914 } else if (token == ERROR) {
1915 (*result) -> data.log.priority = log_priority_error;
1916 } else if (token == TOKEN_DEBUG) {
1917 (*result) -> data.log.priority = log_priority_debug;
1918 } else if (token == INFO) {
1919 (*result) -> data.log.priority = log_priority_info;
1921 (*result) -> data.log.priority = log_priority_debug;
1925 token = next_token (&val, (unsigned *)0, cfile);
1926 token = next_token (&val, (unsigned *)0, cfile);
1927 if (token != COMMA) {
1928 parse_warn (cfile, "comma expected.");
1929 skip_to_semi (cfile);
1935 if (!(parse_data_expression
1936 (&(*result) -> data.log.expr, cfile, lose))) {
1937 skip_to_semi (cfile);
1942 token = next_token (&val, (unsigned *)0, cfile);
1943 if (token != RPAREN) {
1944 parse_warn (cfile, "right parenthesis expected.");
1945 skip_to_semi (cfile);
1950 token = next_token (&val, (unsigned *)0, cfile);
1951 if (token != SEMI) {
1952 parse_warn (cfile, "semicolon expected.");
1953 skip_to_semi (cfile);
1959 /* Not really a statement, but we parse it here anyway
1960 because it's appropriate for all DHCP agents with
1963 token = next_token (&val, (unsigned *)0, cfile);
1964 zone = (struct dns_zone *)0;
1965 if (!dns_zone_allocate (&zone, MDL))
1966 log_fatal ("no memory for new zone.");
1967 zone -> name = parse_host_name (cfile);
1968 if (!zone -> name) {
1969 parse_warn (cfile, "expecting hostname.");
1972 skip_to_semi (cfile);
1973 dns_zone_dereference (&zone, MDL);
1976 i = strlen (zone -> name);
1977 if (zone -> name [i - 1] != '.') {
1978 s = dmalloc ((unsigned)i + 2, MDL);
1980 parse_warn (cfile, "no trailing '.' on zone");
1983 strcpy (s, zone -> name);
1986 dfree (zone -> name, MDL);
1989 if (!parse_zone (zone, cfile))
1991 status = enter_dns_zone (zone);
1992 if (status != ISC_R_SUCCESS) {
1993 parse_warn (cfile, "dns zone key %s: %s",
1994 zone -> name, isc_result_totext (status));
1995 dns_zone_dereference (&zone, MDL);
1998 dns_zone_dereference (&zone, MDL);
2001 /* Also not really a statement, but same idea as above. */
2003 token = next_token (&val, (unsigned *)0, cfile);
2004 if (!parse_key (cfile)) {
2011 if (config_universe && is_identifier (token)) {
2012 option = (struct option *)0;
2013 option_hash_lookup (&option, config_universe -> hash,
2016 token = next_token (&val,
2017 (unsigned *)0, cfile);
2018 return parse_option_statement
2019 (result, cfile, 1, option,
2020 supersede_option_statement);
2024 if (token == NUMBER_OR_NAME || token == NAME) {
2025 /* This is rather ugly. Since function calls are
2026 data expressions, fake up an eval statement. */
2027 if (!executable_statement_allocate (result, MDL))
2028 log_fatal ("no memory for eval statement.");
2029 (*result) -> op = eval_statement;
2031 if (!parse_expression (&(*result) -> data.eval,
2032 cfile, lose, context_data,
2033 (struct expression **)0,
2036 parse_warn (cfile, "expecting "
2040 skip_to_semi (cfile);
2041 executable_statement_dereference (result, MDL);
2044 if (!parse_semi (cfile)) {
2046 executable_statement_dereference (result, MDL);
2059 /* zone-statements :== zone-statement |
2060 zone-statement zone-statements
2062 PRIMARY ip-addresses SEMI |
2063 SECONDARY ip-addresses SEMI |
2065 ip-addresses :== ip-addr-or-hostname |
2066 ip-addr-or-hostname COMMA ip-addresses
2067 key-reference :== KEY STRING |
2070 int parse_zone (struct dns_zone *zone, struct parse *cfile)
2075 struct option_cache *oc;
2078 token = next_token (&val, (unsigned *)0, cfile);
2079 if (token != LBRACE) {
2080 parse_warn (cfile, "expecting left brace");
2085 token = peek_token (&val, (unsigned *)0, cfile);
2088 if (zone -> primary) {
2090 "more than one primary.");
2091 skip_to_semi (cfile);
2094 if (!option_cache_allocate (&zone -> primary, MDL))
2095 log_fatal ("can't allocate primary option cache.");
2096 oc = zone -> primary;
2100 if (zone -> secondary) {
2101 parse_warn (cfile, "more than one secondary.");
2102 skip_to_semi (cfile);
2105 if (!option_cache_allocate (&zone -> secondary, MDL))
2106 log_fatal ("can't allocate secondary.");
2107 oc = zone -> secondary;
2109 token = next_token (&val, (unsigned *)0, cfile);
2111 struct expression *expr = (struct expression *)0;
2112 if (!parse_ip_addr_or_hostname (&expr, cfile, 0)) {
2114 "expecting IP addr or hostname.");
2115 skip_to_semi (cfile);
2118 if (oc -> expression) {
2119 struct expression *old =
2120 (struct expression *)0;
2121 expression_reference (&old,
2124 expression_dereference (&oc -> expression,
2126 if (!make_concat (&oc -> expression,
2128 log_fatal ("no memory for concat.");
2129 expression_dereference (&expr, MDL);
2130 expression_dereference (&old, MDL);
2132 expression_reference (&oc -> expression,
2134 expression_dereference (&expr, MDL);
2136 token = next_token (&val, (unsigned *)0, cfile);
2137 } while (token == COMMA);
2138 if (token != SEMI) {
2139 parse_warn (cfile, "expecting semicolon.");
2140 skip_to_semi (cfile);
2146 token = next_token (&val, (unsigned *)0, cfile);
2147 token = peek_token (&val, (unsigned *)0, cfile);
2148 if (token == STRING) {
2149 token = next_token (&val, (unsigned *)0, cfile);
2150 key_name = (char *)0;
2152 key_name = parse_host_name (cfile);
2154 parse_warn (cfile, "expecting key name.");
2155 skip_to_semi (cfile);
2160 if (omapi_auth_key_lookup_name (&zone -> key, val) !=
2162 parse_warn (cfile, "unknown key %s", val);
2164 dfree (key_name, MDL);
2165 if (!parse_semi (cfile))
2175 token = next_token (&val, (unsigned *)0, cfile);
2176 if (token != RBRACE) {
2177 parse_warn (cfile, "expecting right brace.");
2183 /* key-statements :== key-statement |
2184 key-statement key-statements
2186 ALGORITHM host-name SEMI |
2187 secret-definition SEMI
2188 secret-definition :== SECRET base64val |
2191 int parse_key (struct parse *cfile)
2196 struct auth_key *key;
2197 struct data_string ds;
2198 isc_result_t status;
2201 key = (struct auth_key *)0;
2202 if (omapi_auth_key_new (&key, MDL) != ISC_R_SUCCESS)
2203 log_fatal ("no memory for key");
2205 token = peek_token (&val, (unsigned *)0, cfile);
2206 if (token == STRING) {
2207 token = next_token (&val, (unsigned *)0, cfile);
2208 key -> name = dmalloc (strlen (val) + 1, MDL);
2210 log_fatal ("no memory for key name.");
2211 strcpy (key -> name, val);
2214 key -> name = parse_host_name (cfile);
2216 parse_warn (cfile, "expecting key name.");
2217 skip_to_semi (cfile);
2222 token = next_token (&val, (unsigned *)0, cfile);
2223 if (token != LBRACE) {
2224 parse_warn (cfile, "expecting left brace");
2229 token = next_token (&val, (unsigned *)0, cfile);
2232 if (key -> algorithm) {
2234 "key %s: too many algorithms",
2238 key -> algorithm = parse_host_name (cfile);
2239 if (!key -> algorithm) {
2241 "expecting key algorithm name.");
2244 if (!parse_semi (cfile))
2246 /* If the algorithm name isn't an FQDN, tack on
2247 the .SIG-ALG.REG.NET. domain. */
2248 s = strrchr (key -> algorithm, '.');
2250 static char add [] = ".SIG-ALG.REG.INT.";
2251 s = dmalloc (strlen (key -> algorithm) +
2254 log_error ("no memory for key %s.",
2258 strcpy (s, key -> algorithm);
2260 dfree (key -> algorithm, MDL);
2261 key -> algorithm = s;
2263 /* If there is no trailing '.', hack one in. */
2264 s = dmalloc (strlen (key -> algorithm) + 2, MDL);
2266 log_error ("no memory for key %s.",
2270 strcpy (s, key -> algorithm);
2272 dfree (key -> algorithm, MDL);
2273 key -> algorithm = s;
2279 parse_warn (cfile, "key %s: too many secrets",
2284 memset (&ds, 0, sizeof(ds));
2285 if (!parse_base64 (&ds, cfile))
2287 status = omapi_data_string_new (&key -> key, ds.len,
2289 if (status != ISC_R_SUCCESS)
2291 memcpy (key -> key -> value,
2292 ds.buffer -> data, ds.len);
2293 data_string_forget (&ds, MDL);
2295 if (!parse_semi (cfile))
2304 if (token != RBRACE) {
2305 parse_warn (cfile, "expecting right brace.");
2308 /* Allow the BIND 8 syntax, which has a semicolon after each
2310 token = peek_token (&val, (unsigned *)0, cfile);
2312 token = next_token (&val, (unsigned *)0, cfile);
2314 /* Remember the key. */
2315 status = omapi_auth_key_enter (key);
2316 if (status != ISC_R_SUCCESS) {
2317 parse_warn (cfile, "tsig key %s: %s",
2318 key -> name, isc_result_totext (status));
2321 omapi_auth_key_dereference (&key, MDL);
2325 skip_to_rbrace (cfile, 1);
2327 omapi_auth_key_dereference (&key, MDL);
2332 * on-statement :== event-types LBRACE executable-statements RBRACE
2333 * event-types :== event-type OR event-types |
2335 * event-type :== EXPIRY | COMMIT | RELEASE
2338 int parse_on_statement (result, cfile, lose)
2339 struct executable_statement **result;
2340 struct parse *cfile;
2343 enum dhcp_token token;
2346 if (!executable_statement_allocate (result, MDL))
2347 log_fatal ("no memory for new statement.");
2348 (*result) -> op = on_statement;
2351 token = next_token (&val, (unsigned *)0, cfile);
2354 (*result) -> data.on.evtypes |= ON_EXPIRY;
2358 (*result) -> data.on.evtypes |= ON_COMMIT;
2362 (*result) -> data.on.evtypes |= ON_RELEASE;
2366 (*result) -> data.on.evtypes |= ON_TRANSMISSION;
2370 parse_warn (cfile, "expecting a lease event type");
2371 skip_to_semi (cfile);
2373 executable_statement_dereference (result, MDL);
2376 token = next_token (&val, (unsigned *)0, cfile);
2377 } while (token == OR);
2379 /* Semicolon means no statements. */
2383 if (token != LBRACE) {
2384 parse_warn (cfile, "left brace expected.");
2385 skip_to_semi (cfile);
2387 executable_statement_dereference (result, MDL);
2390 if (!parse_executable_statements (&(*result) -> data.on.statements,
2391 cfile, lose, context_any)) {
2393 /* Try to even things up. */
2395 token = next_token (&val,
2396 (unsigned *)0, cfile);
2397 } while (token != END_OF_FILE && token != RBRACE);
2398 executable_statement_dereference (result, MDL);
2402 token = next_token (&val, (unsigned *)0, cfile);
2403 if (token != RBRACE) {
2404 parse_warn (cfile, "right brace expected.");
2405 skip_to_semi (cfile);
2407 executable_statement_dereference (result, MDL);
2414 * switch-statement :== LPAREN expr RPAREN LBRACE executable-statements RBRACE
2418 int parse_switch_statement (result, cfile, lose)
2419 struct executable_statement **result;
2420 struct parse *cfile;
2423 enum dhcp_token token;
2426 if (!executable_statement_allocate (result, MDL))
2427 log_fatal ("no memory for new statement.");
2428 (*result) -> op = switch_statement;
2430 token = next_token (&val, (unsigned *)0, cfile);
2431 if (token != LPAREN) {
2432 parse_warn (cfile, "expecting left brace.");
2435 skip_to_semi (cfile);
2437 executable_statement_dereference (result, MDL);
2441 if (!parse_expression (&(*result) -> data.s_switch.expr,
2442 cfile, lose, context_data_or_numeric,
2443 (struct expression **)0, expr_none)) {
2446 "expecting data or numeric expression.");
2452 token = next_token (&val, (unsigned *)0, cfile);
2453 if (token != RPAREN) {
2454 parse_warn (cfile, "right paren expected.");
2458 token = next_token (&val, (unsigned *)0, cfile);
2459 if (token != LBRACE) {
2460 parse_warn (cfile, "left brace expected.");
2463 if (!(parse_executable_statements
2464 (&(*result) -> data.s_switch.statements, cfile, lose,
2465 (is_data_expression ((*result) -> data.s_switch.expr)
2466 ? context_data : context_numeric)))) {
2468 skip_to_rbrace (cfile, 1);
2469 executable_statement_dereference (result, MDL);
2473 token = next_token (&val, (unsigned *)0, cfile);
2474 if (token != RBRACE) {
2475 parse_warn (cfile, "right brace expected.");
2482 * case-statement :== CASE expr COLON
2486 int parse_case_statement (result, cfile, lose, case_context)
2487 struct executable_statement **result;
2488 struct parse *cfile;
2490 enum expression_context case_context;
2492 enum dhcp_token token;
2495 if (!executable_statement_allocate (result, MDL))
2496 log_fatal ("no memory for new statement.");
2497 (*result) -> op = case_statement;
2499 if (!parse_expression (&(*result) -> data.c_case,
2500 cfile, lose, case_context,
2501 (struct expression **)0, expr_none))
2504 parse_warn (cfile, "expecting %s expression.",
2505 (case_context == context_data
2506 ? "data" : "numeric"));
2510 skip_to_semi (cfile);
2511 executable_statement_dereference (result, MDL);
2515 token = next_token (&val, (unsigned *)0, cfile);
2516 if (token != COLON) {
2517 parse_warn (cfile, "colon expected.");
2524 * if-statement :== boolean-expression LBRACE executable-statements RBRACE
2527 * else-statement :== <null> |
2528 * ELSE LBRACE executable-statements RBRACE |
2529 * ELSE IF if-statement |
2530 * ELSIF if-statement
2533 int parse_if_statement (result, cfile, lose)
2534 struct executable_statement **result;
2535 struct parse *cfile;
2538 enum dhcp_token token;
2542 if (!executable_statement_allocate (result, MDL))
2543 log_fatal ("no memory for if statement.");
2545 (*result) -> op = if_statement;
2547 token = peek_token (&val, (unsigned *)0, cfile);
2548 if (token == LPAREN) {
2550 next_token (&val, (unsigned *)0, cfile);
2555 if (!parse_boolean_expression (&(*result) -> data.ie.expr,
2558 parse_warn (cfile, "boolean expression expected.");
2559 executable_statement_dereference (result, MDL);
2563 #if defined (DEBUG_EXPRESSION_PARSE)
2564 print_expression ("if condition", (*result) -> data.ie.expr);
2567 token = next_token (&val, (unsigned *)0, cfile);
2568 if (token != RPAREN) {
2569 parse_warn (cfile, "expecting right paren.");
2571 executable_statement_dereference (result, MDL);
2575 token = next_token (&val, (unsigned *)0, cfile);
2576 if (token != LBRACE) {
2577 parse_warn (cfile, "left brace expected.");
2578 skip_to_semi (cfile);
2580 executable_statement_dereference (result, MDL);
2583 if (!parse_executable_statements (&(*result) -> data.ie.tc,
2584 cfile, lose, context_any)) {
2586 /* Try to even things up. */
2588 token = next_token (&val,
2589 (unsigned *)0, cfile);
2590 } while (token != END_OF_FILE && token != RBRACE);
2591 executable_statement_dereference (result, MDL);
2595 token = next_token (&val, (unsigned *)0, cfile);
2596 if (token != RBRACE) {
2597 parse_warn (cfile, "right brace expected.");
2598 skip_to_semi (cfile);
2600 executable_statement_dereference (result, MDL);
2603 token = peek_token (&val, (unsigned *)0, cfile);
2604 if (token == ELSE) {
2605 token = next_token (&val, (unsigned *)0, cfile);
2606 token = peek_token (&val, (unsigned *)0, cfile);
2608 token = next_token (&val, (unsigned *)0, cfile);
2609 if (!parse_if_statement (&(*result) -> data.ie.fc,
2613 "expecting if statement");
2614 executable_statement_dereference (result, MDL);
2618 } else if (token != LBRACE) {
2619 parse_warn (cfile, "left brace or if expected.");
2620 skip_to_semi (cfile);
2622 executable_statement_dereference (result, MDL);
2625 token = next_token (&val, (unsigned *)0, cfile);
2626 if (!(parse_executable_statements
2627 (&(*result) -> data.ie.fc,
2628 cfile, lose, context_any))) {
2629 executable_statement_dereference (result, MDL);
2632 token = next_token (&val, (unsigned *)0, cfile);
2633 if (token != RBRACE) {
2634 parse_warn (cfile, "right brace expected.");
2635 skip_to_semi (cfile);
2637 executable_statement_dereference (result, MDL);
2641 } else if (token == ELSIF) {
2642 token = next_token (&val, (unsigned *)0, cfile);
2643 if (!parse_if_statement (&(*result) -> data.ie.fc,
2647 "expecting conditional.");
2648 executable_statement_dereference (result, MDL);
2653 (*result) -> data.ie.fc = (struct executable_statement *)0;
2659 * boolean_expression :== CHECK STRING |
2660 * NOT boolean-expression |
2661 * data-expression EQUAL data-expression |
2662 * data-expression BANG EQUAL data-expression |
2663 * boolean-expression AND boolean-expression |
2664 * boolean-expression OR boolean-expression
2665 * EXISTS OPTION-NAME
2668 int parse_boolean_expression (expr, cfile, lose)
2669 struct expression **expr;
2670 struct parse *cfile;
2673 /* Parse an expression... */
2674 if (!parse_expression (expr, cfile, lose, context_boolean,
2675 (struct expression **)0, expr_none))
2678 if (!is_boolean_expression (*expr) &&
2679 (*expr) -> op != expr_variable_reference &&
2680 (*expr) -> op != expr_funcall) {
2681 parse_warn (cfile, "Expecting a boolean expression.");
2683 expression_dereference (expr, MDL);
2690 * data_expression :== SUBSTRING LPAREN data-expression COMMA
2691 * numeric-expression COMMA
2692 * numeric-expression RPAREN |
2693 * CONCAT LPAREN data-expression COMMA
2694 data-expression RPAREN
2695 * SUFFIX LPAREN data_expression COMMA
2696 * numeric-expression RPAREN |
2697 * OPTION option_name |
2699 * PACKET LPAREN numeric-expression COMMA
2700 * numeric-expression RPAREN |
2702 * colon_seperated_hex_list
2705 int parse_data_expression (expr, cfile, lose)
2706 struct expression **expr;
2707 struct parse *cfile;
2710 /* Parse an expression... */
2711 if (!parse_expression (expr, cfile, lose, context_data,
2712 (struct expression **)0, expr_none))
2715 if (!is_data_expression (*expr) &&
2716 (*expr) -> op != expr_variable_reference &&
2717 (*expr) -> op != expr_funcall) {
2718 parse_warn (cfile, "Expecting a data expression.");
2726 * numeric-expression :== EXTRACT_INT LPAREN data-expression
2727 * COMMA number RPAREN |
2731 int parse_numeric_expression (expr, cfile, lose)
2732 struct expression **expr;
2733 struct parse *cfile;
2736 /* Parse an expression... */
2737 if (!parse_expression (expr, cfile, lose, context_numeric,
2738 (struct expression **)0, expr_none))
2741 if (!is_numeric_expression (*expr) &&
2742 (*expr) -> op != expr_variable_reference &&
2743 (*expr) -> op != expr_funcall) {
2744 parse_warn (cfile, "Expecting a numeric expression.");
2752 * dns-expression :==
2753 * UPDATE LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
2754 * data-expression COMMA numeric-expression RPAREN
2755 * DELETE LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
2756 * data-expression RPAREN
2757 * EXISTS LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
2758 * data-expression RPAREN
2759 * NOT EXISTS LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
2760 * data-expression RPAREN
2761 * ns-class :== IN | CHAOS | HS | NUMBER
2762 * ns-type :== A | PTR | MX | TXT | NUMBER
2765 int parse_dns_expression (expr, cfile, lose)
2766 struct expression **expr;
2767 struct parse *cfile;
2770 /* Parse an expression... */
2771 if (!parse_expression (expr, cfile, lose, context_dns,
2772 (struct expression **)0, expr_none))
2775 if (!is_dns_expression (*expr) &&
2776 (*expr) -> op != expr_variable_reference &&
2777 (*expr) -> op != expr_funcall) {
2778 parse_warn (cfile, "Expecting a dns update subexpression.");
2785 /* Parse a subexpression that does not contain a binary operator. */
2787 int parse_non_binary (expr, cfile, lose, context)
2788 struct expression **expr;
2789 struct parse *cfile;
2791 enum expression_context context;
2793 enum dhcp_token token;
2795 struct collection *col;
2796 struct option *option;
2797 struct expression *nexp, **ep;
2799 enum expr_op opcode;
2802 struct executable_statement *stmt;
2805 isc_result_t status, code;
2808 token = peek_token (&val, (unsigned *)0, cfile);
2810 /* Check for unary operators... */
2813 token = next_token (&val, (unsigned *)0, cfile);
2814 token = next_token (&val, (unsigned *)0, cfile);
2815 if (token != STRING) {
2816 parse_warn (cfile, "string expected.");
2817 skip_to_semi (cfile);
2821 for (col = collections; col; col = col -> next)
2822 if (!strcmp (col -> name, val))
2825 parse_warn (cfile, "unknown collection.");
2829 if (!expression_allocate (expr, MDL))
2830 log_fatal ("can't allocate expression");
2831 (*expr) -> op = expr_check;
2832 (*expr) -> data.check = col;
2836 token = next_token (&val, (unsigned *)0, cfile);
2837 if (context == context_dns) {
2838 token = peek_token (&val, (unsigned *)0, cfile);
2841 if (!expression_allocate (expr, MDL))
2842 log_fatal ("can't allocate expression");
2843 (*expr) -> op = expr_not;
2844 if (!parse_non_binary (&(*expr) -> data.not,
2845 cfile, lose, context_boolean)) {
2847 parse_warn (cfile, "expression expected");
2848 skip_to_semi (cfile);
2851 expression_dereference (expr, MDL);
2854 if (!is_boolean_expression ((*expr) -> data.not)) {
2856 parse_warn (cfile, "boolean expression expected");
2857 skip_to_semi (cfile);
2858 expression_dereference (expr, MDL);
2864 token = next_token (&val, (unsigned *)0, cfile);
2865 if (!parse_expression (expr, cfile, lose, context,
2866 (struct expression **)0, expr_none)) {
2868 parse_warn (cfile, "expression expected");
2869 skip_to_semi (cfile);
2874 token = next_token (&val, (unsigned *)0, cfile);
2875 if (token != RPAREN) {
2877 parse_warn (cfile, "right paren expected");
2878 skip_to_semi (cfile);
2884 if (context == context_dns)
2886 token = next_token (&val, (unsigned *)0, cfile);
2887 if (!expression_allocate (expr, MDL))
2888 log_fatal ("can't allocate expression");
2889 (*expr) -> op = expr_exists;
2891 (*expr) -> data.option = parse_option_name (cfile, 0, &known);
2892 if (!(*expr) -> data.option) {
2894 expression_dereference (expr, MDL);
2900 token = next_token (&val, (unsigned *)0, cfile);
2901 if (!expression_allocate (expr, MDL))
2902 log_fatal ("can't allocate expression");
2903 (*expr) -> op = expr_static;
2907 token = next_token (&val, (unsigned *)0, cfile);
2908 if (!expression_allocate (expr, MDL))
2909 log_fatal ("can't allocate expression");
2910 (*expr) -> op = expr_known;
2914 token = next_token (&val, (unsigned *)0, cfile);
2915 if (!expression_allocate (expr, MDL))
2916 log_fatal ("can't allocate expression");
2917 (*expr) -> op = expr_substring;
2919 token = next_token (&val, (unsigned *)0, cfile);
2920 if (token != LPAREN) {
2922 expression_dereference (expr, MDL);
2923 parse_warn (cfile, "left parenthesis expected.");
2928 if (!parse_data_expression (&(*expr) -> data.substring.expr,
2931 expression_dereference (expr, MDL);
2934 "expecting data expression.");
2935 skip_to_semi (cfile);
2941 token = next_token (&val, (unsigned *)0, cfile);
2942 if (token != COMMA) {
2944 expression_dereference (expr, MDL);
2945 parse_warn (cfile, "comma expected.");
2951 if (!parse_numeric_expression
2952 (&(*expr) -> data.substring.offset,cfile, lose)) {
2956 "expecting numeric expression.");
2957 skip_to_semi (cfile);
2960 expression_dereference (expr, MDL);
2964 token = next_token (&val, (unsigned *)0, cfile);
2968 if (!parse_numeric_expression
2969 (&(*expr) -> data.substring.len, cfile, lose))
2972 token = next_token (&val, (unsigned *)0, cfile);
2973 if (token != RPAREN) {
2975 parse_warn (cfile, "right parenthesis expected.");
2977 expression_dereference (expr, MDL);
2983 token = next_token (&val, (unsigned *)0, cfile);
2984 if (!expression_allocate (expr, MDL))
2985 log_fatal ("can't allocate expression");
2986 (*expr) -> op = expr_suffix;
2988 token = next_token (&val, (unsigned *)0, cfile);
2989 if (token != LPAREN)
2992 if (!parse_data_expression (&(*expr) -> data.suffix.expr,
2996 token = next_token (&val, (unsigned *)0, cfile);
3000 if (!parse_numeric_expression (&(*expr) -> data.suffix.len,
3004 token = next_token (&val, (unsigned *)0, cfile);
3005 if (token != RPAREN)
3010 token = next_token (&val, (unsigned *)0, cfile);
3011 if (!expression_allocate (expr, MDL))
3012 log_fatal ("can't allocate expression");
3013 (*expr) -> op = expr_concat;
3015 token = next_token (&val, (unsigned *)0, cfile);
3016 if (token != LPAREN)
3019 if (!parse_data_expression (&(*expr) -> data.concat [0],
3023 token = next_token (&val, (unsigned *)0, cfile);
3028 if (!parse_data_expression (&(*expr) -> data.concat [1],
3032 token = next_token (&val, (unsigned *)0, cfile);
3034 if (token == COMMA) {
3035 nexp = (struct expression *)0;
3036 if (!expression_allocate (&nexp, MDL))
3037 log_fatal ("can't allocate at CONCAT2");
3038 nexp -> op = expr_concat;
3039 expression_reference (&nexp -> data.concat [0],
3041 expression_dereference (expr, MDL);
3042 expression_reference (expr, nexp, MDL);
3043 expression_dereference (&nexp, MDL);
3044 goto concat_another;
3047 if (token != RPAREN)
3051 case BINARY_TO_ASCII:
3052 token = next_token (&val, (unsigned *)0, cfile);
3053 if (!expression_allocate (expr, MDL))
3054 log_fatal ("can't allocate expression");
3055 (*expr) -> op = expr_binary_to_ascii;
3057 token = next_token (&val, (unsigned *)0, cfile);
3058 if (token != LPAREN)
3061 if (!parse_numeric_expression (&(*expr) -> data.b2a.base,
3065 token = next_token (&val, (unsigned *)0, cfile);
3069 if (!parse_numeric_expression (&(*expr) -> data.b2a.width,
3073 token = next_token (&val, (unsigned *)0, cfile);
3077 if (!parse_data_expression (&(*expr) -> data.b2a.seperator,
3081 token = next_token (&val, (unsigned *)0, cfile);
3085 if (!parse_data_expression (&(*expr) -> data.b2a.buffer,
3089 token = next_token (&val, (unsigned *)0, cfile);
3090 if (token != RPAREN)
3095 token = next_token (&val, (unsigned *)0, cfile);
3096 if (!expression_allocate (expr, MDL))
3097 log_fatal ("can't allocate expression");
3098 (*expr) -> op = expr_reverse;
3100 token = next_token (&val, (unsigned *)0, cfile);
3101 if (token != LPAREN)
3104 if (!(parse_numeric_expression
3105 (&(*expr) -> data.reverse.width, cfile, lose)))
3108 token = next_token (&val, (unsigned *)0, cfile);
3112 if (!(parse_data_expression
3113 (&(*expr) -> data.reverse.buffer, cfile, lose)))
3116 token = next_token (&val, (unsigned *)0, cfile);
3117 if (token != RPAREN)
3122 /* pick (a, b, c) actually produces an internal representation
3123 that looks like pick (a, pick (b, pick (c, nil))). */
3124 token = next_token (&val, (unsigned *)0, cfile);
3125 if (!(expression_allocate (expr, MDL)))
3126 log_fatal ("can't allocate expression");
3128 token = next_token (&val, (unsigned *)0, cfile);
3129 if (token != LPAREN)
3132 nexp = (struct expression *)0;
3133 expression_reference (&nexp, *expr, MDL);
3135 nexp -> op = expr_pick_first_value;
3136 if (!(parse_data_expression
3137 (&nexp -> data.pick_first_value.car,
3141 token = next_token (&val, (unsigned *)0, cfile);
3142 if (token == COMMA) {
3143 struct expression *foo = (struct expression *)0;
3144 if (!expression_allocate (&foo, MDL))
3145 log_fatal ("can't allocate expr");
3146 expression_reference
3147 (&nexp -> data.pick_first_value.cdr, foo, MDL);
3148 expression_dereference (&nexp, MDL);
3149 expression_reference (&nexp, foo, MDL);
3150 expression_dereference (&foo, MDL);
3152 } while (token == COMMA);
3153 expression_dereference (&nexp, MDL);
3155 if (token != RPAREN)
3159 /* dns-update and dns-delete are present for historical
3160 purposes, but are deprecated in favor of ns-update
3161 in combination with update, delete, exists and not
3165 #if !defined (NSUPDATE)
3167 "Please rebuild dhcpd with --with-nsupdate.");
3169 token = next_token (&val, (unsigned *)0, cfile);
3170 if (token == DNS_UPDATE)
3171 opcode = expr_ns_add;
3173 opcode = expr_ns_delete;
3175 token = next_token (&val, (unsigned *)0, cfile);
3176 if (token != LPAREN)
3179 token = next_token (&val, (unsigned *)0, cfile);
3180 if (token != STRING) {
3182 "parse_expression: expecting string.");
3184 skip_to_semi (cfile);
3189 if (!strcasecmp (val, "a"))
3191 else if (!strcasecmp (val, "ptr"))
3193 else if (!strcasecmp (val, "mx"))
3195 else if (!strcasecmp (val, "cname"))
3197 else if (!strcasecmp (val, "TXT"))
3200 parse_warn (cfile, "unexpected rrtype: %s", val);
3204 s = (opcode == expr_ns_add
3206 : "old-dns-delete");
3207 cptr = dmalloc (strlen (s) + 1, MDL);
3209 log_fatal ("can't allocate name for %s", s);
3211 if (!expression_allocate (expr, MDL))
3212 log_fatal ("can't allocate expression");
3213 (*expr) -> op = expr_funcall;
3214 (*expr) -> data.funcall.name = cptr;
3216 /* Fake up a function call. */
3217 ep = &(*expr) -> data.funcall.arglist;
3218 if (!expression_allocate (ep, MDL))
3219 log_fatal ("can't allocate expression");
3220 (*ep) -> op = expr_arg;
3221 if (!make_const_int (&(*ep) -> data.arg.val, u))
3222 log_fatal ("can't allocate rrtype value.");
3224 token = next_token (&val, (unsigned *)0, cfile);
3227 ep = &((*ep) -> data.arg.next);
3228 if (!expression_allocate (ep, MDL))
3229 log_fatal ("can't allocate expression");
3230 (*ep) -> op = expr_arg;
3231 if (!(parse_data_expression (&(*ep) -> data.arg.val,
3235 token = next_token (&val, (unsigned *)0, cfile);
3239 ep = &((*ep) -> data.arg.next);
3240 if (!expression_allocate (ep, MDL))
3241 log_fatal ("can't allocate expression");
3242 (*ep) -> op = expr_arg;
3243 if (!(parse_data_expression (&(*ep) -> data.arg.val,
3247 if (opcode == expr_ns_add) {
3248 token = next_token (&val, (unsigned *)0, cfile);
3252 ep = &((*ep) -> data.arg.next);
3253 if (!expression_allocate (ep, MDL))
3254 log_fatal ("can't allocate expression");
3255 (*ep) -> op = expr_arg;
3256 if (!(parse_numeric_expression (&(*ep) -> data.arg.val,
3259 "expecting numeric expression.");
3264 token = next_token (&val, (unsigned *)0, cfile);
3265 if (token != RPAREN)
3270 #if !defined (NSUPDATE)
3272 "Please rebuild dhcpd with --with-nsupdate.");
3274 token = next_token (&val, (unsigned *)0, cfile);
3275 if (!expression_allocate (expr, MDL))
3276 log_fatal ("can't allocate expression");
3278 token = next_token (&val, (unsigned *)0, cfile);
3279 if (token != LPAREN)
3284 nexp -> op = expr_dns_transaction;
3285 if (!(parse_dns_expression
3286 (&nexp -> data.dns_transaction.car,
3292 "expecting dns expression.");
3294 expression_dereference (expr, MDL);
3299 token = next_token (&val, (unsigned *)0, cfile);
3301 if (token == COMMA) {
3302 if (!(expression_allocate
3303 (&nexp -> data.dns_transaction.cdr,
3306 ("can't allocate expression");
3307 nexp = nexp -> data.dns_transaction.cdr;
3309 } while (token == COMMA);
3311 if (token != RPAREN)
3315 /* NOT EXISTS is special cased above... */
3317 token = peek_token (&val, (unsigned *)0, cfile);
3318 if (token != EXISTS) {
3319 parse_warn (cfile, "expecting DNS prerequisite.");
3323 opcode = expr_ns_not_exists;
3326 opcode = expr_ns_add;
3329 opcode = expr_ns_delete;
3332 opcode = expr_ns_exists;
3334 token = next_token (&val, (unsigned *)0, cfile);
3336 #if !defined (NSUPDATE)
3338 "Please rebuild dhcpd with --with-nsupdate.");
3340 if (!expression_allocate (expr, MDL))
3341 log_fatal ("can't allocate expression");
3342 (*expr) -> op = opcode;
3344 token = next_token (&val, (unsigned *)0, cfile);
3345 if (token != LPAREN)
3348 token = next_token (&val, (unsigned *)0, cfile);
3349 if (!is_identifier (token) && token != NUMBER) {
3350 parse_warn (cfile, "expecting identifier or number.");
3352 expression_dereference (expr, MDL);
3353 skip_to_semi (cfile);
3358 if (token == NUMBER)
3359 (*expr) -> data.ns_add.rrclass = atoi (val);
3360 else if (!strcasecmp (val, "in"))
3361 (*expr) -> data.ns_add.rrclass = C_IN;
3362 else if (!strcasecmp (val, "chaos"))
3363 (*expr) -> data.ns_add.rrclass = C_CHAOS;
3364 else if (!strcasecmp (val, "hs"))
3365 (*expr) -> data.ns_add.rrclass = C_HS;
3367 parse_warn (cfile, "unexpected rrclass: %s", val);
3371 token = next_token (&val, (unsigned *)0, cfile);
3375 token = next_token (&val, (unsigned *)0, cfile);
3376 if (!is_identifier (token) && token != NUMBER) {
3377 parse_warn (cfile, "expecting identifier or number.");
3381 if (token == NUMBER)
3382 (*expr) -> data.ns_add.rrtype = atoi (val);
3383 else if (!strcasecmp (val, "a"))
3384 (*expr) -> data.ns_add.rrtype = T_A;
3385 else if (!strcasecmp (val, "ptr"))
3386 (*expr) -> data.ns_add.rrtype = T_PTR;
3387 else if (!strcasecmp (val, "mx"))
3388 (*expr) -> data.ns_add.rrtype = T_MX;
3389 else if (!strcasecmp (val, "cname"))
3390 (*expr) -> data.ns_add.rrtype = T_CNAME;
3391 else if (!strcasecmp (val, "TXT"))
3392 (*expr) -> data.ns_add.rrtype = T_TXT;
3394 parse_warn (cfile, "unexpected rrtype: %s", val);
3398 token = next_token (&val, (unsigned *)0, cfile);
3402 if (!(parse_data_expression
3403 (&(*expr) -> data.ns_add.rrname, cfile, lose)))
3406 token = next_token (&val, (unsigned *)0, cfile);
3410 if (!(parse_data_expression
3411 (&(*expr) -> data.ns_add.rrdata, cfile, lose)))
3414 if (opcode == expr_ns_add) {
3415 token = next_token (&val, (unsigned *)0, cfile);
3419 if (!(parse_numeric_expression
3420 (&(*expr) -> data.ns_add.ttl, cfile,
3424 "expecting numeric expression.");
3429 token = next_token (&val, (unsigned *)0, cfile);
3430 if (token != RPAREN)
3436 if (!expression_allocate (expr, MDL))
3437 log_fatal ("can't allocate expression");
3438 (*expr) -> op = (token == OPTION
3440 : expr_config_option);
3441 token = next_token (&val, (unsigned *)0, cfile);
3443 (*expr) -> data.option = parse_option_name (cfile, 0, &known);
3444 if (!(*expr) -> data.option) {
3446 expression_dereference (expr, MDL);
3452 token = next_token (&val, (unsigned *)0, cfile);
3453 if (!expression_allocate (expr, MDL))
3454 log_fatal ("can't allocate expression");
3455 (*expr) -> op = expr_hardware;
3458 case LEASED_ADDRESS:
3459 token = next_token (&val, (unsigned *)0, cfile);
3460 if (!expression_allocate (expr, MDL))
3461 log_fatal ("can't allocate expression");
3462 (*expr) -> op = expr_leased_address;
3466 token = next_token (&val, (unsigned *)0, cfile);
3467 if (!expression_allocate (expr, MDL))
3468 log_fatal ("can't allocate expression");
3469 (*expr) -> op = expr_client_state;
3473 token = next_token (&val, (unsigned *)0, cfile);
3474 if (!expression_allocate (expr, MDL))
3475 log_fatal ("can't allocate expression");
3476 (*expr) -> op = expr_filename;
3480 token = next_token (&val, (unsigned *)0, cfile);
3481 if (!expression_allocate (expr, MDL))
3482 log_fatal ("can't allocate expression");
3483 (*expr) -> op = expr_sname;
3487 token = next_token (&val, (unsigned *)0, cfile);
3488 if (!expression_allocate (expr, MDL))
3489 log_fatal ("can't allocate expression");
3490 (*expr) -> op = expr_lease_time;
3494 token = next_token (&val, (unsigned *)0, cfile);
3495 if (!expression_allocate (expr, MDL))
3496 log_fatal ("can't allocate expression");
3497 (*expr) -> op = expr_null;
3500 case HOST_DECL_NAME:
3501 token = next_token (&val, (unsigned *)0, cfile);
3502 if (!expression_allocate (expr, MDL))
3503 log_fatal ("can't allocate expression");
3504 (*expr) -> op = expr_host_decl_name;
3507 case UPDATED_DNS_RR:
3508 token = next_token (&val, (unsigned *)0, cfile);
3510 token = next_token (&val, (unsigned *)0, cfile);
3511 if (token != LPAREN)
3514 token = next_token (&val, (unsigned *)0, cfile);
3515 if (token != STRING) {
3516 parse_warn (cfile, "expecting string.");
3521 if (!strcasecmp (val, "a"))
3522 s = "ddns-fwd-name";
3523 else if (!strcasecmp (val, "ptr"))
3524 s = "ddns-rev-name";
3526 parse_warn (cfile, "invalid DNS rrtype: %s", val);
3530 token = next_token (&val, (unsigned *)0, cfile);
3531 if (token != RPAREN)
3534 if (!expression_allocate (expr, MDL))
3535 log_fatal ("can't allocate expression");
3536 (*expr) -> op = expr_variable_reference;
3537 (*expr) -> data.variable =
3538 dmalloc (strlen (s) + 1, MDL);
3539 if (!(*expr) -> data.variable)
3540 log_fatal ("can't allocate variable name.");
3541 strcpy ((*expr) -> data.variable, s);
3545 token = next_token (&val, (unsigned *)0, cfile);
3546 if (!expression_allocate (expr, MDL))
3547 log_fatal ("can't allocate expression");
3548 (*expr) -> op = expr_packet;
3550 token = next_token (&val, (unsigned *)0, cfile);
3551 if (token != LPAREN)
3554 if (!parse_numeric_expression (&(*expr) -> data.packet.offset,
3558 token = next_token (&val, (unsigned *)0, cfile);
3562 if (!parse_numeric_expression (&(*expr) -> data.packet.len,
3566 token = next_token (&val, (unsigned *)0, cfile);
3567 if (token != RPAREN)
3572 token = next_token (&val, &len, cfile);
3573 if (!make_const_data (expr, (const unsigned char *)val,
3575 log_fatal ("can't make constant string expression.");
3579 token = next_token (&val, (unsigned *)0, cfile);
3580 token = next_token (&val, (unsigned *)0, cfile);
3581 if (token != LPAREN) {
3582 parse_warn (cfile, "left parenthesis expected.");
3587 if (!expression_allocate (expr, MDL))
3588 log_fatal ("can't allocate expression");
3590 if (!parse_data_expression (&(*expr) -> data.extract_int,
3594 "expecting data expression.");
3595 skip_to_semi (cfile);
3598 expression_dereference (expr, MDL);
3602 token = next_token (&val, (unsigned *)0, cfile);
3603 if (token != COMMA) {
3604 parse_warn (cfile, "comma expected.");
3606 expression_dereference (expr, MDL);
3610 token = next_token (&val, (unsigned *)0, cfile);
3611 if (token != NUMBER) {
3612 parse_warn (cfile, "number expected.");
3614 expression_dereference (expr, MDL);
3617 switch (atoi (val)) {
3619 (*expr) -> op = expr_extract_int8;
3623 (*expr) -> op = expr_extract_int16;
3627 (*expr) -> op = expr_extract_int32;
3632 "unsupported integer size %d", atoi (val));
3634 skip_to_semi (cfile);
3635 expression_dereference (expr, MDL);
3639 token = next_token (&val, (unsigned *)0, cfile);
3640 if (token != RPAREN) {
3641 parse_warn (cfile, "right parenthesis expected.");
3643 expression_dereference (expr, MDL);
3649 token = next_token (&val, (unsigned *)0, cfile);
3650 token = next_token (&val, (unsigned *)0, cfile);
3651 if (token != LPAREN) {
3652 parse_warn (cfile, "left parenthesis expected.");
3657 if (!expression_allocate (expr, MDL))
3658 log_fatal ("can't allocate expression");
3660 if (!parse_numeric_expression (&(*expr) -> data.encode_int,
3662 parse_warn (cfile, "expecting numeric expression.");
3663 skip_to_semi (cfile);
3665 expression_dereference (expr, MDL);
3669 token = next_token (&val, (unsigned *)0, cfile);
3670 if (token != COMMA) {
3671 parse_warn (cfile, "comma expected.");
3673 expression_dereference (expr, MDL);
3677 token = next_token (&val, (unsigned *)0, cfile);
3678 if (token != NUMBER) {
3679 parse_warn (cfile, "number expected.");
3681 expression_dereference (expr, MDL);
3684 switch (atoi (val)) {
3686 (*expr) -> op = expr_encode_int8;
3690 (*expr) -> op = expr_encode_int16;
3694 (*expr) -> op = expr_encode_int32;
3699 "unsupported integer size %d", atoi (val));
3701 skip_to_semi (cfile);
3702 expression_dereference (expr, MDL);
3706 token = next_token (&val, (unsigned *)0, cfile);
3707 if (token != RPAREN) {
3708 parse_warn (cfile, "right parenthesis expected.");
3710 expression_dereference (expr, MDL);
3716 /* If we're in a numeric context, this should just be a
3717 number, by itself. */
3718 if (context == context_numeric ||
3719 context == context_data_or_numeric) {
3720 next_token (&val, (unsigned *)0, cfile);
3721 if (!expression_allocate (expr, MDL))
3722 log_fatal ("can't allocate expression");
3723 (*expr) -> op = expr_const_int;
3724 (*expr) -> data.const_int = atoi (val);
3728 case NUMBER_OR_NAME:
3729 if (!expression_allocate (expr, MDL))
3730 log_fatal ("can't allocate expression");
3732 (*expr) -> op = expr_const_data;
3733 if (!parse_cshl (&(*expr) -> data.const_data, cfile)) {
3734 expression_dereference (expr, MDL);
3743 token = next_token (&val, (unsigned *)0, cfile);
3744 if (!expression_allocate (expr, MDL))
3745 log_fatal ("can't allocate expression");
3746 (*expr) -> op = expr_const_int;
3747 (*expr) -> data.const_int = known;
3751 known = ISC_R_SUCCESS;
3755 known = ISC_R_NOTAUTH;
3759 known = ISC_R_NOTIMPLEMENTED;
3763 known = ISC_R_NOTZONE;
3767 known = ISC_R_NXDOMAIN;
3771 known = ISC_R_NXRRSET;
3775 known = ISC_R_REFUSED;
3779 known = ISC_R_SERVFAIL;
3783 known = ISC_R_YXDOMAIN;
3787 known = ISC_R_YXRRSET;
3795 known = S_REBOOTING;
3799 known = S_SELECTING;
3803 known = S_REQUESTING;
3815 known = S_REBINDING;
3819 token = next_token (&val, (unsigned *)0, cfile);
3820 token = next_token (&val, (unsigned *)0, cfile);
3821 if (token != LPAREN)
3824 token = next_token (&val, (unsigned *)0, cfile);
3825 if (token != NAME && token != NUMBER_OR_NAME) {
3826 parse_warn (cfile, "%s can't be a variable name", val);
3827 skip_to_semi (cfile);
3832 if (!expression_allocate (expr, MDL))
3833 log_fatal ("can't allocate expression");
3834 (*expr) -> op = expr_variable_exists;
3835 (*expr) -> data.variable = dmalloc (strlen (val) + 1, MDL);
3836 if (!(*expr)->data.variable)
3837 log_fatal ("can't allocate variable name");
3838 strcpy ((*expr) -> data.variable, val);
3839 token = next_token (&val, (unsigned *)0, cfile);
3840 if (token != RPAREN)
3844 /* Not a valid start to an expression... */
3846 if (token != NAME && token != NUMBER_OR_NAME)
3849 token = next_token (&val, (unsigned *)0, cfile);
3851 /* Save the name of the variable being referenced. */
3852 cptr = dmalloc (strlen (val) + 1, MDL);
3854 log_fatal ("can't allocate variable name");
3857 /* Simple variable reference, as far as we can tell. */
3858 token = peek_token (&val, (unsigned *)0, cfile);
3859 if (token != LPAREN) {
3860 if (!expression_allocate (expr, MDL))
3861 log_fatal ("can't allocate expression");
3862 (*expr) -> op = expr_variable_reference;
3863 (*expr) -> data.variable = cptr;
3867 token = next_token (&val, (unsigned *)0, cfile);
3868 if (!expression_allocate (expr, MDL))
3869 log_fatal ("can't allocate expression");
3870 (*expr) -> op = expr_funcall;
3871 (*expr) -> data.funcall.name = cptr;
3873 /* Now parse the argument list. */
3874 ep = &(*expr) -> data.funcall.arglist;
3876 if (!expression_allocate (ep, MDL))
3877 log_fatal ("can't allocate expression");
3878 (*ep) -> op = expr_arg;
3879 if (!parse_expression (&(*ep) -> data.arg.val,
3880 cfile, lose, context_any,
3881 (struct expression **)0,
3885 "expecting expression.");
3888 skip_to_semi (cfile);
3889 expression_dereference (expr, MDL);
3892 ep = &((*ep) -> data.arg.next);
3893 token = next_token (&val, (unsigned *)0, cfile);
3894 } while (token == COMMA);
3895 if (token != RPAREN) {
3896 parse_warn (cfile, "Right parenthesis expected.");
3897 skip_to_semi (cfile);
3899 expression_dereference (expr, MDL);
3907 /* Parse an expression. */
3909 int parse_expression (expr, cfile, lose, context, plhs, binop)
3910 struct expression **expr;
3911 struct parse *cfile;
3913 enum expression_context context;
3914 struct expression **plhs;
3917 enum dhcp_token token;
3919 struct expression *rhs = (struct expression *)0, *tmp;
3920 struct expression *lhs = (struct expression *)0;
3921 enum expr_op next_op;
3922 enum expression_context
3923 lhs_context = context_any,
3924 rhs_context = context_any;
3926 /* Consume the left hand side we were passed. */
3928 expression_reference (&lhs, *plhs, MDL);
3929 expression_dereference (plhs, MDL);
3933 if (!parse_non_binary (&rhs, cfile, lose, context)) {
3934 /* If we already have a left-hand side, then it's not
3935 okay for there not to be a right-hand side here, so
3936 we need to flag it as an error. */
3940 "expecting right-hand side.");
3942 skip_to_semi (cfile);
3944 expression_dereference (&lhs, MDL);
3949 /* At this point, rhs contains either an entire subexpression,
3950 or at least a left-hand-side. If we do not see a binary token
3951 as the next token, we're done with the expression. */
3953 token = peek_token (&val, (unsigned *)0, cfile);
3956 token = next_token (&val, (unsigned *)0, cfile);
3957 token = peek_token (&val, (unsigned *)0, cfile);
3958 if (token != EQUAL) {
3959 parse_warn (cfile, "! in boolean context without =");
3961 skip_to_semi (cfile);
3963 expression_dereference (&lhs, MDL);
3966 next_op = expr_not_equal;
3967 context = expression_context (rhs);
3971 next_op = expr_equal;
3972 context = expression_context (rhs);
3977 context = expression_context (rhs);
3982 context = expression_context (rhs);
3987 context = expression_context (rhs);
3991 next_op = expr_subtract;
3992 context = expression_context (rhs);
3996 next_op = expr_divide;
3997 context = expression_context (rhs);
4001 next_op = expr_multiply;
4002 context = expression_context (rhs);
4006 next_op = expr_remainder;
4007 context = expression_context (rhs);
4011 next_op = expr_binary_and;
4012 context = expression_context (rhs);
4016 next_op = expr_binary_or;
4017 context = expression_context (rhs);
4021 next_op = expr_binary_xor;
4022 context = expression_context (rhs);
4026 next_op = expr_none;
4029 /* If we have no lhs yet, we just parsed it. */
4031 /* If there was no operator following what we just parsed,
4032 then we're done - return it. */
4033 if (next_op == expr_none) {
4038 rhs = (struct expression *)0;
4040 next_token (&val, (unsigned *)0, cfile);
4044 if (binop != expr_none) {
4045 rhs_context = expression_context(rhs);
4046 lhs_context = expression_context(lhs);
4048 if ((rhs_context != context_any) && (lhs_context != context_any) &&
4049 (rhs_context != lhs_context)) {
4050 parse_warn (cfile, "illegal expression relating different types");
4051 skip_to_semi (cfile);
4052 expression_dereference (&rhs, MDL);
4053 expression_dereference (&lhs, MDL);
4059 case expr_not_equal:
4061 if ((rhs_context != context_data_or_numeric) &&
4062 (rhs_context != context_data) &&
4063 (rhs_context != context_numeric) &&
4064 (rhs_context != context_any)) {
4065 parse_warn (cfile, "expecting data/numeric expression");
4066 skip_to_semi (cfile);
4067 expression_dereference (&rhs, MDL);
4075 if ((rhs_context != context_boolean) &&
4076 (rhs_context != context_any)) {
4077 parse_warn (cfile, "expecting boolean expressions");
4078 skip_to_semi (cfile);
4079 expression_dereference (&rhs, MDL);
4089 case expr_remainder:
4090 case expr_binary_and:
4091 case expr_binary_or:
4092 case expr_binary_xor:
4093 if ((rhs_context != context_numeric) &&
4094 (rhs_context != context_any)) {
4095 parse_warn (cfile, "expecting numeric expressions");
4096 skip_to_semi (cfile);
4097 expression_dereference (&rhs, MDL);
4108 /* Now, if we didn't find a binary operator, we're done parsing
4109 this subexpression, so combine it with the preceding binary
4110 operator and return the result. */
4111 if (next_op == expr_none) {
4112 if (!expression_allocate (expr, MDL))
4113 log_fatal ("Can't allocate expression!");
4115 (*expr) -> op = binop;
4116 /* All the binary operators' data union members
4117 are the same, so we'll cheat and use the member
4118 for the equals operator. */
4119 (*expr) -> data.equal [0] = lhs;
4120 (*expr) -> data.equal [1] = rhs;
4124 /* Eat the operator token - we now know it was a binary operator... */
4125 token = next_token (&val, (unsigned *)0, cfile);
4127 /* If the binary operator we saw previously has a lower precedence
4128 than the next operator, then the rhs we just parsed for that
4129 operator is actually the lhs of the operator with the higher
4130 precedence - to get the real rhs, we need to recurse on the
4132 if (binop != expr_none &&
4133 op_precedence (binop, next_op) < 0) {
4135 rhs = (struct expression *)0;
4136 if (!parse_expression (&rhs, cfile, lose, op_context (next_op),
4140 "expecting a subexpression");
4145 next_op = expr_none;
4148 /* Now combine the LHS and the RHS using binop. */
4149 tmp = (struct expression *)0;
4150 if (!expression_allocate (&tmp, MDL))
4151 log_fatal ("No memory for equal precedence combination.");
4153 /* Store the LHS and RHS. */
4154 tmp -> data.equal [0] = lhs;
4155 tmp -> data.equal [1] = rhs;
4159 tmp = (struct expression *)0;
4160 rhs = (struct expression *)0;
4162 /* Recursions don't return until we have parsed the end of the
4163 expression, so if we recursed earlier, we can now return what
4165 if (next_op == expr_none) {
4174 /* option-statement :== identifier DOT identifier <syntax> SEMI
4175 | identifier <syntax> SEMI
4177 Option syntax is handled specially through format strings, so it
4178 would be painful to come up with BNF for it. However, it always
4179 starts as above and ends in a SEMI. */
4181 int parse_option_statement (result, cfile, lookups, option, op)
4182 struct executable_statement **result;
4183 struct parse *cfile;
4185 struct option *option;
4186 enum statement_op op;
4189 enum dhcp_token token;
4190 const char *fmt = NULL;
4191 struct expression *expr = (struct expression *)0;
4192 struct expression *tmp;
4194 struct executable_statement *stmt;
4197 token = peek_token (&val, (unsigned *)0, cfile);
4198 if (token == SEMI) {
4199 /* Eat the semicolon... */
4200 token = next_token (&val, (unsigned *)0, cfile);
4204 if (token == EQUAL) {
4205 /* Eat the equals sign. */
4206 token = next_token (&val, (unsigned *)0, cfile);
4208 /* Parse a data expression and use its value for the data. */
4209 if (!parse_data_expression (&expr, cfile, &lose)) {
4210 /* In this context, we must have an executable
4211 statement, so if we found something else, it's
4215 "expecting a data expression.");
4216 skip_to_semi (cfile);
4221 /* We got a valid expression, so use it. */
4225 /* Parse the option data... */
4227 /* Set a flag if this is an array of a simple type (i.e.,
4228 not an array of pairs of IP addresses, or something
4230 int uniform = option -> format [1] == 'A';
4233 /* Set fmt to start of format for 'A' and one char back
4235 if ((fmt != NULL) &&
4236 (fmt != option -> format) && (*fmt == 'a'))
4239 fmt = ((fmt == NULL) ||
4240 (*fmt == 'A')) ? option -> format : fmt;
4242 /* 'a' means always uniform */
4243 uniform |= (fmt [1] == 'a');
4245 for ( ; *fmt; fmt++) {
4246 if ((*fmt == 'A') || (*fmt == 'a'))
4251 expr = (struct expression *)0;
4252 if (!parse_option_token (&expr, cfile, &fmt,
4253 tmp, uniform, lookups)) {
4254 if (fmt [1] != 'o') {
4256 expression_dereference (&tmp,
4261 tmp = (struct expression *)0;
4264 expression_dereference (&tmp, MDL);
4266 if ((*fmt == 'A') || (*fmt == 'a')) {
4267 token = peek_token (&val, (unsigned *)0, cfile);
4268 /* Comma means: continue with next element in array */
4269 if (token == COMMA) {
4270 token = next_token (&val,
4271 (unsigned *)0, cfile);
4274 /* no comma: end of array.
4275 'A' or end of string means: leave the loop */
4276 if ((*fmt == 'A') || (fmt[1] == '\0'))
4278 /* 'a' means: go on with next char */
4284 } while ((*fmt == 'A') || (*fmt == 'a'));
4287 if (!parse_semi (cfile))
4289 if (!executable_statement_allocate (result, MDL))
4290 log_fatal ("no memory for option statement.");
4291 (*result) -> op = op;
4292 if (expr && !option_cache (&(*result) -> data.option,
4293 (struct data_string *)0, expr, option, MDL))
4294 log_fatal ("no memory for option cache");
4296 expression_dereference (&expr, MDL);
4300 int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
4301 struct expression **rv;
4302 struct parse *cfile;
4304 struct expression *expr;
4309 enum dhcp_token token;
4310 struct expression *t = (struct expression *)0;
4311 unsigned char buf [4];
4317 struct enumeration_value *e;
4321 token = peek_token (&val, (unsigned *)0, cfile);
4322 if (!is_identifier (token)) {
4323 if ((*fmt) [1] != 'o') {
4324 parse_warn (cfile, "expecting identifier.");
4325 skip_to_semi (cfile);
4329 token = next_token (&val, &len, cfile);
4330 if (!make_const_data (&t, (const unsigned char *)val,
4332 log_fatal ("No memory for %s", val);
4336 g = strchr (*fmt, '.');
4339 "malformed encapsulation format (bug!)");
4340 skip_to_semi (cfile);
4345 token = peek_token (&val, (unsigned *)0, cfile);
4346 if (token == NUMBER_OR_NAME || token == NUMBER) {
4347 if (!expression_allocate (&t, MDL))
4349 if (!parse_cshl (&t -> data.const_data, cfile)) {
4350 expression_dereference (&t, MDL);
4353 t -> op = expr_const_data;
4354 } else if (token == STRING) {
4355 token = next_token (&val, &len, cfile);
4356 if (!make_const_data (&t, (const unsigned char *)val,
4358 log_fatal ("No memory for \"%s\"", val);
4360 if ((*fmt) [1] != 'o') {
4361 parse_warn (cfile, "expecting string %s.",
4362 "or hexadecimal data");
4363 skip_to_semi (cfile);
4369 case 'd': /* Domain name... */
4370 val = parse_host_name (cfile);
4372 parse_warn (cfile, "not a valid domain name.");
4373 skip_to_semi (cfile);
4379 case 't': /* Text string... */
4380 token = peek_token (&val, (unsigned *)0, cfile);
4381 if (token != STRING && !is_identifier (token)) {
4382 if ((*fmt) [1] != 'o') {
4383 parse_warn (cfile, "expecting string.");
4385 skip_to_semi (cfile);
4389 token = next_token (&val, &len, cfile);
4391 if (!make_const_data (&t, (const unsigned char *)val,
4393 log_fatal ("No memory for concatenation");
4398 g = strchr (*fmt, '.');
4400 parse_warn (cfile, "malformed %s (bug!)",
4401 "enumeration format");
4403 skip_to_semi (cfile);
4407 token = next_token (&val, (unsigned *)0, cfile);
4408 if (!is_identifier (token)) {
4410 "identifier expected");
4413 e = find_enumeration_value (f, (*fmt) - f, val);
4415 parse_warn (cfile, "unknown value");
4418 if (!make_const_data (&t, &e -> value, 1, 0, 1, MDL))
4422 case 'I': /* IP address or hostname. */
4424 if (!parse_ip_addr_or_hostname (&t, cfile, uniform))
4427 if (!parse_ip_addr (cfile, &addr))
4429 if (!make_const_data (&t, addr.iabuf, addr.len,
4435 case 'T': /* Lease interval. */
4436 token = peek_token (&val, (unsigned *)0, cfile);
4437 if (token != INFINITE)
4439 token = next_token (&val, (unsigned *)0, cfile);
4441 if (!make_const_data (&t, buf, 4, 0, 1, MDL))
4445 case 'L': /* Unsigned 32-bit integer... */
4446 case 'l': /* Signed 32-bit integer... */
4447 token = peek_token (&val, (unsigned *)0, cfile);
4449 if (token != NUMBER) {
4451 if ((*fmt) [1] != 'o') {
4452 parse_warn (cfile, "expecting number.");
4454 skip_to_semi (cfile);
4458 token = next_token (&val, (unsigned *)0, cfile);
4459 convert_num (cfile, buf, val, 0, 32);
4460 if (!make_const_data (&t, buf, 4, 0, 1, MDL))
4464 case 's': /* Signed 16-bit integer. */
4465 case 'S': /* Unsigned 16-bit integer. */
4466 token = peek_token (&val, (unsigned *)0, cfile);
4467 if (token != NUMBER)
4469 token = next_token (&val, (unsigned *)0, cfile);
4470 convert_num (cfile, buf, val, 0, 16);
4471 if (!make_const_data (&t, buf, 2, 0, 1, MDL))
4475 case 'b': /* Signed 8-bit integer. */
4476 case 'B': /* Unsigned 8-bit integer. */
4477 token = peek_token (&val, (unsigned *)0, cfile);
4478 if (token != NUMBER)
4480 token = next_token (&val, (unsigned *)0, cfile);
4481 convert_num (cfile, buf, val, 0, 8);
4482 if (!make_const_data (&t, buf, 1, 0, 1, MDL))
4486 case 'f': /* Boolean flag. */
4487 token = peek_token (&val, (unsigned *)0, cfile);
4488 if (!is_identifier (token)) {
4489 if ((*fmt) [1] != 'o')
4490 parse_warn (cfile, "expecting identifier.");
4492 if ((*fmt) [1] != 'o') {
4494 skip_to_semi (cfile);
4498 if (!strcasecmp (val, "true")
4499 || !strcasecmp (val, "on"))
4501 else if (!strcasecmp (val, "false")
4502 || !strcasecmp (val, "off"))
4504 else if (!strcasecmp (val, "ignore"))
4507 if ((*fmt) [1] != 'o')
4508 parse_warn (cfile, "expecting boolean.");
4511 token = next_token (&val, (unsigned *)0, cfile);
4512 if (!make_const_data (&t, buf, 1, 0, 1, MDL))
4517 parse_warn (cfile, "Bad format %c in parse_option_token.",
4519 skip_to_semi (cfile);
4523 if (!make_concat (rv, expr, t))
4526 expression_reference (rv, t, MDL);
4527 expression_dereference (&t, MDL);
4531 int parse_option_decl (oc, cfile)
4532 struct option_cache **oc;
4533 struct parse *cfile;
4538 u_int8_t hunkbuf [1024];
4539 unsigned hunkix = 0;
4540 const char *fmt, *f;
4541 struct option *option;
4542 struct iaddr ip_addr;
4548 struct enumeration_value *e;
4550 option = parse_option_name (cfile, 0, &known);
4554 /* Parse the option data... */
4556 /* Set a flag if this is an array of a simple type (i.e.,
4557 not an array of pairs of IP addresses, or something
4559 int uniform = option -> format [1] == 'A';
4561 for (fmt = option -> format; *fmt; fmt++) {
4566 fmt = strchr (fmt, '.');
4569 "malformed %s (bug!)",
4570 "encapsulation format");
4571 skip_to_semi (cfile);
4575 len = parse_X (cfile, &hunkbuf [hunkix],
4576 sizeof hunkbuf - hunkix);
4580 case 't': /* Text string... */
4581 token = next_token (&val,
4583 if (token != STRING) {
4585 "expecting string.");
4586 skip_to_semi (cfile);
4589 if (hunkix + len + 1 > sizeof hunkbuf) {
4591 "option data buffer %s",
4593 skip_to_semi (cfile);
4596 memcpy (&hunkbuf [hunkix], val, len + 1);
4603 fmt = strchr (fmt, '.');
4606 "malformed %s (bug!)",
4607 "enumeration format");
4609 skip_to_semi (cfile);
4612 token = next_token (&val,
4613 (unsigned *)0, cfile);
4614 if (!is_identifier (token)) {
4616 "identifier expected");
4619 e = find_enumeration_value (f, fmt - f, val);
4629 case 'I': /* IP address. */
4630 if (!parse_ip_addr (cfile, &ip_addr))
4636 if (hunkix + len > sizeof hunkbuf) {
4638 "option data buffer %s",
4640 skip_to_semi (cfile);
4643 memcpy (&hunkbuf [hunkix], dp, len);
4647 case 'L': /* Unsigned 32-bit integer... */
4648 case 'l': /* Signed 32-bit integer... */
4649 token = next_token (&val,
4650 (unsigned *)0, cfile);
4651 if (token != NUMBER) {
4654 "expecting number.");
4656 skip_to_semi (cfile);
4659 convert_num (cfile, buf, val, 0, 32);
4664 case 's': /* Signed 16-bit integer. */
4665 case 'S': /* Unsigned 16-bit integer. */
4666 token = next_token (&val,
4667 (unsigned *)0, cfile);
4668 if (token != NUMBER)
4670 convert_num (cfile, buf, val, 0, 16);
4675 case 'b': /* Signed 8-bit integer. */
4676 case 'B': /* Unsigned 8-bit integer. */
4677 token = next_token (&val,
4678 (unsigned *)0, cfile);
4679 if (token != NUMBER)
4681 convert_num (cfile, buf, val, 0, 8);
4686 case 'f': /* Boolean flag. */
4687 token = next_token (&val,
4688 (unsigned *)0, cfile);
4689 if (!is_identifier (token)) {
4691 "expecting identifier.");
4694 skip_to_semi (cfile);
4697 if (!strcasecmp (val, "true")
4698 || !strcasecmp (val, "on"))
4700 else if (!strcasecmp (val, "false")
4701 || !strcasecmp (val, "off"))
4705 "expecting boolean.");
4713 log_error ("parse_option_param: Bad format %c",
4715 skip_to_semi (cfile);
4719 token = next_token (&val, (unsigned *)0, cfile);
4720 } while (*fmt == 'A' && token == COMMA);
4722 if (token != SEMI) {
4723 parse_warn (cfile, "semicolon expected.");
4724 skip_to_semi (cfile);
4728 bp = (struct buffer *)0;
4729 if (!buffer_allocate (&bp, hunkix + nul_term, MDL))
4730 log_fatal ("no memory to store option declaration.");
4732 log_fatal ("out of memory allocating option data.");
4733 memcpy (bp -> data, hunkbuf, hunkix + nul_term);
4735 if (!option_cache_allocate (oc, MDL))
4736 log_fatal ("out of memory allocating option cache.");
4738 (*oc) -> data.buffer = bp;
4739 (*oc) -> data.data = &bp -> data [0];
4740 (*oc) -> data.terminated = nul_term;
4741 (*oc) -> data.len = hunkix;
4742 (*oc) -> option = option;
4746 /* Consider merging parse_cshl into this. */
4748 int parse_X (cfile, buf, max)
4749 struct parse *cfile;
4758 token = peek_token (&val, (unsigned *)0, cfile);
4759 if (token == NUMBER_OR_NAME || token == NUMBER) {
4762 token = next_token (&val, (unsigned *)0, cfile);
4763 if (token != NUMBER && token != NUMBER_OR_NAME) {
4765 "expecting hexadecimal constant.");
4766 skip_to_semi (cfile);
4769 convert_num (cfile, &buf [len], val, 16, 8);
4772 "hexadecimal constant too long.");
4773 skip_to_semi (cfile);
4776 token = peek_token (&val, (unsigned *)0, cfile);
4778 token = next_token (&val,
4779 (unsigned *)0, cfile);
4780 } while (token == COLON);
4782 } else if (token == STRING) {
4783 token = next_token (&val, &len, cfile);
4784 if (len + 1 > max) {
4785 parse_warn (cfile, "string constant too long.");
4786 skip_to_semi (cfile);
4789 memcpy (buf, val, len + 1);
4791 parse_warn (cfile, "expecting string or hexadecimal data");
4792 skip_to_semi (cfile);
4798 int parse_warn (struct parse *cfile, const char *fmt, ...)
4806 do_percentm (mbuf, fmt);
4808 snprintf (fbuf, sizeof fbuf, "%s line %d: %s",
4809 cfile -> tlname, cfile -> lexline, mbuf);
4811 sprintf (fbuf, "%s line %d: %s",
4812 cfile -> tlname, cfile -> lexline, mbuf);
4815 va_start (list, fmt);
4816 vsnprintf (mbuf, sizeof mbuf, fbuf, list);
4821 cfile -> token_line [i] && i < (cfile -> lexchar - 1); i++) {
4822 if (lix < (sizeof lexbuf) - 1)
4823 lexbuf [lix++] = ' ';
4824 if (cfile -> token_line [i] == '\t') {
4826 lix < (sizeof lexbuf) - 1 && (lix & 7); lix++)
4833 syslog (log_priority | LOG_ERR, "%s", mbuf);
4834 syslog (log_priority | LOG_ERR, "%s", cfile -> token_line);
4835 if (cfile -> lexchar < 81)
4836 syslog (log_priority | LOG_ERR, "%s^", lexbuf);
4840 write (2, mbuf, strlen (mbuf));
4842 write (2, cfile -> token_line, strlen (cfile -> token_line));
4844 if (cfile -> lexchar < 81)
4845 write (2, lexbuf, lix);
4846 write (2, "^\n", 2);
4849 cfile -> warnings_occurred = 1;