1 /* clparse.c
2 
3    Parser for dhclient config and lease files... */
4 
5 /*
6  * Copyright (c) 2004-2019 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1996-2003 by Internet Software Consortium
8  *
9  * This Source Code Form is subject to the terms of the Mozilla Public
10  * License, v. 2.0. If a copy of the MPL was not distributed with this
11  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  *   Internet Systems Consortium, Inc.
22  *   950 Charter Street
23  *   Redwood City, CA 94063
24  *   <info@isc.org>
25  *   https://www.isc.org/
26  *
27  */
28 
29 #include "dhcpd.h"
30 #include <errno.h>
31 
32 struct client_config top_level_config;
33 
34 #define NUM_DEFAULT_REQUESTED_OPTS	9
35 /* There can be 2 extra requested options for DHCPv4-over-DHCPv6. */
36 struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 2 + 1];
37 
38 static void parse_client_default_duid(struct parse *cfile);
39 static void parse_client6_lease_statement(struct parse *cfile);
40 #ifdef DHCPv6
41 static struct dhc6_ia *parse_client6_ia_na_statement(struct parse *cfile);
42 static struct dhc6_ia *parse_client6_ia_ta_statement(struct parse *cfile);
43 static struct dhc6_ia *parse_client6_ia_pd_statement(struct parse *cfile);
44 static struct dhc6_addr *parse_client6_iaaddr_statement(struct parse *cfile);
45 static struct dhc6_addr *parse_client6_iaprefix_statement(struct parse *cfile);
46 #endif /* DHCPv6 */
47 
48 static void parse_lease_id_format (struct parse *cfile);
49 
50 extern void discard_duplicate (struct client_lease** lease_list,
51                                struct client_lease* lease);
52 
53 /* client-conf-file :== client-declarations END_OF_FILE
54    client-declarations :== <nil>
55 			 | client-declaration
56 			 | client-declarations client-declaration */
57 
read_client_conf()58 isc_result_t read_client_conf ()
59 {
60 	struct client_config *config;
61 	struct interface_info *ip;
62 	isc_result_t status;
63 	unsigned code;
64 
65         /*
66          * TODO: LATER constant is very undescriptive. We should review it and
67          * change it to something more descriptive or even better remove it
68          * completely as it is currently not used.
69          */
70 #ifdef LATER
71         struct parse *parse = NULL;
72 #endif
73 
74 	/* Initialize the default request list. */
75 	memset(default_requested_options, 0, sizeof(default_requested_options));
76 
77 	/* 1 */
78 	code = DHO_SUBNET_MASK;
79 	option_code_hash_lookup(&default_requested_options[0],
80 				dhcp_universe.code_hash, &code, 0, MDL);
81 
82 	/* 2 */
83 	code = DHO_BROADCAST_ADDRESS;
84 	option_code_hash_lookup(&default_requested_options[1],
85 				dhcp_universe.code_hash, &code, 0, MDL);
86 
87 	/* 3 */
88 	code = DHO_TIME_OFFSET;
89 	option_code_hash_lookup(&default_requested_options[2],
90 				dhcp_universe.code_hash, &code, 0, MDL);
91 
92 	/* 4 */
93 	code = DHO_ROUTERS;
94 	option_code_hash_lookup(&default_requested_options[3],
95 				dhcp_universe.code_hash, &code, 0, MDL);
96 
97 	/* 5 */
98 	code = DHO_DOMAIN_NAME;
99 	option_code_hash_lookup(&default_requested_options[4],
100 				dhcp_universe.code_hash, &code, 0, MDL);
101 
102 	/* 6 */
103 	code = DHO_DOMAIN_NAME_SERVERS;
104 	option_code_hash_lookup(&default_requested_options[5],
105 				dhcp_universe.code_hash, &code, 0, MDL);
106 
107 	/* 7 */
108 	code = DHO_HOST_NAME;
109 	option_code_hash_lookup(&default_requested_options[6],
110 				dhcp_universe.code_hash, &code, 0, MDL);
111 
112 	/* 8 */
113 	code = D6O_NAME_SERVERS;
114 	option_code_hash_lookup(&default_requested_options[7],
115 				dhcpv6_universe.code_hash, &code, 0, MDL);
116 
117 	/* 9 */
118 	code = D6O_DOMAIN_SEARCH;
119 	option_code_hash_lookup(&default_requested_options[8],
120 				dhcpv6_universe.code_hash, &code, 0, MDL);
121 
122 	for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) {
123 		if (default_requested_options[code] == NULL)
124 			log_fatal("Unable to find option definition for "
125 				  "index %u during default parameter request "
126 				  "assembly.", code);
127 	}
128 
129 #ifdef DHCP4o6
130 	/* DHCPv4-over-DHCPv6 extra requested options in code order */
131 	if (dhcpv4_over_dhcpv6 == 1) {
132 		/* The DHCP4o6 server option should be requested */
133 		code = D6O_DHCP4_O_DHCP6_SERVER;
134 		option_code_hash_lookup(&default_requested_options[9],
135 					dhcpv6_universe.code_hash,
136 					&code, 0, MDL);
137 		if (default_requested_options[9] == NULL) {
138 			log_fatal("Unable to find option definition for "
139 				  "index %u during default parameter request "
140 				  "assembly.", code);
141 		}
142 	} else if (dhcpv4_over_dhcpv6 > 1) {
143 		/* Called from run_stateless so the IRT should
144 		   be requested too */
145 		code = D6O_INFORMATION_REFRESH_TIME;
146 		option_code_hash_lookup(&default_requested_options[9],
147 					dhcpv6_universe.code_hash,
148 					&code, 0, MDL);
149 		if (default_requested_options[9] == NULL) {
150 			log_fatal("Unable to find option definition for "
151 				  "index %u during default parameter request "
152 				  "assembly.", code);
153 		}
154 		code = D6O_DHCP4_O_DHCP6_SERVER;
155 		option_code_hash_lookup(&default_requested_options[10],
156 					dhcpv6_universe.code_hash,
157 					&code, 0, MDL);
158 		if (default_requested_options[10] == NULL) {
159 			log_fatal("Unable to find option definition for "
160 				  "index %u during default parameter request "
161 				  "assembly.", code);
162 		}
163 	}
164 #endif
165 
166 	/* Initialize the top level client configuration. */
167 	memset (&top_level_config, 0, sizeof top_level_config);
168 
169 	/* Set some defaults... */
170 	top_level_config.timeout = 60;
171 	top_level_config.select_interval = 0;
172 	top_level_config.reboot_timeout = 10;
173 	top_level_config.retry_interval = 300;
174 	top_level_config.backoff_cutoff = 15;
175 	top_level_config.initial_interval = 3;
176 	top_level_config.lease_id_format = TOKEN_OCTAL;
177 
178 	/*
179 	 * RFC 2131, section 4.4.1 specifies that the client SHOULD wait a
180 	 * random time between 1 and 10 seconds. However, we choose to not
181 	 * implement this default. If user is inclined to really have that
182 	 * delay, he is welcome to do so, using 'initial-delay X;' parameter
183 	 * in config file.
184 	 */
185 	top_level_config.initial_delay = 0;
186 
187 	top_level_config.bootp_policy = P_ACCEPT;
188 	top_level_config.script_name = path_dhclient_script;
189 	top_level_config.requested_options = default_requested_options;
190 	top_level_config.omapi_port = -1;
191 	top_level_config.do_forward_update = 1;
192 	/* Requested lease time, used by DHCPv6 (DHCPv4 uses the option cache)
193 	 */
194 	top_level_config.requested_lease = 7200;
195 
196 	group_allocate (&top_level_config.on_receipt, MDL);
197 	if (!top_level_config.on_receipt)
198 		log_fatal ("no memory for top-level on_receipt group");
199 
200 	group_allocate (&top_level_config.on_transmission, MDL);
201 	if (!top_level_config.on_transmission)
202 		log_fatal ("no memory for top-level on_transmission group");
203 
204 	status = read_client_conf_file (path_dhclient_conf,
205 					(struct interface_info *)0,
206 					&top_level_config);
207 
208 	if (status != ISC_R_SUCCESS) {
209 		;
210 #ifdef LATER
211 		/* Set up the standard name service updater routine. */
212 		status = new_parse(&parse, -1, default_client_config,
213 				   sizeof(default_client_config) - 1,
214 				   "default client configuration", 0);
215 		if (status != ISC_R_SUCCESS)
216 			log_fatal ("can't begin default client config!");
217 	}
218 
219 	if (parse != NULL) {
220 		do {
221 			token = peek_token(&val, NULL, cfile);
222 			if (token == END_OF_FILE)
223 				break;
224 			parse_client_statement(cfile, NULL, &top_level_config);
225 		} while (1);
226 		end_parse(&parse);
227 #endif
228 	}
229 
230 	/* Set up state and config structures for clients that don't
231 	   have per-interface configuration statements. */
232 	config = (struct client_config *)0;
233 	for (ip = interfaces; ip; ip = ip -> next) {
234 		if (!ip -> client) {
235 			ip -> client = (struct client_state *)
236 				dmalloc (sizeof (struct client_state), MDL);
237 			if (!ip -> client)
238 				log_fatal ("no memory for client state.");
239 			memset (ip -> client, 0, sizeof *(ip -> client));
240 			ip -> client -> interface = ip;
241 		}
242 
243 		if (!ip -> client -> config) {
244 			if (!config) {
245 				config = (struct client_config *)
246 					dmalloc (sizeof (struct client_config),
247 						 MDL);
248 				if (!config)
249 				    log_fatal ("no memory for client config.");
250 				memcpy (config, &top_level_config,
251 					sizeof top_level_config);
252 			}
253 			ip -> client -> config = config;
254 		}
255 	}
256 	return status;
257 }
258 
read_client_conf_file(const char * name,struct interface_info * ip,struct client_config * client)259 int read_client_conf_file (const char *name, struct interface_info *ip,
260 			   struct client_config *client)
261 {
262 	int file;
263 	struct parse *cfile;
264 	const char *val;
265 	int token;
266 	isc_result_t status;
267 
268 	if ((file = open (name, O_RDONLY)) < 0)
269 		return uerr2isc (errno);
270 
271 	cfile = NULL;
272 	status = new_parse(&cfile, file, NULL, 0, path_dhclient_conf, 0);
273 	if (status != ISC_R_SUCCESS || cfile == NULL)
274 		return status;
275 
276 	do {
277 		token = peek_token (&val, (unsigned *)0, cfile);
278 		if (token == END_OF_FILE)
279 			break;
280 		parse_client_statement (cfile, ip, client);
281 	} while (1);
282 	skip_token(&val, (unsigned *)0, cfile);
283 	status = (cfile -> warnings_occurred
284 		  ? DHCP_R_BADPARSE
285 		  : ISC_R_SUCCESS);
286 	end_parse (&cfile);
287 	return status;
288 }
289 
290 
291 /* lease-file :== client-lease-statements END_OF_FILE
292    client-lease-statements :== <nil>
293 		     | client-lease-statements LEASE client-lease-statement
294  * This routine looks through a lease file and only tries to parse
295  * the duid statements.
296  */
297 
read_client_duid()298 void read_client_duid ()
299 {
300 	int file;
301 	isc_result_t status;
302 	struct parse *cfile;
303 	const char *val;
304 	int token;
305 
306 	/* Open the lease file.   If we can't open it, just return -
307 	   we can safely trust the server to remember our state. */
308 	if ((file = open (path_dhclient_duid, O_RDONLY)) < 0)
309 		return;
310 
311 	cfile = NULL;
312 	status = new_parse(&cfile, file, NULL, 0, path_dhclient_duid, 0);
313 	if (status != ISC_R_SUCCESS || cfile == NULL)
314 		return;
315 
316 	while ((token = next_token(&val, NULL, cfile)) != END_OF_FILE) {
317 		/*
318 		 * All we care about is DUIDs - if we get anything else
319 		 * just toss it and continue looking for DUIDs until we
320 		 * run out of file.
321 		 */
322 		if (token == DEFAULT_DUID) {
323 			parse_client_default_duid(cfile);
324 		}
325 	}
326 
327 	end_parse(&cfile);
328 }
329 
330 /* lease-file :== client-lease-statements END_OF_FILE
331    client-lease-statements :== <nil>
332 		     | client-lease-statements LEASE client-lease-statement */
333 
read_client_leases()334 void read_client_leases ()
335 {
336 	int file;
337 	isc_result_t status;
338 	struct parse *cfile;
339 	const char *val;
340 	int token;
341 
342 	/* Open the lease file.   If we can't open it, just return -
343 	   we can safely trust the server to remember our state. */
344 	if ((file = open (path_dhclient_db, O_RDONLY)) < 0)
345 		return;
346 
347 	cfile = NULL;
348 	status = new_parse(&cfile, file, NULL, 0, path_dhclient_db, 0);
349 	if (status != ISC_R_SUCCESS || cfile == NULL)
350 		return;
351 
352 	do {
353 		token = next_token (&val, (unsigned *)0, cfile);
354 		if (token == END_OF_FILE)
355 			break;
356 
357 		switch (token) {
358 		      case DEFAULT_DUID:
359 			parse_client_default_duid(cfile);
360 			break;
361 
362 		      case LEASE:
363 			parse_client_lease_statement(cfile, 0);
364 			break;
365 
366 		      case LEASE6:
367 			parse_client6_lease_statement(cfile);
368 			break;
369 
370 		      default:
371 			log_error ("Corrupt lease file - possible data loss!");
372 			skip_to_semi (cfile);
373 			break;
374 		}
375 	} while (1);
376 
377 	end_parse (&cfile);
378 }
379 
380 /* client-declaration :==
381 	SEND option-decl |
382 	DEFAULT option-decl |
383 	SUPERSEDE option-decl |
384 	PREPEND option-decl |
385 	APPEND option-decl |
386 	hardware-declaration |
387 	ALSO REQUEST option-list |
388 	ALSO REQUIRE option-list |
389 	REQUEST option-list |
390 	REQUIRE option-list |
391 	TIMEOUT number |
392 	RETRY number |
393 	REBOOT number |
394 	SELECT_TIMEOUT number |
395 	SCRIPT string |
396 	VENDOR_SPACE string |
397 	interface-declaration |
398 	LEASE client-lease-statement |
399 	ALIAS client-lease-statement |
400 	KEY key-definition */
401 
parse_client_statement(cfile,ip,config)402 void parse_client_statement (cfile, ip, config)
403 	struct parse *cfile;
404 	struct interface_info *ip;
405 	struct client_config *config;
406 {
407 	int token;
408 	const char *val;
409 	struct option *option = NULL;
410 	struct executable_statement *stmt;
411 	int lose;
412 	char *name;
413 	enum policy policy;
414 	int known;
415 	int tmp, i;
416 	isc_result_t status;
417 	struct option ***append_list, **new_list, **cat_list;
418 
419 	switch (peek_token (&val, (unsigned *)0, cfile)) {
420 	      case INCLUDE:
421 		skip_token(&val, (unsigned *)0, cfile);
422 		token = next_token (&val, (unsigned *)0, cfile);
423 		if (token != STRING) {
424 			parse_warn (cfile, "filename string expected.");
425 			skip_to_semi (cfile);
426 		} else {
427 			status = read_client_conf_file (val, ip, config);
428 			if (status != ISC_R_SUCCESS)
429 				parse_warn (cfile, "%s: bad parse.", val);
430 			parse_semi (cfile);
431 		}
432 		return;
433 
434 	      case KEY:
435 		skip_token(&val, (unsigned *)0, cfile);
436 		if (ip) {
437 			/* This may seem arbitrary, but there's a reason for
438 			   doing it: the authentication key database is not
439 			   scoped.  If we allow the user to declare a key other
440 			   than in the outer scope, the user is very likely to
441 			   believe that the key will only be used in that
442 			   scope.  If the user only wants the key to be used on
443 			   one interface, because it's known that the other
444 			   interface may be connected to an insecure net and
445 			   the secret key is considered sensitive, we don't
446 			   want to lull them into believing they've gotten
447 			   their way.   This is a bit contrived, but people
448 			   tend not to be entirely rational about security. */
449 			parse_warn (cfile, "key definition not allowed here.");
450 			skip_to_semi (cfile);
451 			break;
452 		}
453 		parse_key (cfile);
454 		return;
455 
456 	      case TOKEN_ALSO:
457 		/* consume ALSO */
458 		skip_token(&val, NULL, cfile);
459 
460 		/* consume type of ALSO list. */
461 		token = next_token(&val, NULL, cfile);
462 
463 		if (token == REQUEST) {
464 			append_list = &config->requested_options;
465 		} else if (token == REQUIRE) {
466 			append_list = &config->required_options;
467 		} else {
468 			parse_warn(cfile, "expected REQUEST or REQUIRE list");
469 			skip_to_semi(cfile);
470 			return;
471 		}
472 
473 		/* If there is no list, cut the concat short. */
474 		if (*append_list == NULL) {
475 			parse_option_list(cfile, append_list);
476 			return;
477 		}
478 
479 		/* Count the length of the existing list. */
480 		for (i = 0 ; (*append_list)[i] != NULL ; i++)
481 			; /* This space intentionally left blank. */
482 
483 		/* If there's no codes on the list, cut the concat short. */
484 		if (i == 0) {
485 			parse_option_list(cfile, append_list);
486 			return;
487 		}
488 
489 		tmp = parse_option_list(cfile, &new_list);
490 
491 		if (tmp == 0 || new_list == NULL)
492 			return;
493 
494 		/* Allocate 'i + tmp' buckets plus a terminator. */
495 		cat_list = dmalloc(sizeof(struct option *) * (i + tmp + 1),
496 				   MDL);
497 
498 		if (cat_list == NULL) {
499 			log_error("Unable to allocate memory for new "
500 				  "request list.");
501 			skip_to_semi(cfile);
502 			return;
503 		}
504 
505 		for (i = 0 ; (*append_list)[i] != NULL ; i++)
506 			option_reference(&cat_list[i], (*append_list)[i], MDL);
507 
508 		tmp = i;
509 
510 		for (i = 0 ; new_list[i] != 0 ; i++)
511 			option_reference(&cat_list[tmp++], new_list[i], MDL);
512 
513 		cat_list[tmp] = 0;
514 
515 		/* XXX: We cannot free the old list, because it may have been
516 		 * XXX: assigned from an outer configuration scope (or may be
517 		 * XXX: the static default setting).
518 		 */
519 		*append_list = cat_list;
520 
521 		return;
522 
523 		/* REQUIRE can either start a policy statement or a
524 		   comma-separated list of names of required options. */
525 	      case REQUIRE:
526 		skip_token(&val, (unsigned *)0, cfile);
527 		token = peek_token (&val, (unsigned *)0, cfile);
528 		if (token == AUTHENTICATION) {
529 			policy = P_REQUIRE;
530 			goto do_policy;
531 		}
532 		parse_option_list (cfile, &config -> required_options);
533 		return;
534 
535 	      case IGNORE:
536 		skip_token(&val, (unsigned *)0, cfile);
537 		policy = P_IGNORE;
538 		goto do_policy;
539 
540 	      case ACCEPT:
541 		skip_token(&val, (unsigned *)0, cfile);
542 		policy = P_ACCEPT;
543 		goto do_policy;
544 
545 	      case PREFER:
546 		skip_token(&val, (unsigned *)0, cfile);
547 		policy = P_PREFER;
548 		goto do_policy;
549 
550 	      case DONT:
551 		skip_token(&val, (unsigned *)0, cfile);
552 		policy = P_DONT;
553 		goto do_policy;
554 
555 	      do_policy:
556 		token = next_token (&val, (unsigned *)0, cfile);
557 		if (token == AUTHENTICATION) {
558 			if (policy != P_PREFER &&
559 			    policy != P_REQUIRE &&
560 			    policy != P_DONT) {
561 				parse_warn (cfile,
562 					    "invalid authentication policy.");
563 				skip_to_semi (cfile);
564 				return;
565 			}
566 			config -> auth_policy = policy;
567 		} else if (token != TOKEN_BOOTP) {
568 			if (policy != P_PREFER &&
569 			    policy != P_IGNORE &&
570 			    policy != P_ACCEPT) {
571 				parse_warn (cfile, "invalid bootp policy.");
572 				skip_to_semi (cfile);
573 				return;
574 			}
575 			config -> bootp_policy = policy;
576 		} else {
577 			parse_warn (cfile, "expecting a policy type.");
578 			skip_to_semi (cfile);
579 			return;
580 		}
581 		break;
582 
583 	      case OPTION:
584 		skip_token(&val, (unsigned *)0, cfile);
585 		token = peek_token (&val, (unsigned *)0, cfile);
586 		if (token == SPACE) {
587 			if (ip) {
588 				parse_warn (cfile,
589 					    "option space definitions %s",
590 					    " may not be scoped.");
591 				skip_to_semi (cfile);
592 				break;
593 			}
594 			parse_option_space_decl (cfile);
595 			return;
596 		}
597 
598 		known = 0;
599 		status = parse_option_name(cfile, 1, &known, &option);
600 		if (status != ISC_R_SUCCESS || option == NULL)
601 			return;
602 
603 		token = next_token (&val, (unsigned *)0, cfile);
604 		if (token != CODE) {
605 			parse_warn (cfile, "expecting \"code\" keyword.");
606 			skip_to_semi (cfile);
607 			option_dereference(&option, MDL);
608 			return;
609 		}
610 		if (ip) {
611 			parse_warn (cfile,
612 				    "option definitions may only appear in %s",
613 				    "the outermost scope.");
614 			skip_to_semi (cfile);
615 			option_dereference(&option, MDL);
616 			return;
617 		}
618 
619 		/*
620 		 * If the option was known, remove it from the code and name
621 		 * hash tables before redefining it.
622 		 */
623 		if (known) {
624 			option_name_hash_delete(option->universe->name_hash,
625 						option->name, 0, MDL);
626 			option_code_hash_delete(option->universe->code_hash,
627 						&option->code, 0, MDL);
628 		}
629 
630 		parse_option_code_definition(cfile, option);
631 		option_dereference(&option, MDL);
632 		return;
633 
634 	      case MEDIA:
635 		skip_token(&val, (unsigned *)0, cfile);
636 		parse_string_list (cfile, &config -> media, 1);
637 		return;
638 
639 	      case HARDWARE:
640 		skip_token(&val, (unsigned *)0, cfile);
641 		if (ip) {
642 			parse_hardware_param (cfile, &ip -> hw_address);
643 		} else {
644 			parse_warn (cfile, "hardware address parameter %s",
645 				    "not allowed here.");
646 			skip_to_semi (cfile);
647 		}
648 		return;
649 
650 	      case ANYCAST_MAC:
651 		skip_token(&val, NULL, cfile);
652 		if (ip != NULL) {
653 			parse_hardware_param(cfile, &ip->anycast_mac_addr);
654 		} else {
655 			parse_warn(cfile, "anycast mac address parameter "
656 				   "not allowed here.");
657 			skip_to_semi (cfile);
658 		}
659 		return;
660 
661 	      case REQUEST:
662 		skip_token(&val, (unsigned *)0, cfile);
663 		if (config -> requested_options == default_requested_options)
664 			config -> requested_options = NULL;
665 		parse_option_list (cfile, &config -> requested_options);
666 		return;
667 
668 	      case TIMEOUT:
669 		skip_token(&val, (unsigned *)0, cfile);
670 		parse_lease_time (cfile, &config -> timeout);
671 		return;
672 
673 	      case RETRY:
674 		skip_token(&val, (unsigned *)0, cfile);
675 		parse_lease_time (cfile, &config -> retry_interval);
676 		return;
677 
678 	      case SELECT_TIMEOUT:
679 		skip_token(&val, (unsigned *)0, cfile);
680 		parse_lease_time (cfile, &config -> select_interval);
681 		return;
682 
683 	      case OMAPI:
684 		skip_token(&val, (unsigned *)0, cfile);
685 		token = next_token (&val, (unsigned *)0, cfile);
686 		if (token != PORT) {
687 			parse_warn (cfile,
688 				    "unexpected omapi subtype: %s", val);
689 			skip_to_semi (cfile);
690 			return;
691 		}
692 		token = next_token (&val, (unsigned *)0, cfile);
693 		if (token != NUMBER) {
694 			parse_warn (cfile, "invalid port number: `%s'", val);
695 			skip_to_semi (cfile);
696 			return;
697 		}
698 		tmp = atoi (val);
699 		if (tmp < 0 || tmp > 65535)
700 			parse_warn (cfile, "invalid omapi port %d.", tmp);
701 		else if (config != &top_level_config)
702 			parse_warn (cfile,
703 				    "omapi port only works at top level.");
704 		else
705 			config -> omapi_port = tmp;
706 		parse_semi (cfile);
707 		return;
708 
709 	      case DO_FORWARD_UPDATE:
710 		skip_token(&val, (unsigned *)0, cfile);
711 		token = next_token (&val, (unsigned *)0, cfile);
712 		if (!strcasecmp (val, "on") ||
713 		    !strcasecmp (val, "true"))
714 			config -> do_forward_update = 1;
715 		else if (!strcasecmp (val, "off") ||
716 			 !strcasecmp (val, "false"))
717 			config -> do_forward_update = 0;
718 		else {
719 			parse_warn (cfile, "expecting boolean value.");
720 			skip_to_semi (cfile);
721 			return;
722 		}
723 		parse_semi (cfile);
724 		return;
725 
726 	      case REBOOT:
727 		skip_token(&val, (unsigned *)0, cfile);
728 		parse_lease_time (cfile, &config -> reboot_timeout);
729 		return;
730 
731 	      case BACKOFF_CUTOFF:
732 		skip_token(&val, (unsigned *)0, cfile);
733 		parse_lease_time (cfile, &config -> backoff_cutoff);
734 		return;
735 
736 	      case INITIAL_INTERVAL:
737 		skip_token(&val, (unsigned *)0, cfile);
738 		parse_lease_time (cfile, &config -> initial_interval);
739 		return;
740 
741 	      case INITIAL_DELAY:
742 		skip_token(&val, (unsigned *)0, cfile);
743 		parse_lease_time (cfile, &config -> initial_delay);
744 		return;
745 
746 	      case SCRIPT:
747 		skip_token(&val, (unsigned *)0, cfile);
748 		parse_string (cfile, &config -> script_name, (unsigned *)0);
749 		return;
750 
751 	      case VENDOR:
752 		skip_token(&val, (unsigned *)0, cfile);
753 		token = next_token (&val, (unsigned *)0, cfile);
754 		if (token != OPTION) {
755 			parse_warn (cfile, "expecting 'vendor option space'");
756 			skip_to_semi (cfile);
757 			return;
758 		}
759 		token = next_token (&val, (unsigned *)0, cfile);
760 		if (token != SPACE) {
761 			parse_warn (cfile, "expecting 'vendor option space'");
762 			skip_to_semi (cfile);
763 			return;
764 		}
765 		token = next_token (&val, (unsigned *)0, cfile);
766 		if (!is_identifier (token)) {
767 			parse_warn (cfile, "expecting an identifier.");
768 			skip_to_semi (cfile);
769 			return;
770 		}
771 		config -> vendor_space_name = dmalloc (strlen (val) + 1, MDL);
772 		if (!config -> vendor_space_name)
773 			log_fatal ("no memory for vendor option space name.");
774 		strcpy (config -> vendor_space_name, val);
775 		for (i = 0; i < universe_count; i++)
776 			if (!strcmp (universes [i] -> name,
777 				     config -> vendor_space_name))
778 				break;
779 		if (i == universe_count) {
780 			log_error ("vendor option space %s not found.",
781 				   config -> vendor_space_name);
782 		}
783 		parse_semi (cfile);
784 		return;
785 
786 	      case INTERFACE:
787 		skip_token(&val, (unsigned *)0, cfile);
788 		if (ip)
789 			parse_warn (cfile, "nested interface declaration.");
790 		parse_interface_declaration (cfile, config, (char *)0);
791 		return;
792 
793 	      case PSEUDO:
794 		skip_token(&val, (unsigned *)0, cfile);
795 		token = next_token (&val, (unsigned *)0, cfile);
796 		name = dmalloc (strlen (val) + 1, MDL);
797 		if (!name)
798 			log_fatal ("no memory for pseudo interface name");
799 		strcpy (name, val);
800 		parse_interface_declaration (cfile, config, name);
801 		return;
802 
803 	      case LEASE:
804 		skip_token(&val, (unsigned *)0, cfile);
805 		parse_client_lease_statement (cfile, 1);
806 		return;
807 
808 	      case ALIAS:
809 		skip_token(&val, (unsigned *)0, cfile);
810 		parse_client_lease_statement (cfile, 2);
811 		return;
812 
813 	      case REJECT:
814 		skip_token(&val, (unsigned *)0, cfile);
815 		parse_reject_statement (cfile, config);
816 		return;
817 
818 	      case LEASE_ID_FORMAT:
819 		skip_token(&val, (unsigned *)0, cfile);
820 		parse_lease_id_format(cfile);
821 		break;
822 
823 
824 	      default:
825 		lose = 0;
826 		stmt = (struct executable_statement *)0;
827 		if (!parse_executable_statement (&stmt,
828 						 cfile, &lose, context_any)) {
829 			if (!lose) {
830 				parse_warn (cfile, "expecting a statement.");
831 				skip_to_semi (cfile);
832 			}
833 		} else {
834 			struct executable_statement **eptr, *sptr;
835 			if (stmt &&
836 			    (stmt -> op == send_option_statement ||
837 			     (stmt -> op == on_statement &&
838 			      (stmt -> data.on.evtypes & ON_TRANSMISSION)))) {
839 			    eptr = &config -> on_transmission -> statements;
840 			    if (stmt -> op == on_statement) {
841 				    sptr = (struct executable_statement *)0;
842 				    executable_statement_reference
843 					    (&sptr,
844 					     stmt -> data.on.statements, MDL);
845 				    executable_statement_dereference (&stmt,
846 								      MDL);
847 				    executable_statement_reference (&stmt,
848 								    sptr,
849 								    MDL);
850 				    executable_statement_dereference (&sptr,
851 								      MDL);
852 			    }
853 			} else
854 			    eptr = &config -> on_receipt -> statements;
855 
856 			if (stmt) {
857 				for (; *eptr; eptr = &(*eptr) -> next)
858 					;
859 				executable_statement_reference (eptr,
860 								stmt, MDL);
861 			}
862 			return;
863 		}
864 		break;
865 	}
866 	parse_semi (cfile);
867 }
868 
869 /* option-list :== option_name |
870    		   option_list COMMA option_name */
871 
872 int
parse_option_list(struct parse * cfile,struct option *** list)873 parse_option_list(struct parse *cfile, struct option ***list)
874 {
875 	int ix;
876 	int token;
877 	const char *val;
878 	pair p = (pair)0, q = (pair)0, r;
879 	struct option *option = NULL;
880 	isc_result_t status;
881 
882 	ix = 0;
883 	do {
884 		token = peek_token (&val, (unsigned *)0, cfile);
885 		if (token == SEMI) {
886 			token = next_token (&val, (unsigned *)0, cfile);
887 			break;
888 		}
889 		if (!is_identifier (token)) {
890 			parse_warn (cfile, "%s: expected option name.", val);
891 			skip_token(&val, (unsigned *)0, cfile);
892 			skip_to_semi (cfile);
893 			return 0;
894 		}
895 		status = parse_option_name(cfile, 0, NULL, &option);
896 		if (status != ISC_R_SUCCESS || option == NULL) {
897 			parse_warn (cfile, "%s: expected option name.", val);
898 			return 0;
899 		}
900 		r = new_pair (MDL);
901 		if (!r)
902 			log_fatal ("can't allocate pair for option code.");
903 		/* XXX: we should probably carry a reference across this */
904 		r->car = (caddr_t)option;
905 		option_dereference(&option, MDL);
906 		r -> cdr = (pair)0;
907 		if (p)
908 			q -> cdr = r;
909 		else
910 			p = r;
911 		q = r;
912 		++ix;
913 		token = next_token (&val, (unsigned *)0, cfile);
914 	} while (token == COMMA);
915 	if (token != SEMI) {
916 		parse_warn (cfile, "expecting semicolon.");
917 		skip_to_semi (cfile);
918 		return 0;
919 	}
920 	/* XXX we can't free the list here, because we may have copied
921 	   XXX it from an outer config state. */
922 	*list = NULL;
923 	if (ix) {
924 		*list = dmalloc ((ix + 1) * sizeof(struct option *), MDL);
925 		if (!*list)
926 			log_error ("no memory for option list.");
927 		else {
928 			ix = 0;
929 			for (q = p; q; q = q -> cdr)
930 				option_reference(&(*list)[ix++],
931 						 (struct option *)q->car, MDL);
932 			(*list)[ix] = NULL;
933 		}
934 		while (p) {
935 			q = p -> cdr;
936 			free_pair (p, MDL);
937 			p = q;
938 		}
939 	}
940 
941 	return ix;
942 }
943 
944 /* interface-declaration :==
945    	INTERFACE string LBRACE client-declarations RBRACE */
946 
parse_interface_declaration(cfile,outer_config,name)947 void parse_interface_declaration (cfile, outer_config, name)
948 	struct parse *cfile;
949 	struct client_config *outer_config;
950 	char *name;
951 {
952 	int token;
953 	const char *val;
954 	struct client_state *client, **cp;
955 	struct interface_info *ip = (struct interface_info *)0;
956 
957 	token = next_token (&val, (unsigned *)0, cfile);
958 	if (token != STRING) {
959 		parse_warn (cfile, "expecting interface name (in quotes).");
960 		skip_to_semi (cfile);
961 		return;
962 	}
963 
964 	if (!interface_or_dummy (&ip, val))
965 		log_fatal ("Can't allocate interface %s.", val);
966 
967 	/* If we were given a name, this is a pseudo-interface. */
968 	if (name) {
969 		make_client_state (&client);
970 		client -> name = name;
971 		client -> interface = ip;
972 		for (cp = &ip -> client; *cp; cp = &((*cp) -> next))
973 			;
974 		*cp = client;
975 	} else {
976 		if (!ip -> client) {
977 			make_client_state (&ip -> client);
978 			ip -> client -> interface = ip;
979 		}
980 		client = ip -> client;
981 	}
982 
983 	if (!client -> config)
984 		make_client_config (client, outer_config);
985 
986 	ip -> flags &= ~INTERFACE_AUTOMATIC;
987 	interfaces_requested = 1;
988 
989 	token = next_token (&val, (unsigned *)0, cfile);
990 	if (token != LBRACE) {
991 		parse_warn (cfile, "expecting left brace.");
992 		skip_to_semi (cfile);
993 		return;
994 	}
995 
996 	do {
997 		token = peek_token (&val, (unsigned *)0, cfile);
998 		if (token == END_OF_FILE) {
999 			parse_warn (cfile,
1000 				    "unterminated interface declaration.");
1001 			return;
1002 		}
1003 		if (token == RBRACE)
1004 			break;
1005 		parse_client_statement (cfile, ip, client -> config);
1006 	} while (1);
1007 	skip_token(&val, (unsigned *)0, cfile);
1008 }
1009 
interface_or_dummy(struct interface_info ** pi,const char * name)1010 int interface_or_dummy (struct interface_info **pi, const char *name)
1011 {
1012 	struct interface_info *i;
1013 	struct interface_info *ip = (struct interface_info *)0;
1014 	isc_result_t status;
1015 
1016 	/* Find the interface (if any) that matches the name. */
1017 	for (i = interfaces; i; i = i -> next) {
1018 		if (!strcmp (i -> name, name)) {
1019 			interface_reference (&ip, i, MDL);
1020 			break;
1021 		}
1022 	}
1023 
1024 	/* If it's not a real interface, see if it's on the dummy list. */
1025 	if (!ip) {
1026 		for (ip = dummy_interfaces; ip; ip = ip -> next) {
1027 			if (!strcmp (ip -> name, name)) {
1028 				interface_reference (&ip, i, MDL);
1029 				break;
1030 			}
1031 		}
1032 	}
1033 
1034 	/* If we didn't find an interface, make a dummy interface as
1035 	   a placeholder. */
1036 	if (!ip) {
1037 		if ((status = interface_allocate (&ip, MDL)) != ISC_R_SUCCESS)
1038 			log_fatal ("Can't record interface %s: %s",
1039 				   name, isc_result_totext (status));
1040 
1041 		if (strlen(name) >= sizeof(ip->name)) {
1042 			interface_dereference(&ip, MDL);
1043 			return 0;
1044 		}
1045 		strcpy(ip->name, name);
1046 
1047 		if (dummy_interfaces) {
1048 			interface_reference (&ip -> next,
1049 					     dummy_interfaces, MDL);
1050 			interface_dereference (&dummy_interfaces, MDL);
1051 		}
1052 		interface_reference (&dummy_interfaces, ip, MDL);
1053 	}
1054 	if (pi)
1055 		status = interface_reference (pi, ip, MDL);
1056 	else
1057 		status = ISC_R_FAILURE;
1058 	interface_dereference (&ip, MDL);
1059 	if (status != ISC_R_SUCCESS)
1060 		return 0;
1061 	return 1;
1062 }
1063 
make_client_state(state)1064 void make_client_state (state)
1065 	struct client_state **state;
1066 {
1067 	*state = ((struct client_state *)dmalloc (sizeof **state, MDL));
1068 	if (!*state)
1069 		log_fatal ("no memory for client state\n");
1070 	memset (*state, 0, sizeof **state);
1071 }
1072 
make_client_config(client,config)1073 void make_client_config (client, config)
1074 	struct client_state *client;
1075 	struct client_config *config;
1076 {
1077 	client -> config = (((struct client_config *)
1078 			     dmalloc (sizeof (struct client_config), MDL)));
1079 	if (!client -> config)
1080 		log_fatal ("no memory for client config\n");
1081 	memcpy (client -> config, config, sizeof *config);
1082 	if (!clone_group (&client -> config -> on_receipt,
1083 			  config -> on_receipt, MDL) ||
1084 	    !clone_group (&client -> config -> on_transmission,
1085 			  config -> on_transmission, MDL))
1086 		log_fatal ("no memory for client state groups.");
1087 }
1088 
1089 /* client-lease-statement :==
1090 	LBRACE client-lease-declarations RBRACE
1091 
1092 	client-lease-declarations :==
1093 		<nil> |
1094 		client-lease-declaration |
1095 		client-lease-declarations client-lease-declaration */
1096 
1097 
parse_client_lease_statement(cfile,is_static)1098 void parse_client_lease_statement (cfile, is_static)
1099 	struct parse *cfile;
1100 	int is_static;
1101 {
1102 	struct client_lease *lease;
1103 	struct interface_info *ip = (struct interface_info *)0;
1104 	int token;
1105 	const char *val;
1106 	struct client_state *client = (struct client_state *)0;
1107 
1108 	token = next_token (&val, (unsigned *)0, cfile);
1109 	if (token != LBRACE) {
1110 		parse_warn (cfile, "expecting left brace.");
1111 		skip_to_semi (cfile);
1112 		return;
1113 	}
1114 
1115 	lease = ((struct client_lease *)
1116 		 dmalloc (sizeof (struct client_lease), MDL));
1117 	if (!lease)
1118 		log_fatal ("no memory for lease.\n");
1119 	memset (lease, 0, sizeof *lease);
1120 	lease -> is_static = is_static;
1121 	if (!option_state_allocate (&lease -> options, MDL))
1122 		log_fatal ("no memory for lease options.\n");
1123 
1124 	do {
1125 		token = peek_token (&val, (unsigned *)0, cfile);
1126 		if (token == END_OF_FILE) {
1127 			parse_warn (cfile, "unterminated lease declaration.");
1128 			return;
1129 		}
1130 		if (token == RBRACE)
1131 			break;
1132 		parse_client_lease_declaration (cfile, lease, &ip, &client);
1133 	} while (1);
1134 	skip_token(&val, (unsigned *)0, cfile);
1135 
1136 	/* If the lease declaration didn't include an interface
1137 	   declaration that we recognized, it's of no use to us. */
1138 	if (!ip) {
1139 		destroy_client_lease (lease);
1140 		return;
1141 	}
1142 
1143 	/* Make sure there's a client state structure... */
1144 	if (!ip -> client) {
1145 		make_client_state (&ip -> client);
1146 		ip -> client -> interface = ip;
1147 	}
1148 	if (!client)
1149 		client = ip -> client;
1150 
1151 	/* If this is an alias lease, it doesn't need to be sorted in. */
1152 	if (is_static == 2) {
1153 		ip -> client -> alias = lease;
1154 		return;
1155 	}
1156 
1157 	/* The new lease may supersede a lease that's not the
1158 	   active lease but is still on the lease list, so scan the
1159 	   lease list looking for a lease with the same address, and
1160 	   if we find it, toss it. We only allow supercession if
1161 	   the leases originated from the same source. In other words,
1162 	   either both are from the config file or both are from the lease
1163 	   file.  This keeps us from discarding fallback leases */
1164 	discard_duplicate (&client->leases, lease);
1165 
1166 	/* If this is a preloaded lease, just put it on the list of recorded
1167 	   leases - don't make it the active lease. */
1168 	if (is_static) {
1169 		lease -> next = client -> leases;
1170 		client -> leases = lease;
1171 		return;
1172 	}
1173 
1174 	/* The last lease in the lease file on a particular interface is
1175 	   the active lease for that interface.    Of course, we don't know
1176 	   what the last lease in the file is until we've parsed the whole
1177 	   file, so at this point, we assume that the lease we just parsed
1178 	   is the active lease for its interface.   If there's already
1179 	   an active lease for the interface, and this lease is for the same
1180 	   ip address, then we just toss the old active lease and replace
1181 	   it with this one.   If this lease is for a different address,
1182 	   then if the old active lease has expired, we dump it; if not,
1183 	   we put it on the list of leases for this interface which are
1184 	   still valid but no longer active. */
1185 	if (client -> active) {
1186 		if (client -> active -> expiry < cur_time)
1187 			destroy_client_lease (client -> active);
1188 		else if (client -> active -> address.len ==
1189 			 lease -> address.len &&
1190 			 !memcmp (client -> active -> address.iabuf,
1191 				  lease -> address.iabuf,
1192 				  lease -> address.len))
1193 			destroy_client_lease (client -> active);
1194 		else {
1195 			client -> active -> next = client -> leases;
1196 			client -> leases = client -> active;
1197 		}
1198 	}
1199 	client -> active = lease;
1200 
1201 	/* phew. */
1202 }
1203 
1204 /* client-lease-declaration :==
1205 	BOOTP |
1206 	INTERFACE string |
1207 	FIXED_ADDR ip_address |
1208 	FILENAME string |
1209 	SERVER_NAME string |
1210 	OPTION option-decl |
1211 	RENEW time-decl |
1212 	REBIND time-decl |
1213 	EXPIRE time-decl |
1214 	KEY id */
1215 
parse_client_lease_declaration(cfile,lease,ipp,clientp)1216 void parse_client_lease_declaration (cfile, lease, ipp, clientp)
1217 	struct parse *cfile;
1218 	struct client_lease *lease;
1219 	struct interface_info **ipp;
1220 	struct client_state **clientp;
1221 {
1222 	int token;
1223 	const char *val;
1224 	struct interface_info *ip;
1225 	struct option_cache *oc;
1226 	struct client_state *client = (struct client_state *)0;
1227 
1228 	switch (next_token (&val, (unsigned *)0, cfile)) {
1229 	      case KEY:
1230 		token = next_token (&val, (unsigned *)0, cfile);
1231 		if (token != STRING && !is_identifier (token)) {
1232 			parse_warn (cfile, "expecting key name.");
1233 			skip_to_semi (cfile);
1234 			break;
1235 		}
1236 		if (omapi_auth_key_lookup_name (&lease -> key, val) !=
1237 		    ISC_R_SUCCESS)
1238 			parse_warn (cfile, "unknown key %s", val);
1239 		parse_semi (cfile);
1240 		break;
1241 	      case TOKEN_BOOTP:
1242 		lease -> is_bootp = 1;
1243 		break;
1244 
1245 	      case INTERFACE:
1246 		token = next_token (&val, (unsigned *)0, cfile);
1247 		if (token != STRING) {
1248 			parse_warn (cfile,
1249 				    "expecting interface name (in quotes).");
1250 			skip_to_semi (cfile);
1251 			break;
1252 		}
1253 		if (!interface_or_dummy (ipp, val))
1254 			log_fatal ("Can't allocate interface %s.", val);
1255 		break;
1256 
1257 	      case NAME:
1258 		token = next_token (&val, (unsigned *)0, cfile);
1259 		ip = *ipp;
1260 		if (!ip) {
1261 			parse_warn (cfile, "state name precedes interface.");
1262 			break;
1263 		}
1264 		for (client = ip -> client; client; client = client -> next)
1265 			if (client -> name && !strcmp (client -> name, val))
1266 				break;
1267 		if (!client)
1268 			parse_warn (cfile,
1269 				    "lease specified for unknown pseudo.");
1270 		*clientp = client;
1271 		break;
1272 
1273 	      case FIXED_ADDR:
1274 		if (!parse_ip_addr (cfile, &lease -> address))
1275 			return;
1276 		break;
1277 
1278 	      case MEDIUM:
1279 		parse_string_list (cfile, &lease -> medium, 0);
1280 		return;
1281 
1282 	      case FILENAME:
1283 		parse_string (cfile, &lease -> filename, (unsigned *)0);
1284 		return;
1285 
1286 	      case SERVER_NAME:
1287 		parse_string (cfile, &lease -> server_name, (unsigned *)0);
1288 		return;
1289 
1290 	      case RENEW:
1291 		lease -> renewal = parse_date (cfile);
1292 		return;
1293 
1294 	      case REBIND:
1295 		lease -> rebind = parse_date (cfile);
1296 		return;
1297 
1298 	      case EXPIRE:
1299 		lease -> expiry = parse_date (cfile);
1300 		return;
1301 
1302 	      case OPTION:
1303 		oc = (struct option_cache *)0;
1304 		if (parse_option_decl (&oc, cfile)) {
1305 			save_option(oc->option->universe, lease->options, oc);
1306 			option_cache_dereference (&oc, MDL);
1307 		}
1308 		return;
1309 
1310 	      default:
1311 		parse_warn (cfile, "expecting lease declaration.");
1312 		skip_to_semi (cfile);
1313 		break;
1314 	}
1315 	token = next_token (&val, (unsigned *)0, cfile);
1316 	if (token != SEMI) {
1317 		parse_warn (cfile, "expecting semicolon.");
1318 		skip_to_semi (cfile);
1319 	}
1320 }
1321 
1322 /* Parse a default-duid ""; statement.
1323  */
1324 static void
parse_client_default_duid(struct parse * cfile)1325 parse_client_default_duid(struct parse *cfile)
1326 {
1327 	struct data_string new_duid;
1328 	u_int8_t buf[128];
1329 	unsigned len;
1330 
1331 	len = parse_X(cfile, buf, sizeof(buf));
1332 	if (len <= 2) {
1333 		parse_warn(cfile, "Invalid DUID contents.");
1334 		skip_to_semi(cfile);
1335 		return;
1336 	}
1337 
1338 	memset(&new_duid, 0, sizeof(new_duid));
1339 	if (!buffer_allocate(&new_duid.buffer, len, MDL)) {
1340 		parse_warn(cfile, "Out of memory parsing default DUID.");
1341 		skip_to_semi(cfile);
1342 		return;
1343 	}
1344 	new_duid.data = new_duid.buffer->data;
1345 	new_duid.len = len;
1346 
1347 	memcpy(new_duid.buffer->data, buf, len);
1348 
1349 	/* Rotate the last entry into place. */
1350 	if (default_duid.buffer != NULL)
1351 		data_string_forget(&default_duid, MDL);
1352 	data_string_copy(&default_duid, &new_duid, MDL);
1353 	data_string_forget(&new_duid, MDL);
1354 
1355 	parse_semi(cfile);
1356 }
1357 
1358 /* Parse a lease6 {} construct.  The v6 client is a little different
1359  * than the v4 client today, in that it only retains one lease, the
1360  * active lease, and discards any less recent information.  It may
1361  * be useful in the future to cache additional information, but it
1362  * is not worth the effort for the moment.
1363  */
1364 static void
parse_client6_lease_statement(struct parse * cfile)1365 parse_client6_lease_statement(struct parse *cfile)
1366 {
1367 #if !defined(DHCPv6)
1368 	parse_warn(cfile, "No DHCPv6 support.");
1369 	skip_to_semi(cfile);
1370 #else /* defined(DHCPv6) */
1371 	struct option_cache *oc = NULL;
1372 	struct dhc6_lease *lease;
1373 	struct dhc6_ia **ia;
1374 	struct client_state *client = NULL;
1375 	struct interface_info *iface = NULL;
1376 	struct data_string ds;
1377 	const char *val;
1378 	unsigned len;
1379 	int token, has_ia, no_semi, has_name;
1380 
1381 	token = next_token(NULL, NULL, cfile);
1382 	if (token != LBRACE) {
1383 		parse_warn(cfile, "Expecting open curly brace.");
1384 		skip_to_semi(cfile);
1385 		return;
1386 	}
1387 
1388 	lease = dmalloc(sizeof(*lease), MDL);
1389 	if (lease == NULL) {
1390 		parse_warn(cfile, "Unable to allocate lease state.");
1391 		skip_to_rbrace(cfile, 1);
1392 		return;
1393 	}
1394 
1395 	option_state_allocate(&lease->options, MDL);
1396 	if (lease->options == NULL) {
1397 		parse_warn(cfile, "Unable to allocate option cache.");
1398 		skip_to_rbrace(cfile, 1);
1399 		dfree(lease, MDL);
1400 		return;
1401 	}
1402 
1403 	has_ia = 0;
1404 	has_name = 0;
1405 	ia = &lease->bindings;
1406 	token = next_token(&val, NULL, cfile);
1407 	while (token != RBRACE) {
1408 		no_semi = 0;
1409 
1410 		switch(token) {
1411 		      case IA_NA:
1412 			*ia = parse_client6_ia_na_statement(cfile);
1413 			if (*ia != NULL) {
1414 				ia = &(*ia)->next;
1415 				has_ia = 1;
1416 			}
1417 
1418 			no_semi = 1;
1419 
1420 			break;
1421 
1422 		      case IA_TA:
1423 			*ia = parse_client6_ia_ta_statement(cfile);
1424 			if (*ia != NULL) {
1425 				ia = &(*ia)->next;
1426 				has_ia = 1;
1427 			}
1428 
1429 			no_semi = 1;
1430 
1431 			break;
1432 
1433 		      case IA_PD:
1434 			*ia = parse_client6_ia_pd_statement(cfile);
1435 			if (*ia != NULL) {
1436 				ia = &(*ia)->next;
1437 				has_ia = 1;
1438 			}
1439 
1440 			no_semi = 1;
1441 
1442 			break;
1443 
1444 		      case INTERFACE:
1445 			if (iface != NULL) {
1446 				parse_warn(cfile, "Multiple interface names?");
1447 				skip_to_semi(cfile);
1448 				no_semi = 1;
1449 				break;
1450 			}
1451 
1452 			token = next_token(&val, &len, cfile);
1453 			if (token != STRING) {
1454 			      strerror:
1455 				parse_warn(cfile, "Expecting a string.");
1456 				skip_to_semi(cfile);
1457 				no_semi = 1;
1458 				break;
1459 			}
1460 
1461 			for (iface = interfaces ; iface != NULL ;
1462 			     iface = iface->next) {
1463 				if (strcmp(iface->name, val) == 0)
1464 					break;
1465 			}
1466 
1467 			if (iface == NULL) {
1468 				parse_warn(cfile, "Unknown interface.");
1469 				break;
1470 			}
1471 
1472 			break;
1473 
1474 		      case NAME:
1475 			has_name = 1;
1476 
1477 			if (client != NULL) {
1478 				parse_warn(cfile, "Multiple state names?");
1479 				skip_to_semi(cfile);
1480 				no_semi = 1;
1481 				break;
1482 			}
1483 
1484 			if (iface == NULL) {
1485 				parse_warn(cfile, "Client name without "
1486 						  "interface.");
1487 				skip_to_semi(cfile);
1488 				no_semi = 1;
1489 				break;
1490 			}
1491 
1492 			token = next_token(&val, &len, cfile);
1493 			if (token != STRING)
1494 				goto strerror;
1495 
1496 			for (client = iface->client ; client != NULL ;
1497 			     client = client->next) {
1498 				if ((client->name != NULL) &&
1499 				    (strcmp(client->name, val) == 0))
1500 					break;
1501 			}
1502 
1503 			if (client == NULL) {
1504 				parse_warn(cfile, "Unknown client state %s.",
1505 					   val);
1506 				break;
1507 			}
1508 
1509 			break;
1510 
1511 		      case OPTION:
1512 			if (parse_option_decl(&oc, cfile)) {
1513 				save_option(oc->option->universe,
1514 					    lease->options, oc);
1515 				option_cache_dereference(&oc, MDL);
1516 			}
1517 			no_semi = 1;
1518 			break;
1519 
1520 		      case TOKEN_RELEASED:
1521 		      case TOKEN_ABANDONED:
1522 			lease->released = ISC_TRUE;
1523 			break;
1524 
1525 		      default:
1526 			parse_warn(cfile, "Unexpected token, %s.", val);
1527 			no_semi = 1;
1528 			skip_to_semi(cfile);
1529 			break;
1530 		}
1531 
1532 		if (!no_semi)
1533 			parse_semi(cfile);
1534 
1535 		token = next_token(&val, NULL, cfile);
1536 
1537 		if (token == END_OF_FILE) {
1538 			parse_warn(cfile, "Unexpected end of file.");
1539 			break;
1540 		}
1541 	}
1542 
1543 	if (!has_ia) {
1544 		log_debug("Lease with no IA's discarded from lease db.");
1545 		dhc6_lease_destroy(&lease, MDL);
1546 		return;
1547 	}
1548 
1549 	if (iface == NULL)
1550 		parse_warn(cfile, "Lease has no interface designation.");
1551 	else if (!has_name && (client == NULL)) {
1552 		for (client = iface->client ; client != NULL ;
1553 		     client = client->next) {
1554 			if (client->name == NULL)
1555 				break;
1556 		}
1557 	}
1558 
1559 	if (client == NULL) {
1560 		parse_warn(cfile, "No matching client state.");
1561 		dhc6_lease_destroy(&lease, MDL);
1562 		return;
1563 	}
1564 
1565 	/* Fetch Preference option from option cache. */
1566 	memset(&ds, 0, sizeof(ds));
1567 	oc = lookup_option(&dhcpv6_universe, lease->options, D6O_PREFERENCE);
1568 	if ((oc != NULL) &&
1569 	    evaluate_option_cache(&ds, NULL, NULL, NULL, lease->options,
1570 				  NULL, &global_scope, oc, MDL)) {
1571 		if (ds.len != 1) {
1572 			log_error("Invalid length of DHCPv6 Preference option "
1573 				  "(%d != 1)", ds.len);
1574 			data_string_forget(&ds, MDL);
1575 			dhc6_lease_destroy(&lease, MDL);
1576 			return;
1577 		} else
1578 			lease->pref = ds.data[0];
1579 
1580 		data_string_forget(&ds, MDL);
1581 	}
1582 
1583 	/* Fetch server-id option from option cache. */
1584 	oc = lookup_option(&dhcpv6_universe, lease->options, D6O_SERVERID);
1585 	if ((oc == NULL) ||
1586 	    !evaluate_option_cache(&lease->server_id, NULL, NULL, NULL,
1587 				   lease->options, NULL, &global_scope, oc,
1588 				   MDL) ||
1589 	    (lease->server_id.len == 0)) {
1590 		/* This should be impossible... */
1591 		log_error("Invalid SERVERID option cache.");
1592 		dhc6_lease_destroy(&lease, MDL);
1593 		return;
1594 	}
1595 
1596 	if (client->active_lease != NULL)
1597 		dhc6_lease_destroy(&client->active_lease, MDL);
1598 
1599 	client->active_lease = lease;
1600 #endif /* defined(DHCPv6) */
1601 }
1602 
1603 /* Parse an ia_na object from the client lease.
1604  */
1605 #ifdef DHCPv6
1606 static struct dhc6_ia *
parse_client6_ia_na_statement(struct parse * cfile)1607 parse_client6_ia_na_statement(struct parse *cfile)
1608 {
1609 	struct option_cache *oc = NULL;
1610 	struct dhc6_ia *ia;
1611 	struct dhc6_addr **addr;
1612 	const char *val;
1613 	int token, no_semi, len;
1614 	u_int8_t buf[5];
1615 
1616 	ia = dmalloc(sizeof(*ia), MDL);
1617 	if (ia == NULL) {
1618 		parse_warn(cfile, "Out of memory allocating IA_NA state.");
1619 		skip_to_semi(cfile);
1620 		return NULL;
1621 	}
1622 	ia->ia_type = D6O_IA_NA;
1623 
1624 	/* Get IAID. */
1625 	len = parse_X(cfile, buf, 5);
1626 	if (len == 4) {
1627 		memcpy(ia->iaid, buf, 4);
1628 	} else {
1629 		parse_warn(cfile, "Expecting IAID of length 4, got %d.", len);
1630 		skip_to_semi(cfile);
1631 		dfree(ia, MDL);
1632 		return NULL;
1633 	}
1634 
1635 	token = next_token(NULL, NULL, cfile);
1636 	if (token != LBRACE) {
1637 		parse_warn(cfile, "Expecting open curly brace.");
1638 		skip_to_semi(cfile);
1639 		dfree(ia, MDL);
1640 		return NULL;
1641 	}
1642 
1643 	option_state_allocate(&ia->options, MDL);
1644 	if (ia->options == NULL) {
1645 		parse_warn(cfile, "Unable to allocate option state.");
1646 		skip_to_rbrace(cfile, 1);
1647 		dfree(ia, MDL);
1648 		return NULL;
1649 	}
1650 
1651 	addr = &ia->addrs;
1652 	token = next_token(&val, NULL, cfile);
1653 	while (token != RBRACE) {
1654 		no_semi = 0;
1655 
1656 		switch (token) {
1657 		      case STARTS:
1658 			token = next_token(&val, NULL, cfile);
1659 			if (token == NUMBER) {
1660 				ia->starts = atoi(val);
1661 			} else {
1662 				parse_warn(cfile, "Expecting a number.");
1663 				skip_to_semi(cfile);
1664 				no_semi = 1;
1665 			}
1666 			break;
1667 
1668 		      case RENEW:
1669 			token = next_token(&val, NULL, cfile);
1670 			if (token == NUMBER) {
1671 				ia->renew = atoi(val);
1672 			} else {
1673 				parse_warn(cfile, "Expecting a number.");
1674 				skip_to_semi(cfile);
1675 				no_semi = 1;
1676 			}
1677 			break;
1678 
1679 		      case REBIND:
1680 			token = next_token(&val, NULL, cfile);
1681 			if (token == NUMBER) {
1682 				ia->rebind = atoi(val);
1683 			} else {
1684 				parse_warn(cfile, "Expecting a number.");
1685 				skip_to_semi(cfile);
1686 				no_semi = 1;
1687 			}
1688 			break;
1689 
1690 		      case IAADDR:
1691 			*addr = parse_client6_iaaddr_statement(cfile);
1692 
1693 			if (*addr != NULL)
1694 				addr = &(*addr)->next;
1695 
1696 			no_semi = 1;
1697 
1698 			break;
1699 
1700 		      case OPTION:
1701 			if (parse_option_decl(&oc, cfile)) {
1702 				save_option(oc->option->universe,
1703 					    ia->options, oc);
1704 				option_cache_dereference(&oc, MDL);
1705 			}
1706 			no_semi = 1;
1707 			break;
1708 
1709 		      default:
1710 			parse_warn(cfile, "Unexpected token.");
1711 			no_semi = 1;
1712 			skip_to_semi(cfile);
1713 			break;
1714 		}
1715 
1716 		if (!no_semi)
1717 			parse_semi(cfile);
1718 
1719 		token = next_token(&val, NULL, cfile);
1720 
1721 		if (token == END_OF_FILE) {
1722 			parse_warn(cfile, "Unexpected end of file.");
1723 			break;
1724 		}
1725 	}
1726 
1727 	return ia;
1728 }
1729 #endif /* DHCPv6 */
1730 
1731 /* Parse an ia_ta object from the client lease.
1732  */
1733 #ifdef DHCPv6
1734 static struct dhc6_ia *
parse_client6_ia_ta_statement(struct parse * cfile)1735 parse_client6_ia_ta_statement(struct parse *cfile)
1736 {
1737 	struct option_cache *oc = NULL;
1738 	struct dhc6_ia *ia;
1739 	struct dhc6_addr **addr;
1740 	const char *val;
1741 	int token, no_semi, len;
1742 	u_int8_t buf[5];
1743 
1744 	ia = dmalloc(sizeof(*ia), MDL);
1745 	if (ia == NULL) {
1746 		parse_warn(cfile, "Out of memory allocating IA_TA state.");
1747 		skip_to_semi(cfile);
1748 		return NULL;
1749 	}
1750 	ia->ia_type = D6O_IA_TA;
1751 
1752 	/* Get IAID. */
1753 	len = parse_X(cfile, buf, 5);
1754 	if (len == 4) {
1755 		memcpy(ia->iaid, buf, 4);
1756 	} else {
1757 		parse_warn(cfile, "Expecting IAID of length 4, got %d.", len);
1758 		skip_to_semi(cfile);
1759 		dfree(ia, MDL);
1760 		return NULL;
1761 	}
1762 
1763 	token = next_token(NULL, NULL, cfile);
1764 	if (token != LBRACE) {
1765 		parse_warn(cfile, "Expecting open curly brace.");
1766 		skip_to_semi(cfile);
1767 		dfree(ia, MDL);
1768 		return NULL;
1769 	}
1770 
1771 	option_state_allocate(&ia->options, MDL);
1772 	if (ia->options == NULL) {
1773 		parse_warn(cfile, "Unable to allocate option state.");
1774 		skip_to_rbrace(cfile, 1);
1775 		dfree(ia, MDL);
1776 		return NULL;
1777 	}
1778 
1779 	addr = &ia->addrs;
1780 	token = next_token(&val, NULL, cfile);
1781 	while (token != RBRACE) {
1782 		no_semi = 0;
1783 
1784 		switch (token) {
1785 		      case STARTS:
1786 			token = next_token(&val, NULL, cfile);
1787 			if (token == NUMBER) {
1788 				ia->starts = atoi(val);
1789 			} else {
1790 				parse_warn(cfile, "Expecting a number.");
1791 				skip_to_semi(cfile);
1792 				no_semi = 1;
1793 			}
1794 			break;
1795 
1796 			/* No RENEW or REBIND */
1797 
1798 		      case IAADDR:
1799 			*addr = parse_client6_iaaddr_statement(cfile);
1800 
1801 			if (*addr != NULL)
1802 				addr = &(*addr)->next;
1803 
1804 			no_semi = 1;
1805 
1806 			break;
1807 
1808 		      case OPTION:
1809 			if (parse_option_decl(&oc, cfile)) {
1810 				save_option(oc->option->universe,
1811 					    ia->options, oc);
1812 				option_cache_dereference(&oc, MDL);
1813 			}
1814 			no_semi = 1;
1815 			break;
1816 
1817 		      default:
1818 			parse_warn(cfile, "Unexpected token.");
1819 			no_semi = 1;
1820 			skip_to_semi(cfile);
1821 			break;
1822 		}
1823 
1824 		if (!no_semi)
1825 			parse_semi(cfile);
1826 
1827 		token = next_token(&val, NULL, cfile);
1828 
1829 		if (token == END_OF_FILE) {
1830 			parse_warn(cfile, "Unexpected end of file.");
1831 			break;
1832 		}
1833 	}
1834 
1835 	return ia;
1836 }
1837 #endif /* DHCPv6 */
1838 
1839 /* Parse an ia_pd object from the client lease.
1840  */
1841 #ifdef DHCPv6
1842 static struct dhc6_ia *
parse_client6_ia_pd_statement(struct parse * cfile)1843 parse_client6_ia_pd_statement(struct parse *cfile)
1844 {
1845 	struct option_cache *oc = NULL;
1846 	struct dhc6_ia *ia;
1847 	struct dhc6_addr **pref;
1848 	const char *val;
1849 	int token, no_semi, len;
1850 	u_int8_t buf[5];
1851 
1852 	ia = dmalloc(sizeof(*ia), MDL);
1853 	if (ia == NULL) {
1854 		parse_warn(cfile, "Out of memory allocating IA_PD state.");
1855 		skip_to_semi(cfile);
1856 		return NULL;
1857 	}
1858 	ia->ia_type = D6O_IA_PD;
1859 
1860 	/* Get IAID. */
1861 	len = parse_X(cfile, buf, 5);
1862 	if (len == 4) {
1863 		memcpy(ia->iaid, buf, 4);
1864 	} else {
1865 		parse_warn(cfile, "Expecting IAID of length 4, got %d.", len);
1866 		skip_to_semi(cfile);
1867 		dfree(ia, MDL);
1868 		return NULL;
1869 	}
1870 
1871 	token = next_token(NULL, NULL, cfile);
1872 	if (token != LBRACE) {
1873 		parse_warn(cfile, "Expecting open curly brace.");
1874 		skip_to_semi(cfile);
1875 		dfree(ia, MDL);
1876 		return NULL;
1877 	}
1878 
1879 	option_state_allocate(&ia->options, MDL);
1880 	if (ia->options == NULL) {
1881 		parse_warn(cfile, "Unable to allocate option state.");
1882 		skip_to_rbrace(cfile, 1);
1883 		dfree(ia, MDL);
1884 		return NULL;
1885 	}
1886 
1887 	pref = &ia->addrs;
1888 	token = next_token(&val, NULL, cfile);
1889 	while (token != RBRACE) {
1890 		no_semi = 0;
1891 
1892 		switch (token) {
1893 		      case STARTS:
1894 			token = next_token(&val, NULL, cfile);
1895 			if (token == NUMBER) {
1896 				ia->starts = atoi(val);
1897 			} else {
1898 				parse_warn(cfile, "Expecting a number.");
1899 				skip_to_semi(cfile);
1900 				no_semi = 1;
1901 			}
1902 			break;
1903 
1904 		      case RENEW:
1905 			token = next_token(&val, NULL, cfile);
1906 			if (token == NUMBER) {
1907 				ia->renew = atoi(val);
1908 			} else {
1909 				parse_warn(cfile, "Expecting a number.");
1910 				skip_to_semi(cfile);
1911 				no_semi = 1;
1912 			}
1913 			break;
1914 
1915 		      case REBIND:
1916 			token = next_token(&val, NULL, cfile);
1917 			if (token == NUMBER) {
1918 				ia->rebind = atoi(val);
1919 			} else {
1920 				parse_warn(cfile, "Expecting a number.");
1921 				skip_to_semi(cfile);
1922 				no_semi = 1;
1923 			}
1924 			break;
1925 
1926 		      case IAPREFIX:
1927 			*pref = parse_client6_iaprefix_statement(cfile);
1928 
1929 			if (*pref != NULL)
1930 				pref = &(*pref)->next;
1931 
1932 			no_semi = 1;
1933 
1934 			break;
1935 
1936 		      case OPTION:
1937 			if (parse_option_decl(&oc, cfile)) {
1938 				save_option(oc->option->universe,
1939 					    ia->options, oc);
1940 				option_cache_dereference(&oc, MDL);
1941 			}
1942 			no_semi = 1;
1943 			break;
1944 
1945 		      default:
1946 			parse_warn(cfile, "Unexpected token.");
1947 			no_semi = 1;
1948 			skip_to_semi(cfile);
1949 			break;
1950 		}
1951 
1952 		if (!no_semi)
1953 			parse_semi(cfile);
1954 
1955 		token = next_token(&val, NULL, cfile);
1956 
1957 		if (token == END_OF_FILE) {
1958 			parse_warn(cfile, "Unexpected end of file.");
1959 			break;
1960 		}
1961 	}
1962 
1963 	return ia;
1964 }
1965 #endif /* DHCPv6 */
1966 
1967 /* Parse an iaaddr {} structure. */
1968 #ifdef DHCPv6
1969 static struct dhc6_addr *
parse_client6_iaaddr_statement(struct parse * cfile)1970 parse_client6_iaaddr_statement(struct parse *cfile)
1971 {
1972 	struct option_cache *oc = NULL;
1973 	struct dhc6_addr *addr;
1974 	const char *val;
1975 	int token, no_semi;
1976 
1977 	addr = dmalloc(sizeof(*addr), MDL);
1978 	if (addr == NULL) {
1979 		parse_warn(cfile, "Unable to allocate IAADDR state.");
1980 		skip_to_semi(cfile);
1981 		return NULL;
1982 	}
1983 
1984 	/* Get IP address. */
1985 	if (!parse_ip6_addr(cfile, &addr->address)) {
1986 		skip_to_semi(cfile);
1987 		dfree(addr, MDL);
1988 		return NULL;
1989 	}
1990 
1991 	token = next_token(NULL, NULL, cfile);
1992 	if (token != LBRACE) {
1993 		parse_warn(cfile, "Expecting open curly bracket.");
1994 		skip_to_semi(cfile);
1995 		dfree(addr, MDL);
1996 		return NULL;
1997 	}
1998 
1999 	option_state_allocate(&addr->options, MDL);
2000 	if (addr->options == NULL) {
2001 		parse_warn(cfile, "Unable to allocate option state.");
2002 		skip_to_semi(cfile);
2003 		dfree(addr, MDL);
2004 		return NULL;
2005 	}
2006 
2007 	token = next_token(&val, NULL, cfile);
2008 	while (token != RBRACE) {
2009 		no_semi = 0;
2010 
2011 		switch (token) {
2012 		      case STARTS:
2013 			token = next_token(&val, NULL, cfile);
2014 			if (token == NUMBER) {
2015 				addr->starts = atoi(val);
2016 			} else {
2017 				parse_warn(cfile, "Expecting a number.");
2018 				skip_to_semi(cfile);
2019 				no_semi = 1;
2020 			}
2021 			break;
2022 
2023 		      case PREFERRED_LIFE:
2024 			token = next_token(&val, NULL, cfile);
2025 			if (token == NUMBER) {
2026 				addr->preferred_life = atoi(val);
2027 			} else {
2028 				parse_warn(cfile, "Expecting a number.");
2029 				skip_to_semi(cfile);
2030 				no_semi = 1;
2031 			}
2032 			break;
2033 
2034 		      case MAX_LIFE:
2035 			token = next_token(&val, NULL, cfile);
2036 			if (token == NUMBER) {
2037 				addr->max_life = atoi(val);
2038 			} else {
2039 				parse_warn(cfile, "Expecting a number.");
2040 				skip_to_semi(cfile);
2041 				no_semi = 1;
2042 			}
2043 			break;
2044 
2045 		      case OPTION:
2046 			if (parse_option_decl(&oc, cfile)) {
2047 				save_option(oc->option->universe,
2048 					    addr->options, oc);
2049 				option_cache_dereference(&oc, MDL);
2050 			}
2051 			no_semi = 1;
2052 			break;
2053 
2054 		      default:
2055 			parse_warn(cfile, "Unexpected token.");
2056 			skip_to_rbrace(cfile, 1);
2057 			no_semi = 1;
2058 			break;
2059 		}
2060 
2061 		if (!no_semi)
2062 			parse_semi(cfile);
2063 
2064 		token = next_token(&val, NULL, cfile);
2065 		if (token == END_OF_FILE) {
2066 			parse_warn(cfile, "Unexpected end of file.");
2067 			break;
2068 		}
2069 	}
2070 
2071 	return addr;
2072 }
2073 #endif /* DHCPv6 */
2074 
2075 /* Parse an iaprefix {} structure. */
2076 #ifdef DHCPv6
2077 static struct dhc6_addr *
parse_client6_iaprefix_statement(struct parse * cfile)2078 parse_client6_iaprefix_statement(struct parse *cfile)
2079 {
2080 	struct option_cache *oc = NULL;
2081 	struct dhc6_addr *pref;
2082 	const char *val;
2083 	int token, no_semi;
2084 
2085 	pref = dmalloc(sizeof(*pref), MDL);
2086 	if (pref == NULL) {
2087 		parse_warn(cfile, "Unable to allocate IAPREFIX state.");
2088 		skip_to_semi(cfile);
2089 		return NULL;
2090 	}
2091 
2092 	/* Get IP prefix. */
2093 	if (!parse_ip6_prefix(cfile, &pref->address, &pref->plen)) {
2094 		skip_to_semi(cfile);
2095 		dfree(pref, MDL);
2096 		return NULL;
2097 	}
2098 
2099 	token = next_token(NULL, NULL, cfile);
2100 	if (token != LBRACE) {
2101 		parse_warn(cfile, "Expecting open curly bracket.");
2102 		skip_to_semi(cfile);
2103 		dfree(pref, MDL);
2104 		return NULL;
2105 	}
2106 
2107 	option_state_allocate(&pref->options, MDL);
2108 	if (pref->options == NULL) {
2109 		parse_warn(cfile, "Unable to allocate option state.");
2110 		skip_to_semi(cfile);
2111 		dfree(pref, MDL);
2112 		return NULL;
2113 	}
2114 
2115 	token = next_token(&val, NULL, cfile);
2116 	while (token != RBRACE) {
2117 		no_semi = 0;
2118 
2119 		switch (token) {
2120 		      case STARTS:
2121 			token = next_token(&val, NULL, cfile);
2122 			if (token == NUMBER) {
2123 				pref->starts = atoi(val);
2124 			} else {
2125 				parse_warn(cfile, "Expecting a number.");
2126 				skip_to_semi(cfile);
2127 				no_semi = 1;
2128 			}
2129 			break;
2130 
2131 		      case PREFERRED_LIFE:
2132 			token = next_token(&val, NULL, cfile);
2133 			if (token == NUMBER) {
2134 				pref->preferred_life = atoi(val);
2135 			} else {
2136 				parse_warn(cfile, "Expecting a number.");
2137 				skip_to_semi(cfile);
2138 				no_semi = 1;
2139 			}
2140 			break;
2141 
2142 		      case MAX_LIFE:
2143 			token = next_token(&val, NULL, cfile);
2144 			if (token == NUMBER) {
2145 				pref->max_life = atoi(val);
2146 			} else {
2147 				parse_warn(cfile, "Expecting a number.");
2148 				skip_to_semi(cfile);
2149 				no_semi = 1;
2150 			}
2151 			break;
2152 
2153 		      case OPTION:
2154 			if (parse_option_decl(&oc, cfile)) {
2155 				save_option(oc->option->universe,
2156 					    pref->options, oc);
2157 				option_cache_dereference(&oc, MDL);
2158 			}
2159 			no_semi = 1;
2160 			break;
2161 
2162 		      default:
2163 			parse_warn(cfile, "Unexpected token.");
2164 			skip_to_rbrace(cfile, 1);
2165 			no_semi = 1;
2166 			break;
2167 		}
2168 
2169 		if (!no_semi)
2170 			parse_semi(cfile);
2171 
2172 		token = next_token(&val, NULL, cfile);
2173 		if (token == END_OF_FILE) {
2174 			parse_warn(cfile, "Unexpected end of file.");
2175 			break;
2176 		}
2177 	}
2178 
2179 	return pref;
2180 }
2181 #endif /* DHCPv6 */
2182 
parse_string_list(cfile,lp,multiple)2183 void parse_string_list (cfile, lp, multiple)
2184 	struct parse *cfile;
2185 	struct string_list **lp;
2186 	int multiple;
2187 {
2188 	int token;
2189 	const char *val;
2190 	struct string_list *cur, *tmp;
2191 
2192 	/* Find the last medium in the media list. */
2193 	if (*lp) {
2194 		for (cur = *lp; cur -> next; cur = cur -> next)
2195 			;
2196 	} else {
2197 		cur = (struct string_list *)0;
2198 	}
2199 
2200 	do {
2201 		token = next_token (&val, (unsigned *)0, cfile);
2202 		if (token != STRING) {
2203 			parse_warn (cfile, "Expecting media options.");
2204 			skip_to_semi (cfile);
2205 			return;
2206 		}
2207 
2208 		tmp = ((struct string_list *)
2209 		       dmalloc (strlen (val) + sizeof (struct string_list),
2210 				MDL));
2211 		if (!tmp)
2212 			log_fatal ("no memory for string list entry.");
2213 
2214 		strcpy (tmp -> string, val);
2215 		tmp -> next = (struct string_list *)0;
2216 
2217 		/* Store this medium at the end of the media list. */
2218 		if (cur)
2219 			cur -> next = tmp;
2220 		else
2221 			*lp = tmp;
2222 		cur = tmp;
2223 
2224 		token = next_token (&val, (unsigned *)0, cfile);
2225 	} while (multiple && token == COMMA);
2226 
2227 	if (token != SEMI) {
2228 		parse_warn (cfile, "expecting semicolon.");
2229 		skip_to_semi (cfile);
2230 	}
2231 }
2232 
parse_reject_statement(cfile,config)2233 void parse_reject_statement (cfile, config)
2234 	struct parse *cfile;
2235 	struct client_config *config;
2236 {
2237 	int token;
2238 	const char *val;
2239 	struct iaddrmatch match;
2240 	struct iaddrmatchlist *list;
2241 	int i;
2242 
2243 	do {
2244 		if (!parse_ip_addr_with_subnet (cfile, &match)) {
2245 			/* no warn: parser will have reported what's wrong */
2246 			skip_to_semi (cfile);
2247 			return;
2248 		}
2249 
2250 		/* check mask is not all zeros (because that would
2251 		 * reject EVERY address).  This check could be
2252 		 * simplified if we assume that the mask *always*
2253 		 * represents a prefix .. but perhaps it might be
2254 		 * useful to have a mask which is not a proper prefix
2255 		 * (perhaps for ipv6?).  The following is almost as
2256 		 * efficient as inspection of match.mask.iabuf[0] when
2257 		 * it IS a true prefix, and is more general when it is
2258 		 * not.
2259 		 */
2260 
2261 		for (i=0 ; i < match.mask.len ; i++) {
2262 		    if (match.mask.iabuf[i]) {
2263 			break;
2264 		    }
2265 		}
2266 
2267 		if (i == match.mask.len) {
2268 		    /* oops we found all zeros */
2269 		    parse_warn(cfile, "zero-length prefix is not permitted "
2270 				      "for reject statement");
2271 		    skip_to_semi(cfile);
2272 		    return;
2273 		}
2274 
2275 		list = dmalloc(sizeof(struct iaddrmatchlist), MDL);
2276 		if (!list)
2277 			log_fatal ("no memory for reject list!");
2278 
2279 		list->match = match;
2280 		list->next = config->reject_list;
2281 		config->reject_list = list;
2282 
2283 		token = next_token (&val, (unsigned *)0, cfile);
2284 	} while (token == COMMA);
2285 
2286 	if (token != SEMI) {
2287 		parse_warn (cfile, "expecting semicolon.");
2288 		skip_to_semi (cfile);
2289 	}
2290 }
2291 
2292 /* allow-deny-keyword :== BOOTP
2293    			| BOOTING
2294 			| DYNAMIC_BOOTP
2295 			| UNKNOWN_CLIENTS */
2296 
parse_allow_deny(oc,cfile,flag)2297 int parse_allow_deny (oc, cfile, flag)
2298 	struct option_cache **oc;
2299 	struct parse *cfile;
2300 	int flag;
2301 {
2302 	parse_warn (cfile, "allow/deny/ignore not permitted here.");
2303 	skip_to_semi (cfile);
2304 	return 0;
2305 }
2306 
2307 
2308 
2309 /*!
2310  * \brief Parses an lease-id-format statement
2311  *
2312  * A valid statement looks like this:
2313  *
2314  *	lease-id-format :==
2315  *		LEASE_ID_FORMAT TOKEN_OCTAL | TOKEN_HEX ;
2316  *
2317  * This function is used to parse the lease-id-format statement. It sets
2318  * top_level_config.lease_id_format.
2319  *
2320  * \param cfile the current parse file
2321  *
2322 */
parse_lease_id_format(struct parse * cfile)2323 void parse_lease_id_format (struct parse *cfile)
2324 {
2325 	enum dhcp_token token;
2326 	const char *val;
2327 
2328 	token = next_token(&val, NULL, cfile);
2329 	switch(token) {
2330 	case TOKEN_OCTAL:
2331 		top_level_config.lease_id_format = TOKEN_OCTAL;
2332 		break;
2333 	case TOKEN_HEX:
2334 		top_level_config.lease_id_format = TOKEN_HEX;
2335 		break;
2336 	default:
2337 		parse_warn(cfile, "lease-id-format is invalid: "
2338                                    " it must be octal or hex.");
2339 		skip_to_semi(cfile);
2340 		return;
2341 	}
2342 
2343 	log_debug("lease_id_format is: %s",
2344 		  (top_level_config.lease_id_format == TOKEN_OCTAL
2345 		   ? "octal" : "hex"));
2346 
2347 }
2348