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''.
45 static char copyright[] =
46 "$Id: parse.c,v 1.104.2.12 2002/11/17 02:58:34 dhankins Exp $ Copyright (c) 1995-2002 The Internet Software Consortium. All rights reserved.\n";
51 /* Enumerations can be specified in option formats, and are used for
52 parsing, so we define the routines that manage them here. */
54 struct enumeration *enumerations;
56 void add_enumeration (struct enumeration *enumeration)
58 enumeration -> next = enumerations;
59 enumerations = enumeration;
62 struct enumeration *find_enumeration (const char *name, int length)
64 struct enumeration *e;
66 for (e = enumerations; e; e = e -> next)
67 if (strlen (e -> name) == length &&
68 !memcmp (e -> name, name, (unsigned)length))
70 return (struct enumeration *)0;
73 struct enumeration_value *find_enumeration_value (const char *name,
77 struct enumeration *e;
80 e = find_enumeration (name, length);
82 for (i = 0; e -> values [i].name; i++) {
83 if (!strcmp (value, e -> values [i].name))
84 return &e -> values [i];
87 return (struct enumeration_value *)0;
90 /* Skip to the semicolon ending the current statement. If we encounter
91 braces, the matching closing brace terminates the statement. If we
92 encounter a right brace but haven't encountered a left brace, return
93 leaving the brace in the token buffer for the caller. If we see a
94 semicolon and haven't seen a left brace, return. This lets us skip
99 statement foo bar { statement { } }
104 void skip_to_semi (cfile)
107 skip_to_rbrace (cfile, 0);
110 void skip_to_rbrace (cfile, brace_count)
114 enum dhcp_token token;
117 #if defined (DEBUG_TOKEN)
118 log_error ("skip_to_rbrace: %d\n", brace_count);
121 token = peek_token (&val, (unsigned *)0, cfile);
122 if (token == RBRACE) {
123 token = next_token (&val, (unsigned *)0, cfile);
129 } else if (token == LBRACE) {
131 } else if (token == SEMI && !brace_count) {
132 token = next_token (&val, (unsigned *)0, cfile);
134 } else if (token == EOL) {
135 /* EOL only happens when parsing /etc/resolv.conf,
136 and we treat it like a semicolon because the
137 resolv.conf file is line-oriented. */
138 token = next_token (&val, (unsigned *)0, cfile);
141 token = next_token (&val, (unsigned *)0, cfile);
142 } while (token != END_OF_FILE);
145 int parse_semi (cfile)
148 enum dhcp_token token;
151 token = next_token (&val, (unsigned *)0, cfile);
153 parse_warn (cfile, "semicolon expected.");
154 skip_to_semi (cfile);
160 /* string-parameter :== STRING SEMI */
162 int parse_string (cfile, sptr, lptr)
168 enum dhcp_token token;
172 token = next_token (&val, &len, cfile);
173 if (token != STRING) {
174 parse_warn (cfile, "expecting a string");
175 skip_to_semi (cfile);
178 s = (char *)dmalloc (len + 1, MDL);
180 log_fatal ("no memory for string %s.", val);
181 memcpy (s, val, len + 1);
183 if (!parse_semi (cfile)) {
197 * hostname :== IDENTIFIER
199 * | hostname DOT IDENTIFIER
202 char *parse_host_name (cfile)
206 enum dhcp_token token;
213 /* Read a dotted hostname... */
215 /* Read a token, which should be an identifier. */
216 token = peek_token (&val, (unsigned *)0, cfile);
217 if (!is_identifier (token) && token != NUMBER)
219 token = next_token (&val, (unsigned *)0, cfile);
221 /* Store this identifier... */
222 if (!(s = (char *)dmalloc (strlen (val) + 1, MDL)))
223 log_fatal ("can't allocate temp space for hostname.");
225 c = cons ((caddr_t)s, c);
226 len += strlen (s) + 1;
227 /* Look for a dot; if it's there, keep going, otherwise
229 token = peek_token (&val, (unsigned *)0, cfile);
231 token = next_token (&val, (unsigned *)0, cfile);
235 } while (token == DOT);
237 /* Should be at least one token. */
241 /* Assemble the hostname together into a string. */
242 if (!(s = (char *)dmalloc (len + ltid, MDL)))
243 log_fatal ("can't allocate space for hostname.");
250 unsigned l = strlen ((char *)(c -> car));
252 memcpy (t, (char *)(c -> car), l);
253 /* Free up temp space. */
254 dfree (c -> car, MDL);
263 /* ip-addr-or-hostname :== ip-address | hostname
264 ip-address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
266 Parse an ip address or a hostname. If uniform is zero, put in
267 an expr_substring node to limit hostnames that evaluate to more
268 than one IP address. */
270 int parse_ip_addr_or_hostname (expr, cfile, uniform)
271 struct expression **expr;
276 enum dhcp_token token;
277 unsigned char addr [4];
278 unsigned len = sizeof addr;
280 struct expression *x = (struct expression *)0;
282 token = peek_token (&val, (unsigned *)0, cfile);
283 if (is_identifier (token)) {
284 name = parse_host_name (cfile);
287 if (!make_host_lookup (expr, name))
290 if (!make_limit (&x, *expr, 4))
292 expression_dereference (expr, MDL);
295 } else if (token == NUMBER) {
296 if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
298 return make_const_data (expr, addr, len, 0, 1, MDL);
300 if (token != RBRACE && token != LBRACE)
301 token = next_token (&val, (unsigned *)0, cfile);
302 parse_warn (cfile, "%s (%d): expecting IP address or hostname",
305 skip_to_semi (cfile);
313 * ip-address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
316 int parse_ip_addr (cfile, addr)
321 enum dhcp_token token;
324 if (parse_numeric_aggregate (cfile, addr -> iabuf,
325 &addr -> len, DOT, 10, 8))
331 * hardware-parameter :== HARDWARE hardware-type colon-seperated-hex-list SEMI
332 * hardware-type :== ETHERNET | TOKEN_RING | FDDI
335 void parse_hardware_param (cfile, hardware)
337 struct hardware *hardware;
340 enum dhcp_token token;
344 token = next_token (&val, (unsigned *)0, cfile);
347 hardware -> hbuf [0] = HTYPE_ETHER;
350 hardware -> hbuf [0] = HTYPE_IEEE802;
353 hardware -> hbuf [0] = HTYPE_FDDI;
356 if (!strncmp (val, "unknown-", 8)) {
357 hardware -> hbuf [0] = atoi (&val [8]);
360 "expecting a network hardware type");
361 skip_to_semi (cfile);
367 /* Parse the hardware address information. Technically,
368 it would make a lot of sense to restrict the length of the
369 data we'll accept here to the length of a particular hardware
370 address type. Unfortunately, there are some broken clients
371 out there that put bogus data in the chaddr buffer, and we accept
372 that data in the lease file rather than simply failing on such
375 token = peek_token (&val, (unsigned *)0, cfile);
377 hardware -> hlen = 1;
380 t = parse_numeric_aggregate (cfile, (unsigned char *)0, &hlen,
383 hardware -> hlen = 1;
386 if (hlen + 1 > sizeof hardware -> hbuf) {
388 parse_warn (cfile, "hardware address too long");
390 hardware -> hlen = hlen + 1;
391 memcpy ((unsigned char *)&hardware -> hbuf [1], t, hlen);
392 if (hlen + 1 < sizeof hardware -> hbuf)
393 memset (&hardware -> hbuf [hlen + 1], 0,
394 (sizeof hardware -> hbuf) - hlen - 1);
399 token = next_token (&val, (unsigned *)0, cfile);
401 parse_warn (cfile, "expecting semicolon.");
402 skip_to_semi (cfile);
406 /* lease-time :== NUMBER SEMI */
408 void parse_lease_time (cfile, timep)
413 enum dhcp_token token;
415 token = next_token (&val, (unsigned *)0, cfile);
416 if (token != NUMBER) {
417 parse_warn (cfile, "Expecting numeric lease time");
418 skip_to_semi (cfile);
421 convert_num (cfile, (unsigned char *)timep, val, 10, 32);
422 /* Unswap the number - convert_num returns stuff in NBO. */
423 *timep = ntohl (*timep); /* XXX */
428 /* No BNF for numeric aggregates - that's defined by the caller. What
429 this function does is to parse a sequence of numbers seperated by
430 the token specified in seperator. If max is zero, any number of
431 numbers will be parsed; otherwise, exactly max numbers are
432 expected. Base and size tell us how to internalize the numbers
433 once they've been tokenized. */
435 unsigned char *parse_numeric_aggregate (cfile, buf,
436 max, seperator, base, size)
445 enum dhcp_token token;
446 unsigned char *bufp = buf, *s, *t;
451 bufp = (unsigned char *)dmalloc (*max * size / 8, MDL);
453 log_fatal ("no space for numeric aggregate");
460 token = peek_token (&val, (unsigned *)0, cfile);
461 if (token != seperator) {
464 if (token != RBRACE && token != LBRACE)
465 token = next_token (&val,
468 parse_warn (cfile, "too few numbers.");
470 skip_to_semi (cfile);
471 return (unsigned char *)0;
473 token = next_token (&val, (unsigned *)0, cfile);
475 token = next_token (&val, (unsigned *)0, cfile);
477 if (token == END_OF_FILE) {
478 parse_warn (cfile, "unexpected end of file");
482 /* Allow NUMBER_OR_NAME if base is 16. */
483 if (token != NUMBER &&
484 (base != 16 || token != NUMBER_OR_NAME)) {
485 parse_warn (cfile, "expecting numeric value.");
486 skip_to_semi (cfile);
487 return (unsigned char *)0;
489 /* If we can, convert the number now; otherwise, build
490 a linked list of all the numbers. */
492 convert_num (cfile, s, val, base, size);
495 t = (unsigned char *)dmalloc (strlen (val) + 1, MDL);
497 log_fatal ("no temp space for number.");
498 strcpy ((char *)t, val);
499 c = cons ((caddr_t)t, c);
501 } while (++count != *max);
503 /* If we had to cons up a list, convert it now. */
505 bufp = (unsigned char *)dmalloc (count * size / 8, MDL);
507 log_fatal ("no space for numeric aggregate.");
508 s = bufp + count - size / 8;
513 convert_num (cfile, s, (char *)(c -> car), base, size);
515 /* Free up temp space. */
516 dfree (c -> car, MDL);
523 void convert_num (cfile, buf, str, base, size)
530 const char *ptr = str;
541 /* If base wasn't specified, figure it out from the data. */
543 if (ptr [0] == '0') {
544 if (ptr [1] == 'x') {
547 } else if (isascii (ptr [1]) && isdigit (ptr [1])) {
560 /* XXX assumes ASCII... */
562 tval = tval - 'a' + 10;
563 else if (tval >= 'A')
564 tval = tval - 'A' + 10;
565 else if (tval >= '0')
568 parse_warn (cfile, "Bogus number: %s.", str);
573 "Bogus number %s: digit %d not in base %d",
577 val = val * base + tval;
581 max = (1 << (size - 1));
583 max = (1 << (size - 1)) + ((1 << (size - 1)) - 1);
588 "%s%lo exceeds max (%d) for precision.",
590 (unsigned long)val, max);
594 "%s%lx exceeds max (%d) for precision.",
596 (unsigned long)val, max);
600 "%s%lu exceeds max (%d) for precision.",
602 (unsigned long)val, max);
610 *buf = -(unsigned long)val;
613 putShort (buf, -(long)val);
616 putLong (buf, -(long)val);
620 "Unexpected integer size: %d\n", size);
626 *buf = (u_int8_t)val;
629 putUShort (buf, (u_int16_t)val);
636 "Unexpected integer size: %d\n", size);
643 * date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER
644 * NUMBER COLON NUMBER COLON NUMBER SEMI |
645 * NUMBER NUMBER SLASH NUMBER SLASH NUMBER
646 * NUMBER COLON NUMBER COLON NUMBER NUMBER SEMI |
649 * Dates are stored in GMT or with a timezone offset; first number is day
650 * of week; next is year/month/day; next is hours:minutes:seconds on a
651 * 24-hour clock, followed by the timezone offset in seconds, which is
655 TIME parse_date (cfile)
660 int tzoff, wday, year, mon, mday, hour, min, sec;
662 enum dhcp_token token;
663 static int months [11] = { 31, 59, 90, 120, 151, 181,
664 212, 243, 273, 304, 334 };
666 /* Day of week, or "never"... */
667 token = next_token (&val, (unsigned *)0, cfile);
668 if (token == NEVER) {
669 if (!parse_semi (cfile))
674 if (token != NUMBER) {
675 parse_warn (cfile, "numeric day of week expected.");
677 skip_to_semi (cfile);
683 token = next_token (&val, (unsigned *)0, cfile);
684 if (token != NUMBER) {
685 parse_warn (cfile, "numeric year expected.");
687 skip_to_semi (cfile);
691 /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
692 somebody invents a time machine, I think we can safely disregard
693 it. This actually works around a stupid Y2K bug that was present
694 in a very early beta release of dhcpd. */
699 /* Slash seperating year from month... */
700 token = next_token (&val, (unsigned *)0, cfile);
701 if (token != SLASH) {
703 "expected slash seperating year from month.");
705 skip_to_semi (cfile);
710 token = next_token (&val, (unsigned *)0, cfile);
711 if (token != NUMBER) {
712 parse_warn (cfile, "numeric month expected.");
714 skip_to_semi (cfile);
717 mon = atoi (val) - 1;
719 /* Slash seperating month from day... */
720 token = next_token (&val, (unsigned *)0, cfile);
721 if (token != SLASH) {
723 "expected slash seperating month from day.");
725 skip_to_semi (cfile);
730 token = next_token (&val, (unsigned *)0, cfile);
731 if (token != NUMBER) {
732 parse_warn (cfile, "numeric day of month expected.");
734 skip_to_semi (cfile);
740 token = next_token (&val, (unsigned *)0, cfile);
741 if (token != NUMBER) {
742 parse_warn (cfile, "numeric hour expected.");
744 skip_to_semi (cfile);
749 /* Colon seperating hour from minute... */
750 token = next_token (&val, (unsigned *)0, cfile);
751 if (token != COLON) {
753 "expected colon seperating hour from minute.");
755 skip_to_semi (cfile);
760 token = next_token (&val, (unsigned *)0, cfile);
761 if (token != NUMBER) {
762 parse_warn (cfile, "numeric minute expected.");
764 skip_to_semi (cfile);
769 /* Colon seperating minute from second... */
770 token = next_token (&val, (unsigned *)0, cfile);
771 if (token != COLON) {
773 "expected colon seperating hour from minute.");
775 skip_to_semi (cfile);
780 token = next_token (&val, (unsigned *)0, cfile);
781 if (token != NUMBER) {
782 parse_warn (cfile, "numeric minute expected.");
784 skip_to_semi (cfile);
789 token = peek_token (&val, (unsigned *)0, cfile);
790 if (token == NUMBER) {
791 token = next_token (&val, (unsigned *)0, cfile);
796 /* Make sure the date ends in a semicolon... */
797 if (!parse_semi (cfile))
800 /* Guess the time value... */
801 guess = ((((((365 * (year - 70) + /* Days in years since '70 */
802 (year - 69) / 4 + /* Leap days since '70 */
803 (mon /* Days in months this year */
806 (mon > 1 && /* Leap day this year */
807 !((year - 72) & 3)) +
808 mday - 1) * 24) + /* Day of month */
810 min) * 60) + sec + tzoff;
812 /* This guess could be wrong because of leap seconds or other
813 weirdness we don't know about that the system does. For
814 now, we're just going to accept the guess, but at some point
815 it might be nice to do a successive approximation here to
816 get an exact value. Even if the error is small, if the
817 server is restarted frequently (and thus the lease database
818 is reread), the error could accumulate into something
825 * option-name :== IDENTIFIER |
826 IDENTIFIER . IDENTIFIER
829 struct option *parse_option_name (cfile, allocate, known)
835 enum dhcp_token token;
837 struct universe *universe;
838 struct option *option;
840 token = next_token (&val, (unsigned *)0, cfile);
841 if (!is_identifier (token)) {
843 "expecting identifier after option keyword.");
845 skip_to_semi (cfile);
846 return (struct option *)0;
848 uname = dmalloc (strlen (val) + 1, MDL);
850 log_fatal ("no memory for uname information.");
852 token = peek_token (&val, (unsigned *)0, cfile);
854 /* Go ahead and take the DOT token... */
855 token = next_token (&val, (unsigned *)0, cfile);
857 /* The next token should be an identifier... */
858 token = next_token (&val, (unsigned *)0, cfile);
859 if (!is_identifier (token)) {
860 parse_warn (cfile, "expecting identifier after '.'");
862 skip_to_semi (cfile);
863 return (struct option *)0;
866 /* Look up the option name hash table for the specified
868 universe = (struct universe *)0;
869 if (!universe_hash_lookup (&universe, universe_hash,
871 parse_warn (cfile, "no option space named %s.", uname);
872 skip_to_semi (cfile);
873 return (struct option *)0;
876 /* Use the default hash table, which contains all the
877 standard dhcp option names. */
879 universe = &dhcp_universe;
882 /* Look up the actual option info... */
883 option = (struct option *)0;
884 option_hash_lookup (&option, universe -> hash, val, 0, MDL);
886 /* If we didn't get an option structure, it's an undefined option. */
891 /* If we've been told to allocate, that means that this
892 (might) be an option code definition, so we'll create
893 an option structure just in case. */
895 option = new_option (MDL);
897 option -> name = val;
901 s = dmalloc (strlen (val) + 1, MDL);
903 log_fatal ("no memory for option %s.%s",
904 universe -> name, val);
908 option -> universe = universe;
913 parse_warn (cfile, "no option named %s", val);
915 parse_warn (cfile, "no option named %s in space %s",
917 skip_to_semi (cfile);
918 return (struct option *)0;
921 /* Free the initial identifier token. */
926 /* IDENTIFIER SEMI */
928 void parse_option_space_decl (cfile)
933 struct universe **ua, *nu;
936 next_token (&val, (unsigned *)0, cfile); /* Discard the SPACE token,
937 which was checked by the
939 token = next_token (&val, (unsigned *)0, cfile);
940 if (!is_identifier (token)) {
941 parse_warn (cfile, "expecting identifier.");
942 skip_to_semi (cfile);
945 nu = new_universe (MDL);
947 log_fatal ("No memory for new option space.");
949 /* Set up the server option universe... */
950 s = dmalloc (strlen (val) + 1, MDL);
952 log_fatal ("No memory for new option space name.");
955 nu -> lookup_func = lookup_hashed_option;
956 nu -> option_state_dereference =
957 hashed_option_state_dereference;
958 nu -> foreach = hashed_option_space_foreach;
959 nu -> save_func = save_hashed_option;
960 nu -> delete_func = delete_hashed_option;
961 nu -> encapsulate = hashed_option_space_encapsulate;
962 nu -> decode = parse_option_buffer;
963 nu -> length_size = 1;
965 nu -> store_tag = putUChar;
966 nu -> store_length = putUChar;
967 nu -> index = universe_count++;
968 if (nu -> index >= universe_max) {
969 ua = dmalloc (universe_max * 2 * sizeof *ua, MDL);
971 log_fatal ("No memory to expand option space array.");
972 memcpy (ua, universes, universe_max * sizeof *ua);
974 dfree (universes, MDL);
977 universes [nu -> index] = nu;
978 option_new_hash (&nu -> hash, 1, MDL);
980 log_fatal ("Can't allocate %s option hash table.", nu -> name);
981 universe_hash_add (universe_hash, nu -> name, 0, nu, MDL);
985 /* This is faked up to look good right now. Ideally, this should do a
986 recursive parse and allow arbitrary data structure definitions, but for
987 now it just allows you to specify a single type, an array of single types,
988 a sequence of types, or an array of sequences of types.
990 ocd :== NUMBER EQUALS ocsd SEMI
994 ARRAY OF ocsd_simple_type_sequence
996 ocsd_type_sequence :== LBRACE ocsd_types RBRACE
998 ocsd_simple_type_sequence :== LBRACE ocsd_simple_types RBRACE
1000 ocsd_types :== ocsd_type |
1001 ocsd_types ocsd_type
1003 ocsd_type :== ocsd_simple_type |
1004 ARRAY OF ocsd_simple_type
1006 ocsd_simple_types :== ocsd_simple_type |
1007 ocsd_simple_types ocsd_simple_type
1009 ocsd_simple_type :== BOOLEAN |
1011 SIGNED INTEGER NUMBER |
1012 UNSIGNED INTEGER NUMBER |
1016 ENCAPSULATE identifier */
1018 int parse_option_code_definition (cfile, option)
1019 struct parse *cfile;
1020 struct option *option;
1023 enum dhcp_token token;
1024 unsigned arrayp = 0;
1026 int no_more_in_record = 0;
1033 int has_encapsulation = 0;
1035 /* Parse the option code. */
1036 token = next_token (&val, (unsigned *)0, cfile);
1037 if (token != NUMBER) {
1038 parse_warn (cfile, "expecting option code number.");
1039 skip_to_semi (cfile);
1042 option -> code = atoi (val);
1044 token = next_token (&val, (unsigned *)0, cfile);
1045 if (token != EQUAL) {
1046 parse_warn (cfile, "expecting \"=\"");
1047 skip_to_semi (cfile);
1051 /* See if this is an array. */
1052 token = next_token (&val, (unsigned *)0, cfile);
1053 if (token == ARRAY) {
1054 token = next_token (&val, (unsigned *)0, cfile);
1056 parse_warn (cfile, "expecting \"of\".");
1057 skip_to_semi (cfile);
1061 token = next_token (&val, (unsigned *)0, cfile);
1064 if (token == LBRACE) {
1066 token = next_token (&val, (unsigned *)0, cfile);
1069 /* At this point we're expecting a data type. */
1071 if (has_encapsulation) {
1073 "encapsulate must always be the last item.");
1074 skip_to_semi (cfile);
1081 parse_warn (cfile, "no nested arrays.");
1082 skip_to_rbrace (cfile, recordp);
1084 skip_to_semi (cfile);
1087 token = next_token (&val, (unsigned *)0, cfile);
1089 parse_warn (cfile, "expecting \"of\".");
1090 skip_to_semi (cfile);
1093 arrayp = recordp + 1;
1094 token = next_token (&val, (unsigned *)0, cfile);
1095 if ((recordp) && (token == LBRACE)) {
1097 "only uniform array inside record.");
1098 skip_to_rbrace (cfile, recordp + 1);
1099 skip_to_semi (cfile);
1109 token = next_token (&val, (unsigned *)0, cfile);
1110 if (token != NUMBER) {
1111 parse_warn (cfile, "expecting number.");
1112 skip_to_rbrace (cfile, recordp);
1114 skip_to_semi (cfile);
1117 switch (atoi (val)) {
1119 type = is_signed ? 'b' : 'B';
1122 type = is_signed ? 's' : 'S';
1125 type = is_signed ? 'l' : 'L';
1129 "%s bit precision is not supported.", val);
1130 skip_to_rbrace (cfile, recordp);
1132 skip_to_semi (cfile);
1139 token = next_token (&val, (unsigned *)0, cfile);
1140 if (token != INTEGER) {
1141 parse_warn (cfile, "expecting \"integer\" keyword.");
1142 skip_to_rbrace (cfile, recordp);
1144 skip_to_semi (cfile);
1162 parse_warn (cfile, "arrays of text strings not %s",
1164 skip_to_rbrace (cfile, recordp);
1166 skip_to_semi (cfile);
1169 no_more_in_record = 1;
1176 token = next_token (&val, (unsigned *)0, cfile);
1177 if (!is_identifier (token)) {
1179 "expecting option space identifier");
1180 skip_to_semi (cfile);
1183 if (strlen (val) + tokix + 2 > sizeof (tokbuf))
1185 tokbuf [tokix++] = 'E';
1186 strcpy (&tokbuf [tokix], val);
1187 tokix += strlen (val);
1189 has_encapsulation = 1;
1193 parse_warn (cfile, "unknown data type %s", val);
1194 skip_to_rbrace (cfile, recordp);
1196 skip_to_semi (cfile);
1200 if (tokix == sizeof tokbuf) {
1202 parse_warn (cfile, "too many types in record.");
1203 skip_to_rbrace (cfile, recordp);
1205 skip_to_semi (cfile);
1208 tokbuf [tokix++] = type;
1211 token = next_token (&val, (unsigned *)0, cfile);
1212 if (arrayp > recordp) {
1213 if (tokix == sizeof tokbuf) {
1215 "too many types in record.");
1216 skip_to_rbrace (cfile, 1);
1217 skip_to_semi (cfile);
1221 tokbuf[tokix++] = 'a';
1223 if (token == COMMA) {
1224 if (no_more_in_record) {
1226 "%s must be at end of record.",
1227 type == 't' ? "text" : "string");
1228 skip_to_rbrace (cfile, 1);
1230 skip_to_semi (cfile);
1233 token = next_token (&val, (unsigned *)0, cfile);
1236 if (token != RBRACE) {
1237 parse_warn (cfile, "expecting right brace.");
1238 skip_to_rbrace (cfile, 1);
1240 skip_to_semi (cfile);
1244 if (!parse_semi (cfile)) {
1245 parse_warn (cfile, "semicolon expected.");
1246 skip_to_semi (cfile);
1248 skip_to_semi (cfile);
1251 if (has_encapsulation && arrayp) {
1253 "Arrays of encapsulations don't make sense.");
1256 if (has_encapsulation && tokbuf [0] == 'E')
1257 has_encapsulation = 0;
1258 s = dmalloc (tokix +
1260 (has_encapsulation ? 1 : 0) + 1, MDL);
1262 log_fatal ("no memory for option format.");
1263 if (has_encapsulation)
1265 memcpy (s + has_encapsulation, tokbuf, tokix);
1266 tokix += has_encapsulation;
1268 s [tokix++] = (arrayp > recordp) ? 'a' : 'A';
1270 option -> format = s;
1271 if (option -> universe -> options [option -> code]) {
1272 /* XXX Free the option, but we can't do that now because they
1273 XXX may start out static. */
1275 option -> universe -> options [option -> code] = option;
1276 option_hash_add (option -> universe -> hash,
1277 (const char *)option -> name,
1283 * base64 :== NUMBER_OR_STRING
1286 int parse_base64 (data, cfile)
1287 struct data_string *data;
1288 struct parse *cfile;
1290 enum dhcp_token token;
1294 static unsigned char
1295 from64 [] = {64, 64, 64, 64, 64, 64, 64, 64, /* \"#$%&' */
1296 64, 64, 64, 62, 64, 64, 64, 63, /* ()*+,-./ */
1297 52, 53, 54, 55, 56, 57, 58, 59, /* 01234567 */
1298 60, 61, 64, 64, 64, 64, 64, 64, /* 89:;<=>? */
1299 64, 0, 1, 2, 3, 4, 5, 6, /* @ABCDEFG */
1300 7, 8, 9, 10, 11, 12, 13, 14, /* HIJKLMNO */
1301 15, 16, 17, 18, 19, 20, 21, 22, /* PQRSTUVW */
1302 23, 24, 25, 64, 64, 64, 64, 64, /* XYZ[\]^_ */
1303 64, 26, 27, 28, 29, 30, 31, 32, /* 'abcdefg */
1304 33, 34, 35, 36, 37, 38, 39, 40, /* hijklmno */
1305 41, 42, 43, 44, 45, 46, 47, 48, /* pqrstuvw */
1306 49, 50, 51, 64, 64, 64, 64, 64}; /* xyz{|}~ */
1307 struct string_list *bufs = (struct string_list *)0,
1308 *last = (struct string_list *)0,
1313 /* It's possible for a + or a / to cause a base64 quantity to be
1314 tokenized into more than one token, so we have to parse them all
1315 in before decoding. */
1319 token = next_token (&val, &l, cfile);
1320 t = dmalloc (l + sizeof *t, MDL);
1322 log_fatal ("no memory for base64 buffer.");
1323 memset (t, 0, (sizeof *t) - 1);
1324 memcpy (t -> string, val, l + 1);
1331 token = peek_token (&val, (unsigned *)0, cfile);
1332 } while (token == NUMBER_OR_NAME || token == NAME || token == EQUAL ||
1333 token == NUMBER || token == PLUS || token == SLASH ||
1337 data -> len = (data -> len * 3) / 4;
1338 if (!buffer_allocate (&data -> buffer, data -> len, MDL)) {
1339 parse_warn (cfile, "can't allocate buffer for base64 data.");
1341 data -> data = (unsigned char *)0;
1346 for (t = bufs; t; t = t -> next) {
1347 for (i = 0; t -> string [i]; i++) {
1348 unsigned foo = t -> string [i];
1349 if (terminated && foo != '=') {
1351 "stuff after base64 '=' terminator: %s.",
1355 if (foo < ' ' || foo > 'z') {
1358 "invalid base64 character %d.",
1361 data_string_forget (data, MDL);
1367 foo = from64 [foo - ' '];
1370 acc = (acc << 6) + foo;
1375 data -> buffer -> data [j++] = (acc >> 4);
1380 data -> buffer -> data [j++] = (acc >> 2);
1384 data -> buffer -> data [j++] = acc;
1395 "partial base64 value left over: %d.",
1400 data -> data = data -> buffer -> data;
1402 for (t = bufs; t; t = last) {
1414 * colon-seperated-hex-list :== NUMBER |
1415 * NUMBER COLON colon-seperated-hex-list
1418 int parse_cshl (data, cfile)
1419 struct data_string *data;
1420 struct parse *cfile;
1422 u_int8_t ibuf [128];
1425 struct option_tag *sl = (struct option_tag *)0;
1426 struct option_tag *next, **last = &sl;
1427 enum dhcp_token token;
1432 token = next_token (&val, (unsigned *)0, cfile);
1433 if (token != NUMBER && token != NUMBER_OR_NAME) {
1434 parse_warn (cfile, "expecting hexadecimal number.");
1435 skip_to_semi (cfile);
1436 for (; sl; sl = next) {
1442 if (ilen == sizeof ibuf) {
1443 next = (struct option_tag *)
1445 sizeof (struct option_tag), MDL);
1447 log_fatal ("no memory for string list.");
1448 memcpy (next -> data, ibuf, ilen);
1450 last = &next -> next;
1454 convert_num (cfile, &ibuf [ilen++], val, 16, 8);
1456 token = peek_token (&val, (unsigned *)0, cfile);
1459 token = next_token (&val, (unsigned *)0, cfile);
1462 if (!buffer_allocate (&data -> buffer, tlen + ilen, MDL))
1463 log_fatal ("no memory to store octet data.");
1464 data -> data = &data -> buffer -> data [0];
1465 data -> len = tlen + ilen;
1466 data -> terminated = 0;
1468 rvp = &data -> buffer -> data [0];
1471 memcpy (rvp, sl -> data, sizeof ibuf);
1477 memcpy (rvp, ibuf, ilen);
1482 * executable-statements :== executable-statement executable-statements |
1483 * executable-statement
1485 * executable-statement :==
1487 * ADD class-name SEMI |
1489 * OPTION option-parameter SEMI |
1490 * SUPERSEDE option-parameter SEMI |
1491 * PREPEND option-parameter SEMI |
1492 * APPEND option-parameter SEMI
1495 int parse_executable_statements (statements, cfile, lose, case_context)
1496 struct executable_statement **statements;
1497 struct parse *cfile;
1499 enum expression_context case_context;
1501 struct executable_statement **next;
1504 while (parse_executable_statement (next, cfile, lose, case_context))
1505 next = &((*next) -> next);
1511 int parse_executable_statement (result, cfile, lose, case_context)
1512 struct executable_statement **result;
1513 struct parse *cfile;
1515 enum expression_context case_context;
1517 enum dhcp_token token;
1519 struct executable_statement base;
1521 struct option *option;
1522 struct option_cache *cache;
1526 struct dns_zone *zone;
1527 isc_result_t status;
1530 token = peek_token (&val, (unsigned *)0, cfile);
1533 next_token (&val, (unsigned *)0, cfile);
1534 return parse_if_statement (result, cfile, lose);
1537 token = next_token (&val, (unsigned *)0, cfile);
1538 token = next_token (&val, (unsigned *)0, cfile);
1539 if (token != STRING) {
1540 parse_warn (cfile, "expecting class name.");
1541 skip_to_semi (cfile);
1545 cta = (struct class *)0;
1546 status = find_class (&cta, val, MDL);
1547 if (status != ISC_R_SUCCESS) {
1548 parse_warn (cfile, "class %s: %s",
1549 val, isc_result_totext (status));
1550 skip_to_semi (cfile);
1554 if (!parse_semi (cfile)) {
1558 if (!executable_statement_allocate (result, MDL))
1559 log_fatal ("no memory for new statement.");
1560 (*result) -> op = add_statement;
1561 (*result) -> data.add = cta;
1565 token = next_token (&val, (unsigned *)0, cfile);
1566 if (!parse_semi (cfile)) {
1570 if (!executable_statement_allocate (result, MDL))
1571 log_fatal ("no memory for new statement.");
1572 (*result) -> op = break_statement;
1576 token = next_token (&val, (unsigned *)0, cfile);
1578 option = parse_option_name (cfile, 0, &known);
1583 return parse_option_statement (result, cfile, 1, option,
1584 send_option_statement);
1588 token = next_token (&val, (unsigned *)0, cfile);
1590 option = parse_option_name (cfile, 0, &known);
1595 return parse_option_statement (result, cfile, 1, option,
1596 supersede_option_statement);
1607 token = next_token (&val, (unsigned *)0, cfile);
1608 cache = (struct option_cache *)0;
1609 if (!parse_allow_deny (&cache, cfile, flag))
1611 if (!executable_statement_allocate (result, MDL))
1612 log_fatal ("no memory for new statement.");
1613 (*result) -> op = supersede_option_statement;
1614 (*result) -> data.option = cache;
1618 token = next_token (&val, (unsigned *)0, cfile);
1619 token = peek_token (&val, (unsigned *)0, cfile);
1621 goto switch_default;
1623 option = parse_option_name (cfile, 0, &known);
1628 return parse_option_statement (result, cfile, 1, option,
1629 default_option_statement);
1632 token = next_token (&val, (unsigned *)0, cfile);
1634 option = parse_option_name (cfile, 0, &known);
1639 return parse_option_statement (result, cfile, 1, option,
1640 prepend_option_statement);
1643 token = next_token (&val, (unsigned *)0, cfile);
1645 option = parse_option_name (cfile, 0, &known);
1650 return parse_option_statement (result, cfile, 1, option,
1651 append_option_statement);
1654 token = next_token (&val, (unsigned *)0, cfile);
1655 return parse_on_statement (result, cfile, lose);
1658 token = next_token (&val, (unsigned *)0, cfile);
1659 return parse_switch_statement (result, cfile, lose);
1662 token = next_token (&val, (unsigned *)0, cfile);
1663 if (case_context == context_any) {
1665 "case statement in inappropriate scope.");
1667 skip_to_semi (cfile);
1670 return parse_case_statement (result,
1671 cfile, lose, case_context);
1674 token = next_token (&val, (unsigned *)0, cfile);
1675 if (case_context == context_any) {
1676 parse_warn (cfile, "switch default statement in %s",
1677 "inappropriate scope.");
1682 if (!executable_statement_allocate (result, MDL))
1683 log_fatal ("no memory for default statement.");
1684 (*result) -> op = default_statement;
1690 token = next_token (&val, (unsigned *)0, cfile);
1691 if (token == DEFINE)
1696 token = next_token (&val, (unsigned *)0, cfile);
1697 if (token != NAME && token != NUMBER_OR_NAME) {
1699 "%s can't be a variable name", val);
1701 skip_to_semi (cfile);
1706 if (!executable_statement_allocate (result, MDL))
1707 log_fatal ("no memory for set statement.");
1708 (*result) -> op = flag ? define_statement : set_statement;
1709 (*result) -> data.set.name = dmalloc (strlen (val) + 1, MDL);
1710 if (!(*result)->data.set.name)
1711 log_fatal ("can't allocate variable name");
1712 strcpy ((*result) -> data.set.name, val);
1713 token = next_token (&val, (unsigned *)0, cfile);
1715 if (token == LPAREN) {
1716 struct string_list *head, *cur, *new;
1717 struct expression *expr;
1718 head = cur = (struct string_list *)0;
1720 token = next_token (&val,
1721 (unsigned *)0, cfile);
1722 if (token == RPAREN)
1724 if (token != NAME && token != NUMBER_OR_NAME) {
1726 "expecting argument name");
1727 skip_to_rbrace (cfile, 0);
1729 executable_statement_dereference
1733 new = ((struct string_list *)
1734 dmalloc (sizeof (struct string_list) +
1735 strlen (val), MDL));
1737 log_fatal ("can't allocate string.");
1738 memset (new, 0, sizeof *new);
1739 strcpy (new -> string, val);
1746 token = next_token (&val,
1747 (unsigned *)0, cfile);
1748 } while (token == COMMA);
1750 if (token != RPAREN) {
1751 parse_warn (cfile, "expecting right paren.");
1753 skip_to_semi (cfile);
1755 executable_statement_dereference (result, MDL);
1759 token = next_token (&val, (unsigned *)0, cfile);
1760 if (token != LBRACE) {
1761 parse_warn (cfile, "expecting left brace.");
1765 expr = (struct expression *)0;
1766 if (!(expression_allocate (&expr, MDL)))
1767 log_fatal ("can't allocate expression.");
1768 expr -> op = expr_function;
1769 if (!fundef_allocate (&expr -> data.func, MDL))
1770 log_fatal ("can't allocate fundef.");
1771 expr -> data.func -> args = head;
1772 (*result) -> data.set.expr = expr;
1774 if (!(parse_executable_statements
1775 (&expr -> data.func -> statements, cfile, lose,
1781 token = next_token (&val, (unsigned *)0, cfile);
1782 if (token != RBRACE) {
1783 parse_warn (cfile, "expecting rigt brace.");
1787 if (token != EQUAL) {
1789 "expecting '=' in %s statement.",
1790 flag ? "define" : "set");
1794 if (!parse_expression (&(*result) -> data.set.expr,
1795 cfile, lose, context_any,
1796 (struct expression **)0,
1800 "expecting expression.");
1803 skip_to_semi (cfile);
1804 executable_statement_dereference (result, MDL);
1807 if (!parse_semi (cfile)) {
1809 executable_statement_dereference (result, MDL);
1816 token = next_token (&val, (unsigned *)0, cfile);
1818 token = next_token (&val, (unsigned *)0, cfile);
1819 if (token != NAME && token != NUMBER_OR_NAME) {
1821 "%s can't be a variable name", val);
1823 skip_to_semi (cfile);
1828 if (!executable_statement_allocate (result, MDL))
1829 log_fatal ("no memory for set statement.");
1830 (*result) -> op = unset_statement;
1831 (*result) -> data.unset = dmalloc (strlen (val) + 1, MDL);
1832 if (!(*result)->data.unset)
1833 log_fatal ("can't allocate variable name");
1834 strcpy ((*result) -> data.unset, val);
1835 if (!parse_semi (cfile)) {
1837 executable_statement_dereference (result, MDL);
1843 token = next_token (&val, (unsigned *)0, cfile);
1845 if (!executable_statement_allocate (result, MDL))
1846 log_fatal ("no memory for eval statement.");
1847 (*result) -> op = eval_statement;
1849 if (!parse_expression (&(*result) -> data.eval,
1850 cfile, lose, context_data, /* XXX */
1851 (struct expression **)0, expr_none)) {
1854 "expecting data expression.");
1857 skip_to_semi (cfile);
1858 executable_statement_dereference (result, MDL);
1861 if (!parse_semi (cfile)) {
1863 executable_statement_dereference (result, MDL);
1868 token = next_token (&val, (unsigned *)0, cfile);
1870 if (!executable_statement_allocate (result, MDL))
1871 log_fatal ("no memory for return statement.");
1872 (*result) -> op = return_statement;
1874 if (!parse_expression (&(*result) -> data.retval,
1875 cfile, lose, context_data,
1876 (struct expression **)0, expr_none)) {
1879 "expecting data expression.");
1882 skip_to_semi (cfile);
1883 executable_statement_dereference (result, MDL);
1886 if (!parse_semi (cfile)) {
1888 executable_statement_dereference (result, MDL);
1894 token = next_token (&val, (unsigned *)0, cfile);
1896 if (!executable_statement_allocate (result, MDL))
1897 log_fatal ("no memory for log statement.");
1898 (*result) -> op = log_statement;
1900 token = next_token (&val, (unsigned *)0, cfile);
1901 if (token != LPAREN) {
1902 parse_warn (cfile, "left parenthesis expected.");
1903 skip_to_semi (cfile);
1908 token = peek_token (&val, (unsigned *)0, cfile);
1910 if (token == FATAL) {
1911 (*result) -> data.log.priority = log_priority_fatal;
1912 } else if (token == ERROR) {
1913 (*result) -> data.log.priority = log_priority_error;
1914 } else if (token == TOKEN_DEBUG) {
1915 (*result) -> data.log.priority = log_priority_debug;
1916 } else if (token == INFO) {
1917 (*result) -> data.log.priority = log_priority_info;
1919 (*result) -> data.log.priority = log_priority_debug;
1923 token = next_token (&val, (unsigned *)0, cfile);
1924 token = next_token (&val, (unsigned *)0, cfile);
1925 if (token != COMMA) {
1926 parse_warn (cfile, "comma expected.");
1927 skip_to_semi (cfile);
1933 if (!(parse_data_expression
1934 (&(*result) -> data.log.expr, cfile, lose))) {
1935 skip_to_semi (cfile);
1940 token = next_token (&val, (unsigned *)0, cfile);
1941 if (token != RPAREN) {
1942 parse_warn (cfile, "right parenthesis expected.");
1943 skip_to_semi (cfile);
1948 token = next_token (&val, (unsigned *)0, cfile);
1949 if (token != SEMI) {
1950 parse_warn (cfile, "semicolon expected.");
1951 skip_to_semi (cfile);
1957 /* Not really a statement, but we parse it here anyway
1958 because it's appropriate for all DHCP agents with
1961 token = next_token (&val, (unsigned *)0, cfile);
1962 zone = (struct dns_zone *)0;
1963 if (!dns_zone_allocate (&zone, MDL))
1964 log_fatal ("no memory for new zone.");
1965 zone -> name = parse_host_name (cfile);
1966 if (!zone -> name) {
1967 parse_warn (cfile, "expecting hostname.");
1970 skip_to_semi (cfile);
1971 dns_zone_dereference (&zone, MDL);
1974 i = strlen (zone -> name);
1975 if (zone -> name [i - 1] != '.') {
1976 s = dmalloc ((unsigned)i + 2, MDL);
1978 parse_warn (cfile, "no trailing '.' on zone");
1981 strcpy (s, zone -> name);
1984 dfree (zone -> name, MDL);
1987 if (!parse_zone (zone, cfile))
1989 status = enter_dns_zone (zone);
1990 if (status != ISC_R_SUCCESS) {
1991 parse_warn (cfile, "dns zone key %s: %s",
1992 zone -> name, isc_result_totext (status));
1993 dns_zone_dereference (&zone, MDL);
1996 dns_zone_dereference (&zone, MDL);
1999 /* Also not really a statement, but same idea as above. */
2001 token = next_token (&val, (unsigned *)0, cfile);
2002 if (!parse_key (cfile)) {
2009 if (config_universe && is_identifier (token)) {
2010 option = (struct option *)0;
2011 option_hash_lookup (&option, config_universe -> hash,
2014 token = next_token (&val,
2015 (unsigned *)0, cfile);
2016 return parse_option_statement
2017 (result, cfile, 1, option,
2018 supersede_option_statement);
2022 if (token == NUMBER_OR_NAME || token == NAME) {
2023 /* This is rather ugly. Since function calls are
2024 data expressions, fake up an eval statement. */
2025 if (!executable_statement_allocate (result, MDL))
2026 log_fatal ("no memory for eval statement.");
2027 (*result) -> op = eval_statement;
2029 if (!parse_expression (&(*result) -> data.eval,
2030 cfile, lose, context_data,
2031 (struct expression **)0,
2034 parse_warn (cfile, "expecting "
2038 skip_to_semi (cfile);
2039 executable_statement_dereference (result, MDL);
2042 if (!parse_semi (cfile)) {
2044 executable_statement_dereference (result, MDL);
2057 /* zone-statements :== zone-statement |
2058 zone-statement zone-statements
2060 PRIMARY ip-addresses SEMI |
2061 SECONDARY ip-addresses SEMI |
2063 ip-addresses :== ip-addr-or-hostname |
2064 ip-addr-or-hostname COMMA ip-addresses
2065 key-reference :== KEY STRING |
2068 int parse_zone (struct dns_zone *zone, struct parse *cfile)
2073 struct option_cache *oc;
2076 token = next_token (&val, (unsigned *)0, cfile);
2077 if (token != LBRACE) {
2078 parse_warn (cfile, "expecting left brace");
2083 token = peek_token (&val, (unsigned *)0, cfile);
2086 if (zone -> primary) {
2088 "more than one primary.");
2089 skip_to_semi (cfile);
2092 if (!option_cache_allocate (&zone -> primary, MDL))
2093 log_fatal ("can't allocate primary option cache.");
2094 oc = zone -> primary;
2098 if (zone -> secondary) {
2099 parse_warn (cfile, "more than one secondary.");
2100 skip_to_semi (cfile);
2103 if (!option_cache_allocate (&zone -> secondary, MDL))
2104 log_fatal ("can't allocate secondary.");
2105 oc = zone -> secondary;
2107 token = next_token (&val, (unsigned *)0, cfile);
2109 struct expression *expr = (struct expression *)0;
2110 if (!parse_ip_addr_or_hostname (&expr, cfile, 0)) {
2112 "expecting IP addr or hostname.");
2113 skip_to_semi (cfile);
2116 if (oc -> expression) {
2117 struct expression *old =
2118 (struct expression *)0;
2119 expression_reference (&old,
2122 expression_dereference (&oc -> expression,
2124 if (!make_concat (&oc -> expression,
2126 log_fatal ("no memory for concat.");
2127 expression_dereference (&expr, MDL);
2128 expression_dereference (&old, MDL);
2130 expression_reference (&oc -> expression,
2132 expression_dereference (&expr, MDL);
2134 token = next_token (&val, (unsigned *)0, cfile);
2135 } while (token == COMMA);
2136 if (token != SEMI) {
2137 parse_warn (cfile, "expecting semicolon.");
2138 skip_to_semi (cfile);
2144 token = next_token (&val, (unsigned *)0, cfile);
2145 token = peek_token (&val, (unsigned *)0, cfile);
2146 if (token == STRING) {
2147 token = next_token (&val, (unsigned *)0, cfile);
2148 key_name = (char *)0;
2150 key_name = parse_host_name (cfile);
2152 parse_warn (cfile, "expecting key name.");
2153 skip_to_semi (cfile);
2158 if (omapi_auth_key_lookup_name (&zone -> key, val) !=
2160 parse_warn (cfile, "unknown key %s", val);
2162 dfree (key_name, MDL);
2163 if (!parse_semi (cfile))
2173 token = next_token (&val, (unsigned *)0, cfile);
2174 if (token != RBRACE) {
2175 parse_warn (cfile, "expecting right brace.");
2181 /* key-statements :== key-statement |
2182 key-statement key-statements
2184 ALGORITHM host-name SEMI |
2185 secret-definition SEMI
2186 secret-definition :== SECRET base64val |
2189 int parse_key (struct parse *cfile)
2194 struct auth_key *key;
2195 struct data_string ds;
2196 isc_result_t status;
2199 key = (struct auth_key *)0;
2200 if (omapi_auth_key_new (&key, MDL) != ISC_R_SUCCESS)
2201 log_fatal ("no memory for key");
2203 token = peek_token (&val, (unsigned *)0, cfile);
2204 if (token == STRING) {
2205 token = next_token (&val, (unsigned *)0, cfile);
2206 key -> name = dmalloc (strlen (val) + 1, MDL);
2208 log_fatal ("no memory for key name.");
2209 strcpy (key -> name, val);
2212 key -> name = parse_host_name (cfile);
2214 parse_warn (cfile, "expecting key name.");
2215 skip_to_semi (cfile);
2220 token = next_token (&val, (unsigned *)0, cfile);
2221 if (token != LBRACE) {
2222 parse_warn (cfile, "expecting left brace");
2227 token = next_token (&val, (unsigned *)0, cfile);
2230 if (key -> algorithm) {
2232 "key %s: too many algorithms",
2236 key -> algorithm = parse_host_name (cfile);
2237 if (!key -> algorithm) {
2239 "expecting key algorithm name.");
2242 if (!parse_semi (cfile))
2244 /* If the algorithm name isn't an FQDN, tack on
2245 the .SIG-ALG.REG.NET. domain. */
2246 s = strrchr (key -> algorithm, '.');
2248 static char add [] = ".SIG-ALG.REG.INT.";
2249 s = dmalloc (strlen (key -> algorithm) +
2252 log_error ("no memory for key %s.",
2256 strcpy (s, key -> algorithm);
2258 dfree (key -> algorithm, MDL);
2259 key -> algorithm = s;
2261 /* If there is no trailing '.', hack one in. */
2262 s = dmalloc (strlen (key -> algorithm) + 2, MDL);
2264 log_error ("no memory for key %s.",
2268 strcpy (s, key -> algorithm);
2270 dfree (key -> algorithm, MDL);
2271 key -> algorithm = s;
2277 parse_warn (cfile, "key %s: too many secrets",
2282 memset (&ds, 0, sizeof(ds));
2283 if (!parse_base64 (&ds, cfile))
2285 status = omapi_data_string_new (&key -> key, ds.len,
2287 if (status != ISC_R_SUCCESS)
2289 memcpy (key -> key -> value,
2290 ds.buffer -> data, ds.len);
2291 data_string_forget (&ds, MDL);
2293 if (!parse_semi (cfile))
2302 if (token != RBRACE) {
2303 parse_warn (cfile, "expecting right brace.");
2306 /* Allow the BIND 8 syntax, which has a semicolon after each
2308 token = peek_token (&val, (unsigned *)0, cfile);
2310 token = next_token (&val, (unsigned *)0, cfile);
2312 /* Remember the key. */
2313 status = omapi_auth_key_enter (key);
2314 if (status != ISC_R_SUCCESS) {
2315 parse_warn (cfile, "tsig key %s: %s",
2316 key -> name, isc_result_totext (status));
2319 omapi_auth_key_dereference (&key, MDL);
2323 skip_to_rbrace (cfile, 1);
2325 omapi_auth_key_dereference (&key, MDL);
2330 * on-statement :== event-types LBRACE executable-statements RBRACE
2331 * event-types :== event-type OR event-types |
2333 * event-type :== EXPIRY | COMMIT | RELEASE
2336 int parse_on_statement (result, cfile, lose)
2337 struct executable_statement **result;
2338 struct parse *cfile;
2341 enum dhcp_token token;
2344 if (!executable_statement_allocate (result, MDL))
2345 log_fatal ("no memory for new statement.");
2346 (*result) -> op = on_statement;
2349 token = next_token (&val, (unsigned *)0, cfile);
2352 (*result) -> data.on.evtypes |= ON_EXPIRY;
2356 (*result) -> data.on.evtypes |= ON_COMMIT;
2360 (*result) -> data.on.evtypes |= ON_RELEASE;
2364 (*result) -> data.on.evtypes |= ON_TRANSMISSION;
2368 parse_warn (cfile, "expecting a lease event type");
2369 skip_to_semi (cfile);
2371 executable_statement_dereference (result, MDL);
2374 token = next_token (&val, (unsigned *)0, cfile);
2375 } while (token == OR);
2377 /* Semicolon means no statements. */
2381 if (token != LBRACE) {
2382 parse_warn (cfile, "left brace expected.");
2383 skip_to_semi (cfile);
2385 executable_statement_dereference (result, MDL);
2388 if (!parse_executable_statements (&(*result) -> data.on.statements,
2389 cfile, lose, context_any)) {
2391 /* Try to even things up. */
2393 token = next_token (&val,
2394 (unsigned *)0, cfile);
2395 } while (token != END_OF_FILE && token != RBRACE);
2396 executable_statement_dereference (result, MDL);
2400 token = next_token (&val, (unsigned *)0, cfile);
2401 if (token != RBRACE) {
2402 parse_warn (cfile, "right brace expected.");
2403 skip_to_semi (cfile);
2405 executable_statement_dereference (result, MDL);
2412 * switch-statement :== LPAREN expr RPAREN LBRACE executable-statements RBRACE
2416 int parse_switch_statement (result, cfile, lose)
2417 struct executable_statement **result;
2418 struct parse *cfile;
2421 enum dhcp_token token;
2424 if (!executable_statement_allocate (result, MDL))
2425 log_fatal ("no memory for new statement.");
2426 (*result) -> op = switch_statement;
2428 token = next_token (&val, (unsigned *)0, cfile);
2429 if (token != LPAREN) {
2430 parse_warn (cfile, "expecting left brace.");
2433 skip_to_semi (cfile);
2435 executable_statement_dereference (result, MDL);
2439 if (!parse_expression (&(*result) -> data.s_switch.expr,
2440 cfile, lose, context_data_or_numeric,
2441 (struct expression **)0, expr_none)) {
2444 "expecting data or numeric expression.");
2450 token = next_token (&val, (unsigned *)0, cfile);
2451 if (token != RPAREN) {
2452 parse_warn (cfile, "right paren expected.");
2456 token = next_token (&val, (unsigned *)0, cfile);
2457 if (token != LBRACE) {
2458 parse_warn (cfile, "left brace expected.");
2461 if (!(parse_executable_statements
2462 (&(*result) -> data.s_switch.statements, cfile, lose,
2463 (is_data_expression ((*result) -> data.s_switch.expr)
2464 ? context_data : context_numeric)))) {
2466 skip_to_rbrace (cfile, 1);
2467 executable_statement_dereference (result, MDL);
2471 token = next_token (&val, (unsigned *)0, cfile);
2472 if (token != RBRACE) {
2473 parse_warn (cfile, "right brace expected.");
2480 * case-statement :== CASE expr COLON
2484 int parse_case_statement (result, cfile, lose, case_context)
2485 struct executable_statement **result;
2486 struct parse *cfile;
2488 enum expression_context case_context;
2490 enum dhcp_token token;
2493 if (!executable_statement_allocate (result, MDL))
2494 log_fatal ("no memory for new statement.");
2495 (*result) -> op = case_statement;
2497 if (!parse_expression (&(*result) -> data.c_case,
2498 cfile, lose, case_context,
2499 (struct expression **)0, expr_none))
2502 parse_warn (cfile, "expecting %s expression.",
2503 (case_context == context_data
2504 ? "data" : "numeric"));
2508 skip_to_semi (cfile);
2509 executable_statement_dereference (result, MDL);
2513 token = next_token (&val, (unsigned *)0, cfile);
2514 if (token != COLON) {
2515 parse_warn (cfile, "colon expected.");
2522 * if-statement :== boolean-expression LBRACE executable-statements RBRACE
2525 * else-statement :== <null> |
2526 * ELSE LBRACE executable-statements RBRACE |
2527 * ELSE IF if-statement |
2528 * ELSIF if-statement
2531 int parse_if_statement (result, cfile, lose)
2532 struct executable_statement **result;
2533 struct parse *cfile;
2536 enum dhcp_token token;
2540 if (!executable_statement_allocate (result, MDL))
2541 log_fatal ("no memory for if statement.");
2543 (*result) -> op = if_statement;
2545 token = peek_token (&val, (unsigned *)0, cfile);
2546 if (token == LPAREN) {
2548 next_token (&val, (unsigned *)0, cfile);
2553 if (!parse_boolean_expression (&(*result) -> data.ie.expr,
2556 parse_warn (cfile, "boolean expression expected.");
2557 executable_statement_dereference (result, MDL);
2561 #if defined (DEBUG_EXPRESSION_PARSE)
2562 print_expression ("if condition", (*result) -> data.ie.expr);
2565 token = next_token (&val, (unsigned *)0, cfile);
2566 if (token != RPAREN) {
2567 parse_warn (cfile, "expecting right paren.");
2569 executable_statement_dereference (result, MDL);
2573 token = next_token (&val, (unsigned *)0, cfile);
2574 if (token != LBRACE) {
2575 parse_warn (cfile, "left brace expected.");
2576 skip_to_semi (cfile);
2578 executable_statement_dereference (result, MDL);
2581 if (!parse_executable_statements (&(*result) -> data.ie.tc,
2582 cfile, lose, context_any)) {
2584 /* Try to even things up. */
2586 token = next_token (&val,
2587 (unsigned *)0, cfile);
2588 } while (token != END_OF_FILE && token != RBRACE);
2589 executable_statement_dereference (result, MDL);
2593 token = next_token (&val, (unsigned *)0, cfile);
2594 if (token != RBRACE) {
2595 parse_warn (cfile, "right brace expected.");
2596 skip_to_semi (cfile);
2598 executable_statement_dereference (result, MDL);
2601 token = peek_token (&val, (unsigned *)0, cfile);
2602 if (token == ELSE) {
2603 token = next_token (&val, (unsigned *)0, cfile);
2604 token = peek_token (&val, (unsigned *)0, cfile);
2606 token = next_token (&val, (unsigned *)0, cfile);
2607 if (!parse_if_statement (&(*result) -> data.ie.fc,
2611 "expecting if statement");
2612 executable_statement_dereference (result, MDL);
2616 } else if (token != LBRACE) {
2617 parse_warn (cfile, "left brace or if expected.");
2618 skip_to_semi (cfile);
2620 executable_statement_dereference (result, MDL);
2623 token = next_token (&val, (unsigned *)0, cfile);
2624 if (!(parse_executable_statements
2625 (&(*result) -> data.ie.fc,
2626 cfile, lose, context_any))) {
2627 executable_statement_dereference (result, MDL);
2630 token = next_token (&val, (unsigned *)0, cfile);
2631 if (token != RBRACE) {
2632 parse_warn (cfile, "right brace expected.");
2633 skip_to_semi (cfile);
2635 executable_statement_dereference (result, MDL);
2639 } else if (token == ELSIF) {
2640 token = next_token (&val, (unsigned *)0, cfile);
2641 if (!parse_if_statement (&(*result) -> data.ie.fc,
2645 "expecting conditional.");
2646 executable_statement_dereference (result, MDL);
2651 (*result) -> data.ie.fc = (struct executable_statement *)0;
2657 * boolean_expression :== CHECK STRING |
2658 * NOT boolean-expression |
2659 * data-expression EQUAL data-expression |
2660 * data-expression BANG EQUAL data-expression |
2661 * boolean-expression AND boolean-expression |
2662 * boolean-expression OR boolean-expression
2663 * EXISTS OPTION-NAME
2666 int parse_boolean_expression (expr, cfile, lose)
2667 struct expression **expr;
2668 struct parse *cfile;
2671 /* Parse an expression... */
2672 if (!parse_expression (expr, cfile, lose, context_boolean,
2673 (struct expression **)0, expr_none))
2676 if (!is_boolean_expression (*expr) &&
2677 (*expr) -> op != expr_variable_reference &&
2678 (*expr) -> op != expr_funcall) {
2679 parse_warn (cfile, "Expecting a boolean expression.");
2681 expression_dereference (expr, MDL);
2688 * data_expression :== SUBSTRING LPAREN data-expression COMMA
2689 * numeric-expression COMMA
2690 * numeric-expression RPAREN |
2691 * CONCAT LPAREN data-expression COMMA
2692 data-expression RPAREN
2693 * SUFFIX LPAREN data_expression COMMA
2694 * numeric-expression RPAREN |
2695 * OPTION option_name |
2697 * PACKET LPAREN numeric-expression COMMA
2698 * numeric-expression RPAREN |
2700 * colon_seperated_hex_list
2703 int parse_data_expression (expr, cfile, lose)
2704 struct expression **expr;
2705 struct parse *cfile;
2708 /* Parse an expression... */
2709 if (!parse_expression (expr, cfile, lose, context_data,
2710 (struct expression **)0, expr_none))
2713 if (!is_data_expression (*expr) &&
2714 (*expr) -> op != expr_variable_reference &&
2715 (*expr) -> op != expr_funcall) {
2716 parse_warn (cfile, "Expecting a data expression.");
2724 * numeric-expression :== EXTRACT_INT LPAREN data-expression
2725 * COMMA number RPAREN |
2729 int parse_numeric_expression (expr, cfile, lose)
2730 struct expression **expr;
2731 struct parse *cfile;
2734 /* Parse an expression... */
2735 if (!parse_expression (expr, cfile, lose, context_numeric,
2736 (struct expression **)0, expr_none))
2739 if (!is_numeric_expression (*expr) &&
2740 (*expr) -> op != expr_variable_reference &&
2741 (*expr) -> op != expr_funcall) {
2742 parse_warn (cfile, "Expecting a numeric expression.");
2750 * dns-expression :==
2751 * UPDATE LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
2752 * data-expression COMMA numeric-expression RPAREN
2753 * DELETE LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
2754 * data-expression RPAREN
2755 * EXISTS LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
2756 * data-expression RPAREN
2757 * NOT EXISTS LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
2758 * data-expression RPAREN
2759 * ns-class :== IN | CHAOS | HS | NUMBER
2760 * ns-type :== A | PTR | MX | TXT | NUMBER
2763 int parse_dns_expression (expr, cfile, lose)
2764 struct expression **expr;
2765 struct parse *cfile;
2768 /* Parse an expression... */
2769 if (!parse_expression (expr, cfile, lose, context_dns,
2770 (struct expression **)0, expr_none))
2773 if (!is_dns_expression (*expr) &&
2774 (*expr) -> op != expr_variable_reference &&
2775 (*expr) -> op != expr_funcall) {
2776 parse_warn (cfile, "Expecting a dns update subexpression.");
2783 /* Parse a subexpression that does not contain a binary operator. */
2785 int parse_non_binary (expr, cfile, lose, context)
2786 struct expression **expr;
2787 struct parse *cfile;
2789 enum expression_context context;
2791 enum dhcp_token token;
2793 struct collection *col;
2794 struct option *option;
2795 struct expression *nexp, **ep;
2797 enum expr_op opcode;
2800 struct executable_statement *stmt;
2803 isc_result_t status, code;
2806 token = peek_token (&val, (unsigned *)0, cfile);
2808 /* Check for unary operators... */
2811 token = next_token (&val, (unsigned *)0, cfile);
2812 token = next_token (&val, (unsigned *)0, cfile);
2813 if (token != STRING) {
2814 parse_warn (cfile, "string expected.");
2815 skip_to_semi (cfile);
2819 for (col = collections; col; col = col -> next)
2820 if (!strcmp (col -> name, val))
2823 parse_warn (cfile, "unknown collection.");
2827 if (!expression_allocate (expr, MDL))
2828 log_fatal ("can't allocate expression");
2829 (*expr) -> op = expr_check;
2830 (*expr) -> data.check = col;
2834 token = next_token (&val, (unsigned *)0, cfile);
2835 if (context == context_dns) {
2836 token = peek_token (&val, (unsigned *)0, cfile);
2839 if (!expression_allocate (expr, MDL))
2840 log_fatal ("can't allocate expression");
2841 (*expr) -> op = expr_not;
2842 if (!parse_non_binary (&(*expr) -> data.not,
2843 cfile, lose, context_boolean)) {
2845 parse_warn (cfile, "expression expected");
2846 skip_to_semi (cfile);
2849 expression_dereference (expr, MDL);
2852 if (!is_boolean_expression ((*expr) -> data.not)) {
2854 parse_warn (cfile, "boolean expression expected");
2855 skip_to_semi (cfile);
2856 expression_dereference (expr, MDL);
2862 token = next_token (&val, (unsigned *)0, cfile);
2863 if (!parse_expression (expr, cfile, lose, context,
2864 (struct expression **)0, expr_none)) {
2866 parse_warn (cfile, "expression expected");
2867 skip_to_semi (cfile);
2872 token = next_token (&val, (unsigned *)0, cfile);
2873 if (token != RPAREN) {
2875 parse_warn (cfile, "right paren expected");
2876 skip_to_semi (cfile);
2882 if (context == context_dns)
2884 token = next_token (&val, (unsigned *)0, cfile);
2885 if (!expression_allocate (expr, MDL))
2886 log_fatal ("can't allocate expression");
2887 (*expr) -> op = expr_exists;
2889 (*expr) -> data.option = parse_option_name (cfile, 0, &known);
2890 if (!(*expr) -> data.option) {
2892 expression_dereference (expr, MDL);
2898 token = next_token (&val, (unsigned *)0, cfile);
2899 if (!expression_allocate (expr, MDL))
2900 log_fatal ("can't allocate expression");
2901 (*expr) -> op = expr_static;
2905 token = next_token (&val, (unsigned *)0, cfile);
2906 if (!expression_allocate (expr, MDL))
2907 log_fatal ("can't allocate expression");
2908 (*expr) -> op = expr_known;
2912 token = next_token (&val, (unsigned *)0, cfile);
2913 if (!expression_allocate (expr, MDL))
2914 log_fatal ("can't allocate expression");
2915 (*expr) -> op = expr_substring;
2917 token = next_token (&val, (unsigned *)0, cfile);
2918 if (token != LPAREN) {
2920 expression_dereference (expr, MDL);
2921 parse_warn (cfile, "left parenthesis expected.");
2926 if (!parse_data_expression (&(*expr) -> data.substring.expr,
2929 expression_dereference (expr, MDL);
2932 "expecting data expression.");
2933 skip_to_semi (cfile);
2939 token = next_token (&val, (unsigned *)0, cfile);
2940 if (token != COMMA) {
2942 expression_dereference (expr, MDL);
2943 parse_warn (cfile, "comma expected.");
2949 if (!parse_numeric_expression
2950 (&(*expr) -> data.substring.offset,cfile, lose)) {
2954 "expecting numeric expression.");
2955 skip_to_semi (cfile);
2958 expression_dereference (expr, MDL);
2962 token = next_token (&val, (unsigned *)0, cfile);
2966 if (!parse_numeric_expression
2967 (&(*expr) -> data.substring.len, cfile, lose))
2970 token = next_token (&val, (unsigned *)0, cfile);
2971 if (token != RPAREN) {
2973 parse_warn (cfile, "right parenthesis expected.");
2975 expression_dereference (expr, MDL);
2981 token = next_token (&val, (unsigned *)0, cfile);
2982 if (!expression_allocate (expr, MDL))
2983 log_fatal ("can't allocate expression");
2984 (*expr) -> op = expr_suffix;
2986 token = next_token (&val, (unsigned *)0, cfile);
2987 if (token != LPAREN)
2990 if (!parse_data_expression (&(*expr) -> data.suffix.expr,
2994 token = next_token (&val, (unsigned *)0, cfile);
2998 if (!parse_numeric_expression (&(*expr) -> data.suffix.len,
3002 token = next_token (&val, (unsigned *)0, cfile);
3003 if (token != RPAREN)
3008 token = next_token (&val, (unsigned *)0, cfile);
3009 if (!expression_allocate (expr, MDL))
3010 log_fatal ("can't allocate expression");
3011 (*expr) -> op = expr_concat;
3013 token = next_token (&val, (unsigned *)0, cfile);
3014 if (token != LPAREN)
3017 if (!parse_data_expression (&(*expr) -> data.concat [0],
3021 token = next_token (&val, (unsigned *)0, cfile);
3026 if (!parse_data_expression (&(*expr) -> data.concat [1],
3030 token = next_token (&val, (unsigned *)0, cfile);
3032 if (token == COMMA) {
3033 nexp = (struct expression *)0;
3034 if (!expression_allocate (&nexp, MDL))
3035 log_fatal ("can't allocate at CONCAT2");
3036 nexp -> op = expr_concat;
3037 expression_reference (&nexp -> data.concat [0],
3039 expression_dereference (expr, MDL);
3040 expression_reference (expr, nexp, MDL);
3041 expression_dereference (&nexp, MDL);
3042 goto concat_another;
3045 if (token != RPAREN)
3049 case BINARY_TO_ASCII:
3050 token = next_token (&val, (unsigned *)0, cfile);
3051 if (!expression_allocate (expr, MDL))
3052 log_fatal ("can't allocate expression");
3053 (*expr) -> op = expr_binary_to_ascii;
3055 token = next_token (&val, (unsigned *)0, cfile);
3056 if (token != LPAREN)
3059 if (!parse_numeric_expression (&(*expr) -> data.b2a.base,
3063 token = next_token (&val, (unsigned *)0, cfile);
3067 if (!parse_numeric_expression (&(*expr) -> data.b2a.width,
3071 token = next_token (&val, (unsigned *)0, cfile);
3075 if (!parse_data_expression (&(*expr) -> data.b2a.seperator,
3079 token = next_token (&val, (unsigned *)0, cfile);
3083 if (!parse_data_expression (&(*expr) -> data.b2a.buffer,
3087 token = next_token (&val, (unsigned *)0, cfile);
3088 if (token != RPAREN)
3093 token = next_token (&val, (unsigned *)0, cfile);
3094 if (!expression_allocate (expr, MDL))
3095 log_fatal ("can't allocate expression");
3096 (*expr) -> op = expr_reverse;
3098 token = next_token (&val, (unsigned *)0, cfile);
3099 if (token != LPAREN)
3102 if (!(parse_numeric_expression
3103 (&(*expr) -> data.reverse.width, cfile, lose)))
3106 token = next_token (&val, (unsigned *)0, cfile);
3110 if (!(parse_data_expression
3111 (&(*expr) -> data.reverse.buffer, cfile, lose)))
3114 token = next_token (&val, (unsigned *)0, cfile);
3115 if (token != RPAREN)
3120 /* pick (a, b, c) actually produces an internal representation
3121 that looks like pick (a, pick (b, pick (c, nil))). */
3122 token = next_token (&val, (unsigned *)0, cfile);
3123 if (!(expression_allocate (expr, MDL)))
3124 log_fatal ("can't allocate expression");
3126 token = next_token (&val, (unsigned *)0, cfile);
3127 if (token != LPAREN)
3130 nexp = (struct expression *)0;
3131 expression_reference (&nexp, *expr, MDL);
3133 nexp -> op = expr_pick_first_value;
3134 if (!(parse_data_expression
3135 (&nexp -> data.pick_first_value.car,
3139 token = next_token (&val, (unsigned *)0, cfile);
3140 if (token == COMMA) {
3141 struct expression *foo = (struct expression *)0;
3142 if (!expression_allocate (&foo, MDL))
3143 log_fatal ("can't allocate expr");
3144 expression_reference
3145 (&nexp -> data.pick_first_value.cdr, foo, MDL);
3146 expression_dereference (&nexp, MDL);
3147 expression_reference (&nexp, foo, MDL);
3148 expression_dereference (&foo, MDL);
3150 } while (token == COMMA);
3151 expression_dereference (&nexp, MDL);
3153 if (token != RPAREN)
3157 /* dns-update and dns-delete are present for historical
3158 purposes, but are deprecated in favor of ns-update
3159 in combination with update, delete, exists and not
3163 #if !defined (NSUPDATE)
3165 "Please rebuild dhcpd with --with-nsupdate.");
3167 token = next_token (&val, (unsigned *)0, cfile);
3168 if (token == DNS_UPDATE)
3169 opcode = expr_ns_add;
3171 opcode = expr_ns_delete;
3173 token = next_token (&val, (unsigned *)0, cfile);
3174 if (token != LPAREN)
3177 token = next_token (&val, (unsigned *)0, cfile);
3178 if (token != STRING) {
3180 "parse_expression: expecting string.");
3182 skip_to_semi (cfile);
3187 if (!strcasecmp (val, "a"))
3189 else if (!strcasecmp (val, "ptr"))
3191 else if (!strcasecmp (val, "mx"))
3193 else if (!strcasecmp (val, "cname"))
3195 else if (!strcasecmp (val, "TXT"))
3198 parse_warn (cfile, "unexpected rrtype: %s", val);
3202 s = (opcode == expr_ns_add
3204 : "old-dns-delete");
3205 cptr = dmalloc (strlen (s) + 1, MDL);
3207 log_fatal ("can't allocate name for %s", s);
3209 if (!expression_allocate (expr, MDL))
3210 log_fatal ("can't allocate expression");
3211 (*expr) -> op = expr_funcall;
3212 (*expr) -> data.funcall.name = cptr;
3214 /* Fake up a function call. */
3215 ep = &(*expr) -> data.funcall.arglist;
3216 if (!expression_allocate (ep, MDL))
3217 log_fatal ("can't allocate expression");
3218 (*ep) -> op = expr_arg;
3219 if (!make_const_int (&(*ep) -> data.arg.val, u))
3220 log_fatal ("can't allocate rrtype value.");
3222 token = next_token (&val, (unsigned *)0, cfile);
3225 ep = &((*ep) -> data.arg.next);
3226 if (!expression_allocate (ep, MDL))
3227 log_fatal ("can't allocate expression");
3228 (*ep) -> op = expr_arg;
3229 if (!(parse_data_expression (&(*ep) -> data.arg.val,
3233 token = next_token (&val, (unsigned *)0, cfile);
3237 ep = &((*ep) -> data.arg.next);
3238 if (!expression_allocate (ep, MDL))
3239 log_fatal ("can't allocate expression");
3240 (*ep) -> op = expr_arg;
3241 if (!(parse_data_expression (&(*ep) -> data.arg.val,
3245 if (opcode == expr_ns_add) {
3246 token = next_token (&val, (unsigned *)0, cfile);
3250 ep = &((*ep) -> data.arg.next);
3251 if (!expression_allocate (ep, MDL))
3252 log_fatal ("can't allocate expression");
3253 (*ep) -> op = expr_arg;
3254 if (!(parse_numeric_expression (&(*ep) -> data.arg.val,
3257 "expecting numeric expression.");
3262 token = next_token (&val, (unsigned *)0, cfile);
3263 if (token != RPAREN)
3268 #if !defined (NSUPDATE)
3270 "Please rebuild dhcpd with --with-nsupdate.");
3272 token = next_token (&val, (unsigned *)0, cfile);
3273 if (!expression_allocate (expr, MDL))
3274 log_fatal ("can't allocate expression");
3276 token = next_token (&val, (unsigned *)0, cfile);
3277 if (token != LPAREN)
3282 nexp -> op = expr_dns_transaction;
3283 if (!(parse_dns_expression
3284 (&nexp -> data.dns_transaction.car,
3290 "expecting dns expression.");
3292 expression_dereference (expr, MDL);
3297 token = next_token (&val, (unsigned *)0, cfile);
3299 if (token == COMMA) {
3300 if (!(expression_allocate
3301 (&nexp -> data.dns_transaction.cdr,
3304 ("can't allocate expression");
3305 nexp = nexp -> data.dns_transaction.cdr;
3307 } while (token == COMMA);
3309 if (token != RPAREN)
3313 /* NOT EXISTS is special cased above... */
3315 token = peek_token (&val, (unsigned *)0, cfile);
3316 if (token != EXISTS) {
3317 parse_warn (cfile, "expecting DNS prerequisite.");
3321 opcode = expr_ns_not_exists;
3324 opcode = expr_ns_add;
3327 opcode = expr_ns_delete;
3330 opcode = expr_ns_exists;
3332 token = next_token (&val, (unsigned *)0, cfile);
3334 #if !defined (NSUPDATE)
3336 "Please rebuild dhcpd with --with-nsupdate.");
3338 if (!expression_allocate (expr, MDL))
3339 log_fatal ("can't allocate expression");
3340 (*expr) -> op = opcode;
3342 token = next_token (&val, (unsigned *)0, cfile);
3343 if (token != LPAREN)
3346 token = next_token (&val, (unsigned *)0, cfile);
3347 if (!is_identifier (token) && token != NUMBER) {
3348 parse_warn (cfile, "expecting identifier or number.");
3350 expression_dereference (expr, MDL);
3351 skip_to_semi (cfile);
3356 if (token == NUMBER)
3357 (*expr) -> data.ns_add.rrclass = atoi (val);
3358 else if (!strcasecmp (val, "in"))
3359 (*expr) -> data.ns_add.rrclass = C_IN;
3360 else if (!strcasecmp (val, "chaos"))
3361 (*expr) -> data.ns_add.rrclass = C_CHAOS;
3362 else if (!strcasecmp (val, "hs"))
3363 (*expr) -> data.ns_add.rrclass = C_HS;
3365 parse_warn (cfile, "unexpected rrclass: %s", val);
3369 token = next_token (&val, (unsigned *)0, cfile);
3373 token = next_token (&val, (unsigned *)0, cfile);
3374 if (!is_identifier (token) && token != NUMBER) {
3375 parse_warn (cfile, "expecting identifier or number.");
3379 if (token == NUMBER)
3380 (*expr) -> data.ns_add.rrtype = atoi (val);
3381 else if (!strcasecmp (val, "a"))
3382 (*expr) -> data.ns_add.rrtype = T_A;
3383 else if (!strcasecmp (val, "ptr"))
3384 (*expr) -> data.ns_add.rrtype = T_PTR;
3385 else if (!strcasecmp (val, "mx"))
3386 (*expr) -> data.ns_add.rrtype = T_MX;
3387 else if (!strcasecmp (val, "cname"))
3388 (*expr) -> data.ns_add.rrtype = T_CNAME;
3389 else if (!strcasecmp (val, "TXT"))
3390 (*expr) -> data.ns_add.rrtype = T_TXT;
3392 parse_warn (cfile, "unexpected rrtype: %s", val);
3396 token = next_token (&val, (unsigned *)0, cfile);
3400 if (!(parse_data_expression
3401 (&(*expr) -> data.ns_add.rrname, cfile, lose)))
3404 token = next_token (&val, (unsigned *)0, cfile);
3408 if (!(parse_data_expression
3409 (&(*expr) -> data.ns_add.rrdata, cfile, lose)))
3412 if (opcode == expr_ns_add) {
3413 token = next_token (&val, (unsigned *)0, cfile);
3417 if (!(parse_numeric_expression
3418 (&(*expr) -> data.ns_add.ttl, cfile,
3422 "expecting numeric expression.");
3427 token = next_token (&val, (unsigned *)0, cfile);
3428 if (token != RPAREN)
3434 if (!expression_allocate (expr, MDL))
3435 log_fatal ("can't allocate expression");
3436 (*expr) -> op = (token == OPTION
3438 : expr_config_option);
3439 token = next_token (&val, (unsigned *)0, cfile);
3441 (*expr) -> data.option = parse_option_name (cfile, 0, &known);
3442 if (!(*expr) -> data.option) {
3444 expression_dereference (expr, MDL);
3450 token = next_token (&val, (unsigned *)0, cfile);
3451 if (!expression_allocate (expr, MDL))
3452 log_fatal ("can't allocate expression");
3453 (*expr) -> op = expr_hardware;
3456 case LEASED_ADDRESS:
3457 token = next_token (&val, (unsigned *)0, cfile);
3458 if (!expression_allocate (expr, MDL))
3459 log_fatal ("can't allocate expression");
3460 (*expr) -> op = expr_leased_address;
3464 token = next_token (&val, (unsigned *)0, cfile);
3465 if (!expression_allocate (expr, MDL))
3466 log_fatal ("can't allocate expression");
3467 (*expr) -> op = expr_client_state;
3471 token = next_token (&val, (unsigned *)0, cfile);
3472 if (!expression_allocate (expr, MDL))
3473 log_fatal ("can't allocate expression");
3474 (*expr) -> op = expr_filename;
3478 token = next_token (&val, (unsigned *)0, cfile);
3479 if (!expression_allocate (expr, MDL))
3480 log_fatal ("can't allocate expression");
3481 (*expr) -> op = expr_sname;
3485 token = next_token (&val, (unsigned *)0, cfile);
3486 if (!expression_allocate (expr, MDL))
3487 log_fatal ("can't allocate expression");
3488 (*expr) -> op = expr_lease_time;
3492 token = next_token (&val, (unsigned *)0, cfile);
3493 if (!expression_allocate (expr, MDL))
3494 log_fatal ("can't allocate expression");
3495 (*expr) -> op = expr_null;
3498 case HOST_DECL_NAME:
3499 token = next_token (&val, (unsigned *)0, cfile);
3500 if (!expression_allocate (expr, MDL))
3501 log_fatal ("can't allocate expression");
3502 (*expr) -> op = expr_host_decl_name;
3505 case UPDATED_DNS_RR:
3506 token = next_token (&val, (unsigned *)0, cfile);
3508 token = next_token (&val, (unsigned *)0, cfile);
3509 if (token != LPAREN)
3512 token = next_token (&val, (unsigned *)0, cfile);
3513 if (token != STRING) {
3514 parse_warn (cfile, "expecting string.");
3519 if (!strcasecmp (val, "a"))
3520 s = "ddns-fwd-name";
3521 else if (!strcasecmp (val, "ptr"))
3522 s = "ddns-rev-name";
3524 parse_warn (cfile, "invalid DNS rrtype: %s", val);
3528 token = next_token (&val, (unsigned *)0, cfile);
3529 if (token != RPAREN)
3532 if (!expression_allocate (expr, MDL))
3533 log_fatal ("can't allocate expression");
3534 (*expr) -> op = expr_variable_reference;
3535 (*expr) -> data.variable =
3536 dmalloc (strlen (s) + 1, MDL);
3537 if (!(*expr) -> data.variable)
3538 log_fatal ("can't allocate variable name.");
3539 strcpy ((*expr) -> data.variable, s);
3543 token = next_token (&val, (unsigned *)0, cfile);
3544 if (!expression_allocate (expr, MDL))
3545 log_fatal ("can't allocate expression");
3546 (*expr) -> op = expr_packet;
3548 token = next_token (&val, (unsigned *)0, cfile);
3549 if (token != LPAREN)
3552 if (!parse_numeric_expression (&(*expr) -> data.packet.offset,
3556 token = next_token (&val, (unsigned *)0, cfile);
3560 if (!parse_numeric_expression (&(*expr) -> data.packet.len,
3564 token = next_token (&val, (unsigned *)0, cfile);
3565 if (token != RPAREN)
3570 token = next_token (&val, &len, cfile);
3571 if (!make_const_data (expr, (const unsigned char *)val,
3573 log_fatal ("can't make constant string expression.");
3577 token = next_token (&val, (unsigned *)0, cfile);
3578 token = next_token (&val, (unsigned *)0, cfile);
3579 if (token != LPAREN) {
3580 parse_warn (cfile, "left parenthesis expected.");
3585 if (!expression_allocate (expr, MDL))
3586 log_fatal ("can't allocate expression");
3588 if (!parse_data_expression (&(*expr) -> data.extract_int,
3592 "expecting data expression.");
3593 skip_to_semi (cfile);
3596 expression_dereference (expr, MDL);
3600 token = next_token (&val, (unsigned *)0, cfile);
3601 if (token != COMMA) {
3602 parse_warn (cfile, "comma expected.");
3604 expression_dereference (expr, MDL);
3608 token = next_token (&val, (unsigned *)0, cfile);
3609 if (token != NUMBER) {
3610 parse_warn (cfile, "number expected.");
3612 expression_dereference (expr, MDL);
3615 switch (atoi (val)) {
3617 (*expr) -> op = expr_extract_int8;
3621 (*expr) -> op = expr_extract_int16;
3625 (*expr) -> op = expr_extract_int32;
3630 "unsupported integer size %d", atoi (val));
3632 skip_to_semi (cfile);
3633 expression_dereference (expr, MDL);
3637 token = next_token (&val, (unsigned *)0, cfile);
3638 if (token != RPAREN) {
3639 parse_warn (cfile, "right parenthesis expected.");
3641 expression_dereference (expr, MDL);
3647 token = next_token (&val, (unsigned *)0, cfile);
3648 token = next_token (&val, (unsigned *)0, cfile);
3649 if (token != LPAREN) {
3650 parse_warn (cfile, "left parenthesis expected.");
3655 if (!expression_allocate (expr, MDL))
3656 log_fatal ("can't allocate expression");
3658 if (!parse_numeric_expression (&(*expr) -> data.encode_int,
3660 parse_warn (cfile, "expecting numeric expression.");
3661 skip_to_semi (cfile);
3663 expression_dereference (expr, MDL);
3667 token = next_token (&val, (unsigned *)0, cfile);
3668 if (token != COMMA) {
3669 parse_warn (cfile, "comma expected.");
3671 expression_dereference (expr, MDL);
3675 token = next_token (&val, (unsigned *)0, cfile);
3676 if (token != NUMBER) {
3677 parse_warn (cfile, "number expected.");
3679 expression_dereference (expr, MDL);
3682 switch (atoi (val)) {
3684 (*expr) -> op = expr_encode_int8;
3688 (*expr) -> op = expr_encode_int16;
3692 (*expr) -> op = expr_encode_int32;
3697 "unsupported integer size %d", atoi (val));
3699 skip_to_semi (cfile);
3700 expression_dereference (expr, MDL);
3704 token = next_token (&val, (unsigned *)0, cfile);
3705 if (token != RPAREN) {
3706 parse_warn (cfile, "right parenthesis expected.");
3708 expression_dereference (expr, MDL);
3714 /* If we're in a numeric context, this should just be a
3715 number, by itself. */
3716 if (context == context_numeric ||
3717 context == context_data_or_numeric) {
3718 next_token (&val, (unsigned *)0, cfile);
3719 if (!expression_allocate (expr, MDL))
3720 log_fatal ("can't allocate expression");
3721 (*expr) -> op = expr_const_int;
3722 (*expr) -> data.const_int = atoi (val);
3726 case NUMBER_OR_NAME:
3727 if (!expression_allocate (expr, MDL))
3728 log_fatal ("can't allocate expression");
3730 (*expr) -> op = expr_const_data;
3731 if (!parse_cshl (&(*expr) -> data.const_data, cfile)) {
3732 expression_dereference (expr, MDL);
3741 token = next_token (&val, (unsigned *)0, cfile);
3742 if (!expression_allocate (expr, MDL))
3743 log_fatal ("can't allocate expression");
3744 (*expr) -> op = expr_const_int;
3745 (*expr) -> data.const_int = known;
3749 known = ISC_R_SUCCESS;
3753 known = ISC_R_NOTAUTH;
3757 known = ISC_R_NOTIMPLEMENTED;
3761 known = ISC_R_NOTZONE;
3765 known = ISC_R_NXDOMAIN;
3769 known = ISC_R_NXRRSET;
3773 known = ISC_R_REFUSED;
3777 known = ISC_R_SERVFAIL;
3781 known = ISC_R_YXDOMAIN;
3785 known = ISC_R_YXRRSET;
3793 known = S_REBOOTING;
3797 known = S_SELECTING;
3801 known = S_REQUESTING;
3813 known = S_REBINDING;
3817 token = next_token (&val, (unsigned *)0, cfile);
3818 token = next_token (&val, (unsigned *)0, cfile);
3819 if (token != LPAREN)
3822 token = next_token (&val, (unsigned *)0, cfile);
3823 if (token != NAME && token != NUMBER_OR_NAME) {
3824 parse_warn (cfile, "%s can't be a variable name", val);
3825 skip_to_semi (cfile);
3830 if (!expression_allocate (expr, MDL))
3831 log_fatal ("can't allocate expression");
3832 (*expr) -> op = expr_variable_exists;
3833 (*expr) -> data.variable = dmalloc (strlen (val) + 1, MDL);
3834 if (!(*expr)->data.variable)
3835 log_fatal ("can't allocate variable name");
3836 strcpy ((*expr) -> data.variable, val);
3837 token = next_token (&val, (unsigned *)0, cfile);
3838 if (token != RPAREN)
3842 /* Not a valid start to an expression... */
3844 if (token != NAME && token != NUMBER_OR_NAME)
3847 token = next_token (&val, (unsigned *)0, cfile);
3849 /* Save the name of the variable being referenced. */
3850 cptr = dmalloc (strlen (val) + 1, MDL);
3852 log_fatal ("can't allocate variable name");
3855 /* Simple variable reference, as far as we can tell. */
3856 token = peek_token (&val, (unsigned *)0, cfile);
3857 if (token != LPAREN) {
3858 if (!expression_allocate (expr, MDL))
3859 log_fatal ("can't allocate expression");
3860 (*expr) -> op = expr_variable_reference;
3861 (*expr) -> data.variable = cptr;
3865 token = next_token (&val, (unsigned *)0, cfile);
3866 if (!expression_allocate (expr, MDL))
3867 log_fatal ("can't allocate expression");
3868 (*expr) -> op = expr_funcall;
3869 (*expr) -> data.funcall.name = cptr;
3871 /* Now parse the argument list. */
3872 ep = &(*expr) -> data.funcall.arglist;
3874 if (!expression_allocate (ep, MDL))
3875 log_fatal ("can't allocate expression");
3876 (*ep) -> op = expr_arg;
3877 if (!parse_expression (&(*ep) -> data.arg.val,
3878 cfile, lose, context_any,
3879 (struct expression **)0,
3883 "expecting expression.");
3886 skip_to_semi (cfile);
3887 expression_dereference (expr, MDL);
3890 ep = &((*ep) -> data.arg.next);
3891 token = next_token (&val, (unsigned *)0, cfile);
3892 } while (token == COMMA);
3893 if (token != RPAREN) {
3894 parse_warn (cfile, "Right parenthesis expected.");
3895 skip_to_semi (cfile);
3897 expression_dereference (expr, MDL);
3905 /* Parse an expression. */
3907 int parse_expression (expr, cfile, lose, context, plhs, binop)
3908 struct expression **expr;
3909 struct parse *cfile;
3911 enum expression_context context;
3912 struct expression **plhs;
3915 enum dhcp_token token;
3917 struct expression *rhs = (struct expression *)0, *tmp;
3918 struct expression *lhs = (struct expression *)0;
3919 enum expr_op next_op;
3920 enum expression_context
3921 lhs_context = context_any,
3922 rhs_context = context_any;
3924 /* Consume the left hand side we were passed. */
3926 expression_reference (&lhs, *plhs, MDL);
3927 expression_dereference (plhs, MDL);
3931 if (!parse_non_binary (&rhs, cfile, lose, context)) {
3932 /* If we already have a left-hand side, then it's not
3933 okay for there not to be a right-hand side here, so
3934 we need to flag it as an error. */
3938 "expecting right-hand side.");
3940 skip_to_semi (cfile);
3942 expression_dereference (&lhs, MDL);
3947 /* At this point, rhs contains either an entire subexpression,
3948 or at least a left-hand-side. If we do not see a binary token
3949 as the next token, we're done with the expression. */
3951 token = peek_token (&val, (unsigned *)0, cfile);
3954 token = next_token (&val, (unsigned *)0, cfile);
3955 token = peek_token (&val, (unsigned *)0, cfile);
3956 if (token != EQUAL) {
3957 parse_warn (cfile, "! in boolean context without =");
3959 skip_to_semi (cfile);
3961 expression_dereference (&lhs, MDL);
3964 next_op = expr_not_equal;
3965 context = expression_context (rhs);
3969 next_op = expr_equal;
3970 context = expression_context (rhs);
3975 context = expression_context (rhs);
3980 context = expression_context (rhs);
3985 context = expression_context (rhs);
3989 next_op = expr_subtract;
3990 context = expression_context (rhs);
3994 next_op = expr_divide;
3995 context = expression_context (rhs);
3999 next_op = expr_multiply;
4000 context = expression_context (rhs);
4004 next_op = expr_remainder;
4005 context = expression_context (rhs);
4009 next_op = expr_binary_and;
4010 context = expression_context (rhs);
4014 next_op = expr_binary_or;
4015 context = expression_context (rhs);
4019 next_op = expr_binary_xor;
4020 context = expression_context (rhs);
4024 next_op = expr_none;
4027 /* If we have no lhs yet, we just parsed it. */
4029 /* If there was no operator following what we just parsed,
4030 then we're done - return it. */
4031 if (next_op == expr_none) {
4036 rhs = (struct expression *)0;
4038 next_token (&val, (unsigned *)0, cfile);
4042 if (binop != expr_none) {
4043 if (expression_context (rhs) != expression_context (lhs)) {
4044 parse_warn (cfile, "illegal expression relating different types");
4045 skip_to_semi (cfile);
4046 expression_dereference (&rhs, MDL);
4047 expression_dereference (&lhs, MDL);
4053 case expr_not_equal:
4055 if ((expression_context(rhs) != context_data_or_numeric) &&
4056 (expression_context(rhs) != context_data) &&
4057 (expression_context(rhs) != context_numeric)) {
4058 parse_warn (cfile, "expecting data/numeric expression");
4059 skip_to_semi (cfile);
4060 expression_dereference (&rhs, MDL);
4068 if (expression_context(rhs) != context_boolean) {
4069 parse_warn (cfile, "expecting boolean expressions");
4070 skip_to_semi (cfile);
4071 expression_dereference (&rhs, MDL);
4081 case expr_remainder:
4082 case expr_binary_and:
4083 case expr_binary_or:
4084 case expr_binary_xor:
4085 if (expression_context(rhs) != context_numeric) {
4086 parse_warn (cfile, "expecting numeric expressions");
4087 skip_to_semi (cfile);
4088 expression_dereference (&rhs, MDL);
4099 /* Now, if we didn't find a binary operator, we're done parsing
4100 this subexpression, so combine it with the preceding binary
4101 operator and return the result. */
4102 if (next_op == expr_none) {
4103 if (!expression_allocate (expr, MDL))
4104 log_fatal ("Can't allocate expression!");
4106 (*expr) -> op = binop;
4107 /* All the binary operators' data union members
4108 are the same, so we'll cheat and use the member
4109 for the equals operator. */
4110 (*expr) -> data.equal [0] = lhs;
4111 (*expr) -> data.equal [1] = rhs;
4115 /* Eat the operator token - we now know it was a binary operator... */
4116 token = next_token (&val, (unsigned *)0, cfile);
4118 /* If the binary operator we saw previously has a lower precedence
4119 than the next operator, then the rhs we just parsed for that
4120 operator is actually the lhs of the operator with the higher
4121 precedence - to get the real rhs, we need to recurse on the
4123 if (binop != expr_none &&
4124 op_precedence (binop, next_op) < 0) {
4126 rhs = (struct expression *)0;
4127 if (!parse_expression (&rhs, cfile, lose, op_context (next_op),
4131 "expecting a subexpression");
4136 next_op = expr_none;
4139 /* Now combine the LHS and the RHS using binop. */
4140 tmp = (struct expression *)0;
4141 if (!expression_allocate (&tmp, MDL))
4142 log_fatal ("No memory for equal precedence combination.");
4144 /* Store the LHS and RHS. */
4145 tmp -> data.equal [0] = lhs;
4146 tmp -> data.equal [1] = rhs;
4150 tmp = (struct expression *)0;
4151 rhs = (struct expression *)0;
4153 /* Recursions don't return until we have parsed the end of the
4154 expression, so if we recursed earlier, we can now return what
4156 if (next_op == expr_none) {
4165 /* option-statement :== identifier DOT identifier <syntax> SEMI
4166 | identifier <syntax> SEMI
4168 Option syntax is handled specially through format strings, so it
4169 would be painful to come up with BNF for it. However, it always
4170 starts as above and ends in a SEMI. */
4172 int parse_option_statement (result, cfile, lookups, option, op)
4173 struct executable_statement **result;
4174 struct parse *cfile;
4176 struct option *option;
4177 enum statement_op op;
4180 enum dhcp_token token;
4181 const char *fmt = NULL;
4182 struct expression *expr = (struct expression *)0;
4183 struct expression *tmp;
4185 struct executable_statement *stmt;
4188 token = peek_token (&val, (unsigned *)0, cfile);
4189 if (token == SEMI) {
4190 /* Eat the semicolon... */
4191 token = next_token (&val, (unsigned *)0, cfile);
4195 if (token == EQUAL) {
4196 /* Eat the equals sign. */
4197 token = next_token (&val, (unsigned *)0, cfile);
4199 /* Parse a data expression and use its value for the data. */
4200 if (!parse_data_expression (&expr, cfile, &lose)) {
4201 /* In this context, we must have an executable
4202 statement, so if we found something else, it's
4206 "expecting a data expression.");
4207 skip_to_semi (cfile);
4212 /* We got a valid expression, so use it. */
4216 /* Parse the option data... */
4218 /* Set a flag if this is an array of a simple type (i.e.,
4219 not an array of pairs of IP addresses, or something
4221 int uniform = option -> format [1] == 'A';
4224 /* Set fmt to start of format for 'A' and one char back
4226 if ((fmt != NULL) &&
4227 (fmt != option -> format) && (*fmt == 'a'))
4230 fmt = ((fmt == NULL) ||
4231 (*fmt == 'A')) ? option -> format : fmt;
4233 /* 'a' means always uniform */
4234 uniform |= (fmt [1] == 'a');
4236 for ( ; *fmt; fmt++) {
4237 if ((*fmt == 'A') || (*fmt == 'a'))
4242 expr = (struct expression *)0;
4243 if (!parse_option_token (&expr, cfile, &fmt,
4244 tmp, uniform, lookups)) {
4245 if (fmt [1] != 'o') {
4247 expression_dereference (&tmp,
4252 tmp = (struct expression *)0;
4255 expression_dereference (&tmp, MDL);
4257 if ((*fmt == 'A') || (*fmt == 'a')) {
4258 token = peek_token (&val, (unsigned *)0, cfile);
4259 /* Comma means: continue with next element in array */
4260 if (token == COMMA) {
4261 token = next_token (&val,
4262 (unsigned *)0, cfile);
4265 /* no comma: end of array.
4266 'A' or end of string means: leave the loop */
4267 if ((*fmt == 'A') || (fmt[1] == '\0'))
4269 /* 'a' means: go on with next char */
4275 } while ((*fmt == 'A') || (*fmt == 'a'));
4278 if (!parse_semi (cfile))
4280 if (!executable_statement_allocate (result, MDL))
4281 log_fatal ("no memory for option statement.");
4282 (*result) -> op = op;
4283 if (expr && !option_cache (&(*result) -> data.option,
4284 (struct data_string *)0, expr, option, MDL))
4285 log_fatal ("no memory for option cache");
4287 expression_dereference (&expr, MDL);
4291 int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
4292 struct expression **rv;
4293 struct parse *cfile;
4295 struct expression *expr;
4300 enum dhcp_token token;
4301 struct expression *t = (struct expression *)0;
4302 unsigned char buf [4];
4308 struct enumeration_value *e;
4312 token = peek_token (&val, (unsigned *)0, cfile);
4313 if (!is_identifier (token)) {
4314 if ((*fmt) [1] != 'o') {
4315 parse_warn (cfile, "expecting identifier.");
4316 skip_to_semi (cfile);
4320 token = next_token (&val, &len, cfile);
4321 if (!make_const_data (&t, (const unsigned char *)val,
4323 log_fatal ("No memory for %s", val);
4327 g = strchr (*fmt, '.');
4330 "malformed encapsulation format (bug!)");
4331 skip_to_semi (cfile);
4336 token = peek_token (&val, (unsigned *)0, cfile);
4337 if (token == NUMBER_OR_NAME || token == NUMBER) {
4338 if (!expression_allocate (&t, MDL))
4340 if (!parse_cshl (&t -> data.const_data, cfile)) {
4341 expression_dereference (&t, MDL);
4344 t -> op = expr_const_data;
4345 } else if (token == STRING) {
4346 token = next_token (&val, &len, cfile);
4347 if (!make_const_data (&t, (const unsigned char *)val,
4349 log_fatal ("No memory for \"%s\"", val);
4351 if ((*fmt) [1] != 'o') {
4352 parse_warn (cfile, "expecting string %s.",
4353 "or hexadecimal data");
4354 skip_to_semi (cfile);
4360 case 'd': /* Domain name... */
4361 val = parse_host_name (cfile);
4363 parse_warn (cfile, "not a valid domain name.");
4364 skip_to_semi (cfile);
4370 case 't': /* Text string... */
4371 token = peek_token (&val, (unsigned *)0, cfile);
4372 if (token != STRING && !is_identifier (token)) {
4373 if ((*fmt) [1] != 'o') {
4374 parse_warn (cfile, "expecting string.");
4376 skip_to_semi (cfile);
4380 token = next_token (&val, &len, cfile);
4382 if (!make_const_data (&t, (const unsigned char *)val,
4384 log_fatal ("No memory for concatenation");
4389 g = strchr (*fmt, '.');
4391 parse_warn (cfile, "malformed %s (bug!)",
4392 "enumeration format");
4394 skip_to_semi (cfile);
4398 token = next_token (&val, (unsigned *)0, cfile);
4399 if (!is_identifier (token)) {
4401 "identifier expected");
4404 e = find_enumeration_value (f, (*fmt) - f, val);
4406 parse_warn (cfile, "unknown value");
4409 if (!make_const_data (&t, &e -> value, 1, 0, 1, MDL))
4413 case 'I': /* IP address or hostname. */
4415 if (!parse_ip_addr_or_hostname (&t, cfile, uniform))
4418 if (!parse_ip_addr (cfile, &addr))
4420 if (!make_const_data (&t, addr.iabuf, addr.len,
4426 case 'T': /* Lease interval. */
4427 token = peek_token (&val, (unsigned *)0, cfile);
4428 if (token != INFINITE)
4430 token = next_token (&val, (unsigned *)0, cfile);
4432 if (!make_const_data (&t, buf, 4, 0, 1, MDL))
4436 case 'L': /* Unsigned 32-bit integer... */
4437 case 'l': /* Signed 32-bit integer... */
4438 token = peek_token (&val, (unsigned *)0, cfile);
4440 if (token != NUMBER) {
4442 if ((*fmt) [1] != 'o') {
4443 parse_warn (cfile, "expecting number.");
4445 skip_to_semi (cfile);
4449 token = next_token (&val, (unsigned *)0, cfile);
4450 convert_num (cfile, buf, val, 0, 32);
4451 if (!make_const_data (&t, buf, 4, 0, 1, MDL))
4455 case 's': /* Signed 16-bit integer. */
4456 case 'S': /* Unsigned 16-bit integer. */
4457 token = peek_token (&val, (unsigned *)0, cfile);
4458 if (token != NUMBER)
4460 token = next_token (&val, (unsigned *)0, cfile);
4461 convert_num (cfile, buf, val, 0, 16);
4462 if (!make_const_data (&t, buf, 2, 0, 1, MDL))
4466 case 'b': /* Signed 8-bit integer. */
4467 case 'B': /* Unsigned 8-bit integer. */
4468 token = peek_token (&val, (unsigned *)0, cfile);
4469 if (token != NUMBER)
4471 token = next_token (&val, (unsigned *)0, cfile);
4472 convert_num (cfile, buf, val, 0, 8);
4473 if (!make_const_data (&t, buf, 1, 0, 1, MDL))
4477 case 'f': /* Boolean flag. */
4478 token = peek_token (&val, (unsigned *)0, cfile);
4479 if (!is_identifier (token)) {
4480 if ((*fmt) [1] != 'o')
4481 parse_warn (cfile, "expecting identifier.");
4483 if ((*fmt) [1] != 'o') {
4485 skip_to_semi (cfile);
4489 if (!strcasecmp (val, "true")
4490 || !strcasecmp (val, "on"))
4492 else if (!strcasecmp (val, "false")
4493 || !strcasecmp (val, "off"))
4495 else if (!strcasecmp (val, "ignore"))
4498 if ((*fmt) [1] != 'o')
4499 parse_warn (cfile, "expecting boolean.");
4502 token = next_token (&val, (unsigned *)0, cfile);
4503 if (!make_const_data (&t, buf, 1, 0, 1, MDL))
4508 parse_warn (cfile, "Bad format %c in parse_option_token.",
4510 skip_to_semi (cfile);
4514 if (!make_concat (rv, expr, t))
4517 expression_reference (rv, t, MDL);
4518 expression_dereference (&t, MDL);
4522 int parse_option_decl (oc, cfile)
4523 struct option_cache **oc;
4524 struct parse *cfile;
4529 u_int8_t hunkbuf [1024];
4530 unsigned hunkix = 0;
4531 const char *fmt, *f;
4532 struct option *option;
4533 struct iaddr ip_addr;
4539 struct enumeration_value *e;
4541 option = parse_option_name (cfile, 0, &known);
4545 /* Parse the option data... */
4547 /* Set a flag if this is an array of a simple type (i.e.,
4548 not an array of pairs of IP addresses, or something
4550 int uniform = option -> format [1] == 'A';
4552 for (fmt = option -> format; *fmt; fmt++) {
4557 fmt = strchr (fmt, '.');
4560 "malformed %s (bug!)",
4561 "encapsulation format");
4562 skip_to_semi (cfile);
4566 len = parse_X (cfile, &hunkbuf [hunkix],
4567 sizeof hunkbuf - hunkix);
4571 case 't': /* Text string... */
4572 token = next_token (&val,
4574 if (token != STRING) {
4576 "expecting string.");
4577 skip_to_semi (cfile);
4580 if (hunkix + len + 1 > sizeof hunkbuf) {
4582 "option data buffer %s",
4584 skip_to_semi (cfile);
4587 memcpy (&hunkbuf [hunkix], val, len + 1);
4594 fmt = strchr (fmt, '.');
4597 "malformed %s (bug!)",
4598 "enumeration format");
4600 skip_to_semi (cfile);
4603 token = next_token (&val,
4604 (unsigned *)0, cfile);
4605 if (!is_identifier (token)) {
4607 "identifier expected");
4610 e = find_enumeration_value (f, fmt - f, val);
4620 case 'I': /* IP address. */
4621 if (!parse_ip_addr (cfile, &ip_addr))
4627 if (hunkix + len > sizeof hunkbuf) {
4629 "option data buffer %s",
4631 skip_to_semi (cfile);
4634 memcpy (&hunkbuf [hunkix], dp, len);
4638 case 'L': /* Unsigned 32-bit integer... */
4639 case 'l': /* Signed 32-bit integer... */
4640 token = next_token (&val,
4641 (unsigned *)0, cfile);
4642 if (token != NUMBER) {
4645 "expecting number.");
4647 skip_to_semi (cfile);
4650 convert_num (cfile, buf, val, 0, 32);
4655 case 's': /* Signed 16-bit integer. */
4656 case 'S': /* Unsigned 16-bit integer. */
4657 token = next_token (&val,
4658 (unsigned *)0, cfile);
4659 if (token != NUMBER)
4661 convert_num (cfile, buf, val, 0, 16);
4666 case 'b': /* Signed 8-bit integer. */
4667 case 'B': /* Unsigned 8-bit integer. */
4668 token = next_token (&val,
4669 (unsigned *)0, cfile);
4670 if (token != NUMBER)
4672 convert_num (cfile, buf, val, 0, 8);
4677 case 'f': /* Boolean flag. */
4678 token = next_token (&val,
4679 (unsigned *)0, cfile);
4680 if (!is_identifier (token)) {
4682 "expecting identifier.");
4685 skip_to_semi (cfile);
4688 if (!strcasecmp (val, "true")
4689 || !strcasecmp (val, "on"))
4691 else if (!strcasecmp (val, "false")
4692 || !strcasecmp (val, "off"))
4696 "expecting boolean.");
4704 log_error ("parse_option_param: Bad format %c",
4706 skip_to_semi (cfile);
4710 token = next_token (&val, (unsigned *)0, cfile);
4711 } while (*fmt == 'A' && token == COMMA);
4713 if (token != SEMI) {
4714 parse_warn (cfile, "semicolon expected.");
4715 skip_to_semi (cfile);
4719 bp = (struct buffer *)0;
4720 if (!buffer_allocate (&bp, hunkix + nul_term, MDL))
4721 log_fatal ("no memory to store option declaration.");
4723 log_fatal ("out of memory allocating option data.");
4724 memcpy (bp -> data, hunkbuf, hunkix + nul_term);
4726 if (!option_cache_allocate (oc, MDL))
4727 log_fatal ("out of memory allocating option cache.");
4729 (*oc) -> data.buffer = bp;
4730 (*oc) -> data.data = &bp -> data [0];
4731 (*oc) -> data.terminated = nul_term;
4732 (*oc) -> data.len = hunkix;
4733 (*oc) -> option = option;
4737 /* Consider merging parse_cshl into this. */
4739 int parse_X (cfile, buf, max)
4740 struct parse *cfile;
4749 token = peek_token (&val, (unsigned *)0, cfile);
4750 if (token == NUMBER_OR_NAME || token == NUMBER) {
4753 token = next_token (&val, (unsigned *)0, cfile);
4754 if (token != NUMBER && token != NUMBER_OR_NAME) {
4756 "expecting hexadecimal constant.");
4757 skip_to_semi (cfile);
4760 convert_num (cfile, &buf [len], val, 16, 8);
4763 "hexadecimal constant too long.");
4764 skip_to_semi (cfile);
4767 token = peek_token (&val, (unsigned *)0, cfile);
4769 token = next_token (&val,
4770 (unsigned *)0, cfile);
4771 } while (token == COLON);
4773 } else if (token == STRING) {
4774 token = next_token (&val, &len, cfile);
4775 if (len + 1 > max) {
4776 parse_warn (cfile, "string constant too long.");
4777 skip_to_semi (cfile);
4780 memcpy (buf, val, len + 1);
4782 parse_warn (cfile, "expecting string or hexadecimal data");
4783 skip_to_semi (cfile);
4789 int parse_warn (struct parse *cfile, const char *fmt, ...)
4797 do_percentm (mbuf, fmt);
4799 snprintf (fbuf, sizeof fbuf, "%s line %d: %s",
4800 cfile -> tlname, cfile -> lexline, mbuf);
4802 sprintf (fbuf, "%s line %d: %s",
4803 cfile -> tlname, cfile -> lexline, mbuf);
4806 va_start (list, fmt);
4807 vsnprintf (mbuf, sizeof mbuf, fbuf, list);
4812 cfile -> token_line [i] && i < (cfile -> lexchar - 1); i++) {
4813 if (lix < (sizeof lexbuf) - 1)
4814 lexbuf [lix++] = ' ';
4815 if (cfile -> token_line [i] == '\t') {
4817 lix < (sizeof lexbuf) - 1 && (lix & 7); lix++)
4824 syslog (log_priority | LOG_ERR, "%s", mbuf);
4825 syslog (log_priority | LOG_ERR, "%s", cfile -> token_line);
4826 if (cfile -> lexchar < 81)
4827 syslog (log_priority | LOG_ERR, "%s^", lexbuf);
4831 write (2, mbuf, strlen (mbuf));
4833 write (2, cfile -> token_line, strlen (cfile -> token_line));
4835 if (cfile -> lexchar < 81)
4836 write (2, lexbuf, lix);
4837 write (2, "^\n", 2);
4840 cfile -> warnings_occurred = 1;