xref: /minix3/external/bsd/dhcp/dist/server/confpars.c (revision d56f51ea7d8b9045e5c8e2028422523d3f9a5840)
1 /*	$NetBSD: confpars.c,v 1.2 2014/07/12 12:09:38 spz Exp $	*/
2 /* confpars.c
3 
4    Parser for dhcpd config file... */
5 
6 /*
7  * Copyright (c) 2004-2014 by Internet Systems Consortium, Inc. ("ISC")
8  * Copyright (c) 1995-2003 by Internet Software Consortium
9  *
10  * Permission to use, copy, modify, and distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  *
22  *   Internet Systems Consortium, Inc.
23  *   950 Charter Street
24  *   Redwood City, CA 94063
25  *   <info@isc.org>
26  *   https://www.isc.org/
27  *
28  */
29 
30 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: confpars.c,v 1.2 2014/07/12 12:09:38 spz Exp $");
32 
33 /*! \file server/confpars.c */
34 
35 #include "dhcpd.h"
36 
37 static unsigned char global_host_once = 1;
38 
39 static int parse_binding_value(struct parse *cfile,
40 				struct binding_value *value);
41 
42 #if defined (TRACING)
43 trace_type_t *trace_readconf_type;
44 trace_type_t *trace_readleases_type;
45 
46 void parse_trace_setup ()
47 {
48 	trace_readconf_type = trace_type_register ("readconf", (void *)0,
49 						   trace_conf_input,
50 						   trace_conf_stop, MDL);
51 	trace_readleases_type = trace_type_register ("readleases", (void *)0,
52 						     trace_conf_input,
53 						     trace_conf_stop, MDL);
54 }
55 #endif
56 
57 /* conf-file :== parameters declarations END_OF_FILE
58    parameters :== <nil> | parameter | parameters parameter
59    declarations :== <nil> | declaration | declarations declaration */
60 
61 isc_result_t readconf ()
62 {
63 	isc_result_t res;
64 
65 	res = read_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP, 0);
66 #if defined(LDAP_CONFIGURATION)
67 	if (res != ISC_R_SUCCESS)
68 		return (res);
69 
70 	return ldap_read_config ();
71 #else
72 	return (res);
73 #endif
74 }
75 
76 isc_result_t read_conf_file (const char *filename, struct group *group,
77 			     int group_type, int leasep)
78 {
79 	int file;
80 	struct parse *cfile;
81 	isc_result_t status;
82 #if defined (TRACING)
83 	char *fbuf, *dbuf;
84 	off_t flen;
85 	int result;
86 	unsigned tflen, ulen;
87 	trace_type_t *ttype;
88 
89 	if (leasep)
90 		ttype = trace_readleases_type;
91 	else
92 		ttype = trace_readconf_type;
93 
94 	/* If we're in playback, we need to snarf the contents of the
95 	   named file out of the playback file rather than trying to
96 	   open and read it. */
97 	if (trace_playback ()) {
98 		dbuf = (char *)0;
99 		tflen = 0;
100 		status = trace_get_file (ttype, filename, &tflen, &dbuf);
101 		if (status != ISC_R_SUCCESS)
102 			return status;
103 		ulen = tflen;
104 
105 		/* What we get back is filename\0contents, where contents is
106 		   terminated just by the length.  So we figure out the length
107 		   of the filename, and subtract that and the NUL from the
108 		   total length to get the length of the contents of the file.
109 		   We make fbuf a pointer to the contents of the file, and
110 		   leave dbuf as it is so we can free it later. */
111 		tflen = strlen (dbuf);
112 		ulen = ulen - tflen - 1;
113 		fbuf = dbuf + tflen + 1;
114 		goto memfile;
115 	}
116 #endif
117 
118 	if ((file = open (filename, O_RDONLY)) < 0) {
119 		if (leasep) {
120 			log_error ("Can't open lease database %s: %m --",
121 				   path_dhcpd_db);
122 			log_error ("  check for failed database %s!",
123 				   "rewrite attempt");
124 			log_error ("Please read the dhcpd.leases manual%s",
125 				   " page if you");
126 			log_fatal ("don't know what to do about this.");
127 		} else {
128 			log_fatal ("Can't open %s: %m", filename);
129 		}
130 	}
131 
132 	cfile = (struct parse *)0;
133 #if defined (TRACING)
134 	flen = lseek (file, (off_t)0, SEEK_END);
135 	if (flen < 0) {
136 	      boom:
137 		log_fatal ("Can't lseek on %s: %m", filename);
138 	}
139 	if (lseek (file, (off_t)0, SEEK_SET) < 0)
140 		goto boom;
141 	/* Can't handle files greater than 2^31-1. */
142 	if (flen > 0x7FFFFFFFUL)
143 		log_fatal ("%s: file is too long to buffer.", filename);
144 	ulen = flen;
145 
146 	/* Allocate a buffer that will be what's written to the tracefile,
147 	   and also will be what we parse from. */
148 	tflen = strlen (filename);
149 	dbuf = dmalloc (ulen + tflen + 1, MDL);
150 	if (!dbuf)
151 		log_fatal ("No memory for %s (%d bytes)",
152 			   filename, ulen);
153 
154 	/* Copy the name into the beginning, nul-terminated. */
155 	strcpy (dbuf, filename);
156 
157 	/* Load the file in after the NUL. */
158 	fbuf = dbuf + tflen + 1;
159 	result = read (file, fbuf, ulen);
160 	if (result < 0)
161 		log_fatal ("Can't read in %s: %m", filename);
162 	if (result != ulen)
163 		log_fatal ("%s: short read of %d bytes instead of %d.",
164 			   filename, ulen, result);
165 	close (file);
166       memfile:
167 	/* If we're recording, write out the filename and file contents. */
168 	if (trace_record ())
169 		trace_write_packet (ttype, ulen + tflen + 1, dbuf, MDL);
170 	status = new_parse(&cfile, -1, fbuf, ulen, filename, 0); /* XXX */
171 #else
172 	status = new_parse(&cfile, file, NULL, 0, filename, 0);
173 #endif
174 	if (status != ISC_R_SUCCESS || cfile == NULL)
175 		return status;
176 
177 	if (leasep)
178 		status = lease_file_subparse (cfile);
179 	else
180 		status = conf_file_subparse (cfile, group, group_type);
181 	end_parse (&cfile);
182 #if defined (TRACING)
183 	dfree (dbuf, MDL);
184 #endif
185 	return status;
186 }
187 
188 #if defined (TRACING)
189 void trace_conf_input (trace_type_t *ttype, unsigned len, char *data)
190 {
191 	char *fbuf;
192 	unsigned flen;
193 	unsigned tflen;
194 	struct parse *cfile = (struct parse *)0;
195 	static int postconf_initialized;
196 	static int leaseconf_initialized;
197 	isc_result_t status;
198 
199 	/* Do what's done above, except that we don't have to read in the
200 	   data, because it's already been read for us. */
201 	tflen = strlen (data);
202 	flen = len - tflen - 1;
203 	fbuf = data + tflen + 1;
204 
205 	/* If we're recording, write out the filename and file contents. */
206 	if (trace_record ())
207 		trace_write_packet (ttype, len, data, MDL);
208 
209 	status = new_parse(&cfile, -1, fbuf, flen, data, 0);
210 	if (status == ISC_R_SUCCESS || cfile != NULL) {
211 		if (ttype == trace_readleases_type)
212 			lease_file_subparse (cfile);
213 		else
214 			conf_file_subparse (cfile, root_group, ROOT_GROUP);
215 		end_parse (&cfile);
216 	}
217 
218 	/* Postconfiguration needs to be done after the config file
219 	   has been loaded. */
220 	if (!postconf_initialized && ttype == trace_readconf_type) {
221 		postconf_initialization (0);
222 		postconf_initialized = 1;
223 	}
224 
225 	if (!leaseconf_initialized && ttype == trace_readleases_type) {
226 		db_startup (0);
227 		leaseconf_initialized = 1;
228 		postdb_startup ();
229 	}
230 }
231 
232 void trace_conf_stop (trace_type_t *ttype) { }
233 #endif
234 
235 /* conf-file :== parameters declarations END_OF_FILE
236    parameters :== <nil> | parameter | parameters parameter
237    declarations :== <nil> | declaration | declarations declaration */
238 
239 isc_result_t conf_file_subparse (struct parse *cfile, struct group *group,
240 				 int group_type)
241 {
242 	const char *val;
243 	enum dhcp_token token;
244 	int declaration = 0;
245 	int status;
246 
247 	do {
248 		token = peek_token (&val, (unsigned *)0, cfile);
249 		if (token == END_OF_FILE)
250 			break;
251 		declaration = parse_statement (cfile, group, group_type,
252 					       (struct host_decl *)0,
253 					       declaration);
254 	} while (1);
255 	skip_token(&val, (unsigned *)0, cfile);
256 
257 	status = cfile->warnings_occurred ? DHCP_R_BADPARSE : ISC_R_SUCCESS;
258 	return status;
259 }
260 
261 /* lease-file :== lease-declarations END_OF_FILE
262    lease-statements :== <nil>
263    		     | lease-declaration
264 		     | lease-declarations lease-declaration */
265 
266 isc_result_t lease_file_subparse (struct parse *cfile)
267 {
268 	const char *val;
269 	enum dhcp_token token;
270 	isc_result_t status;
271 
272 	do {
273 		token = next_token (&val, (unsigned *)0, cfile);
274 		if (token == END_OF_FILE)
275 			break;
276 		if (token == LEASE) {
277 			struct lease *lease = (struct lease *)0;
278 			if (parse_lease_declaration (&lease, cfile)) {
279 				enter_lease (lease);
280 				lease_dereference (&lease, MDL);
281 			} else
282 				parse_warn (cfile,
283 					    "possibly corrupt lease file");
284 		} else if (token == IA_NA) {
285 			parse_ia_na_declaration(cfile);
286 		} else if (token == IA_TA) {
287 			parse_ia_ta_declaration(cfile);
288 		} else if (token == IA_PD) {
289 			parse_ia_pd_declaration(cfile);
290 		} else if (token == CLASS) {
291 			parse_class_declaration(0, cfile, root_group,
292 						CLASS_TYPE_CLASS);
293 		} else if (token == SUBCLASS) {
294 			parse_class_declaration(0, cfile, root_group,
295 						CLASS_TYPE_SUBCLASS);
296 		} else if (token == HOST) {
297 			parse_host_declaration (cfile, root_group);
298 		} else if (token == GROUP) {
299 			parse_group_declaration (cfile, root_group);
300 #if defined (FAILOVER_PROTOCOL)
301 		} else if (token == FAILOVER) {
302 			parse_failover_state_declaration
303 				(cfile, (dhcp_failover_state_t *)0);
304 #endif
305 #ifdef DHCPv6
306 		} else if (token == SERVER_DUID) {
307 			parse_server_duid(cfile);
308 #endif /* DHCPv6 */
309 		} else {
310 			log_error ("Corrupt lease file - possible data loss!");
311 			skip_to_semi (cfile);
312 		}
313 
314 	} while (1);
315 
316 	status = cfile->warnings_occurred ? DHCP_R_BADPARSE : ISC_R_SUCCESS;
317 	return status;
318 }
319 
320 /* statement :== parameter | declaration
321 
322    parameter :== DEFAULT_LEASE_TIME lease_time
323 	       | MAX_LEASE_TIME lease_time
324 	       | DYNAMIC_BOOTP_LEASE_CUTOFF date
325 	       | DYNAMIC_BOOTP_LEASE_LENGTH lease_time
326 	       | BOOT_UNKNOWN_CLIENTS boolean
327 	       | ONE_LEASE_PER_CLIENT boolean
328 	       | GET_LEASE_HOSTNAMES boolean
329 	       | USE_HOST_DECL_NAME boolean
330 	       | NEXT_SERVER ip-addr-or-hostname SEMI
331 	       | option_parameter
332 	       | SERVER-IDENTIFIER ip-addr-or-hostname SEMI
333 	       | FILENAME string-parameter
334 	       | SERVER_NAME string-parameter
335 	       | hardware-parameter
336 	       | fixed-address-parameter
337 	       | ALLOW allow-deny-keyword
338 	       | DENY allow-deny-keyword
339 	       | USE_LEASE_ADDR_FOR_DEFAULT_ROUTE boolean
340 	       | AUTHORITATIVE
341 	       | NOT AUTHORITATIVE
342 
343    declaration :== host-declaration
344 		 | group-declaration
345 		 | shared-network-declaration
346 		 | subnet-declaration
347 		 | VENDOR_CLASS class-declaration
348 		 | USER_CLASS class-declaration
349 		 | RANGE address-range-declaration */
350 
351 int parse_statement (cfile, group, type, host_decl, declaration)
352 	struct parse *cfile;
353 	struct group *group;
354 	int type;
355 	struct host_decl *host_decl;
356 	int declaration;
357 {
358 	enum dhcp_token token;
359 	const char *val;
360 	struct shared_network *share;
361 	char *n;
362 	struct hardware hardware;
363 	struct executable_statement *et, *ep;
364 	struct option *option = NULL;
365 	struct option_cache *cache;
366 	int lose;
367 	int known;
368 	isc_result_t status;
369 	unsigned code;
370 
371 	token = peek_token (&val, (unsigned *)0, cfile);
372 
373 	switch (token) {
374 	      case INCLUDE:
375 		skip_token(&val, (unsigned *)0, cfile);
376 		token = next_token (&val, (unsigned *)0, cfile);
377 		if (token != STRING) {
378 			parse_warn (cfile, "filename string expected.");
379 			skip_to_semi (cfile);
380 		} else {
381 			status = read_conf_file (val, group, type, 0);
382 			if (status != ISC_R_SUCCESS)
383 				parse_warn (cfile, "%s: bad parse.", val);
384 			parse_semi (cfile);
385 		}
386 		return 1;
387 
388 	      case HOST:
389 		skip_token(&val, (unsigned *)0, cfile);
390 		if (type != HOST_DECL && type != CLASS_DECL) {
391 			if (global_host_once &&
392 			    (type == SUBNET_DECL || type == SHARED_NET_DECL)) {
393 				global_host_once = 0;
394 				log_error("WARNING: Host declarations are "
395 					  "global.  They are not limited to "
396 					  "the scope you declared them in.");
397 			}
398 
399 			parse_host_declaration (cfile, group);
400 		} else {
401 			parse_warn (cfile,
402 				    "host declarations not allowed here.");
403 			skip_to_semi (cfile);
404 		}
405 		return 1;
406 
407 	      case GROUP:
408 		skip_token(&val, (unsigned *)0, cfile);
409 		if (type != HOST_DECL && type != CLASS_DECL)
410 			parse_group_declaration (cfile, group);
411 		else {
412 			parse_warn (cfile,
413 				    "group declarations not allowed here.");
414 			skip_to_semi (cfile);
415 		}
416 		return 1;
417 
418 	      case SHARED_NETWORK:
419 		skip_token(&val, (unsigned *)0, cfile);
420 		if (type == SHARED_NET_DECL ||
421 		    type == HOST_DECL ||
422 		    type == SUBNET_DECL ||
423 		    type == CLASS_DECL) {
424 			parse_warn (cfile, "shared-network parameters not %s.",
425 				    "allowed here");
426 			skip_to_semi (cfile);
427 			break;
428 		}
429 
430 		parse_shared_net_declaration (cfile, group);
431 		return 1;
432 
433 	      case SUBNET:
434 	      case SUBNET6:
435 		skip_token(&val, (unsigned *)0, cfile);
436 		if (type == HOST_DECL || type == SUBNET_DECL ||
437 		    type == CLASS_DECL) {
438 			parse_warn (cfile,
439 				    "subnet declarations not allowed here.");
440 			skip_to_semi (cfile);
441 			return 1;
442 		}
443 
444 		/* If we're in a subnet declaration, just do the parse. */
445 		if (group->shared_network != NULL) {
446 			if (token == SUBNET) {
447 				parse_subnet_declaration(cfile,
448 							 group->shared_network);
449 			} else {
450 				parse_subnet6_declaration(cfile,
451 							 group->shared_network);
452 			}
453 			break;
454 		}
455 
456 		/*
457 		 * Otherwise, cons up a fake shared network structure
458 		 * and populate it with the lone subnet...because the
459 		 * intention most likely is to refer to the entire link
460 		 * by shorthand, any configuration inside the subnet is
461 		 * actually placed in the shared-network's group.
462 		 */
463 
464 		share = NULL;
465 		status = shared_network_allocate (&share, MDL);
466 		if (status != ISC_R_SUCCESS)
467 			log_fatal ("Can't allocate shared subnet: %s",
468 				   isc_result_totext (status));
469 		if (!clone_group (&share -> group, group, MDL))
470 			log_fatal ("Can't allocate group for shared net");
471 		shared_network_reference (&share -> group -> shared_network,
472 					  share, MDL);
473 
474 		/*
475 		 * This is an implicit shared network, not explicit in
476 		 * the config.
477 		 */
478 		share->flags |= SHARED_IMPLICIT;
479 
480 		if (token == SUBNET) {
481 			parse_subnet_declaration(cfile, share);
482 		} else {
483 			parse_subnet6_declaration(cfile, share);
484 		}
485 
486 		/* share -> subnets is the subnet we just parsed. */
487 		if (share->subnets) {
488 			interface_reference(&share->interface,
489 					    share->subnets->interface,
490 					    MDL);
491 
492 			/* Make the shared network name from network number. */
493 			if (token == SUBNET) {
494 				n = piaddrmask(&share->subnets->net,
495 					       &share->subnets->netmask);
496 			} else {
497 				n = piaddrcidr(&share->subnets->net,
498 					       share->subnets->prefix_len);
499 			}
500 
501 			share->name = strdup(n);
502 
503 			if (share->name == NULL)
504 				log_fatal("Out of memory allocating default "
505 					  "shared network name (\"%s\").", n);
506 
507 			/* Copy the authoritative parameter from the subnet,
508 			   since there is no opportunity to declare it here. */
509 			share->group->authoritative =
510 				share->subnets->group->authoritative;
511 			enter_shared_network(share);
512 		}
513 		shared_network_dereference(&share, MDL);
514 		return 1;
515 
516 	      case VENDOR_CLASS:
517 		skip_token(&val, (unsigned *)0, cfile);
518 		if (type == CLASS_DECL) {
519 			parse_warn (cfile,
520 				    "class declarations not allowed here.");
521 			skip_to_semi (cfile);
522 			break;
523 		}
524 		parse_class_declaration(NULL, cfile, group, CLASS_TYPE_VENDOR);
525 		return 1;
526 
527 	      case USER_CLASS:
528 		skip_token(&val, (unsigned *)0, cfile);
529 		if (type == CLASS_DECL) {
530 			parse_warn (cfile,
531 				    "class declarations not allowed here.");
532 			skip_to_semi (cfile);
533 			break;
534 		}
535 		parse_class_declaration(NULL, cfile, group, CLASS_TYPE_USER);
536 		return 1;
537 
538 	      case CLASS:
539 		skip_token(&val, (unsigned *)0, cfile);
540 		if (type == CLASS_DECL) {
541 			parse_warn (cfile,
542 				    "class declarations not allowed here.");
543 			skip_to_semi (cfile);
544 			break;
545 		}
546 		parse_class_declaration(NULL, cfile, group, CLASS_TYPE_CLASS);
547 		return 1;
548 
549 	      case SUBCLASS:
550 		skip_token(&val, (unsigned *)0, cfile);
551 		if (type == CLASS_DECL) {
552 			parse_warn (cfile,
553 				    "class declarations not allowed here.");
554 			skip_to_semi (cfile);
555 			break;
556 		}
557 		parse_class_declaration(NULL, cfile, group,
558 					CLASS_TYPE_SUBCLASS);
559 		return 1;
560 
561 	      case HARDWARE:
562 		skip_token(&val, (unsigned *)0, cfile);
563 		memset (&hardware, 0, sizeof hardware);
564 		if (host_decl && memcmp(&hardware, &(host_decl->interface),
565 					sizeof(hardware)) != 0) {
566 			parse_warn(cfile, "Host %s hardware address already "
567 					  "configured.", host_decl->name);
568 			break;
569 		}
570 
571 		parse_hardware_param (cfile, &hardware);
572 		if (host_decl)
573 			host_decl -> interface = hardware;
574 		else
575 			parse_warn (cfile, "hardware address parameter %s",
576 				    "not allowed here.");
577 		break;
578 
579 	      case FIXED_ADDR:
580 	      case FIXED_ADDR6:
581 		skip_token(&val, NULL, cfile);
582 		cache = NULL;
583 		if (parse_fixed_addr_param(&cache, cfile, token)) {
584 			if (host_decl) {
585 				if (host_decl->fixed_addr) {
586 					option_cache_dereference(&cache, MDL);
587 					parse_warn(cfile,
588 						   "Only one fixed address "
589 						   "declaration per host.");
590 				} else {
591 					host_decl->fixed_addr = cache;
592 				}
593 			} else {
594 				parse_warn(cfile,
595 					   "fixed-address parameter not "
596 					   "allowed here.");
597 				option_cache_dereference(&cache, MDL);
598 			}
599 		}
600 		break;
601 
602 	      case POOL:
603 		skip_token(&val, (unsigned *)0, cfile);
604 		if (type == POOL_DECL) {
605 			parse_warn (cfile, "pool declared within pool.");
606 			skip_to_semi(cfile);
607 		} else if (type != SUBNET_DECL && type != SHARED_NET_DECL) {
608 			parse_warn (cfile, "pool declared outside of network");
609 			skip_to_semi(cfile);
610 		} else
611 			parse_pool_statement (cfile, group, type);
612 
613 		return declaration;
614 
615 	      case RANGE:
616 		skip_token(&val, (unsigned *)0, cfile);
617 		if (type != SUBNET_DECL || !group -> subnet) {
618 			parse_warn (cfile,
619 				    "range declaration not allowed here.");
620 			skip_to_semi (cfile);
621 			return declaration;
622 		}
623 		parse_address_range (cfile, group, type, (struct pool *)0,
624 				     (struct lease **)0);
625 		return declaration;
626 
627 #ifdef DHCPv6
628 	      case RANGE6:
629 		skip_token(NULL, NULL, cfile);
630 	        if ((type != SUBNET_DECL) || (group->subnet == NULL)) {
631 			parse_warn (cfile,
632 				    "range6 declaration not allowed here.");
633 			skip_to_semi(cfile);
634 			return declaration;
635 		}
636 	      	parse_address_range6(cfile, group, NULL);
637 		return declaration;
638 
639 	      case PREFIX6:
640 		skip_token(NULL, NULL, cfile);
641 		if ((type != SUBNET_DECL) || (group->subnet == NULL)) {
642 			parse_warn (cfile,
643 				    "prefix6 declaration not allowed here.");
644 			skip_to_semi(cfile);
645 			return declaration;
646 		}
647 	      	parse_prefix6(cfile, group, NULL);
648 		return declaration;
649 
650 	      case FIXED_PREFIX6:
651 		skip_token(&val, NULL, cfile);
652 		if (!host_decl) {
653 			parse_warn (cfile,
654 				    "fixed-prefix6 declaration not "
655 				    "allowed here.");
656 			skip_to_semi(cfile);
657 			break;
658 		}
659 		parse_fixed_prefix6(cfile, host_decl);
660 		break;
661 
662 	      case POOL6:
663 		skip_token(&val, NULL, cfile);
664 		if (type == POOL_DECL) {
665 			parse_warn (cfile, "pool declared within pool.");
666 			skip_to_semi(cfile);
667 		} else if (type != SUBNET_DECL) {
668 			parse_warn (cfile, "pool declared outside of network");
669 			skip_to_semi(cfile);
670 		} else
671 			parse_pool6_statement (cfile, group, type);
672 
673 		return declaration;
674 
675 #endif /* DHCPv6 */
676 
677 	      case TOKEN_NOT:
678 		skip_token(&val, (unsigned *)0, cfile);
679 		token = next_token (&val, (unsigned *)0, cfile);
680 		switch (token) {
681 		      case AUTHORITATIVE:
682 			group -> authoritative = 0;
683 			goto authoritative;
684 		      default:
685 			parse_warn (cfile, "expecting assertion");
686 			skip_to_semi (cfile);
687 			break;
688 		}
689 		break;
690 	      case AUTHORITATIVE:
691 		skip_token(&val, (unsigned *)0, cfile);
692 		group -> authoritative = 1;
693 	      authoritative:
694 		if (type == HOST_DECL)
695 			parse_warn (cfile, "authority makes no sense here.");
696 		parse_semi (cfile);
697 		break;
698 
699 		/* "server-identifier" is a special hack, equivalent to
700 		   "option dhcp-server-identifier". */
701 	      case SERVER_IDENTIFIER:
702 		code = DHO_DHCP_SERVER_IDENTIFIER;
703 		if (!option_code_hash_lookup(&option, dhcp_universe.code_hash,
704 					     &code, 0, MDL))
705 			log_fatal("Server identifier not in hash (%s:%d).",
706 				  MDL);
707 		skip_token(&val, (unsigned *)0, cfile);
708 		goto finish_option;
709 
710 	      case OPTION:
711 		skip_token(&val, (unsigned *)0, cfile);
712 		token = peek_token (&val, (unsigned *)0, cfile);
713 		if (token == SPACE) {
714 			if (type != ROOT_GROUP) {
715 				parse_warn (cfile,
716 					    "option space definitions %s",
717 					    "may not be scoped.");
718 				skip_to_semi (cfile);
719 				break;
720 			}
721 			parse_option_space_decl (cfile);
722 			return declaration;
723 		}
724 
725 		known = 0;
726 		status = parse_option_name(cfile, 1, &known, &option);
727 		if (status == ISC_R_SUCCESS) {
728 			token = peek_token (&val, (unsigned *)0, cfile);
729 			if (token == CODE) {
730 				if (type != ROOT_GROUP) {
731 					parse_warn (cfile,
732 						    "option definitions%s",
733 						    " may not be scoped.");
734 					skip_to_semi (cfile);
735 					option_dereference(&option, MDL);
736 					break;
737 				}
738 				skip_token(&val, (unsigned *)0, cfile);
739 
740 				/*
741 				 * If the option was known, remove it from the
742 				 * code and name hashes before redefining it.
743 				 */
744 				if (known) {
745 					option_name_hash_delete(
746 						option->universe->name_hash,
747 							option->name, 0, MDL);
748 					option_code_hash_delete(
749 						option->universe->code_hash,
750 							&option->code, 0, MDL);
751 				}
752 
753 				parse_option_code_definition(cfile, option);
754 				option_dereference(&option, MDL);
755 				return declaration;
756 			}
757 
758 			/* If this wasn't an option code definition, don't
759 			   allow an unknown option. */
760 			if (!known) {
761 				parse_warn (cfile, "unknown option %s.%s",
762 					    option -> universe -> name,
763 					    option -> name);
764 				skip_to_semi (cfile);
765 				option_dereference(&option, MDL);
766 				return declaration;
767 			}
768 
769 		      finish_option:
770 			et = (struct executable_statement *)0;
771 			if (!parse_option_statement
772 				(&et, cfile, 1, option,
773 				 supersede_option_statement))
774 				return declaration;
775 			option_dereference(&option, MDL);
776 			goto insert_statement;
777 		} else
778 			return declaration;
779 
780 		break;
781 
782 	      case FAILOVER:
783 		if (type != ROOT_GROUP && type != SHARED_NET_DECL) {
784 			parse_warn (cfile, "failover peers may only be %s",
785 				    "defined in shared-network");
786 			log_error ("declarations and the outer scope.");
787 			skip_to_semi (cfile);
788 			break;
789 		}
790 		token = next_token (&val, (unsigned *)0, cfile);
791 #if defined (FAILOVER_PROTOCOL)
792 		parse_failover_peer (cfile, group, type);
793 #else
794 		parse_warn (cfile, "No failover support.");
795 		skip_to_semi (cfile);
796 #endif
797 		break;
798 
799 #ifdef DHCPv6
800 	      case SERVER_DUID:
801 		parse_server_duid_conf(cfile);
802 		break;
803 #endif /* DHCPv6 */
804 
805 	      default:
806 		et = (struct executable_statement *)0;
807 		lose = 0;
808 		if (!parse_executable_statement (&et, cfile, &lose,
809 						 context_any)) {
810 			if (!lose) {
811 				if (declaration)
812 					parse_warn (cfile,
813 						    "expecting a declaration");
814 				else
815 					parse_warn (cfile,
816 						    "expecting a parameter %s",
817 						    "or declaration");
818 				skip_to_semi (cfile);
819 			}
820 			return declaration;
821 		}
822 		if (!et)
823 			return declaration;
824 	      insert_statement:
825 		if (group -> statements) {
826 			int multi = 0;
827 
828 			/* If this set of statements is only referenced
829 			   by this group, just add the current statement
830 			   to the end of the chain. */
831 			for (ep = group -> statements; ep -> next;
832 			     ep = ep -> next)
833 				if (ep -> refcnt > 1) /* XXX */
834 					multi = 1;
835 			if (!multi) {
836 				executable_statement_reference (&ep -> next,
837 								et, MDL);
838 				executable_statement_dereference (&et, MDL);
839 				return declaration;
840 			}
841 
842 			/* Otherwise, make a parent chain, and put the
843 			   current group statements first and the new
844 			   statement in the next pointer. */
845 			ep = (struct executable_statement *)0;
846 			if (!executable_statement_allocate (&ep, MDL))
847 				log_fatal ("No memory for statements.");
848 			ep -> op = statements_statement;
849 			executable_statement_reference (&ep -> data.statements,
850 							group -> statements,
851 							MDL);
852 			executable_statement_reference (&ep -> next, et, MDL);
853 			executable_statement_dereference (&group -> statements,
854 							  MDL);
855 			executable_statement_reference (&group -> statements,
856 							ep, MDL);
857 			executable_statement_dereference (&ep, MDL);
858 		} else {
859 			executable_statement_reference (&group -> statements,
860 							et, MDL);
861 		}
862 		executable_statement_dereference (&et, MDL);
863 		return declaration;
864 	}
865 
866 	return 0;
867 }
868 
869 #if defined (FAILOVER_PROTOCOL)
870 void parse_failover_peer (cfile, group, type)
871 	struct parse *cfile;
872 	struct group *group;
873 	int type;
874 {
875 	enum dhcp_token token;
876 	const char *val;
877 	dhcp_failover_state_t *peer;
878 	u_int32_t *tp;
879 	char *name;
880 	u_int32_t split;
881 	u_int8_t hba [32];
882 	unsigned hba_len = sizeof hba;
883 	int i;
884 	struct expression *expr;
885 	isc_result_t status;
886 	dhcp_failover_config_t *cp;
887 
888 	token = next_token (&val, (unsigned *)0, cfile);
889 	if (token != PEER) {
890 		parse_warn (cfile, "expecting \"peer\"");
891 		skip_to_semi (cfile);
892 		return;
893 	}
894 
895 	token = next_token (&val, (unsigned *)0, cfile);
896 	if (is_identifier (token) || token == STRING) {
897 		name = dmalloc (strlen (val) + 1, MDL);
898 		if (!name)
899 			log_fatal ("no memory for peer name %s", name);
900 		strcpy (name, val);
901 	} else {
902 		parse_warn (cfile, "expecting failover peer name.");
903 		skip_to_semi (cfile);
904 		return;
905 	}
906 
907 	/* See if there's a peer declaration by this name. */
908 	peer = (dhcp_failover_state_t *)0;
909 	find_failover_peer (&peer, name, MDL);
910 
911 	token = next_token (&val, (unsigned *)0, cfile);
912 	if (token == SEMI) {
913 		dfree (name, MDL);
914 		if (type != SHARED_NET_DECL)
915 			parse_warn (cfile, "failover peer reference not %s",
916 				    "in shared-network declaration");
917 		else {
918 			if (!peer) {
919 				parse_warn (cfile, "reference to unknown%s%s",
920 					    " failover peer ", name);
921 				return;
922 			}
923 			dhcp_failover_state_reference
924 				(&group -> shared_network -> failover_peer,
925 				 peer, MDL);
926 		}
927 		dhcp_failover_state_dereference (&peer, MDL);
928 		return;
929 	} else if (token == STATE) {
930 		if (!peer) {
931 			parse_warn (cfile, "state declaration for unknown%s%s",
932 				    " failover peer ", name);
933 			return;
934 		}
935 		parse_failover_state_declaration (cfile, peer);
936 		dhcp_failover_state_dereference (&peer, MDL);
937 		return;
938 	} else if (token != LBRACE) {
939 		parse_warn (cfile, "expecting left brace");
940 		skip_to_semi (cfile);
941 	}
942 
943 	/* Make sure this isn't a redeclaration. */
944 	if (peer) {
945 		parse_warn (cfile, "redeclaration of failover peer %s", name);
946 		skip_to_rbrace (cfile, 1);
947 		dhcp_failover_state_dereference (&peer, MDL);
948 		return;
949 	}
950 
951 	status = dhcp_failover_state_allocate (&peer, MDL);
952 	if (status != ISC_R_SUCCESS)
953 		log_fatal ("Can't allocate failover peer %s: %s",
954 			   name, isc_result_totext (status));
955 
956 	/* Save the name. */
957 	peer -> name = name;
958 
959 	do {
960 		cp = &peer -> me;
961 	      peer:
962 		token = next_token (&val, (unsigned *)0, cfile);
963 		switch (token) {
964 		      case RBRACE:
965 			break;
966 
967 		      case PRIMARY:
968 			peer -> i_am = primary;
969 			break;
970 
971 		      case SECONDARY:
972 			peer -> i_am = secondary;
973 			if (peer -> hba)
974 				parse_warn (cfile,
975 					    "secondary may not define %s",
976 					    "load balance settings.");
977 			break;
978 
979 		      case PEER:
980 			cp = &peer -> partner;
981 			goto peer;
982 
983 		      case ADDRESS:
984 			expr = (struct expression *)0;
985 			if (!parse_ip_addr_or_hostname (&expr, cfile, 0)) {
986 				skip_to_rbrace (cfile, 1);
987 				dhcp_failover_state_dereference (&peer, MDL);
988 				return;
989 			}
990 			option_cache (&cp -> address,
991 				      (struct data_string *)0, expr,
992 				      (struct option *)0, MDL);
993 			expression_dereference (&expr, MDL);
994 			break;
995 
996 		      case PORT:
997 			token = next_token (&val, (unsigned *)0, cfile);
998 			if (token != NUMBER) {
999 				parse_warn (cfile, "expecting number");
1000 				skip_to_rbrace (cfile, 1);
1001 			}
1002 			cp -> port = atoi (val);
1003 			break;
1004 
1005 		      case MAX_LEASE_MISBALANCE:
1006 			tp = &peer->max_lease_misbalance;
1007 			goto parse_idle;
1008 
1009 		      case MAX_LEASE_OWNERSHIP:
1010 			tp = &peer->max_lease_ownership;
1011 			goto parse_idle;
1012 
1013 		      case MAX_BALANCE:
1014 			tp = &peer->max_balance;
1015 			goto parse_idle;
1016 
1017 		      case MIN_BALANCE:
1018 			tp = &peer->min_balance;
1019 			goto parse_idle;
1020 
1021 		      case AUTO_PARTNER_DOWN:
1022 			tp = &peer->auto_partner_down;
1023 			goto parse_idle;
1024 
1025 		      case MAX_RESPONSE_DELAY:
1026 			tp = &cp -> max_response_delay;
1027 		      parse_idle:
1028 			token = next_token (&val, (unsigned *)0, cfile);
1029 			if (token != NUMBER) {
1030 				parse_warn (cfile, "expecting number.");
1031 				skip_to_rbrace (cfile, 1);
1032 				dhcp_failover_state_dereference (&peer, MDL);
1033 				return;
1034 			}
1035 			*tp = atoi (val);
1036 			break;
1037 
1038 		      case MAX_UNACKED_UPDATES:
1039 			tp = &cp -> max_flying_updates;
1040 			goto parse_idle;
1041 
1042 		      case MCLT:
1043 			tp = &peer -> mclt;
1044 			goto parse_idle;
1045 
1046 		      case HBA:
1047 			hba_len = 32;
1048 			if (peer -> i_am == secondary)
1049 				parse_warn (cfile,
1050 					    "secondary may not define %s",
1051 					    "load balance settings.");
1052 			if (!parse_numeric_aggregate (cfile, hba, &hba_len,
1053 						      COLON, 16, 8)) {
1054 				skip_to_rbrace (cfile, 1);
1055 				dhcp_failover_state_dereference (&peer, MDL);
1056 				return;
1057 			}
1058 			if (hba_len != 32) {
1059 				parse_warn (cfile,
1060 					    "HBA must be exactly 32 bytes.");
1061 				break;
1062 			}
1063 		      make_hba:
1064 			peer -> hba = dmalloc (32, MDL);
1065 			if (!peer -> hba) {
1066 				dfree (peer -> name, MDL);
1067 				dfree (peer, MDL);
1068 			}
1069 			memcpy (peer -> hba, hba, 32);
1070 			break;
1071 
1072 		      case SPLIT:
1073 			token = next_token (&val, (unsigned *)0, cfile);
1074 			if (peer -> i_am == secondary)
1075 				parse_warn (cfile,
1076 					    "secondary may not define %s",
1077 					    "load balance settings.");
1078 			if (token != NUMBER) {
1079 				parse_warn (cfile, "expecting number");
1080 				skip_to_rbrace (cfile, 1);
1081 				dhcp_failover_state_dereference (&peer, MDL);
1082 				return;
1083 			}
1084 			split = atoi (val);
1085 			if (split > 255) {
1086 				parse_warn (cfile, "split must be < 256");
1087 			} else {
1088 				memset (hba, 0, sizeof hba);
1089 				for (i = 0; i < split; i++) {
1090 					if (i < split)
1091 						hba [i / 8] |= (1 << (i & 7));
1092 				}
1093 				goto make_hba;
1094 			}
1095 			break;
1096 
1097 		      case LOAD:
1098 			token = next_token (&val, (unsigned *)0, cfile);
1099 			if (token != BALANCE) {
1100 				parse_warn (cfile, "expecting 'balance'");
1101 			      badload:
1102 				skip_to_rbrace (cfile, 1);
1103 				break;
1104 			}
1105 			token = next_token (&val, (unsigned *)0, cfile);
1106 			if (token != TOKEN_MAX) {
1107 				parse_warn (cfile, "expecting 'max'");
1108 				goto badload;
1109 			}
1110 			token = next_token (&val, (unsigned *)0, cfile);
1111 			if (token != SECONDS) {
1112 				parse_warn (cfile, "expecting 'secs'");
1113 				goto badload;
1114 			}
1115 			token = next_token (&val, (unsigned *)0, cfile);
1116 			if (token != NUMBER) {
1117 				parse_warn (cfile, "expecting number");
1118 				goto badload;
1119 			}
1120 			peer -> load_balance_max_secs = atoi (val);
1121 			break;
1122 
1123 		      default:
1124 			parse_warn (cfile,
1125 				    "invalid statement in peer declaration");
1126 			skip_to_rbrace (cfile, 1);
1127 			dhcp_failover_state_dereference (&peer, MDL);
1128 			return;
1129 		}
1130 		if (token != RBRACE && !parse_semi (cfile)) {
1131 			skip_to_rbrace (cfile, 1);
1132 			dhcp_failover_state_dereference (&peer, MDL);
1133 			return;
1134 		}
1135 	} while (token != RBRACE);
1136 
1137 	/* me.address can be null; the failover link initiate code tries to
1138 	 * derive a reasonable address to use.
1139 	 */
1140 	if (!peer -> partner.address)
1141 		parse_warn (cfile, "peer address may not be omitted");
1142 
1143 	if (!peer->me.port)
1144 		peer->me.port = DEFAULT_FAILOVER_PORT;
1145 	if (!peer->partner.port)
1146 		peer->partner.port = DEFAULT_FAILOVER_PORT;
1147 
1148 	if (peer -> i_am == primary) {
1149 	    if (!peer -> hba) {
1150 		parse_warn (cfile,
1151 			    "primary failover server must have hba or split.");
1152 	    } else if (!peer -> mclt) {
1153 		parse_warn (cfile,
1154 			    "primary failover server must have mclt.");
1155 	    }
1156 	}
1157 
1158 	if (!peer->max_lease_misbalance)
1159 		peer->max_lease_misbalance = DEFAULT_MAX_LEASE_MISBALANCE;
1160 	if (!peer->max_lease_ownership)
1161 		peer->max_lease_ownership = DEFAULT_MAX_LEASE_OWNERSHIP;
1162 	if (!peer->max_balance)
1163 		peer->max_balance = DEFAULT_MAX_BALANCE_TIME;
1164 	if (!peer->min_balance)
1165 		peer->min_balance = DEFAULT_MIN_BALANCE_TIME;
1166 	if (!peer->me.max_flying_updates)
1167 		peer->me.max_flying_updates = DEFAULT_MAX_FLYING_UPDATES;
1168 	if (!peer->me.max_response_delay)
1169 		peer->me.max_response_delay = DEFAULT_MAX_RESPONSE_DELAY;
1170 
1171 	if (type == SHARED_NET_DECL)
1172 		group->shared_network->failover_peer = peer;
1173 
1174 	/* Set the initial state. */
1175 	if (peer -> i_am == primary) {
1176 		peer -> me.state = recover;
1177 		peer -> me.stos = cur_time;
1178 		peer -> partner.state = unknown_state;
1179 		peer -> partner.stos = cur_time;
1180 	} else {
1181 		peer -> me.state = recover;
1182 		peer -> me.stos = cur_time;
1183 		peer -> partner.state = unknown_state;
1184 		peer -> partner.stos = cur_time;
1185 	}
1186 
1187 	status = enter_failover_peer (peer);
1188 	if (status != ISC_R_SUCCESS)
1189 		parse_warn (cfile, "failover peer %s: %s",
1190 			    peer -> name, isc_result_totext (status));
1191 	dhcp_failover_state_dereference (&peer, MDL);
1192 }
1193 
1194 void parse_failover_state_declaration (struct parse *cfile,
1195 				       dhcp_failover_state_t *peer)
1196 {
1197 	enum dhcp_token token;
1198 	const char *val;
1199 	char *name;
1200 	dhcp_failover_state_t *state;
1201 	dhcp_failover_config_t *cp;
1202 
1203 	if (!peer) {
1204 		token = next_token (&val, (unsigned *)0, cfile);
1205 		if (token != PEER) {
1206 			parse_warn (cfile, "expecting \"peer\"");
1207 			skip_to_semi (cfile);
1208 			return;
1209 		}
1210 
1211 		token = next_token (&val, (unsigned *)0, cfile);
1212 		if (is_identifier (token) || token == STRING) {
1213 			name = dmalloc (strlen (val) + 1, MDL);
1214 			if (!name)
1215 				log_fatal ("failover peer name %s: no memory",
1216 					   name);
1217 			strcpy (name, val);
1218 		} else {
1219 			parse_warn (cfile, "expecting failover peer name.");
1220 			skip_to_semi (cfile);
1221 			return;
1222 		}
1223 
1224 		/* See if there's a peer declaration by this name. */
1225 		state = (dhcp_failover_state_t *)0;
1226 		find_failover_peer (&state, name, MDL);
1227 		if (!state) {
1228 			parse_warn (cfile, "unknown failover peer: %s", name);
1229 			skip_to_semi (cfile);
1230 			return;
1231 		}
1232 
1233 		token = next_token (&val, (unsigned *)0, cfile);
1234 		if (token != STATE) {
1235 			parse_warn (cfile, "expecting 'state'");
1236 			if (token != SEMI)
1237 				skip_to_semi (cfile);
1238 			return;
1239 		}
1240 	} else {
1241 		state = (dhcp_failover_state_t *)0;
1242 		dhcp_failover_state_reference (&state, peer, MDL);
1243 	}
1244 	token = next_token (&val, (unsigned *)0, cfile);
1245 	if (token != LBRACE) {
1246 		parse_warn (cfile, "expecting left brace");
1247 		if (token != SEMI)
1248 			skip_to_semi (cfile);
1249 		dhcp_failover_state_dereference (&state, MDL);
1250 		return;
1251 	}
1252 	do {
1253 		token = next_token (&val, (unsigned *)0, cfile);
1254 		switch (token) {
1255 		      case RBRACE:
1256 			break;
1257 		      case MY:
1258 			cp = &state -> me;
1259 		      do_state:
1260 			token = next_token (&val, (unsigned *)0, cfile);
1261 			if (token != STATE) {
1262 				parse_warn (cfile, "expecting 'state'");
1263 				goto bogus;
1264 			}
1265 			parse_failover_state (cfile,
1266 					      &cp -> state, &cp -> stos);
1267 			break;
1268 
1269 		      case PARTNER:
1270 			cp = &state -> partner;
1271 			goto do_state;
1272 
1273 		      case MCLT:
1274 			if (state -> i_am == primary) {
1275 				parse_warn (cfile,
1276 					    "mclt not valid for primary");
1277 				goto bogus;
1278 			}
1279 			token = next_token (&val, (unsigned *)0, cfile);
1280 			if (token != NUMBER) {
1281 				parse_warn (cfile, "expecting a number.");
1282 				goto bogus;
1283 			}
1284 			state -> mclt = atoi (val);
1285 			parse_semi (cfile);
1286 			break;
1287 
1288 		      default:
1289 			parse_warn (cfile, "expecting state setting.");
1290 		      bogus:
1291 			skip_to_rbrace (cfile, 1);
1292 			dhcp_failover_state_dereference (&state, MDL);
1293 			return;
1294 		}
1295 	} while (token != RBRACE);
1296 	dhcp_failover_state_dereference (&state, MDL);
1297 }
1298 
1299 void parse_failover_state (cfile, state, stos)
1300 	struct parse *cfile;
1301 	enum failover_state *state;
1302 	TIME *stos;
1303 {
1304 	enum dhcp_token token;
1305 	const char *val;
1306 	enum failover_state state_in;
1307 	TIME stos_in;
1308 
1309 	token = next_token (&val, (unsigned *)0, cfile);
1310 	switch (token) {
1311 	      case UNKNOWN_STATE:
1312 		state_in = unknown_state;
1313 		break;
1314 
1315 	      case PARTNER_DOWN:
1316 		state_in = partner_down;
1317 		break;
1318 
1319 	      case NORMAL:
1320 		state_in = normal;
1321 		break;
1322 
1323 	      case COMMUNICATIONS_INTERRUPTED:
1324 		state_in = communications_interrupted;
1325 		break;
1326 
1327 	      case CONFLICT_DONE:
1328 		state_in = conflict_done;
1329 		break;
1330 
1331 	      case RESOLUTION_INTERRUPTED:
1332 		state_in = resolution_interrupted;
1333 		break;
1334 
1335 	      case POTENTIAL_CONFLICT:
1336 		state_in = potential_conflict;
1337 		break;
1338 
1339 	      case RECOVER:
1340 		state_in = recover;
1341 		break;
1342 
1343 	      case RECOVER_WAIT:
1344 		state_in = recover_wait;
1345 		break;
1346 
1347 	      case RECOVER_DONE:
1348 		state_in = recover_done;
1349 		break;
1350 
1351 	      case SHUTDOWN:
1352 		state_in = shut_down;
1353 		break;
1354 
1355 	      case PAUSED:
1356 		state_in = paused;
1357 		break;
1358 
1359 	      case STARTUP:
1360 		state_in = startup;
1361 		break;
1362 
1363 	      default:
1364 		parse_warn (cfile, "unknown failover state");
1365 		skip_to_semi (cfile);
1366 		return;
1367 	}
1368 
1369 	token = next_token (&val, (unsigned *)0, cfile);
1370 	if (token == SEMI) {
1371 		stos_in = cur_time;
1372 	} else {
1373 		if (token != AT) {
1374 			parse_warn (cfile, "expecting \"at\"");
1375 			skip_to_semi (cfile);
1376 			return;
1377 		}
1378 
1379 		stos_in = parse_date (cfile);
1380 		if (!stos_in)
1381 			return;
1382 	}
1383 
1384 	/* Now that we've apparently gotten a clean parse, we
1385 	   can trust that this is a state that was fully committed to
1386 	   disk, so we can install it. */
1387 	*stos = stos_in;
1388 	*state = state_in;
1389 }
1390 #endif /* defined (FAILOVER_PROTOCOL) */
1391 
1392 /*!
1393  *
1394  * \brief Parse allow and deny statements
1395  *
1396  * This function handles the common processing code for permit and deny
1397  * statements in the parse_pool_statement and parse_pool6_statement functions.
1398  * It reads in the configuration and constructs a new permit structure that it
1399  * attachs to the permit_head passed in from the caller.
1400  *
1401  * The allow or deny token should already be consumed, this function expects
1402  * one of the following:
1403  *   known-clients;
1404  *   unknown-clients;
1405  *   known clients;
1406  *   unknown clients;
1407  *   authenticated clients;
1408  *   unauthenticated clients;
1409  *   all clients;
1410  *   dynamic bootp clients;
1411  *   members of <class name>;
1412  *   after <date>;
1413  *
1414  * \param[in] cfile       = the configuration file being parsed
1415  * \param[in] permit_head = the head of the permit list (permit or prohibit)
1416  *			    to which to attach the newly created  permit structure
1417  * \param[in] is_allow    = 1 if this is being invoked for an allow statement
1418  *			  = 0 if this is being invoked for a deny statement
1419  * \param[in] valid_from   = pointers to the time values from the enclosing pool
1420  * \param[in] valid_until    or pond structure. One of them will be filled in if
1421  *			     the configuration includes an "after" clause
1422  */
1423 
1424 static void get_permit(struct parse *cfile, struct permit **permit_head,
1425 	        int is_allow, TIME *valid_from, TIME *valid_until)
1426 {
1427 	enum dhcp_token token;
1428 	struct permit *permit;
1429 	const char *val;
1430 	int need_clients = 1;
1431 	TIME t;
1432 
1433 	/* Create our permit structure */
1434 	permit = new_permit(MDL);
1435 	if (!permit)
1436 		log_fatal ("no memory for permit");
1437 
1438 	token = next_token(&val, NULL, cfile);
1439 	switch (token) {
1440 	      case UNKNOWN:
1441 		permit->type = permit_unknown_clients;
1442 		break;
1443 
1444 	      case KNOWN_CLIENTS:
1445 		need_clients = 0;
1446 		permit->type = permit_known_clients;
1447 		break;
1448 
1449 	      case UNKNOWN_CLIENTS:
1450 		need_clients = 0;
1451 		permit->type = permit_unknown_clients;
1452 		break;
1453 
1454 	      case KNOWN:
1455 		permit->type = permit_known_clients;
1456 		break;
1457 
1458 	      case AUTHENTICATED:
1459 		permit->type = permit_authenticated_clients;
1460 		break;
1461 
1462 	      case UNAUTHENTICATED:
1463 		permit->type = permit_unauthenticated_clients;
1464 		break;
1465 
1466 	      case ALL:
1467 		permit->type = permit_all_clients;
1468 		break;
1469 
1470 	      case DYNAMIC:
1471 		permit->type = permit_dynamic_bootp_clients;
1472 		if (next_token (&val, NULL, cfile) != TOKEN_BOOTP) {
1473 			parse_warn (cfile, "expecting \"bootp\"");
1474 			skip_to_semi (cfile);
1475 			free_permit (permit, MDL);
1476 			return;
1477 		}
1478 		break;
1479 
1480 	      case MEMBERS:
1481 		need_clients = 0;
1482 		if (next_token (&val, NULL, cfile) != OF) {
1483 			parse_warn (cfile, "expecting \"of\"");
1484 			skip_to_semi (cfile);
1485 			free_permit (permit, MDL);
1486 			return;
1487 		}
1488 		if (next_token (&val, NULL, cfile) != STRING) {
1489 			parse_warn (cfile, "expecting class name.");
1490 			skip_to_semi (cfile);
1491 			free_permit (permit, MDL);
1492 			return;
1493 		}
1494 		permit->type = permit_class;
1495 		permit->class = NULL;
1496 		find_class(&permit->class, val, MDL);
1497 		if (!permit->class)
1498 			parse_warn(cfile, "no such class: %s", val);
1499 		break;
1500 
1501 	      case AFTER:
1502 		need_clients = 0;
1503 		if (*valid_from || *valid_until) {
1504 			parse_warn(cfile, "duplicate \"after\" clause.");
1505 			skip_to_semi(cfile);
1506 			free_permit(permit, MDL);
1507 			return;
1508 		}
1509 		t = parse_date_core(cfile);
1510 		permit->type = permit_after;
1511 		permit->after = t;
1512 		if (is_allow) {
1513 			*valid_from = t;
1514 		} else {
1515 			*valid_until = t;
1516 		}
1517 		break;
1518 
1519 	      default:
1520 		parse_warn (cfile, "expecting permit type.");
1521 		skip_to_semi (cfile);
1522 		free_permit (permit, MDL);
1523 		return;
1524 	}
1525 
1526 	/*
1527 	 * The need_clients flag is set if we are expecting the
1528 	 * CLIENTS token
1529 	 */
1530 	if ((need_clients != 0)  &&
1531 	    (next_token (&val, NULL, cfile) != CLIENTS)) {
1532 		parse_warn (cfile, "expecting \"clients\"");
1533 		skip_to_semi (cfile);
1534 		free_permit (permit, MDL);
1535 		return;
1536 	}
1537 
1538 	while (*permit_head)
1539 		permit_head = &((*permit_head)->next);
1540 	*permit_head = permit;
1541 	parse_semi (cfile);
1542 
1543 	return;
1544 }
1545 
1546 /* Permit_list_match returns 1 if every element of the permit list in lhs
1547    also appears in rhs.   Note that this doesn't by itself mean that the
1548    two lists are equal - to check for equality, permit_list_match has to
1549    return 1 with (list1, list2) and with (list2, list1). */
1550 
1551 int permit_list_match (struct permit *lhs, struct permit *rhs)
1552 {
1553 	struct permit *plp, *prp;
1554 	int matched;
1555 
1556 	if (!lhs)
1557 		return 1;
1558 	if (!rhs)
1559 		return 0;
1560 	for (plp = lhs; plp; plp = plp -> next) {
1561 		matched = 0;
1562 		for (prp = rhs; prp; prp = prp -> next) {
1563 			if (prp -> type == plp -> type &&
1564 			    (prp -> type != permit_class ||
1565 			     prp -> class == plp -> class)) {
1566 				matched = 1;
1567 				break;
1568 			}
1569 		}
1570 		if (!matched)
1571 			return 0;
1572 	}
1573 	return 1;
1574 }
1575 
1576 /*!
1577  *
1578  * \brief Parse a pool statement
1579  *
1580  * Pool statements are used to group declarations and permit & deny information
1581  * with a specific address range.  They must be declared within a shared network
1582  * or subnet and there may be multiple pools withing a shared network or subnet.
1583  * Each pool may have a different set of permit or deny options.
1584  *
1585  * \param[in] cfile = the configuration file being parsed
1586  * \param[in] group = the group structure for this pool
1587  * \param[in] type  = the type of the enclosing statement.  This must be
1588  *		      SHARED_NET_DECL or SUBNET_DECL for this function.
1589  *
1590  * \return
1591  * void - This function either parses the statement and updates the structures
1592  *        or it generates an error message and possible halts the program if
1593  *        it encounters a problem.
1594  */
1595 void parse_pool_statement (cfile, group, type)
1596 	struct parse *cfile;
1597 	struct group *group;
1598 	int type;
1599 {
1600 	enum dhcp_token token;
1601 	const char *val;
1602 	int done = 0;
1603 	struct pool *pool, **p, *pp;
1604 	int declaration = 0;
1605 	isc_result_t status;
1606 	struct lease *lpchain = NULL, *lp;
1607 
1608 	pool = NULL;
1609 	status = pool_allocate(&pool, MDL);
1610 	if (status != ISC_R_SUCCESS)
1611 		log_fatal ("no memory for pool: %s",
1612 			   isc_result_totext (status));
1613 
1614 	if (type == SUBNET_DECL)
1615 		shared_network_reference(&pool->shared_network,
1616 					 group->subnet->shared_network,
1617 					 MDL);
1618 	else if (type == SHARED_NET_DECL)
1619 		shared_network_reference(&pool->shared_network,
1620 					 group->shared_network, MDL);
1621 	else {
1622 		parse_warn(cfile, "Dynamic pools are only valid inside "
1623 				  "subnet or shared-network statements.");
1624 		skip_to_semi(cfile);
1625 		return;
1626 	}
1627 
1628 	if (pool->shared_network == NULL ||
1629             !clone_group(&pool->group, pool->shared_network->group, MDL))
1630 		log_fatal("can't clone pool group.");
1631 
1632 #if defined (FAILOVER_PROTOCOL)
1633 	/* Inherit the failover peer from the shared network. */
1634 	if (pool->shared_network->failover_peer)
1635 	    dhcp_failover_state_reference
1636 		    (&pool->failover_peer,
1637 		     pool->shared_network->failover_peer, MDL);
1638 #endif
1639 
1640 	if (!parse_lbrace(cfile)) {
1641 		pool_dereference(&pool, MDL);
1642 		return;
1643 	}
1644 
1645 	do {
1646 		token = peek_token(&val, NULL, cfile);
1647 		switch (token) {
1648 		      case TOKEN_NO:
1649 			skip_token(&val, NULL, cfile);
1650 			token = next_token(&val, NULL, cfile);
1651 			if (token != FAILOVER ||
1652 			    (token = next_token(&val, NULL, cfile)) != PEER) {
1653 				parse_warn(cfile,
1654 					   "expecting \"failover peer\".");
1655 				skip_to_semi(cfile);
1656 				continue;
1657 			}
1658 #if defined (FAILOVER_PROTOCOL)
1659 			if (pool->failover_peer)
1660 				dhcp_failover_state_dereference
1661 					(&pool->failover_peer, MDL);
1662 #endif
1663 			break;
1664 
1665 #if defined (FAILOVER_PROTOCOL)
1666 		      case FAILOVER:
1667 			skip_token(&val, NULL, cfile);
1668 			token = next_token (&val, NULL, cfile);
1669 			if (token != PEER) {
1670 				parse_warn(cfile, "expecting 'peer'.");
1671 				skip_to_semi(cfile);
1672 				break;
1673 			}
1674 			token = next_token(&val, NULL, cfile);
1675 			if (token != STRING) {
1676 				parse_warn(cfile, "expecting string.");
1677 				skip_to_semi(cfile);
1678 				break;
1679 			}
1680 			if (pool->failover_peer)
1681 				dhcp_failover_state_dereference
1682 					(&pool->failover_peer, MDL);
1683 			status = find_failover_peer(&pool->failover_peer,
1684 						    val, MDL);
1685 			if (status != ISC_R_SUCCESS)
1686 				parse_warn(cfile,
1687 					   "failover peer %s: %s", val,
1688 					   isc_result_totext (status));
1689 			else
1690 				pool->failover_peer->pool_count++;
1691 			parse_semi(cfile);
1692 			break;
1693 #endif
1694 
1695 		      case RANGE:
1696 			skip_token(&val, NULL, cfile);
1697 			parse_address_range (cfile, group, type,
1698 					     pool, &lpchain);
1699 			break;
1700 		      case ALLOW:
1701 			skip_token(&val, NULL, cfile);
1702 			get_permit(cfile, &pool->permit_list, 1,
1703 				   &pool->valid_from, &pool->valid_until);
1704 			break;
1705 
1706 		      case DENY:
1707 			skip_token(&val, NULL, cfile);
1708 			get_permit(cfile, &pool->prohibit_list, 0,
1709 				   &pool->valid_from, &pool->valid_until);
1710 			break;
1711 
1712 		      case RBRACE:
1713 			skip_token(&val, NULL, cfile);
1714 			done = 1;
1715 			break;
1716 
1717 		      case END_OF_FILE:
1718 			/*
1719 			 * We can get to END_OF_FILE if, for instance,
1720 			 * the parse_statement() reads all available tokens
1721 			 * and leaves us at the end.
1722 			 */
1723 			parse_warn(cfile, "unexpected end of file");
1724 			goto cleanup;
1725 
1726 		      default:
1727 			declaration = parse_statement(cfile, pool->group,
1728 						      POOL_DECL, NULL,
1729 						       declaration);
1730 			break;
1731 		}
1732 	} while (!done);
1733 
1734 	/* See if there's already a pool into which we can merge this one. */
1735 	for (pp = pool->shared_network->pools; pp; pp = pp->next) {
1736 		if (pp->group->statements != pool->group->statements)
1737 			continue;
1738 #if defined (FAILOVER_PROTOCOL)
1739 		if (pool->failover_peer != pp->failover_peer)
1740 			continue;
1741 #endif
1742 		if (!permit_list_match(pp->permit_list,
1743 				       pool->permit_list) ||
1744 		    !permit_list_match(pool->permit_list,
1745 				       pp->permit_list) ||
1746 		    !permit_list_match(pp->prohibit_list,
1747 				       pool->prohibit_list) ||
1748 		    !permit_list_match(pool->prohibit_list,
1749 				       pp->prohibit_list))
1750 			continue;
1751 
1752 		/* Okay, we can merge these two pools.    All we have to
1753 		   do is fix up the leases, which all point to their pool. */
1754 		for (lp = lpchain; lp; lp = lp->next) {
1755 			pool_dereference(&lp->pool, MDL);
1756 			pool_reference(&lp->pool, pp, MDL);
1757 		}
1758 		break;
1759 	}
1760 
1761 	/* If we didn't succeed in merging this pool into another, put
1762 	   it on the list. */
1763 	if (!pp) {
1764 		p = &pool->shared_network->pools;
1765 		for (; *p; p = &((*p)->next))
1766 			;
1767 		pool_reference(p, pool, MDL);
1768 	}
1769 
1770 	/* Don't allow a pool declaration with no addresses, since it is
1771 	   probably a configuration error. */
1772 	if (!lpchain) {
1773 		parse_warn(cfile, "Pool declaration with no address range.");
1774 		log_error("Pool declarations must always contain at least");
1775 		log_error("one range statement.");
1776 	}
1777 
1778 cleanup:
1779 	/* Dereference the lease chain. */
1780 	lp = NULL;
1781 	while (lpchain) {
1782 		lease_reference(&lp, lpchain, MDL);
1783 		lease_dereference(&lpchain, MDL);
1784 		if (lp->next) {
1785 			lease_reference(&lpchain, lp->next, MDL);
1786 			lease_dereference(&lp->next, MDL);
1787 			lease_dereference(&lp, MDL);
1788 		}
1789 	}
1790 	pool_dereference(&pool, MDL);
1791 }
1792 
1793 /* Expect a left brace; if there isn't one, skip over the rest of the
1794    statement and return zero; otherwise, return 1. */
1795 
1796 int parse_lbrace (cfile)
1797 	struct parse *cfile;
1798 {
1799 	enum dhcp_token token;
1800 	const char *val;
1801 
1802 	token = next_token (&val, (unsigned *)0, cfile);
1803 	if (token != LBRACE) {
1804 		parse_warn (cfile, "expecting left brace.");
1805 		skip_to_semi (cfile);
1806 		return 0;
1807 	}
1808 	return 1;
1809 }
1810 
1811 
1812 /* host-declaration :== hostname RBRACE parameters declarations LBRACE */
1813 
1814 void parse_host_declaration (cfile, group)
1815 	struct parse *cfile;
1816 	struct group *group;
1817 {
1818 	const char *val;
1819 	enum dhcp_token token;
1820 	struct host_decl *host;
1821 	char *name;
1822 	int declaration = 0;
1823 	int dynamicp = 0;
1824 	int deleted = 0;
1825 	isc_result_t status;
1826 	int known;
1827 	struct option *option;
1828 	struct expression *expr = NULL;
1829 
1830 	name = parse_host_name (cfile);
1831 	if (!name) {
1832 		parse_warn (cfile, "expecting a name for host declaration.");
1833 		skip_to_semi (cfile);
1834 		return;
1835 	}
1836 
1837 	host = (struct host_decl *)0;
1838 	status = host_allocate (&host, MDL);
1839 	if (status != ISC_R_SUCCESS)
1840 		log_fatal ("can't allocate host decl struct %s: %s",
1841 			   name, isc_result_totext (status));
1842 	host -> name = name;
1843 	if (!clone_group (&host -> group, group, MDL)) {
1844 		log_fatal ("can't clone group for host %s", name);
1845 	      boom:
1846 		host_dereference (&host, MDL);
1847 		return;
1848 	}
1849 
1850 	if (!parse_lbrace (cfile))
1851 		goto boom;
1852 
1853 	do {
1854 		token = peek_token (&val, (unsigned *)0, cfile);
1855 		if (token == RBRACE) {
1856 			skip_token(&val, (unsigned *)0, cfile);
1857 			break;
1858 		}
1859 		if (token == END_OF_FILE) {
1860 			skip_token(&val, (unsigned *)0, cfile);
1861 			parse_warn (cfile, "unexpected end of file");
1862 			break;
1863 		}
1864 		/* If the host declaration was created by the server,
1865 		   remember to save it. */
1866 		if (token == DYNAMIC) {
1867 			dynamicp = 1;
1868 			skip_token(&val, (unsigned *)0, cfile);
1869 			if (!parse_semi (cfile))
1870 				break;
1871 			continue;
1872 		}
1873 		/* If the host declaration was created by the server,
1874 		   remember to save it. */
1875 		if (token == TOKEN_DELETED) {
1876 			deleted = 1;
1877 			skip_token(&val, (unsigned *)0, cfile);
1878 			if (!parse_semi (cfile))
1879 				break;
1880 			continue;
1881 		}
1882 
1883 		if (token == GROUP) {
1884 			struct group_object *go;
1885 			skip_token(&val, (unsigned *)0, cfile);
1886 			token = next_token (&val, (unsigned *)0, cfile);
1887 			if (token != STRING && !is_identifier (token)) {
1888 				parse_warn (cfile,
1889 					    "expecting string or identifier.");
1890 				skip_to_rbrace (cfile, 1);
1891 				break;
1892 			}
1893 			go = (struct group_object *)0;
1894 			if (!group_hash_lookup (&go, group_name_hash,
1895 						val, strlen (val), MDL)) {
1896 			    parse_warn (cfile, "unknown group %s in host %s",
1897 					val, host -> name);
1898 			} else {
1899 				if (host -> named_group)
1900 					group_object_dereference
1901 						(&host -> named_group, MDL);
1902 				group_object_reference (&host -> named_group,
1903 							go, MDL);
1904 				group_object_dereference (&go, MDL);
1905 			}
1906 			if (!parse_semi (cfile))
1907 				break;
1908 			continue;
1909 		}
1910 
1911 		if (token == UID) {
1912 			const char *s;
1913 			unsigned char *t = 0;
1914 			unsigned len;
1915 
1916 			skip_token(&val, (unsigned *)0, cfile);
1917 			data_string_forget (&host -> client_identifier, MDL);
1918 
1919 			if (host->client_identifier.len != 0) {
1920 				parse_warn(cfile, "Host %s already has a "
1921 						  "client identifier.",
1922 					   host->name);
1923 				break;
1924 			}
1925 
1926 			/* See if it's a string or a cshl. */
1927 			token = peek_token (&val, (unsigned *)0, cfile);
1928 			if (token == STRING) {
1929 				skip_token(&val, &len, cfile);
1930 				s = val;
1931 				host -> client_identifier.terminated = 1;
1932 			} else {
1933 				len = 0;
1934 				t = parse_numeric_aggregate
1935 					(cfile,
1936 					 (unsigned char *)0, &len, ':', 16, 8);
1937 				if (!t) {
1938 					parse_warn (cfile,
1939 						    "expecting hex list.");
1940 					skip_to_semi (cfile);
1941 				}
1942 				s = (const char *)t;
1943 			}
1944 			if (!buffer_allocate
1945 			    (&host -> client_identifier.buffer,
1946 			     len + host -> client_identifier.terminated, MDL))
1947 				log_fatal ("no memory for uid for host %s.",
1948 					   host -> name);
1949 			host -> client_identifier.data =
1950 				host -> client_identifier.buffer -> data;
1951 			host -> client_identifier.len = len;
1952 			memcpy (host -> client_identifier.buffer -> data, s,
1953 				len + host -> client_identifier.terminated);
1954 			if (t)
1955 				dfree (t, MDL);
1956 
1957 			if (!parse_semi (cfile))
1958 				break;
1959 			continue;
1960 		}
1961 
1962 		if (token == HOST_IDENTIFIER) {
1963 			if (host->host_id_option != NULL) {
1964 				parse_warn(cfile,
1965 					   "only one host-identifier allowed "
1966 					   "per host");
1967 				skip_to_rbrace(cfile, 1);
1968 				break;
1969 			}
1970 	      		skip_token(&val, NULL, cfile);
1971 			token = next_token(&val, NULL, cfile);
1972 			if (token == V6RELOPT) {
1973 				token = next_token(&val, NULL, cfile);
1974 				if (token != NUMBER) {
1975 					parse_warn(cfile,
1976 						   "host-identifier v6relopt "
1977 						   "must have a number");
1978 					skip_to_rbrace(cfile, 1);
1979 					break;
1980 				}
1981 				host->relays = atoi(val);
1982 				if (host->relays < 0) {
1983 					parse_warn(cfile,
1984 						   "host-identifier v6relopt "
1985 						   "must have a number >= 0");
1986 					skip_to_rbrace(cfile, 1);
1987 					break;
1988 				}
1989 			} else if (token != OPTION) {
1990 				parse_warn(cfile,
1991 					   "host-identifier must be an option"
1992 					   " or v6relopt");
1993 				skip_to_rbrace(cfile, 1);
1994 				break;
1995 			}
1996 			known = 0;
1997 			option = NULL;
1998 			status = parse_option_name(cfile, 1, &known, &option);
1999 			if ((status != ISC_R_SUCCESS) || (option == NULL)) {
2000 				break;
2001 			}
2002 			if (!known) {
2003 				parse_warn(cfile, "unknown option %s.%s",
2004 					   option->universe->name,
2005 					   option->name);
2006 				skip_to_rbrace(cfile, 1);
2007 				break;
2008 			}
2009 
2010                         if (! parse_option_data(&expr, cfile, 1, option)) {
2011 		        	skip_to_rbrace(cfile, 1);
2012 		        	option_dereference(&option, MDL);
2013 		        	break;
2014                         }
2015 
2016 			if (!parse_semi(cfile)) {
2017 				skip_to_rbrace(cfile, 1);
2018 				expression_dereference(&expr, MDL);
2019 				option_dereference(&option, MDL);
2020 				break;
2021 			}
2022 
2023 			option_reference(&host->host_id_option, option, MDL);
2024 			option_dereference(&option, MDL);
2025 			data_string_copy(&host->host_id,
2026 					 &expr->data.const_data, MDL);
2027 			expression_dereference(&expr, MDL);
2028 			continue;
2029 		}
2030 
2031 		declaration = parse_statement(cfile, host->group, HOST_DECL,
2032                                               host, declaration);
2033 	} while (1);
2034 
2035 	if (deleted) {
2036 		struct host_decl *hp = (struct host_decl *)0;
2037 		if (host_hash_lookup (&hp, host_name_hash,
2038 				      (unsigned char *)host -> name,
2039 				      strlen (host -> name), MDL)) {
2040 			delete_host (hp, 0);
2041 			host_dereference (&hp, MDL);
2042 		}
2043 	} else {
2044 		if (host -> named_group && host -> named_group -> group) {
2045 			if (host -> group -> statements ||
2046 			    (host -> group -> authoritative !=
2047 			     host -> named_group -> group -> authoritative)) {
2048 				if (host -> group -> next)
2049 				    group_dereference (&host -> group -> next,
2050 						       MDL);
2051 				group_reference (&host -> group -> next,
2052 						 host -> named_group -> group,
2053 						 MDL);
2054 			} else {
2055 				group_dereference (&host -> group, MDL);
2056 				group_reference (&host -> group,
2057 						 host -> named_group -> group,
2058 						 MDL);
2059 			}
2060 		}
2061 
2062 		if (dynamicp)
2063 			host -> flags |= HOST_DECL_DYNAMIC;
2064 		else
2065 			host -> flags |= HOST_DECL_STATIC;
2066 
2067 		status = enter_host (host, dynamicp, 0);
2068 		if (status != ISC_R_SUCCESS)
2069 			parse_warn (cfile, "host %s: %s", host -> name,
2070 				    isc_result_totext (status));
2071 	}
2072 	host_dereference (&host, MDL);
2073 }
2074 
2075 /* class-declaration :== STRING LBRACE parameters declarations RBRACE
2076 */
2077 
2078 int parse_class_declaration (cp, cfile, group, type)
2079 	struct class **cp;
2080 	struct parse *cfile;
2081 	struct group *group;
2082 	int type;
2083 {
2084 	const char *val;
2085 	enum dhcp_token token;
2086 	struct class *class = NULL, *pc = NULL;
2087 	int declaration = 0;
2088 	int lose = 0;
2089 	struct data_string data;
2090 	char *name;
2091 	const char *tname;
2092 	struct executable_statement *stmt = NULL;
2093 	int new = 1;
2094 	isc_result_t status = ISC_R_FAILURE;
2095 	int matchedonce = 0;
2096 	int submatchedonce = 0;
2097 	unsigned code;
2098 
2099 	token = next_token (&val, NULL, cfile);
2100 	if (token != STRING) {
2101 		parse_warn (cfile, "Expecting class name");
2102 		skip_to_semi (cfile);
2103 		return 0;
2104 	}
2105 
2106 	/* See if there's already a class with the specified name. */
2107 	find_class (&pc, val, MDL);
2108 
2109 	/* If it is a class, we're updating it.  If it's any of the other
2110 	 * types (subclass, vendor or user class), the named class is a
2111 	 * reference to the parent class so its mandatory.
2112 	 */
2113 	if (pc && (type == CLASS_TYPE_CLASS)) {
2114 		class_reference(&class, pc, MDL);
2115 		new = 0;
2116 		class_dereference(&pc, MDL);
2117 	} else if (!pc && (type != CLASS_TYPE_CLASS)) {
2118 		parse_warn(cfile, "no class named %s", val);
2119 		skip_to_semi(cfile);
2120 		return 0;
2121 	}
2122 
2123 	/* The old vendor-class and user-class declarations had an implicit
2124 	   match.   We don't do the implicit match anymore.   Instead, for
2125 	   backward compatibility, we have an implicit-vendor-class and an
2126 	   implicit-user-class.   vendor-class and user-class declarations
2127 	   are turned into subclasses of the implicit classes, and the
2128 	   submatch expression of the implicit classes extracts the contents of
2129 	   the vendor class or user class. */
2130 	if ((type == CLASS_TYPE_VENDOR) || (type == CLASS_TYPE_USER)) {
2131 		data.len = strlen (val);
2132 		data.buffer = NULL;
2133 		if (!buffer_allocate (&data.buffer, data.len + 1, MDL))
2134 			log_fatal ("no memory for class name.");
2135 		data.data = &data.buffer -> data [0];
2136 		data.terminated = 1;
2137 
2138 		tname = type ? "implicit-vendor-class" : "implicit-user-class";
2139 	} else if (type == CLASS_TYPE_CLASS) {
2140 		tname = val;
2141 	} else {
2142 		tname = NULL;
2143 	}
2144 
2145 	if (tname) {
2146 		name = dmalloc (strlen (tname) + 1, MDL);
2147 		if (!name)
2148 			log_fatal ("No memory for class name %s.", tname);
2149 		strcpy (name, val);
2150 	} else
2151 		name = NULL;
2152 
2153 	/* If this is a straight subclass, parse the hash string. */
2154 	if (type == CLASS_TYPE_SUBCLASS) {
2155 		token = peek_token (&val, NULL, cfile);
2156 		if (token == STRING) {
2157 			skip_token(&val, &data.len, cfile);
2158 			data.buffer = NULL;
2159 
2160 			if (!buffer_allocate (&data.buffer,
2161 					      data.len + 1, MDL)) {
2162 				if (pc)
2163 					class_dereference (&pc, MDL);
2164 
2165 				return 0;
2166 			}
2167 			data.terminated = 1;
2168 			data.data = &data.buffer -> data [0];
2169 			memcpy ((char *)data.buffer -> data, val,
2170 				data.len + 1);
2171 		} else if (token == NUMBER_OR_NAME || token == NUMBER) {
2172 			memset (&data, 0, sizeof data);
2173 			if (!parse_cshl (&data, cfile)) {
2174 				if (pc)
2175 					class_dereference (&pc, MDL);
2176 				return 0;
2177 			}
2178 		} else {
2179 			parse_warn (cfile, "Expecting string or hex list.");
2180 			if (pc)
2181 				class_dereference (&pc, MDL);
2182 			return 0;
2183 		}
2184 	}
2185 
2186 	/* See if there's already a class in the hash table matching the
2187 	   hash data. */
2188 	if (type != CLASS_TYPE_CLASS)
2189 		class_hash_lookup (&class, pc -> hash,
2190 				   (const char *)data.data, data.len, MDL);
2191 
2192 	/* If we didn't find an existing class, allocate a new one. */
2193 	if (!class) {
2194 		/* Allocate the class structure... */
2195 		if (type == CLASS_TYPE_SUBCLASS) {
2196 			status = subclass_allocate (&class, MDL);
2197 		} else {
2198 			status = class_allocate (&class, MDL);
2199 		}
2200 		if (pc) {
2201 			group_reference (&class -> group, pc -> group, MDL);
2202 			class_reference (&class -> superclass, pc, MDL);
2203 			class -> lease_limit = pc -> lease_limit;
2204 			if (class -> lease_limit) {
2205 				class -> billed_leases =
2206 					dmalloc (class -> lease_limit *
2207 						 sizeof (struct lease *), MDL);
2208 				if (!class -> billed_leases)
2209 					log_fatal ("no memory for billing");
2210 				memset (class -> billed_leases, 0,
2211 					(class -> lease_limit *
2212 					 sizeof (struct lease *)));
2213 			}
2214 			data_string_copy (&class -> hash_string, &data, MDL);
2215 			if (!pc -> hash &&
2216 			    !class_new_hash (&pc->hash, SCLASS_HASH_SIZE, MDL))
2217 				log_fatal ("No memory for subclass hash.");
2218 			class_hash_add (pc -> hash,
2219 					(const char *)class -> hash_string.data,
2220 					class -> hash_string.len,
2221 					(void *)class, MDL);
2222 		} else {
2223 			if (class->group)
2224 				group_dereference(&class->group, MDL);
2225 			if (!clone_group (&class -> group, group, MDL))
2226 				log_fatal ("no memory to clone class group.");
2227 		}
2228 
2229 		/* If this is an implicit vendor or user class, add a
2230 		   statement that causes the vendor or user class ID to
2231 		   be sent back in the reply. */
2232 		if (type == CLASS_TYPE_VENDOR || type == CLASS_TYPE_USER) {
2233 			stmt = NULL;
2234 			if (!executable_statement_allocate (&stmt, MDL))
2235 				log_fatal ("no memory for class statement.");
2236 			stmt -> op = supersede_option_statement;
2237 			if (option_cache_allocate (&stmt -> data.option,
2238 						   MDL)) {
2239 				stmt -> data.option -> data = data;
2240 				code = (type == CLASS_TYPE_VENDOR)
2241 					? DHO_VENDOR_CLASS_IDENTIFIER
2242 					: DHO_USER_CLASS;
2243 				option_code_hash_lookup(
2244 						&stmt->data.option->option,
2245 							dhcp_universe.code_hash,
2246 							&code, 0, MDL);
2247 			}
2248 			class -> statements = stmt;
2249 		}
2250 
2251 		/* Save the name, if there is one. */
2252 		if (class->name != NULL)
2253 			dfree(class->name, MDL);
2254 		class->name = name;
2255 	}
2256 
2257 	if (type != CLASS_TYPE_CLASS)
2258 		data_string_forget(&data, MDL);
2259 
2260 	/* Spawned classes don't have to have their own settings. */
2261 	if (class -> superclass) {
2262 		token = peek_token (&val, NULL, cfile);
2263 		if (token == SEMI) {
2264 			skip_token(&val, NULL, cfile);
2265 
2266 			if (cp)
2267 				status = class_reference (cp, class, MDL);
2268 			class_dereference (&class, MDL);
2269 			if (pc)
2270 				class_dereference (&pc, MDL);
2271 			return cp ? (status == ISC_R_SUCCESS) : 1;
2272 		}
2273 		/* Give the subclass its own group. */
2274 		if (!clone_group (&class -> group, class -> group, MDL))
2275 			log_fatal ("can't clone class group.");
2276 
2277 	}
2278 
2279 	if (!parse_lbrace (cfile)) {
2280 		class_dereference (&class, MDL);
2281 		if (pc)
2282 			class_dereference (&pc, MDL);
2283 		return 0;
2284 	}
2285 
2286 	do {
2287 		token = peek_token (&val, NULL, cfile);
2288 		if (token == RBRACE) {
2289 			skip_token(&val, NULL, cfile);
2290 			break;
2291 		} else if (token == END_OF_FILE) {
2292 			skip_token(&val, NULL, cfile);
2293 			parse_warn (cfile, "unexpected end of file");
2294 			break;
2295 		} else if (token == DYNAMIC) {
2296 			class->flags |= CLASS_DECL_DYNAMIC;
2297 			skip_token(&val, NULL, cfile);
2298 			if (!parse_semi (cfile))
2299 				break;
2300 			continue;
2301 		} else if (token == TOKEN_DELETED) {
2302 			class->flags |= CLASS_DECL_DELETED;
2303 			skip_token(&val, NULL, cfile);
2304 			if (!parse_semi (cfile))
2305 				break;
2306 			continue;
2307 		} else if (token == MATCH) {
2308 			if (pc) {
2309 				parse_warn (cfile,
2310 					    "invalid match in subclass.");
2311 				skip_to_semi (cfile);
2312 				break;
2313 			}
2314 			skip_token(&val, NULL, cfile);
2315 			token = peek_token (&val, NULL, cfile);
2316 			if (token != IF)
2317 				goto submatch;
2318 			skip_token(&val, NULL, cfile);
2319 			if (matchedonce) {
2320 				parse_warn(cfile, "A class may only have "
2321 						  "one 'match if' clause.");
2322 				skip_to_semi(cfile);
2323 				break;
2324 			}
2325 			matchedonce = 1;
2326 			if (class->expr)
2327 				expression_dereference(&class->expr, MDL);
2328 			if (!parse_boolean_expression (&class->expr, cfile,
2329 						       &lose)) {
2330 				if (!lose) {
2331 					parse_warn (cfile,
2332 						    "expecting boolean expr.");
2333 					skip_to_semi (cfile);
2334 				}
2335 			} else {
2336 #if defined (DEBUG_EXPRESSION_PARSE)
2337 				print_expression ("class match",
2338 						  class -> expr);
2339 #endif
2340 				parse_semi (cfile);
2341 			}
2342 		} else if (token == SPAWN) {
2343 			skip_token(&val, NULL, cfile);
2344 			if (pc) {
2345 				parse_warn (cfile,
2346 					    "invalid spawn in subclass.");
2347 				skip_to_semi (cfile);
2348 				break;
2349 			}
2350 			class -> spawning = 1;
2351 			token = next_token (&val, NULL, cfile);
2352 			if (token != WITH) {
2353 				parse_warn (cfile,
2354 					    "expecting with after spawn");
2355 				skip_to_semi (cfile);
2356 				break;
2357 			}
2358 		      submatch:
2359 			if (submatchedonce) {
2360 				parse_warn (cfile,
2361 					    "can't override existing %s.",
2362 					    "submatch/spawn");
2363 				skip_to_semi (cfile);
2364 				break;
2365 			}
2366 			submatchedonce = 1;
2367 			if (class->submatch)
2368 				expression_dereference(&class->submatch, MDL);
2369 			if (!parse_data_expression (&class -> submatch,
2370 						    cfile, &lose)) {
2371 				if (!lose) {
2372 					parse_warn (cfile,
2373 						    "expecting data expr.");
2374 					skip_to_semi (cfile);
2375 				}
2376 			} else {
2377 #if defined (DEBUG_EXPRESSION_PARSE)
2378 				print_expression ("class submatch",
2379 						  class -> submatch);
2380 #endif
2381 				parse_semi (cfile);
2382 			}
2383 		} else if (token == LEASE) {
2384 			skip_token(&val, NULL, cfile);
2385 			token = next_token (&val, NULL, cfile);
2386 			if (token != LIMIT) {
2387 				parse_warn (cfile, "expecting \"limit\"");
2388 				if (token != SEMI)
2389 					skip_to_semi (cfile);
2390 				break;
2391 			}
2392 			token = next_token (&val, NULL, cfile);
2393 			if (token != NUMBER) {
2394 				parse_warn (cfile, "expecting a number");
2395 				if (token != SEMI)
2396 					skip_to_semi (cfile);
2397 				break;
2398 			}
2399 			class -> lease_limit = atoi (val);
2400 			if (class->billed_leases)
2401 				dfree(class->billed_leases, MDL);
2402 			class -> billed_leases =
2403 				dmalloc (class -> lease_limit *
2404 					 sizeof (struct lease *), MDL);
2405 			if (!class -> billed_leases)
2406 				log_fatal ("no memory for billed leases.");
2407 			memset (class -> billed_leases, 0,
2408 				(class -> lease_limit *
2409 				 sizeof (struct lease *)));
2410 			have_billing_classes = 1;
2411 			parse_semi (cfile);
2412 		} else {
2413 			declaration = parse_statement (cfile, class -> group,
2414 						       CLASS_DECL, NULL,
2415 						       declaration);
2416 		}
2417 	} while (1);
2418 
2419 	if (class->flags & CLASS_DECL_DELETED) {
2420 		if (type == CLASS_TYPE_CLASS) {
2421 			struct class *theclass = NULL;
2422 
2423 			status = find_class(&theclass, class->name, MDL);
2424 			if (status == ISC_R_SUCCESS) {
2425 				delete_class(theclass, 0);
2426 				class_dereference(&theclass, MDL);
2427 			}
2428 		} else {
2429 			class_hash_delete(pc->hash,
2430 					  (char *)class->hash_string.data,
2431 					  class->hash_string.len, MDL);
2432 		}
2433 	} else if (type == CLASS_TYPE_CLASS && new) {
2434 		if (!collections -> classes)
2435 			class_reference (&collections -> classes, class, MDL);
2436 		else {
2437 			struct class *c;
2438 			for (c = collections -> classes;
2439 			     c -> nic; c = c -> nic)
2440 				;
2441 			class_reference (&c -> nic, class, MDL);
2442 		}
2443 	}
2444 
2445 	if (cp)				/* should always be 0??? */
2446 		status = class_reference (cp, class, MDL);
2447 	class_dereference (&class, MDL);
2448 	if (pc)
2449 		class_dereference (&pc, MDL);
2450 	return cp ? (status == ISC_R_SUCCESS) : 1;
2451 }
2452 
2453 /* shared-network-declaration :==
2454 			hostname LBRACE declarations parameters RBRACE */
2455 
2456 void parse_shared_net_declaration (cfile, group)
2457 	struct parse *cfile;
2458 	struct group *group;
2459 {
2460 	const char *val;
2461 	enum dhcp_token token;
2462 	struct shared_network *share;
2463 	char *name;
2464 	int declaration = 0;
2465 	isc_result_t status;
2466 
2467 	share = (struct shared_network *)0;
2468 	status = shared_network_allocate (&share, MDL);
2469 	if (status != ISC_R_SUCCESS)
2470 		log_fatal ("Can't allocate shared subnet: %s",
2471 			   isc_result_totext (status));
2472 	if (clone_group (&share -> group, group, MDL) == 0) {
2473 		log_fatal ("Can't clone group for shared net");
2474 	}
2475 	shared_network_reference (&share -> group -> shared_network,
2476 				  share, MDL);
2477 
2478 	/* Get the name of the shared network... */
2479 	token = peek_token (&val, (unsigned *)0, cfile);
2480 	if (token == STRING) {
2481 		skip_token(&val, (unsigned *)0, cfile);
2482 
2483 		if (val [0] == 0) {
2484 			parse_warn (cfile, "zero-length shared network name");
2485 			val = "<no-name-given>";
2486 		}
2487 		name = dmalloc (strlen (val) + 1, MDL);
2488 		if (!name)
2489 			log_fatal ("no memory for shared network name");
2490 		strcpy (name, val);
2491 	} else {
2492 		name = parse_host_name (cfile);
2493 		if (!name) {
2494 			parse_warn (cfile,
2495 				     "expecting a name for shared-network");
2496 			skip_to_semi (cfile);
2497 			shared_network_dereference (&share, MDL);
2498 			return;
2499 		}
2500 	}
2501 	share -> name = name;
2502 
2503 	if (!parse_lbrace (cfile)) {
2504 		shared_network_dereference (&share, MDL);
2505 		return;
2506 	}
2507 
2508 	do {
2509 		token = peek_token (&val, (unsigned *)0, cfile);
2510 		if (token == RBRACE) {
2511 			skip_token(&val, (unsigned *)0, cfile);
2512 			if (!share -> subnets)
2513 				parse_warn (cfile,
2514 					    "empty shared-network decl");
2515 			else
2516 				enter_shared_network (share);
2517 			shared_network_dereference (&share, MDL);
2518 			return;
2519 		} else if (token == END_OF_FILE) {
2520 			skip_token(&val, (unsigned *)0, cfile);
2521 			parse_warn (cfile, "unexpected end of file");
2522 			break;
2523 		} else if (token == INTERFACE) {
2524 			skip_token(&val, (unsigned *)0, cfile);
2525 			token = next_token (&val, (unsigned *)0, cfile);
2526 			new_shared_network_interface (cfile, share, val);
2527 			if (!parse_semi (cfile))
2528 				break;
2529 			continue;
2530 		}
2531 
2532 		declaration = parse_statement (cfile, share -> group,
2533 					       SHARED_NET_DECL,
2534 					       (struct host_decl *)0,
2535 					       declaration);
2536 	} while (1);
2537 	shared_network_dereference (&share, MDL);
2538 }
2539 
2540 
2541 static int
2542 common_subnet_parsing(struct parse *cfile,
2543 		      struct shared_network *share,
2544 		      struct subnet *subnet) {
2545 	enum dhcp_token token;
2546 	struct subnet *t, *u;
2547 	const char *val;
2548 	int declaration = 0;
2549 
2550 	enter_subnet(subnet);
2551 
2552 	if (!parse_lbrace(cfile)) {
2553 		subnet_dereference(&subnet, MDL);
2554 		return 0;
2555 	}
2556 
2557 	do {
2558 		token = peek_token(&val, NULL, cfile);
2559 		if (token == RBRACE) {
2560 			skip_token(&val, NULL, cfile);
2561 			break;
2562 		} else if (token == END_OF_FILE) {
2563 			skip_token(&val, NULL, cfile);
2564 			parse_warn (cfile, "unexpected end of file");
2565 			break;
2566 		} else if (token == INTERFACE) {
2567 			skip_token(&val, NULL, cfile);
2568 			token = next_token(&val, NULL, cfile);
2569 			new_shared_network_interface(cfile, share, val);
2570 			if (!parse_semi(cfile))
2571 				break;
2572 			continue;
2573 		}
2574 		declaration = parse_statement(cfile, subnet->group,
2575 					      SUBNET_DECL,
2576 					      NULL,
2577 					      declaration);
2578 	} while (1);
2579 
2580 	/* Add the subnet to the list of subnets in this shared net. */
2581 	if (share->subnets == NULL) {
2582 		subnet_reference(&share->subnets, subnet, MDL);
2583 	} else {
2584 		u = NULL;
2585 		for (t = share->subnets; t->next_sibling; t = t->next_sibling) {
2586 			if (subnet_inner_than(subnet, t, 0)) {
2587 				subnet_reference(&subnet->next_sibling, t, MDL);
2588 				if (u) {
2589 					subnet_dereference(&u->next_sibling,
2590 							   MDL);
2591 					subnet_reference(&u->next_sibling,
2592 							 subnet, MDL);
2593 				} else {
2594 					subnet_dereference(&share->subnets,
2595 							   MDL);
2596 					subnet_reference(&share->subnets,
2597 							 subnet, MDL);
2598 				}
2599 				subnet_dereference(&subnet, MDL);
2600 				return 1;
2601 			}
2602 			u = t;
2603 		}
2604 		subnet_reference(&t->next_sibling, subnet, MDL);
2605 	}
2606 	subnet_dereference(&subnet, MDL);
2607 	return 1;
2608 }
2609 
2610 /* subnet-declaration :==
2611 	net NETMASK netmask RBRACE parameters declarations LBRACE */
2612 
2613 void parse_subnet_declaration (cfile, share)
2614 	struct parse *cfile;
2615 	struct shared_network *share;
2616 {
2617 	const char *val;
2618 	enum dhcp_token token;
2619 	struct subnet *subnet;
2620 	struct iaddr iaddr;
2621 	unsigned char addr [4];
2622 	unsigned len = sizeof addr;
2623 	isc_result_t status;
2624 
2625 	subnet = (struct subnet *)0;
2626 	status = subnet_allocate (&subnet, MDL);
2627 	if (status != ISC_R_SUCCESS)
2628 		log_fatal ("Allocation of new subnet failed: %s",
2629 			   isc_result_totext (status));
2630 	shared_network_reference (&subnet -> shared_network, share, MDL);
2631 
2632 	/*
2633 	 * If our parent shared network was implicitly created by the software,
2634 	 * and not explicitly configured by the user, then we actually put all
2635 	 * configuration scope in the parent (the shared network and subnet
2636 	 * share the same {}-level scope).
2637 	 *
2638 	 * Otherwise, we clone the parent group and continue as normal.
2639 	 */
2640 	if (share->flags & SHARED_IMPLICIT) {
2641 		group_reference(&subnet->group, share->group, MDL);
2642 	} else {
2643 		if (!clone_group(&subnet->group, share->group, MDL)) {
2644 			log_fatal("Allocation of group for new subnet failed.");
2645 		}
2646 	}
2647 	subnet_reference (&subnet -> group -> subnet, subnet, MDL);
2648 
2649 	/* Get the network number... */
2650 	if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8)) {
2651 		subnet_dereference (&subnet, MDL);
2652 		return;
2653 	}
2654 	memcpy (iaddr.iabuf, addr, len);
2655 	iaddr.len = len;
2656 	subnet -> net = iaddr;
2657 
2658 	token = next_token (&val, (unsigned *)0, cfile);
2659 	if (token != NETMASK) {
2660 		parse_warn (cfile, "Expecting netmask");
2661 		skip_to_semi (cfile);
2662 		return;
2663 	}
2664 
2665 	/* Get the netmask... */
2666 	if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8)) {
2667 		subnet_dereference (&subnet, MDL);
2668 		return;
2669 	}
2670 	memcpy (iaddr.iabuf, addr, len);
2671 	iaddr.len = len;
2672 	subnet -> netmask = iaddr;
2673 
2674 	/* Validate the network number/netmask pair. */
2675 	if (host_addr (subnet -> net, subnet -> netmask)) {
2676 		char *maskstr;
2677 
2678 		maskstr = strdup (piaddr (subnet -> netmask));
2679 		parse_warn (cfile,
2680 		   "subnet %s netmask %s: bad subnet number/mask combination.",
2681 			    piaddr (subnet -> net), maskstr);
2682 		free(maskstr);
2683 		subnet_dereference (&subnet, MDL);
2684 		skip_to_semi (cfile);
2685 		return;
2686 	}
2687 
2688 	common_subnet_parsing(cfile, share, subnet);
2689 }
2690 
2691 /* subnet6-declaration :==
2692 	net / bits RBRACE parameters declarations LBRACE */
2693 
2694 void
2695 parse_subnet6_declaration(struct parse *cfile, struct shared_network *share) {
2696 #if !defined(DHCPv6)
2697 	parse_warn(cfile, "No DHCPv6 support.");
2698 	skip_to_semi(cfile);
2699 #else /* defined(DHCPv6) */
2700 	struct subnet *subnet;
2701 	isc_result_t status;
2702 	enum dhcp_token token;
2703 	const char *val;
2704 	char *endp;
2705 	int ofs;
2706 	const static int mask[] = { 0x00, 0x80, 0xC0, 0xE0,
2707 				    0xF0, 0xF8, 0xFC, 0xFE };
2708 	struct iaddr iaddr;
2709 
2710         if (local_family != AF_INET6) {
2711                 parse_warn(cfile, "subnet6 statement is only supported "
2712 				  "in DHCPv6 mode.");
2713                 skip_to_semi(cfile);
2714                 return;
2715         }
2716 
2717 	subnet = NULL;
2718 	status = subnet_allocate(&subnet, MDL);
2719 	if (status != ISC_R_SUCCESS) {
2720 		log_fatal("Allocation of new subnet failed: %s",
2721 			  isc_result_totext(status));
2722 	}
2723 	shared_network_reference(&subnet->shared_network, share, MDL);
2724 
2725 	/*
2726 	 * If our parent shared network was implicitly created by the software,
2727 	 * and not explicitly configured by the user, then we actually put all
2728 	 * configuration scope in the parent (the shared network and subnet
2729 	 * share the same {}-level scope).
2730 	 *
2731 	 * Otherwise, we clone the parent group and continue as normal.
2732 	 */
2733 	if (share->flags & SHARED_IMPLICIT) {
2734 		group_reference(&subnet->group, share->group, MDL);
2735 	} else {
2736 		if (!clone_group(&subnet->group, share->group, MDL)) {
2737 			log_fatal("Allocation of group for new subnet failed.");
2738 		}
2739 	}
2740 	subnet_reference(&subnet->group->subnet, subnet, MDL);
2741 
2742 	if (!parse_ip6_addr(cfile, &subnet->net)) {
2743 		subnet_dereference(&subnet, MDL);
2744 		return;
2745 	}
2746 
2747 	token = next_token(&val, NULL, cfile);
2748 	if (token != SLASH) {
2749 		parse_warn(cfile, "Expecting a '/'.");
2750 		skip_to_semi(cfile);
2751 		return;
2752 	}
2753 
2754 	token = next_token(&val, NULL, cfile);
2755 	if (token != NUMBER) {
2756 		parse_warn(cfile, "Expecting a number.");
2757 		skip_to_semi(cfile);
2758 		return;
2759 	}
2760 
2761 	subnet->prefix_len = strtol(val, &endp, 10);
2762 	if ((subnet->prefix_len < 0) ||
2763 	    (subnet->prefix_len > 128) ||
2764 	    (*endp != '\0')) {
2765 	    	parse_warn(cfile, "Expecting a number between 0 and 128.");
2766 		skip_to_semi(cfile);
2767 		return;
2768 	}
2769 
2770 	if (!is_cidr_mask_valid(&subnet->net, subnet->prefix_len)) {
2771 		parse_warn(cfile, "New subnet mask too short.");
2772 		skip_to_semi(cfile);
2773 		return;
2774 	}
2775 
2776 	/*
2777 	 * Create a netmask.
2778 	 */
2779 	subnet->netmask.len = 16;
2780 	ofs = subnet->prefix_len / 8;
2781 	if (ofs < subnet->netmask.len) {
2782 		subnet->netmask.iabuf[ofs] = mask[subnet->prefix_len % 8];
2783 	}
2784 	while (--ofs >= 0) {
2785 		subnet->netmask.iabuf[ofs] = 0xFF;
2786 	}
2787 
2788 	/* Validate the network number/netmask pair. */
2789 	iaddr = subnet_number(subnet->net, subnet->netmask);
2790 	if (memcmp(&iaddr, &subnet->net, 16) != 0) {
2791 		parse_warn(cfile,
2792 		   "subnet %s/%d: prefix not long enough for address.",
2793 			    piaddr(subnet->net), subnet->prefix_len);
2794 		subnet_dereference(&subnet, MDL);
2795 		skip_to_semi(cfile);
2796 		return;
2797 	}
2798 
2799 	if (!common_subnet_parsing(cfile, share, subnet)) {
2800 		return;
2801 	}
2802 #endif /* defined(DHCPv6) */
2803 }
2804 
2805 /* group-declaration :== RBRACE parameters declarations LBRACE */
2806 
2807 void parse_group_declaration (cfile, group)
2808 	struct parse *cfile;
2809 	struct group *group;
2810 {
2811 	const char *val;
2812 	enum dhcp_token token;
2813 	struct group *g;
2814 	int declaration = 0;
2815 	struct group_object *t = NULL;
2816 	isc_result_t status;
2817 	char *name = NULL;
2818 	int deletedp = 0;
2819 	int dynamicp = 0;
2820 	int staticp = 0;
2821 
2822 	g = NULL;
2823 	if (!clone_group(&g, group, MDL))
2824 		log_fatal("no memory for explicit group.");
2825 
2826 	token = peek_token(&val, NULL, cfile);
2827 	if (is_identifier (token) || token == STRING) {
2828 		skip_token(&val, NULL, cfile);
2829 
2830 		name = dmalloc(strlen(val) + 1, MDL);
2831 		if (!name)
2832 			log_fatal("no memory for group decl name %s", val);
2833 		strcpy(name, val);
2834 	}
2835 
2836 	if (!parse_lbrace(cfile)) {
2837 		group_dereference(&g, MDL);
2838 		return;
2839 	}
2840 
2841 	do {
2842 		token = peek_token(&val, NULL, cfile);
2843 		if (token == RBRACE) {
2844 			skip_token(&val, NULL, cfile);
2845 			break;
2846 		} else if (token == END_OF_FILE) {
2847 			skip_token(&val, NULL, cfile);
2848 			parse_warn(cfile, "unexpected end of file");
2849 			break;
2850 		} else if (token == TOKEN_DELETED) {
2851 			skip_token(&val, NULL, cfile);
2852 			parse_semi(cfile);
2853 			deletedp = 1;
2854 		} else if (token == DYNAMIC) {
2855 			skip_token(&val, NULL, cfile);
2856 			parse_semi(cfile);
2857 			dynamicp = 1;
2858 		} else if (token == STATIC) {
2859 			skip_token(&val, NULL, cfile);
2860 			parse_semi(cfile);
2861 			staticp = 1;
2862 		}
2863 		declaration = parse_statement(cfile, g, GROUP_DECL,
2864 					      NULL, declaration);
2865 	} while (1);
2866 
2867 	if (name) {
2868 		if (deletedp) {
2869 			if (group_name_hash) {
2870 				t = NULL;
2871 				if (group_hash_lookup(&t, group_name_hash,
2872 						      name,
2873 						      strlen(name), MDL)) {
2874 					delete_group(t, 0);
2875 				}
2876 			}
2877 		} else {
2878 			t = NULL;
2879 			status = group_object_allocate(&t, MDL);
2880 			if (status != ISC_R_SUCCESS)
2881 				log_fatal("no memory for group decl %s: %s",
2882 					  val, isc_result_totext(status));
2883 			group_reference(&t->group, g, MDL);
2884 			t->name = name;
2885 			/* no need to include deletedp as it's handled above */
2886 			t->flags = ((staticp ? GROUP_OBJECT_STATIC : 0) |
2887 				    (dynamicp ? GROUP_OBJECT_DYNAMIC : 0));
2888 			supersede_group(t, 0);
2889 		}
2890 		if (t != NULL)
2891 			group_object_dereference(&t, MDL);
2892 	}
2893 }
2894 
2895 /* fixed-addr-parameter :== ip-addrs-or-hostnames SEMI
2896    ip-addrs-or-hostnames :== ip-addr-or-hostname
2897 			   | ip-addrs-or-hostnames ip-addr-or-hostname */
2898 
2899 int
2900 parse_fixed_addr_param(struct option_cache **oc,
2901 		       struct parse *cfile,
2902 		       enum dhcp_token type) {
2903 	int parse_ok;
2904 	const char *val;
2905 	enum dhcp_token token;
2906 	struct expression *expr = NULL;
2907 	struct expression *tmp, *new;
2908 	int status;
2909 
2910 	do {
2911 		tmp = NULL;
2912 		if (type == FIXED_ADDR) {
2913 			parse_ok = parse_ip_addr_or_hostname(&tmp, cfile, 1);
2914 		} else {
2915 			/* INSIST(type == FIXED_ADDR6); */
2916 			parse_ok = parse_ip6_addr_expr(&tmp, cfile);
2917 		}
2918 		if (parse_ok) {
2919 			if (expr != NULL) {
2920 				new = NULL;
2921 				status = make_concat(&new, expr, tmp);
2922 				expression_dereference(&expr, MDL);
2923 				expression_dereference(&tmp, MDL);
2924 				if (!status) {
2925 					return 0;
2926 				}
2927 				expr = new;
2928 			} else {
2929 				expr = tmp;
2930 			}
2931 		} else {
2932 			if (expr != NULL) {
2933 				expression_dereference (&expr, MDL);
2934 			}
2935 			return 0;
2936 		}
2937 		token = peek_token(&val, NULL, cfile);
2938 		if (token == COMMA) {
2939 			token = next_token(&val, NULL, cfile);
2940 		}
2941 	} while (token == COMMA);
2942 
2943 	if (!parse_semi(cfile)) {
2944 		if (expr) {
2945 			expression_dereference (&expr, MDL);
2946 		}
2947 		return 0;
2948 	}
2949 
2950 	status = option_cache(oc, NULL, expr, NULL, MDL);
2951 	expression_dereference(&expr, MDL);
2952 	return status;
2953 }
2954 
2955 /* lease_declaration :== LEASE ip_address LBRACE lease_parameters RBRACE
2956 
2957    lease_parameters :== <nil>
2958 		      | lease_parameter
2959 		      | lease_parameters lease_parameter
2960 
2961    lease_parameter :== STARTS date
2962 		     | ENDS date
2963 		     | TIMESTAMP date
2964 		     | HARDWARE hardware-parameter
2965 		     | UID hex_numbers SEMI
2966 		     | HOSTNAME hostname SEMI
2967 		     | CLIENT_HOSTNAME hostname SEMI
2968 		     | CLASS identifier SEMI
2969 		     | DYNAMIC_BOOTP SEMI */
2970 
2971 int parse_lease_declaration (struct lease **lp, struct parse *cfile)
2972 {
2973 	const char *val;
2974 	enum dhcp_token token;
2975 	unsigned char addr [4];
2976 	unsigned len = sizeof addr;
2977 	int seenmask = 0;
2978 	int seenbit;
2979 	char tbuf [32];
2980 	struct lease *lease;
2981 	struct executable_statement *on;
2982 	int lose;
2983 	TIME t;
2984 	int noequal, newbinding;
2985 	struct binding *binding;
2986 	struct binding_value *nv;
2987 	isc_result_t status;
2988 	struct option_cache *oc;
2989 	pair *p;
2990 	binding_state_t new_state;
2991 	unsigned buflen = 0;
2992 	struct class *class;
2993 
2994 	lease = (struct lease *)0;
2995 	status = lease_allocate (&lease, MDL);
2996 	if (status != ISC_R_SUCCESS)
2997 		return 0;
2998 
2999 	/* Get the address for which the lease has been issued. */
3000 	if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8)) {
3001 		lease_dereference (&lease, MDL);
3002 		return 0;
3003 	}
3004 	memcpy (lease -> ip_addr.iabuf, addr, len);
3005 	lease -> ip_addr.len = len;
3006 
3007 	if (!parse_lbrace (cfile)) {
3008 		lease_dereference (&lease, MDL);
3009 		return 0;
3010 	}
3011 
3012 	do {
3013 		token = next_token (&val, (unsigned *)0, cfile);
3014 		if (token == RBRACE)
3015 			break;
3016 		else if (token == END_OF_FILE) {
3017 			parse_warn (cfile, "unexpected end of file");
3018 			break;
3019 		}
3020 		strncpy (tbuf, val, sizeof tbuf);
3021 		tbuf [(sizeof tbuf) - 1] = 0;
3022 
3023 		/* Parse any of the times associated with the lease. */
3024 		switch (token) {
3025 		      case STARTS:
3026 		      case ENDS:
3027 		      case TIMESTAMP:
3028 		      case TSTP:
3029 		      case TSFP:
3030 		      case ATSFP:
3031 		      case CLTT:
3032 			t = parse_date (cfile);
3033 			switch (token) {
3034 			      case STARTS:
3035 				seenbit = 1;
3036 				lease -> starts = t;
3037 				break;
3038 
3039 			      case ENDS:
3040 				seenbit = 2;
3041 				lease -> ends = t;
3042 				break;
3043 
3044 			      case TSTP:
3045 				seenbit = 65536;
3046 				lease -> tstp = t;
3047 				break;
3048 
3049 			      case TSFP:
3050 				seenbit = 131072;
3051 				lease -> tsfp = t;
3052 				break;
3053 
3054 			      case ATSFP:
3055 				seenbit = 262144;
3056 				lease->atsfp = t;
3057 				break;
3058 
3059 			      case CLTT:
3060 				seenbit = 524288;
3061 				lease -> cltt = t;
3062 				break;
3063 
3064 			      default: /* for gcc, we'll never get here. */
3065 				log_fatal ("Impossible error at %s:%d.", MDL);
3066 				return 0;
3067 			}
3068 			break;
3069 
3070 			/* Colon-separated hexadecimal octets... */
3071 		      case UID:
3072 			seenbit = 8;
3073 			token = peek_token (&val, (unsigned *)0, cfile);
3074 			if (token == STRING) {
3075 				unsigned char *tuid;
3076 				skip_token(&val, &buflen, cfile);
3077 				if (buflen < sizeof lease -> uid_buf) {
3078 					tuid = lease -> uid_buf;
3079 					lease -> uid_max =
3080 						sizeof lease -> uid_buf;
3081 				} else {
3082 					tuid = ((unsigned char *)
3083 						dmalloc (buflen, MDL));
3084 					if (!tuid) {
3085 						log_error ("no space for uid");
3086 						lease_dereference (&lease,
3087 								   MDL);
3088 						return 0;
3089 					}
3090 					lease -> uid_max = buflen;
3091 				}
3092 				lease -> uid_len = buflen;
3093 				memcpy (tuid, val, lease -> uid_len);
3094 				lease -> uid = tuid;
3095 			} else {
3096 				buflen = 0;
3097 				lease -> uid = (parse_numeric_aggregate
3098 						(cfile, (unsigned char *)0,
3099 						 &buflen, ':', 16, 8));
3100 				if (!lease -> uid) {
3101 					lease_dereference (&lease, MDL);
3102 					return 0;
3103 				}
3104 				lease -> uid_len = buflen;
3105 				lease -> uid_max = buflen;
3106 				if (lease -> uid_len == 0) {
3107 					lease -> uid = (unsigned char *)0;
3108 					parse_warn (cfile, "zero-length uid");
3109 					seenbit = 0;
3110 					parse_semi (cfile);
3111 					break;
3112 				}
3113 			}
3114 			parse_semi (cfile);
3115 			if (!lease -> uid) {
3116 				log_fatal ("No memory for lease uid");
3117 			}
3118 			break;
3119 
3120 		      case CLASS:
3121 			seenbit = 32;
3122 			token = next_token (&val, (unsigned *)0, cfile);
3123 			if (!is_identifier (token)) {
3124 				if (token != SEMI)
3125 					skip_to_rbrace (cfile, 1);
3126 				lease_dereference (&lease, MDL);
3127 				return 0;
3128 			}
3129 			parse_semi (cfile);
3130 			/* for now, we aren't using this. */
3131 			break;
3132 
3133 		      case HARDWARE:
3134 			seenbit = 64;
3135 			parse_hardware_param (cfile,
3136 					      &lease -> hardware_addr);
3137 			break;
3138 
3139 		      case TOKEN_RESERVED:
3140 			seenbit = 0;
3141 			lease->flags |= RESERVED_LEASE;
3142 			parse_semi(cfile);
3143 			break;
3144 
3145 		      case DYNAMIC_BOOTP:
3146 			seenbit = 0;
3147 			lease -> flags |= BOOTP_LEASE;
3148 			parse_semi (cfile);
3149 			break;
3150 
3151 			/* XXX: Reverse compatibility? */
3152 		      case TOKEN_ABANDONED:
3153 			seenbit = 256;
3154 			lease -> binding_state = FTS_ABANDONED;
3155 			lease -> next_binding_state = FTS_ABANDONED;
3156 			parse_semi (cfile);
3157 			break;
3158 
3159 		      case TOKEN_NEXT:
3160 			seenbit = 128;
3161 			token = next_token (&val, (unsigned *)0, cfile);
3162 			if (token != BINDING) {
3163 				parse_warn (cfile, "expecting 'binding'");
3164 				skip_to_semi (cfile);
3165 				break;
3166 			}
3167 			goto do_binding_state;
3168 
3169 		      case REWIND:
3170 			seenbit = 512;
3171 			token = next_token(&val, NULL, cfile);
3172 			if (token != BINDING) {
3173 				parse_warn(cfile, "expecting 'binding'");
3174 				skip_to_semi(cfile);
3175 				break;
3176 			}
3177 			goto do_binding_state;
3178 
3179 		      case BINDING:
3180 			seenbit = 256;
3181 
3182 		      do_binding_state:
3183 			token = next_token (&val, (unsigned *)0, cfile);
3184 			if (token != STATE) {
3185 				parse_warn (cfile, "expecting 'state'");
3186 				skip_to_semi (cfile);
3187 				break;
3188 			}
3189 			token = next_token (&val, (unsigned *)0, cfile);
3190 			switch (token) {
3191 			      case TOKEN_ABANDONED:
3192 				new_state = FTS_ABANDONED;
3193 				break;
3194 			      case TOKEN_FREE:
3195 				new_state = FTS_FREE;
3196 				break;
3197 			      case TOKEN_ACTIVE:
3198 				new_state = FTS_ACTIVE;
3199 				break;
3200 			      case TOKEN_EXPIRED:
3201 				new_state = FTS_EXPIRED;
3202 				break;
3203 			      case TOKEN_RELEASED:
3204 				new_state = FTS_RELEASED;
3205 				break;
3206 			      case TOKEN_RESET:
3207 				new_state = FTS_RESET;
3208 				break;
3209 			      case TOKEN_BACKUP:
3210 				new_state = FTS_BACKUP;
3211 				break;
3212 
3213 				/* RESERVED and BOOTP states preserved for
3214 				 * compatibleness with older versions.
3215 				 */
3216 			      case TOKEN_RESERVED:
3217 				new_state = FTS_ACTIVE;
3218 				lease->flags |= RESERVED_LEASE;
3219 				break;
3220 			      case TOKEN_BOOTP:
3221 				new_state = FTS_ACTIVE;
3222 				lease->flags |= BOOTP_LEASE;
3223 				break;
3224 
3225 			      default:
3226 				parse_warn (cfile,
3227 					    "%s: expecting a binding state.",
3228 					    val);
3229 				skip_to_semi (cfile);
3230 				return 0;
3231 			}
3232 
3233 			if (seenbit == 256) {
3234 				lease -> binding_state = new_state;
3235 
3236 				/*
3237 				 * Apply default/conservative next/rewind
3238 				 * binding states if they haven't been set
3239 				 * yet.  These defaults will be over-ridden if
3240 				 * they are set later in parsing.
3241 				 */
3242 				if (!(seenmask & 128))
3243 				    lease->next_binding_state = new_state;
3244 
3245 				/* The most conservative rewind state. */
3246 				if (!(seenmask & 512))
3247 				    lease->rewind_binding_state = new_state;
3248 			} else if (seenbit == 128)
3249 				lease -> next_binding_state = new_state;
3250 			else if (seenbit == 512)
3251 				lease->rewind_binding_state = new_state;
3252 			else
3253 				log_fatal("Impossible condition at %s:%d.",
3254 					  MDL);
3255 
3256 			parse_semi (cfile);
3257 			break;
3258 
3259 		      case CLIENT_HOSTNAME:
3260 			seenbit = 1024;
3261 			token = peek_token (&val, (unsigned *)0, cfile);
3262 			if (token == STRING) {
3263 				if (!parse_string (cfile,
3264 						   &lease -> client_hostname,
3265 						   (unsigned *)0)) {
3266 					lease_dereference (&lease, MDL);
3267 					return 0;
3268 				}
3269 			} else {
3270 				lease -> client_hostname =
3271 					parse_host_name (cfile);
3272 				if (lease -> client_hostname)
3273 					parse_semi (cfile);
3274 				else {
3275 					parse_warn (cfile,
3276 						    "expecting a hostname.");
3277 					skip_to_semi (cfile);
3278 					lease_dereference (&lease, MDL);
3279 					return 0;
3280 				}
3281 			}
3282 			break;
3283 
3284 		      case BILLING:
3285 			seenbit = 2048;
3286 			class = (struct class *)0;
3287 			token = next_token (&val, (unsigned *)0, cfile);
3288 			if (token == CLASS) {
3289 				token = next_token (&val,
3290 						    (unsigned *)0, cfile);
3291 				if (token != STRING) {
3292 					parse_warn (cfile, "expecting string");
3293 					if (token != SEMI)
3294 						skip_to_semi (cfile);
3295 					token = BILLING;
3296 					break;
3297 				}
3298 				if (lease -> billing_class)
3299 				    class_dereference (&lease -> billing_class,
3300 						       MDL);
3301 				find_class (&class, val, MDL);
3302 				if (!class)
3303 					parse_warn (cfile,
3304 						    "unknown class %s", val);
3305 				parse_semi (cfile);
3306 			} else if (token == SUBCLASS) {
3307 				if (lease -> billing_class)
3308 				    class_dereference (&lease -> billing_class,
3309 						       MDL);
3310 				parse_class_declaration(&class, cfile, NULL,
3311 							CLASS_TYPE_SUBCLASS);
3312 			} else {
3313 				parse_warn (cfile, "expecting \"class\"");
3314 				if (token != SEMI)
3315 					skip_to_semi (cfile);
3316 			}
3317 			if (class) {
3318 				class_reference (&lease -> billing_class,
3319 						 class, MDL);
3320 				class_dereference (&class, MDL);
3321 			}
3322 			break;
3323 
3324 		      case ON:
3325 			on = (struct executable_statement *)0;
3326 			lose = 0;
3327 			if (!parse_on_statement (&on, cfile, &lose)) {
3328 				skip_to_rbrace (cfile, 1);
3329 				lease_dereference (&lease, MDL);
3330 				return 0;
3331 			}
3332 			seenbit = 0;
3333 			if ((on->data.on.evtypes & ON_EXPIRY) &&
3334 			    on->data.on.statements) {
3335 				seenbit |= 16384;
3336 				executable_statement_reference
3337 					(&lease->on_star.on_expiry,
3338 					 on->data.on.statements, MDL);
3339 			}
3340 			if ((on->data.on.evtypes & ON_RELEASE) &&
3341 			    on->data.on.statements) {
3342 				seenbit |= 32768;
3343 				executable_statement_reference
3344 					(&lease->on_star.on_release,
3345 					 on->data.on.statements, MDL);
3346 			}
3347 			executable_statement_dereference (&on, MDL);
3348 			break;
3349 
3350 		      case OPTION:
3351 		      case SUPERSEDE:
3352 			noequal = 0;
3353 			seenbit = 0;
3354 			oc = (struct option_cache *)0;
3355 			if (parse_option_decl (&oc, cfile)) {
3356 			    if (oc -> option -> universe !=
3357 				&agent_universe) {
3358 				    parse_warn (cfile,
3359 						"agent option expected.");
3360 				    option_cache_dereference (&oc, MDL);
3361 				    break;
3362 			    }
3363 			    if (!lease -> agent_options &&
3364 				!(option_chain_head_allocate
3365 				  (&lease -> agent_options, MDL))) {
3366 				log_error ("no memory to stash agent option");
3367 				break;
3368 			    }
3369 			    for (p = &lease -> agent_options -> first;
3370 				 *p; p = &((*p) -> cdr))
3371 				    ;
3372 			    *p = cons (0, 0);
3373 			    option_cache_reference (((struct option_cache **)
3374 						     &((*p) -> car)), oc, MDL);
3375 			    option_cache_dereference (&oc, MDL);
3376 			}
3377 			break;
3378 
3379 		      case TOKEN_SET:
3380 			noequal = 0;
3381 
3382 			token = next_token (&val, (unsigned *)0, cfile);
3383 			if (token != NAME && token != NUMBER_OR_NAME) {
3384 				parse_warn (cfile,
3385 					    "%s can't be a variable name",
3386 					    val);
3387 			      badset:
3388 				skip_to_semi (cfile);
3389 				lease_dereference (&lease, MDL);
3390 				return 0;
3391 			}
3392 
3393 			seenbit = 0;
3394 		      special_set:
3395 			if (lease -> scope)
3396 				binding = find_binding (lease -> scope, val);
3397 			else
3398 				binding = (struct binding *)0;
3399 
3400 			if (!binding) {
3401 			    if (!lease -> scope)
3402 				if (!(binding_scope_allocate
3403 				      (&lease -> scope, MDL)))
3404 					log_fatal ("no memory for scope");
3405 			    binding = dmalloc (sizeof *binding, MDL);
3406 			    if (!binding)
3407 				    log_fatal ("No memory for lease %s.",
3408 					       "binding");
3409 			    memset (binding, 0, sizeof *binding);
3410 			    binding -> name =
3411 				    dmalloc (strlen (val) + 1, MDL);
3412 			    if (!binding -> name)
3413 				    log_fatal ("No memory for binding %s.",
3414 					       "name");
3415 			    strcpy (binding -> name, val);
3416 			    newbinding = 1;
3417 			} else  {
3418 			    newbinding = 0;
3419 			}
3420 
3421 			nv = NULL;
3422 			if (!binding_value_allocate(&nv, MDL))
3423 				log_fatal("no memory for binding value.");
3424 
3425 			if (!noequal) {
3426 			    token = next_token (&val, (unsigned *)0, cfile);
3427 			    if (token != EQUAL) {
3428 				parse_warn (cfile,
3429 					    "expecting '=' in set statement.");
3430 				goto badset;
3431 			    }
3432 			}
3433 
3434 			if (!parse_binding_value(cfile, nv)) {
3435 				binding_value_dereference(&nv, MDL);
3436 				lease_dereference(&lease, MDL);
3437 				return 0;
3438 			}
3439 
3440 			if (newbinding) {
3441 				binding_value_reference(&binding->value,
3442 							nv, MDL);
3443 				binding->next = lease->scope->bindings;
3444 				lease->scope->bindings = binding;
3445 			} else {
3446 				binding_value_dereference(&binding->value, MDL);
3447 				binding_value_reference(&binding->value,
3448 							nv, MDL);
3449 			}
3450 
3451 			binding_value_dereference(&nv, MDL);
3452 			parse_semi(cfile);
3453 			break;
3454 
3455 			/* case NAME: */
3456 		      default:
3457 			if (!strcasecmp (val, "ddns-fwd-name")) {
3458 				seenbit = 4096;
3459 				noequal = 1;
3460 				goto special_set;
3461 			} else if (!strcasecmp (val, "ddns-rev-name")) {
3462 				seenbit = 8192;
3463 				noequal = 1;
3464 				goto special_set;
3465 			} else
3466 				parse_warn(cfile, "Unexpected configuration "
3467 						  "directive.");
3468 			skip_to_semi (cfile);
3469 			seenbit = 0;
3470 			lease_dereference (&lease, MDL);
3471 			return 0;
3472 		}
3473 
3474 		if (seenmask & seenbit) {
3475 			parse_warn (cfile,
3476 				    "Too many %s parameters in lease %s\n",
3477 				    tbuf, piaddr (lease -> ip_addr));
3478 		} else
3479 			seenmask |= seenbit;
3480 
3481 	} while (1);
3482 
3483 	/* If no binding state is specified, make one up. */
3484 	if (!(seenmask & 256)) {
3485 		if (lease->ends > cur_time ||
3486 		    lease->on_star.on_expiry || lease->on_star.on_release)
3487 			lease->binding_state = FTS_ACTIVE;
3488 #if defined (FAILOVER_PROTOCOL)
3489 		else if (lease->pool && lease->pool->failover_peer)
3490 			lease->binding_state = FTS_EXPIRED;
3491 #endif
3492 		else
3493 			lease->binding_state = FTS_FREE;
3494 		if (lease->binding_state == FTS_ACTIVE) {
3495 #if defined (FAILOVER_PROTOCOL)
3496 			if (lease->pool && lease->pool->failover_peer)
3497 				lease->next_binding_state = FTS_EXPIRED;
3498 			else
3499 #endif
3500 				lease->next_binding_state = FTS_FREE;
3501 		} else
3502 			lease->next_binding_state = lease->binding_state;
3503 
3504 		/* The most conservative rewind state implies no rewind. */
3505 		lease->rewind_binding_state = lease->binding_state;
3506 	}
3507 
3508 	if (!(seenmask & 65536))
3509 		lease->tstp = lease->ends;
3510 
3511 	lease_reference (lp, lease, MDL);
3512 	lease_dereference (&lease, MDL);
3513 	return 1;
3514 }
3515 
3516 /* Parse the right side of a 'binding value'.
3517  *
3518  * set foo = "bar"; is a string
3519  * set foo = false; is a boolean
3520  * set foo = %31; is a numeric value.
3521  */
3522 static int
3523 parse_binding_value(struct parse *cfile, struct binding_value *value)
3524 {
3525 	struct data_string *data;
3526 	unsigned char *s;
3527 	const char *val;
3528 	unsigned buflen;
3529 	int token;
3530 
3531 	if ((cfile == NULL) || (value == NULL))
3532 		log_fatal("Invalid arguments at %s:%d.", MDL);
3533 
3534 	token = peek_token(&val, NULL, cfile);
3535 	if (token == STRING) {
3536 		skip_token(&val, &buflen, cfile);
3537 
3538 		value->type = binding_data;
3539 		value->value.data.len = buflen;
3540 
3541 		data = &value->value.data;
3542 
3543 		if (!buffer_allocate(&data->buffer, buflen + 1, MDL))
3544 			log_fatal ("No memory for binding.");
3545 
3546 		memcpy(data->buffer->data, val, buflen + 1);
3547 
3548 		data->data = data->buffer->data;
3549 		data->terminated = 1;
3550 	} else if (token == NUMBER_OR_NAME) {
3551 		value->type = binding_data;
3552 
3553 		data = &value->value.data;
3554 		s = parse_numeric_aggregate(cfile, NULL, &data->len,
3555 					    ':', 16, 8);
3556 		if (s == NULL) {
3557 			skip_to_semi(cfile);
3558 			return 0;
3559 		}
3560 
3561 		if (data->len) {
3562 			if (!buffer_allocate(&data->buffer, data->len + 1,
3563 					     MDL))
3564 				log_fatal("No memory for binding.");
3565 
3566 			memcpy(data->buffer->data, s, data->len);
3567 			data->data = data->buffer->data;
3568 
3569 			dfree (s, MDL);
3570 		}
3571 	} else if (token == PERCENT) {
3572 		skip_token(&val, NULL, cfile);
3573 		token = next_token(&val, NULL, cfile);
3574 		if (token != NUMBER) {
3575 			parse_warn(cfile, "expecting decimal number.");
3576 			if (token != SEMI)
3577 				skip_to_semi(cfile);
3578 			return 0;
3579 		}
3580 		value->type = binding_numeric;
3581 		value->value.intval = atol(val);
3582 	} else if (token == NAME) {
3583 		token = next_token(&val, NULL, cfile);
3584 		value->type = binding_boolean;
3585 		if (!strcasecmp(val, "true"))
3586 			value->value.boolean = 1;
3587 		else if (!strcasecmp(val, "false"))
3588 			value->value.boolean = 0;
3589 		else {
3590 			parse_warn(cfile, "expecting true or false");
3591 			if (token != SEMI)
3592 				skip_to_semi(cfile);
3593 			return 0;
3594 		}
3595 	} else {
3596 		parse_warn (cfile, "expecting a constant value.");
3597 		if (token != SEMI)
3598 			skip_to_semi (cfile);
3599 		return 0;
3600 	}
3601 
3602 	return 1;
3603 }
3604 
3605 /* address-range-declaration :== ip-address ip-address SEMI
3606 			       | DYNAMIC_BOOTP ip-address ip-address SEMI */
3607 
3608 void parse_address_range (cfile, group, type, inpool, lpchain)
3609 	struct parse *cfile;
3610 	struct group *group;
3611 	int type;
3612 	struct pool *inpool;
3613 	struct lease **lpchain;
3614 {
3615 	struct iaddr low, high, net;
3616 	unsigned char addr [4];
3617 	unsigned len = sizeof addr;
3618 	enum dhcp_token token;
3619 	const char *val;
3620 	int dynamic = 0;
3621 	struct subnet *subnet;
3622 	struct shared_network *share;
3623 	struct pool *pool;
3624 	isc_result_t status;
3625 
3626 	if ((token = peek_token (&val,
3627 				 (unsigned *)0, cfile)) == DYNAMIC_BOOTP) {
3628 		skip_token(&val, (unsigned *)0, cfile);
3629 		dynamic = 1;
3630 	}
3631 
3632 	/* Get the bottom address in the range... */
3633 	if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
3634 		return;
3635 	memcpy (low.iabuf, addr, len);
3636 	low.len = len;
3637 
3638 	/* Only one address? */
3639 	token = peek_token (&val, (unsigned *)0, cfile);
3640 	if (token == SEMI)
3641 		high = low;
3642 	else {
3643 	/* Get the top address in the range... */
3644 		if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
3645 			return;
3646 		memcpy (high.iabuf, addr, len);
3647 		high.len = len;
3648 	}
3649 
3650 	token = next_token (&val, (unsigned *)0, cfile);
3651 	if (token != SEMI) {
3652 		parse_warn (cfile, "semicolon expected.");
3653 		skip_to_semi (cfile);
3654 		return;
3655 	}
3656 
3657 	if (type == SUBNET_DECL) {
3658 		subnet = group -> subnet;
3659 		share = subnet -> shared_network;
3660 	} else {
3661 		share = group -> shared_network;
3662 		for (subnet = share -> subnets;
3663 		     subnet; subnet = subnet -> next_sibling) {
3664 			net = subnet_number (low, subnet -> netmask);
3665 			if (addr_eq (net, subnet -> net))
3666 				break;
3667 		}
3668 		if (!subnet) {
3669 			parse_warn (cfile, "address range not on network %s",
3670 				    group -> shared_network -> name);
3671 			log_error ("Be sure to place pool statement after %s",
3672 				   "related subnet declarations.");
3673 			return;
3674 		}
3675 	}
3676 
3677 	if (!inpool) {
3678 		struct pool *last = (struct pool *)0;
3679 
3680 		/* If we're permitting dynamic bootp for this range,
3681 		   then look for a pool with an empty prohibit list and
3682 		   a permit list with one entry that permits all clients. */
3683 		for (pool = share -> pools; pool; pool = pool -> next) {
3684 			if ((!dynamic && !pool -> permit_list &&
3685 			     pool -> prohibit_list &&
3686 			     !pool -> prohibit_list -> next &&
3687 			     (pool -> prohibit_list -> type ==
3688 			      permit_dynamic_bootp_clients)) ||
3689 			    (dynamic && !pool -> prohibit_list &&
3690 			     pool -> permit_list &&
3691 			     !pool -> permit_list -> next &&
3692 			     (pool -> permit_list -> type ==
3693 			      permit_all_clients))) {
3694   				break;
3695 			}
3696 			last = pool;
3697 		}
3698 
3699 		/* If we didn't get a pool, make one. */
3700 		if (!pool) {
3701 			struct permit *p;
3702 			status = pool_allocate (&pool, MDL);
3703 			if (status != ISC_R_SUCCESS)
3704 				log_fatal ("no memory for ad-hoc pool: %s",
3705 					   isc_result_totext (status));
3706 			p = new_permit (MDL);
3707 			if (!p)
3708 				log_fatal ("no memory for ad-hoc permit.");
3709 
3710 			/* Dynamic pools permit all clients.   Otherwise
3711 			   we prohibit BOOTP clients. */
3712 			if (dynamic) {
3713 				p -> type = permit_all_clients;
3714 				pool -> permit_list = p;
3715 			} else {
3716 				p -> type = permit_dynamic_bootp_clients;
3717 				pool -> prohibit_list = p;
3718 			}
3719 
3720 			if (share -> pools)
3721 				pool_reference (&last -> next, pool, MDL);
3722 			else
3723 				pool_reference (&share -> pools, pool, MDL);
3724 			shared_network_reference (&pool -> shared_network,
3725 						  share, MDL);
3726 			if (!clone_group (&pool -> group, share -> group, MDL))
3727 				log_fatal ("no memory for anon pool group.");
3728 		} else {
3729 			pool = (struct pool *)0;
3730 			if (last)
3731 				pool_reference (&pool, last, MDL);
3732 			else
3733 				pool_reference (&pool, share -> pools, MDL);
3734 		}
3735 	} else {
3736 		pool = (struct pool *)0;
3737 		pool_reference (&pool, inpool, MDL);
3738 	}
3739 
3740 #if defined (FAILOVER_PROTOCOL)
3741 	if (pool -> failover_peer && dynamic) {
3742 		/* Doctor, do you think I'm overly sensitive
3743 		   about getting bug reports I can't fix? */
3744 		parse_warn (cfile, "dynamic-bootp flag is %s",
3745 			    "not permitted for address");
3746 		log_error ("range declarations where there is a failover");
3747 		log_error ("peer in scope.   If you wish to declare an");
3748 		log_error ("address range from which dynamic bootp leases");
3749 		log_error ("can be allocated, please declare it within a");
3750 		log_error ("pool declaration that also contains the \"no");
3751 		log_error ("failover\" statement.   The failover protocol");
3752 		log_error ("itself does not permit dynamic bootp - this");
3753 		log_error ("is not a limitation specific to the ISC DHCP");
3754 		log_error ("server.   Please don't ask me to defend this");
3755 		log_error ("until you have read and really tried %s",
3756 			   "to understand");
3757 		log_error ("the failover protocol specification.");
3758 
3759 		/* We don't actually bomb at this point - instead,
3760 		   we let parse_lease_file notice the error and
3761 		   bomb at that point - it's easier. */
3762 	}
3763 #endif /* FAILOVER_PROTOCOL */
3764 
3765 	/* Create the new address range... */
3766 	new_address_range (cfile, low, high, subnet, pool, lpchain);
3767 	pool_dereference (&pool, MDL);
3768 }
3769 
3770 #ifdef DHCPv6
3771 static void
3772 add_ipv6_pool_to_subnet(struct subnet *subnet, u_int16_t type,
3773 			struct iaddr *lo_addr, int bits, int units,
3774 			struct ipv6_pond *pond) {
3775 	struct ipv6_pool *pool;
3776 	struct in6_addr tmp_in6_addr;
3777 	int num_pools;
3778 	struct ipv6_pool **tmp;
3779 
3780 	/*
3781 	 * Create our pool.
3782 	 */
3783 	if (lo_addr->len != sizeof(tmp_in6_addr)) {
3784 		log_fatal("Internal error: Attempt to add non-IPv6 address "
3785 			  "to IPv6 shared network.");
3786 	}
3787 	memcpy(&tmp_in6_addr, lo_addr->iabuf, sizeof(tmp_in6_addr));
3788 	pool = NULL;
3789 	if (ipv6_pool_allocate(&pool, type, &tmp_in6_addr,
3790 			       bits, units, MDL) != ISC_R_SUCCESS) {
3791 		log_fatal("Out of memory");
3792 	}
3793 
3794 	/*
3795 	 * Add to our global IPv6 pool set.
3796 	 */
3797 	if (add_ipv6_pool(pool) != ISC_R_SUCCESS) {
3798 		log_fatal ("Out of memory");
3799 	}
3800 
3801 	/*
3802 	 * Link the pool to its network.
3803 	 */
3804 	pool->subnet = NULL;
3805 	subnet_reference(&pool->subnet, subnet, MDL);
3806 	pool->shared_network = NULL;
3807 	shared_network_reference(&pool->shared_network,
3808 				 subnet->shared_network, MDL);
3809 	pool->ipv6_pond = NULL;
3810 	ipv6_pond_reference(&pool->ipv6_pond, pond, MDL);
3811 
3812 	/*
3813 	 * Increase our array size for ipv6_pools in the pond
3814 	 */
3815 	if (pond->ipv6_pools == NULL) {
3816 		num_pools = 0;
3817 	} else {
3818 		num_pools = 0;
3819 		while (pond->ipv6_pools[num_pools] != NULL) {
3820 			num_pools++;
3821 		}
3822 	}
3823 	tmp = dmalloc(sizeof(struct ipv6_pool *) * (num_pools + 2), MDL);
3824 	if (tmp == NULL) {
3825 		log_fatal("Out of memory");
3826 	}
3827 	if (num_pools > 0) {
3828 		memcpy(tmp, pond->ipv6_pools,
3829 		       sizeof(struct ipv6_pool *) * num_pools);
3830 	}
3831 	if (pond->ipv6_pools != NULL) {
3832 		dfree(pond->ipv6_pools, MDL);
3833 	}
3834 	pond->ipv6_pools = tmp;
3835 
3836 	/*
3837 	 * Record this pool in our array of pools for this shared network.
3838 	 */
3839 	ipv6_pool_reference(&pond->ipv6_pools[num_pools], pool, MDL);
3840 	pond->ipv6_pools[num_pools+1] = NULL;
3841 }
3842 
3843 /*!
3844  *
3845  * \brief Find or create a default pond
3846  *
3847  * Find or create an ipv6_pond on which to attach the ipv6_pools.  We
3848  * check the shared network to see if there is a general purpose
3849  * entry - this will have an empty prohibit list and a permit list
3850  * with a single entry that permits all clients.  If the shared
3851  * network doesn't have one of them create it and attach it to
3852  * the shared network and the return argument.
3853  *
3854  * This function is used when we have a range6 or prefix6 statement
3855  * inside a subnet6 statement but outside of a pool6 statement.
3856  * This routine constructs the missing ipv6_pond structure so
3857  * we always have
3858  * shared_network -> ipv6_pond -> ipv6_pool
3859  *
3860  * \param[in] group     = a pointer to the group structure from which
3861  *                        we can find the subnet and shared netowrk
3862  *                        structures
3863  * \param[out] ret_pond = a pointer to space for the pointer to
3864  *                        the structure to return
3865  *
3866  * \return
3867  * void
3868  */
3869 static void
3870 add_ipv6_pond_to_network(struct group *group,
3871 			 struct ipv6_pond **ret_pond) {
3872 
3873 	struct ipv6_pond *pond = NULL, *last = NULL;
3874 	struct permit *p;
3875 	isc_result_t status;
3876 	struct shared_network *shared = group->subnet->shared_network;
3877 
3878 	for (pond = shared->ipv6_pond; pond; pond = pond->next) {
3879 		if ((pond->group->statements == group->statements) &&
3880 		    (pond->prohibit_list == NULL) &&
3881 		    (pond->permit_list != NULL) &&
3882 		    (pond->permit_list->next == NULL) &&
3883 		    (pond->permit_list->type == permit_all_clients)) {
3884 			ipv6_pond_reference(ret_pond, pond, MDL);
3885 			return;
3886 		}
3887 		last = pond;
3888 	}
3889 
3890 	/* no pond available, make one */
3891 	status = ipv6_pond_allocate(&pond, MDL);
3892 	if (status != ISC_R_SUCCESS)
3893 		log_fatal ("no memory for ad-hoc ipv6 pond: %s",
3894 			   isc_result_totext (status));
3895 	p = new_permit (MDL);
3896 	if (p == NULL)
3897 		log_fatal ("no memory for ad-hoc ipv6 permit.");
3898 
3899 	/* we permit all clients */
3900 	p->type = permit_all_clients;
3901 	pond->permit_list = p;
3902 
3903 	/* and attach the pond to the return argument and the shared network */
3904 	ipv6_pond_reference(ret_pond, pond, MDL);
3905 
3906 	if (shared->ipv6_pond)
3907 		ipv6_pond_reference(&last->next, pond, MDL);
3908 	else
3909 		ipv6_pond_reference(&shared->ipv6_pond, pond, MDL);
3910 
3911 	shared_network_reference(&pond->shared_network, shared, MDL);
3912 	if (!clone_group (&pond->group, group, MDL))
3913 		log_fatal ("no memory for anon pool group.");
3914 
3915 	ipv6_pond_dereference(&pond, MDL);
3916 	return;
3917 }
3918 
3919 
3920 /* address-range6-declaration :== ip-address6 ip-address6 SEMI
3921 			       | ip-address6 SLASH number SEMI
3922 			       | ip-address6 [SLASH number] TEMPORARY SEMI */
3923 
3924 void
3925 parse_address_range6(struct parse *cfile,
3926 		     struct group *group,
3927 		     struct ipv6_pond *inpond) {
3928 	struct iaddr lo, hi;
3929 	int bits;
3930 	enum dhcp_token token;
3931 	const char *val;
3932 	struct iaddrcidrnetlist *nets, net;
3933 	struct iaddrcidrnetlist *p;
3934 	u_int16_t type = D6O_IA_NA;
3935 	struct ipv6_pond *pond = NULL;
3936 
3937         if (local_family != AF_INET6) {
3938                 parse_warn(cfile, "range6 statement is only supported "
3939 				  "in DHCPv6 mode.");
3940                 skip_to_semi(cfile);
3941                 return;
3942         }
3943 
3944 	/* This is enforced by the caller, this is just a sanity check. */
3945 	if (group->subnet == NULL)
3946 		log_fatal("Impossible condition at %s:%d.", MDL);
3947 
3948 	/*
3949 	 * Read starting address.
3950 	 */
3951 	if (!parse_ip6_addr(cfile, &lo)) {
3952 		return;
3953 	}
3954 
3955 	/*
3956 	 * zero out the net entry in case we use it
3957 	 */
3958 	memset(&net, 0, sizeof(net));
3959 	net.cidrnet.lo_addr = lo;
3960 
3961 	/*
3962 	 * See if we we're using range or CIDR notation or TEMPORARY
3963 	 */
3964 	token = peek_token(&val, NULL, cfile);
3965 	if (token == SLASH) {
3966 		/*
3967 		 * '/' means CIDR notation, so read the bits we want.
3968 		 */
3969 		skip_token(NULL, NULL, cfile);
3970 		token = next_token(&val, NULL, cfile);
3971 		if (token != NUMBER) {
3972 			parse_warn(cfile, "expecting number");
3973 			skip_to_semi(cfile);
3974 			return;
3975 		}
3976 		net.cidrnet.bits = atoi(val);
3977 		bits = net.cidrnet.bits;
3978 		if ((bits < 0) || (bits > 128)) {
3979 			parse_warn(cfile, "networks have 0 to 128 bits");
3980 			skip_to_semi(cfile);
3981 			return;
3982 		}
3983 
3984 		if (!is_cidr_mask_valid(&net.cidrnet.lo_addr, bits)) {
3985 			parse_warn(cfile, "network mask too short");
3986 			skip_to_semi(cfile);
3987 			return;
3988 		}
3989 
3990 		/*
3991 		 * can be temporary (RFC 4941 like)
3992 		 */
3993 		token = peek_token(&val, NULL, cfile);
3994 		if (token == TEMPORARY) {
3995 			if (bits < 64)
3996 				parse_warn(cfile, "temporary mask too short");
3997 			if (bits == 128)
3998 				parse_warn(cfile, "temporary singleton?");
3999 			skip_token(NULL, NULL, cfile);
4000 			type = D6O_IA_TA;
4001 		}
4002 
4003 		nets = &net;
4004 
4005 	} else if (token == TEMPORARY) {
4006 		/*
4007 		 * temporary (RFC 4941)
4008 		 */
4009 		type = D6O_IA_TA;
4010 		skip_token(NULL, NULL, cfile);
4011 		net.cidrnet.bits = 64;
4012 		if (!is_cidr_mask_valid(&net.cidrnet.lo_addr,
4013 					net.cidrnet.bits)) {
4014 			parse_warn(cfile, "network mask too short");
4015 			skip_to_semi(cfile);
4016 			return;
4017 		}
4018 
4019 		nets = &net;
4020 
4021 	} else {
4022 		/*
4023 		 * No '/', so we are looking for the end address of
4024 		 * the IPv6 pool.
4025 		 */
4026 		if (!parse_ip6_addr(cfile, &hi)) {
4027 			return;
4028 		}
4029 
4030 		/*
4031 		 * Convert our range to a set of CIDR networks.
4032 		 */
4033 		nets = NULL;
4034 		if (range2cidr(&nets, &lo, &hi) != ISC_R_SUCCESS) {
4035 			log_fatal("Error converting range to CIDR networks");
4036 		}
4037 
4038 	}
4039 
4040 	/*
4041 	 * See if we have a pond for this set of pools.
4042 	 * If the caller supplied one we use it, otherwise
4043 	 * check the shared network
4044 	 */
4045 
4046 	if (inpond != NULL) {
4047 		ipv6_pond_reference(&pond, inpond, MDL);
4048 	} else {
4049 		add_ipv6_pond_to_network(group, &pond);
4050 	}
4051 
4052 	/* Now that we have a pond add the nets we have parsed */
4053 	for (p=nets; p != NULL; p=p->next) {
4054 		add_ipv6_pool_to_subnet(group->subnet, type,
4055 					&p->cidrnet.lo_addr,
4056 					p->cidrnet.bits, 128, pond);
4057 	}
4058 
4059 	/* if we allocated a list free it now */
4060 	if (nets != &net)
4061 		free_iaddrcidrnetlist(&nets);
4062 
4063 	ipv6_pond_dereference(&pond, MDL);
4064 
4065 	token = next_token(NULL, NULL, cfile);
4066 	if (token != SEMI) {
4067 		parse_warn(cfile, "semicolon expected.");
4068 		skip_to_semi(cfile);
4069 		return;
4070 	}
4071 }
4072 
4073 /* prefix6-declaration :== ip-address6 ip-address6 SLASH number SEMI */
4074 
4075 void
4076 parse_prefix6(struct parse *cfile,
4077 	      struct group *group,
4078 	      struct ipv6_pond *inpond) {
4079 	struct iaddr lo, hi;
4080 	int bits;
4081 	enum dhcp_token token;
4082 	const char *val;
4083 	struct iaddrcidrnetlist *nets;
4084 	struct iaddrcidrnetlist *p;
4085 	struct ipv6_pond *pond = NULL;
4086 
4087 	if (local_family != AF_INET6) {
4088 		parse_warn(cfile, "prefix6 statement is only supported "
4089 				  "in DHCPv6 mode.");
4090 		skip_to_semi(cfile);
4091 		return;
4092 	}
4093 
4094 	/* This is enforced by the caller, so it's just a sanity check. */
4095 	if (group->subnet == NULL)
4096 		log_fatal("Impossible condition at %s:%d.", MDL);
4097 
4098 	/*
4099 	 * Read starting and ending address.
4100 	 */
4101 	if (!parse_ip6_addr(cfile, &lo)) {
4102 		return;
4103 	}
4104 	if (!parse_ip6_addr(cfile, &hi)) {
4105 		return;
4106 	}
4107 
4108 	/*
4109 	 * Next is '/' number ';'.
4110 	 */
4111 	token = next_token(NULL, NULL, cfile);
4112 	if (token != SLASH) {
4113 		parse_warn(cfile, "expecting '/'");
4114 		if (token != SEMI)
4115 			skip_to_semi(cfile);
4116 		return;
4117 	}
4118 	token = next_token(&val, NULL, cfile);
4119 	if (token != NUMBER) {
4120 		parse_warn(cfile, "expecting number");
4121 		if (token != SEMI)
4122 			skip_to_semi(cfile);
4123 		return;
4124 	}
4125 	bits = atoi(val);
4126 	if ((bits <= 0) || (bits >= 128)) {
4127 		parse_warn(cfile, "networks have 0 to 128 bits (exclusive)");
4128 		return;
4129 	}
4130 	if (!is_cidr_mask_valid(&lo, bits) ||
4131 	    !is_cidr_mask_valid(&hi, bits)) {
4132 		parse_warn(cfile, "network mask too short");
4133 		return;
4134 	}
4135 	token = next_token(NULL, NULL, cfile);
4136 	if (token != SEMI) {
4137 		parse_warn(cfile, "semicolon expected.");
4138 		skip_to_semi(cfile);
4139 		return;
4140 	}
4141 
4142 	/*
4143 	 * Convert our range to a set of CIDR networks.
4144 	 */
4145 	nets = NULL;
4146 	if (range2cidr(&nets, &lo, &hi) != ISC_R_SUCCESS) {
4147 		log_fatal("Error converting prefix to CIDR");
4148 	}
4149 
4150 	/*
4151 	 * See if we have a pond for this set of pools.
4152 	 * If the caller supplied one we use it, otherwise
4153 	 * check the shared network
4154 	 */
4155 
4156 	if (inpond != NULL) {
4157 		ipv6_pond_reference(&pond, inpond, MDL);
4158 	} else {
4159 		add_ipv6_pond_to_network(group, &pond);
4160 	}
4161 
4162 	for (p = nets; p != NULL; p = p->next) {
4163 		/* Normalize and check. */
4164 		if (p->cidrnet.bits == 128) {
4165 			p->cidrnet.bits = bits;
4166 		}
4167 		if (p->cidrnet.bits > bits) {
4168 			parse_warn(cfile, "impossible mask length");
4169 			continue;
4170 		}
4171 		add_ipv6_pool_to_subnet(group->subnet, D6O_IA_PD,
4172 					&p->cidrnet.lo_addr,
4173 					p->cidrnet.bits, bits, pond);
4174 	}
4175 
4176 	free_iaddrcidrnetlist(&nets);
4177 }
4178 
4179 /* fixed-prefix6 :== ip6-address SLASH number SEMI */
4180 
4181 void
4182 parse_fixed_prefix6(struct parse *cfile, struct host_decl *host_decl) {
4183 	struct iaddrcidrnetlist *ia, **h;
4184 	enum dhcp_token token;
4185 	const char *val;
4186 
4187 	/*
4188 	 * Get the head of the fixed-prefix list.
4189 	 */
4190 	h = &host_decl->fixed_prefix;
4191 
4192 	/*
4193 	 * Walk to the end.
4194 	 */
4195 	while (*h != NULL) {
4196 		h = &((*h)->next);
4197 	}
4198 
4199 	/*
4200 	 * Allocate a new iaddrcidrnetlist structure.
4201 	 */
4202 	ia = dmalloc(sizeof(*ia), MDL);
4203 	if (!ia) {
4204 		log_fatal("Out of memory");
4205 	}
4206 
4207 	/*
4208 	 * Parse it.
4209 	 */
4210 	if (!parse_ip6_addr(cfile, &ia->cidrnet.lo_addr)) {
4211 		dfree(ia, MDL);
4212 		return;
4213 	}
4214 	token = next_token(NULL, NULL, cfile);
4215 	if (token != SLASH) {
4216 		dfree(ia, MDL);
4217 		parse_warn(cfile, "expecting '/'");
4218 		if (token != SEMI)
4219 			skip_to_semi(cfile);
4220 		return;
4221 	}
4222 	token = next_token(&val, NULL, cfile);
4223 	if (token != NUMBER) {
4224 		dfree(ia, MDL);
4225 		parse_warn(cfile, "expecting number");
4226 		if (token != SEMI)
4227 			skip_to_semi(cfile);
4228 		return;
4229 	}
4230 	token = next_token(NULL, NULL, cfile);
4231 	if (token != SEMI) {
4232 		dfree(ia, MDL);
4233 		parse_warn(cfile, "semicolon expected.");
4234 		skip_to_semi(cfile);
4235 		return;
4236 	}
4237 
4238 	/*
4239 	 * Fill it.
4240 	 */
4241 	ia->cidrnet.bits = atoi(val);
4242 	if ((ia->cidrnet.bits < 0) || (ia->cidrnet.bits > 128)) {
4243 		dfree(ia, MDL);
4244 		parse_warn(cfile, "networks have 0 to 128 bits");
4245 		return;
4246 	}
4247 	if (!is_cidr_mask_valid(&ia->cidrnet.lo_addr, ia->cidrnet.bits)) {
4248 		dfree(ia, MDL);
4249 		parse_warn(cfile, "network mask too short");
4250 		return;
4251 	}
4252 
4253 	/*
4254 	 * Store it.
4255 	 */
4256 	*h = ia;
4257 	return;
4258 }
4259 
4260 /*!
4261  *
4262  * \brief Parse a pool6 statement
4263  *
4264  * Pool statements are used to group declarations and permit & deny information
4265  * with a specific address range.  They must be declared within a shared network
4266  * or subnet and there may be multiple pools withing a shared network or subnet.
4267  * Each pool may have a different set of permit or deny options.
4268  *
4269  * \param[in] cfile = the configuration file being parsed
4270  * \param[in] group = the group structure for this pool
4271  * \param[in] type  = the type of the enclosing statement.  This must be
4272  *		      SUBNET_DECL for this function.
4273  *
4274  * \return
4275  * void - This function either parses the statement and updates the structures
4276  *        or it generates an error message and possible halts the program if
4277  *        it encounters a problem.
4278  */
4279 void parse_pool6_statement (cfile, group, type)
4280 	struct parse *cfile;
4281 	struct group *group;
4282 	int type;
4283 {
4284 	enum dhcp_token token;
4285 	const char *val;
4286 	int done = 0;
4287 	struct ipv6_pond *pond, **p;
4288 	int declaration = 0;
4289 	isc_result_t status;
4290 
4291 	pond = NULL;
4292 	status = ipv6_pond_allocate(&pond, MDL);
4293 	if (status != ISC_R_SUCCESS)
4294 		log_fatal("no memory for pool6: %s",
4295 			  isc_result_totext (status));
4296 
4297 	if (type == SUBNET_DECL)
4298 		shared_network_reference(&pond->shared_network,
4299 					 group->subnet->shared_network,
4300 					 MDL);
4301 	else {
4302 		parse_warn(cfile, "Dynamic pool6s are only valid inside "
4303 				  "subnet statements.");
4304 		skip_to_semi(cfile);
4305 		return;
4306 	}
4307 
4308 	if (clone_group(&pond->group, group, MDL) == 0)
4309 		log_fatal("can't clone pool6 group.");
4310 
4311 	if (parse_lbrace(cfile) == 0) {
4312 		ipv6_pond_dereference(&pond, MDL);
4313 		return;
4314 	}
4315 
4316 	do {
4317 		token = peek_token(&val, NULL, cfile);
4318 		switch (token) {
4319 		      case RANGE6:
4320 			skip_token(NULL, NULL, cfile);
4321 			parse_address_range6(cfile, group, pond);
4322 			break;
4323 
4324 		      case PREFIX6:
4325 			skip_token(NULL, NULL, cfile);
4326 			parse_prefix6(cfile, group, pond);
4327 			break;
4328 
4329 		      case ALLOW:
4330 			skip_token(NULL, NULL, cfile);
4331 			get_permit(cfile, &pond->permit_list, 1,
4332 				   &pond->valid_from, &pond->valid_until);
4333 			break;
4334 
4335 		      case DENY:
4336 			skip_token(NULL, NULL, cfile);
4337 			get_permit(cfile, &pond->prohibit_list, 0,
4338 				   &pond->valid_from, &pond->valid_until);
4339 			break;
4340 
4341 		      case RBRACE:
4342 			skip_token(&val, NULL, cfile);
4343 			done = 1;
4344 			break;
4345 
4346 		      case END_OF_FILE:
4347 			/*
4348 			 * We can get to END_OF_FILE if, for instance,
4349 			 * the parse_statement() reads all available tokens
4350 			 * and leaves us at the end.
4351 			 */
4352 			parse_warn(cfile, "unexpected end of file");
4353 			goto cleanup;
4354 
4355 		      default:
4356 			declaration = parse_statement(cfile, pond->group,
4357 						      POOL_DECL, NULL,
4358 						      declaration);
4359 			break;
4360 		}
4361 	} while (!done);
4362 
4363 	/*
4364 	 * A possible optimization is to see if this pond can be merged into
4365 	 * an already existing pond.  But I'll pass on that for now as we need
4366 	 * to repoint the leases to the other pond which is annoying. SAR
4367 	 */
4368 
4369 	/*
4370 	 * Add this pond to the list (will need updating if we add the
4371 	 * optimization).
4372 	 */
4373 
4374 	p = &pond->shared_network->ipv6_pond;
4375 	for (; *p; p = &((*p)->next))
4376 		;
4377 	ipv6_pond_reference(p, pond, MDL);
4378 
4379 	/* Don't allow a pool6 declaration with no addresses or
4380 	   prefixes, since it is probably a configuration error. */
4381 	if (pond->ipv6_pools == NULL) {
4382 		parse_warn (cfile, "Pool6 declaration with no %s.",
4383 			    "address range6 or prefix6");
4384 		log_error ("Pool6 declarations must always contain at least");
4385 		log_error ("one range6 or prefix6 statement.");
4386 	}
4387 
4388 cleanup:
4389 	ipv6_pond_dereference(&pond, MDL);
4390 }
4391 
4392 
4393 
4394 #endif /* DHCPv6 */
4395 
4396 /* allow-deny-keyword :== BOOTP
4397    			| BOOTING
4398 			| DYNAMIC_BOOTP
4399 			| UNKNOWN_CLIENTS */
4400 
4401 int parse_allow_deny (oc, cfile, flag)
4402 	struct option_cache **oc;
4403 	struct parse *cfile;
4404 	int flag;
4405 {
4406 	enum dhcp_token token;
4407 	const char *val;
4408 	unsigned char rf = flag;
4409 	unsigned code;
4410 	struct option *option = NULL;
4411 	struct expression *data = (struct expression *)0;
4412 	int status;
4413 
4414 	if (!make_const_data (&data, &rf, 1, 0, 1, MDL))
4415 		return 0;
4416 
4417 	token = next_token (&val, (unsigned *)0, cfile);
4418 	switch (token) {
4419 	      case TOKEN_BOOTP:
4420 		code = SV_ALLOW_BOOTP;
4421 		break;
4422 
4423 	      case BOOTING:
4424 		code = SV_ALLOW_BOOTING;
4425 		break;
4426 
4427 	      case DYNAMIC_BOOTP:
4428 		code = SV_DYNAMIC_BOOTP;
4429 		break;
4430 
4431 	      case UNKNOWN_CLIENTS:
4432 		code = SV_BOOT_UNKNOWN_CLIENTS;
4433 		break;
4434 
4435 	      case DUPLICATES:
4436 		code = SV_DUPLICATES;
4437 		break;
4438 
4439 	      case DECLINES:
4440 		code= SV_DECLINES;
4441 		break;
4442 
4443 	      case CLIENT_UPDATES:
4444 		code = SV_CLIENT_UPDATES;
4445 		break;
4446 
4447 	      case LEASEQUERY:
4448 		code = SV_LEASEQUERY;
4449 		break;
4450 
4451 	      default:
4452 		parse_warn (cfile, "expecting allow/deny key");
4453 		skip_to_semi (cfile);
4454 		return 0;
4455 	}
4456 	/* Reference on option is passed to option cache. */
4457 	if (!option_code_hash_lookup(&option, server_universe.code_hash,
4458 				     &code, 0, MDL))
4459 		log_fatal("Unable to find server option %u (%s:%d).",
4460 			  code, MDL);
4461 	status = option_cache(oc, NULL, data, option, MDL);
4462 	expression_dereference (&data, MDL);
4463 	parse_semi (cfile);
4464 	return status;
4465 }
4466 
4467 void
4468 parse_ia_na_declaration(struct parse *cfile) {
4469 #if !defined(DHCPv6)
4470 	parse_warn(cfile, "No DHCPv6 support.");
4471 	skip_to_semi(cfile);
4472 #else /* defined(DHCPv6) */
4473 	enum dhcp_token token;
4474 	struct ia_xx *ia;
4475 	const char *val;
4476 	struct ia_xx *old_ia;
4477 	unsigned int len;
4478 	u_int32_t iaid;
4479 	struct iaddr iaddr;
4480 	binding_state_t state;
4481 	u_int32_t prefer;
4482 	u_int32_t valid;
4483 	TIME end_time;
4484 	struct iasubopt *iaaddr;
4485 	struct ipv6_pool *pool;
4486 	char addr_buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
4487 	isc_boolean_t newbinding;
4488 	struct binding_scope *scope = NULL;
4489 	struct binding *bnd;
4490 	struct binding_value *nv = NULL;
4491 	struct executable_statement *on_star[2] = {NULL, NULL};
4492 	int lose, i;
4493 
4494         if (local_family != AF_INET6) {
4495                 parse_warn(cfile, "IA_NA is only supported in DHCPv6 mode.");
4496                 skip_to_semi(cfile);
4497                 return;
4498         }
4499 
4500 	token = next_token(&val, &len, cfile);
4501 	if (token != STRING) {
4502 		parse_warn(cfile, "corrupt lease file; "
4503 				  "expecting an iaid+ia_na string");
4504 		skip_to_semi(cfile);
4505 		return;
4506 	}
4507 	if (len < 5) {
4508 		parse_warn(cfile, "corrupt lease file; "
4509 				  "iaid+ia_na string too short");
4510 		skip_to_semi(cfile);
4511 		return;
4512 	}
4513 
4514 	memcpy(&iaid, val, 4);
4515 	ia = NULL;
4516 	if (ia_allocate(&ia, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) {
4517 		log_fatal("Out of memory.");
4518 	}
4519 	ia->ia_type = D6O_IA_NA;
4520 
4521 	token = next_token(&val, NULL, cfile);
4522 	if (token != LBRACE) {
4523 		parse_warn(cfile, "corrupt lease file; expecting left brace");
4524 		skip_to_semi(cfile);
4525 		return;
4526 	}
4527 
4528 	for (;;) {
4529 		token = next_token(&val, NULL, cfile);
4530 		if (token == RBRACE) break;
4531 
4532 		if (token == CLTT) {
4533 			ia->cltt = parse_date (cfile);
4534 			continue;
4535 		}
4536 
4537 		if (token != IAADDR) {
4538 			parse_warn(cfile, "corrupt lease file; "
4539 					  "expecting IAADDR or right brace");
4540 			skip_to_semi(cfile);
4541 			return;
4542 		}
4543 
4544 		if (!parse_ip6_addr(cfile, &iaddr)) {
4545 			parse_warn(cfile, "corrupt lease file; "
4546 					  "expecting IPv6 address");
4547 			skip_to_semi(cfile);
4548 			return;
4549 		}
4550 
4551 		token = next_token(&val, NULL, cfile);
4552 		if (token != LBRACE) {
4553 			parse_warn(cfile, "corrupt lease file; "
4554 					  "expecting left brace");
4555 			skip_to_semi(cfile);
4556 			return;
4557 		}
4558 
4559 		state = FTS_LAST+1;
4560 		prefer = valid = 0;
4561 		end_time = -1;
4562 		for (;;) {
4563 			token = next_token(&val, NULL, cfile);
4564 			if (token == RBRACE) break;
4565 
4566 			switch(token) {
4567 				/* Lease binding state. */
4568 			     case BINDING:
4569 				token = next_token(&val, NULL, cfile);
4570 				if (token != STATE) {
4571 					parse_warn(cfile, "corrupt lease file; "
4572 							  "expecting state");
4573 					skip_to_semi(cfile);
4574 					return;
4575 				}
4576 				token = next_token(&val, NULL, cfile);
4577 				switch (token) {
4578 					case TOKEN_ABANDONED:
4579 						state = FTS_ABANDONED;
4580 						break;
4581 					case TOKEN_FREE:
4582 						state = FTS_FREE;
4583 						break;
4584 					case TOKEN_ACTIVE:
4585 						state = FTS_ACTIVE;
4586 						break;
4587 					case TOKEN_EXPIRED:
4588 						state = FTS_EXPIRED;
4589 						break;
4590 					case TOKEN_RELEASED:
4591 						state = FTS_RELEASED;
4592 						break;
4593 					default:
4594 						parse_warn(cfile,
4595 							   "corrupt lease "
4596 							   "file; "
4597 					    		   "expecting a "
4598 							   "binding state.");
4599 						skip_to_semi(cfile);
4600 						return;
4601 				}
4602 
4603 				token = next_token(&val, NULL, cfile);
4604 				if (token != SEMI) {
4605 					parse_warn(cfile, "corrupt lease file; "
4606 							  "expecting "
4607 							  "semicolon.");
4608 				}
4609 				break;
4610 
4611 				/* Lease preferred lifetime. */
4612 			      case PREFERRED_LIFE:
4613 				token = next_token(&val, NULL, cfile);
4614 				if (token != NUMBER) {
4615 					parse_warn(cfile, "%s is not a valid "
4616 							  "preferred time",
4617 						   val);
4618 					skip_to_semi(cfile);
4619 					continue;
4620 				}
4621 				prefer = atoi (val);
4622 
4623 				/*
4624 				 * Currently we peek for the semi-colon to
4625 				 * allow processing of older lease files that
4626 				 * don't have the semi-colon.  Eventually we
4627 				 * should remove the peeking code.
4628 				 */
4629 				token = peek_token(&val, NULL, cfile);
4630 				if (token == SEMI) {
4631 					skip_token(&val, NULL, cfile);
4632 				} else {
4633 					parse_warn(cfile,
4634 						   "corrupt lease file; "
4635 						   "expecting semicolon.");
4636 				}
4637 				break;
4638 
4639 				/* Lease valid lifetime. */
4640 			      case MAX_LIFE:
4641 				token = next_token(&val, NULL, cfile);
4642 				if (token != NUMBER) {
4643 					parse_warn(cfile, "%s is not a valid "
4644 							  "max time",
4645 						   val);
4646 					skip_to_semi(cfile);
4647 					continue;
4648 				}
4649 				valid = atoi (val);
4650 
4651 				/*
4652 				 * Currently we peek for the semi-colon to
4653 				 * allow processing of older lease files that
4654 				 * don't have the semi-colon.  Eventually we
4655 				 * should remove the peeking code.
4656 				 */
4657 				token = peek_token(&val, NULL, cfile);
4658 				if (token == SEMI) {
4659 					skip_token(&val, NULL, cfile);
4660 				} else {
4661 					parse_warn(cfile,
4662 						   "corrupt lease file; "
4663 						   "expecting semicolon.");
4664 				}
4665 				break;
4666 
4667 				/* Lease expiration time. */
4668 			      case ENDS:
4669 				end_time = parse_date(cfile);
4670 				break;
4671 
4672 				/* Lease binding scopes. */
4673 			      case TOKEN_SET:
4674 				token = next_token(&val, NULL, cfile);
4675 				if ((token != NAME) &&
4676 				    (token != NUMBER_OR_NAME)) {
4677 					parse_warn(cfile, "%s is not a valid "
4678 							  "variable name",
4679 						   val);
4680 					skip_to_semi(cfile);
4681 					continue;
4682 				}
4683 
4684 				if (scope != NULL)
4685 					bnd = find_binding(scope, val);
4686 				else {
4687 					if (!binding_scope_allocate(&scope,
4688 								    MDL)) {
4689 						log_fatal("Out of memory for "
4690 							  "lease binding "
4691 							  "scope.");
4692 					}
4693 
4694 					bnd = NULL;
4695 				}
4696 
4697 				if (bnd == NULL) {
4698 					bnd = dmalloc(sizeof(*bnd),
4699 							  MDL);
4700 					if (bnd == NULL) {
4701 						log_fatal("No memory for "
4702 							  "lease binding.");
4703 					}
4704 
4705 					bnd->name = dmalloc(strlen(val) + 1,
4706 							    MDL);
4707 					if (bnd->name == NULL) {
4708 						log_fatal("No memory for "
4709 							  "binding name.");
4710 					}
4711 					strcpy(bnd->name, val);
4712 
4713 					newbinding = ISC_TRUE;
4714 				} else {
4715 					newbinding = ISC_FALSE;
4716 				}
4717 
4718 				if (!binding_value_allocate(&nv, MDL)) {
4719 					log_fatal("no memory for binding "
4720 						  "value.");
4721 				}
4722 
4723 				token = next_token(NULL, NULL, cfile);
4724 				if (token != EQUAL) {
4725 					parse_warn(cfile, "expecting '=' in "
4726 							  "set statement.");
4727 					goto binding_err;
4728 				}
4729 
4730 				if (!parse_binding_value(cfile, nv)) {
4731 				      binding_err:
4732 					binding_value_dereference(&nv, MDL);
4733 					binding_scope_dereference(&scope, MDL);
4734 					return;
4735 				}
4736 
4737 				if (newbinding) {
4738 					binding_value_reference(&bnd->value,
4739 								nv, MDL);
4740 					bnd->next = scope->bindings;
4741 					scope->bindings = bnd;
4742 				} else {
4743 					binding_value_dereference(&bnd->value,
4744 								  MDL);
4745 					binding_value_reference(&bnd->value,
4746 								nv, MDL);
4747 				}
4748 
4749 				binding_value_dereference(&nv, MDL);
4750 				parse_semi(cfile);
4751 				break;
4752 
4753 			      case ON:
4754 				lose = 0;
4755 				/*
4756 				 * Depending on the user config we may
4757 				 * have one or two on statements.  We
4758 				 * need to save information about both
4759 				 * of them until we allocate the
4760 				 * iasubopt to hold them.
4761 				 */
4762 				if (on_star[0] == NULL) {
4763 					if (!parse_on_statement (&on_star[0],
4764 								 cfile,
4765 								 &lose)) {
4766 						parse_warn(cfile,
4767 							   "corrupt lease "
4768 							   "file; bad ON "
4769 							   "statement");
4770 						skip_to_rbrace (cfile, 1);
4771 						return;
4772 					}
4773 				} else {
4774 					if (!parse_on_statement (&on_star[1],
4775 								 cfile,
4776 								 &lose)) {
4777 						parse_warn(cfile,
4778 							   "corrupt lease "
4779 							   "file; bad ON "
4780 							   "statement");
4781 						skip_to_rbrace (cfile, 1);
4782 						return;
4783 					}
4784 				}
4785 
4786 				break;
4787 
4788 			      default:
4789 				parse_warn(cfile, "corrupt lease file; "
4790 						  "expecting ia_na contents, "
4791 						  "got '%s'", val);
4792 				skip_to_semi(cfile);
4793 				continue;
4794 			}
4795 		}
4796 
4797 		if (state == FTS_LAST+1) {
4798 			parse_warn(cfile, "corrupt lease file; "
4799 					  "missing state in iaaddr");
4800 			return;
4801 		}
4802 		if (end_time == -1) {
4803 			parse_warn(cfile, "corrupt lease file; "
4804 					  "missing end time in iaaddr");
4805 			return;
4806 		}
4807 
4808 		iaaddr = NULL;
4809 		if (iasubopt_allocate(&iaaddr, MDL) != ISC_R_SUCCESS) {
4810 			log_fatal("Out of memory.");
4811 		}
4812 		memcpy(&iaaddr->addr, iaddr.iabuf, sizeof(iaaddr->addr));
4813 		iaaddr->plen = 0;
4814 		iaaddr->state = state;
4815 		iaaddr->prefer = prefer;
4816 		iaaddr->valid = valid;
4817 		if (iaaddr->state == FTS_RELEASED)
4818 			iaaddr->hard_lifetime_end_time = end_time;
4819 
4820 		if (scope != NULL) {
4821 			binding_scope_reference(&iaaddr->scope, scope, MDL);
4822 			binding_scope_dereference(&scope, MDL);
4823 		}
4824 
4825 		/*
4826 		 * Check on both on statements.  Because of how we write the
4827 		 * lease file we know which is which if we have two but it's
4828 		 * easier to write the code to be independent.  We do assume
4829 		 * that the statements won't overlap.
4830 		 */
4831 		for (i = 0;
4832 		     (i < 2) && on_star[i] != NULL ;
4833 		     i++) {
4834 			if ((on_star[i]->data.on.evtypes & ON_EXPIRY) &&
4835 			    on_star[i]->data.on.statements) {
4836 				executable_statement_reference
4837 					(&iaaddr->on_star.on_expiry,
4838 					 on_star[i]->data.on.statements, MDL);
4839 			}
4840 			if ((on_star[i]->data.on.evtypes & ON_RELEASE) &&
4841 			    on_star[i]->data.on.statements) {
4842 				executable_statement_reference
4843 					(&iaaddr->on_star.on_release,
4844 					 on_star[i]->data.on.statements, MDL);
4845 			}
4846 			executable_statement_dereference (&on_star[i], MDL);
4847 		}
4848 
4849 		/* find the pool this address is in */
4850 		pool = NULL;
4851 		if (find_ipv6_pool(&pool, D6O_IA_NA,
4852 				   &iaaddr->addr) != ISC_R_SUCCESS) {
4853 			inet_ntop(AF_INET6, &iaaddr->addr,
4854 				  addr_buf, sizeof(addr_buf));
4855 			parse_warn(cfile, "no pool found for address %s",
4856 				   addr_buf);
4857 			return;
4858 		}
4859 
4860 		/* remove old information */
4861 		if (cleanup_lease6(ia_na_active, pool,
4862 				   iaaddr, ia) != ISC_R_SUCCESS) {
4863 			inet_ntop(AF_INET6, &iaaddr->addr,
4864 				  addr_buf, sizeof(addr_buf));
4865 			parse_warn(cfile, "duplicate na lease for address %s",
4866 				   addr_buf);
4867 		}
4868 
4869 		/*
4870 		 * if we like the lease we add it to our various structues
4871 		 * otherwise we leave it and it will get cleaned when we
4872 		 * do the iasubopt_dereference.
4873 		 */
4874 		if ((state == FTS_ACTIVE) || (state == FTS_ABANDONED)) {
4875 			ia_add_iasubopt(ia, iaaddr, MDL);
4876 			ia_reference(&iaaddr->ia, ia, MDL);
4877 			add_lease6(pool, iaaddr, end_time);
4878 		}
4879 
4880 		iasubopt_dereference(&iaaddr, MDL);
4881 		ipv6_pool_dereference(&pool, MDL);
4882 	}
4883 
4884 	/*
4885 	 * If we have an existing record for this IA_NA, remove it.
4886 	 */
4887 	old_ia = NULL;
4888 	if (ia_hash_lookup(&old_ia, ia_na_active,
4889 			   (unsigned char *)ia->iaid_duid.data,
4890 			   ia->iaid_duid.len, MDL)) {
4891 		ia_hash_delete(ia_na_active,
4892 			       (unsigned char *)ia->iaid_duid.data,
4893 			       ia->iaid_duid.len, MDL);
4894 		ia_dereference(&old_ia, MDL);
4895 	}
4896 
4897 	/*
4898 	 * If we have addresses, add this, otherwise don't bother.
4899 	 */
4900 	if (ia->num_iasubopt > 0) {
4901 		ia_hash_add(ia_na_active,
4902 			    (unsigned char *)ia->iaid_duid.data,
4903 			    ia->iaid_duid.len, ia, MDL);
4904 	}
4905 	ia_dereference(&ia, MDL);
4906 #endif /* defined(DHCPv6) */
4907 }
4908 
4909 void
4910 parse_ia_ta_declaration(struct parse *cfile) {
4911 #if !defined(DHCPv6)
4912 	parse_warn(cfile, "No DHCPv6 support.");
4913 	skip_to_semi(cfile);
4914 #else /* defined(DHCPv6) */
4915 	enum dhcp_token token;
4916 	struct ia_xx *ia;
4917 	const char *val;
4918 	struct ia_xx *old_ia;
4919 	unsigned int len;
4920 	u_int32_t iaid;
4921 	struct iaddr iaddr;
4922 	binding_state_t state;
4923 	u_int32_t prefer;
4924 	u_int32_t valid;
4925 	TIME end_time;
4926 	struct iasubopt *iaaddr;
4927 	struct ipv6_pool *pool;
4928 	char addr_buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
4929 	isc_boolean_t newbinding;
4930 	struct binding_scope *scope = NULL;
4931 	struct binding *bnd;
4932 	struct binding_value *nv = NULL;
4933 	struct executable_statement *on_star[2] = {NULL, NULL};
4934 	int lose, i;
4935 
4936         if (local_family != AF_INET6) {
4937                 parse_warn(cfile, "IA_TA is only supported in DHCPv6 mode.");
4938                 skip_to_semi(cfile);
4939                 return;
4940         }
4941 
4942 	token = next_token(&val, &len, cfile);
4943 	if (token != STRING) {
4944 		parse_warn(cfile, "corrupt lease file; "
4945 				  "expecting an iaid+ia_ta string");
4946 		skip_to_semi(cfile);
4947 		return;
4948 	}
4949 	if (len < 5) {
4950 		parse_warn(cfile, "corrupt lease file; "
4951 				  "iaid+ia_ta string too short");
4952 		skip_to_semi(cfile);
4953 		return;
4954 	}
4955 
4956 	memcpy(&iaid, val, 4);
4957 	ia = NULL;
4958 	if (ia_allocate(&ia, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) {
4959 		log_fatal("Out of memory.");
4960 	}
4961 	ia->ia_type = D6O_IA_TA;
4962 
4963 	token = next_token(&val, NULL, cfile);
4964 	if (token != LBRACE) {
4965 		parse_warn(cfile, "corrupt lease file; expecting left brace");
4966 		skip_to_semi(cfile);
4967 		return;
4968 	}
4969 
4970 	for (;;) {
4971 		token = next_token(&val, NULL, cfile);
4972 		if (token == RBRACE) break;
4973 
4974 		if (token == CLTT) {
4975 			ia->cltt = parse_date (cfile);
4976 			continue;
4977 		}
4978 
4979 		if (token != IAADDR) {
4980 			parse_warn(cfile, "corrupt lease file; "
4981 					  "expecting IAADDR or right brace");
4982 			skip_to_semi(cfile);
4983 			return;
4984 		}
4985 
4986 		if (!parse_ip6_addr(cfile, &iaddr)) {
4987 			parse_warn(cfile, "corrupt lease file; "
4988 					  "expecting IPv6 address");
4989 			skip_to_semi(cfile);
4990 			return;
4991 		}
4992 
4993 		token = next_token(&val, NULL, cfile);
4994 		if (token != LBRACE) {
4995 			parse_warn(cfile, "corrupt lease file; "
4996 					  "expecting left brace");
4997 			skip_to_semi(cfile);
4998 			return;
4999 		}
5000 
5001 		state = FTS_LAST+1;
5002 		prefer = valid = 0;
5003 		end_time = -1;
5004 		for (;;) {
5005 			token = next_token(&val, NULL, cfile);
5006 			if (token == RBRACE) break;
5007 
5008 			switch(token) {
5009 				/* Lease binding state. */
5010 			     case BINDING:
5011 				token = next_token(&val, NULL, cfile);
5012 				if (token != STATE) {
5013 					parse_warn(cfile, "corrupt lease file; "
5014 							  "expecting state");
5015 					skip_to_semi(cfile);
5016 					return;
5017 				}
5018 				token = next_token(&val, NULL, cfile);
5019 				switch (token) {
5020 					case TOKEN_ABANDONED:
5021 						state = FTS_ABANDONED;
5022 						break;
5023 					case TOKEN_FREE:
5024 						state = FTS_FREE;
5025 						break;
5026 					case TOKEN_ACTIVE:
5027 						state = FTS_ACTIVE;
5028 						break;
5029 					case TOKEN_EXPIRED:
5030 						state = FTS_EXPIRED;
5031 						break;
5032 					case TOKEN_RELEASED:
5033 						state = FTS_RELEASED;
5034 						break;
5035 					default:
5036 						parse_warn(cfile,
5037 							   "corrupt lease "
5038 							   "file; "
5039 					    		   "expecting a "
5040 							   "binding state.");
5041 						skip_to_semi(cfile);
5042 						return;
5043 				}
5044 
5045 				token = next_token(&val, NULL, cfile);
5046 				if (token != SEMI) {
5047 					parse_warn(cfile, "corrupt lease file; "
5048 							  "expecting "
5049 							  "semicolon.");
5050 				}
5051 				break;
5052 
5053 				/* Lease preferred lifetime. */
5054 			      case PREFERRED_LIFE:
5055 				token = next_token(&val, NULL, cfile);
5056 				if (token != NUMBER) {
5057 					parse_warn(cfile, "%s is not a valid "
5058 							  "preferred time",
5059 						   val);
5060 					skip_to_semi(cfile);
5061 					continue;
5062 				}
5063 				prefer = atoi (val);
5064 
5065 				/*
5066 				 * Currently we peek for the semi-colon to
5067 				 * allow processing of older lease files that
5068 				 * don't have the semi-colon.  Eventually we
5069 				 * should remove the peeking code.
5070 				 */
5071 				token = peek_token(&val, NULL, cfile);
5072 				if (token == SEMI) {
5073 					skip_token(&val, NULL, cfile);
5074 				} else {
5075 					parse_warn(cfile,
5076 						   "corrupt lease file; "
5077 						   "expecting semicolon.");
5078 				}
5079 				break;
5080 
5081 				/* Lease valid lifetime. */
5082 			      case MAX_LIFE:
5083 				token = next_token(&val, NULL, cfile);
5084 				if (token != NUMBER) {
5085 					parse_warn(cfile, "%s is not a valid "
5086 							  "max time",
5087 						   val);
5088 					skip_to_semi(cfile);
5089 					continue;
5090 				}
5091 				valid = atoi (val);
5092 
5093 				/*
5094 				 * Currently we peek for the semi-colon to
5095 				 * allow processing of older lease files that
5096 				 * don't have the semi-colon.  Eventually we
5097 				 * should remove the peeking code.
5098 				 */
5099 				token = peek_token(&val, NULL, cfile);
5100 				if (token == SEMI) {
5101 					skip_token(&val, NULL, cfile);
5102 				} else {
5103 					parse_warn(cfile,
5104 						   "corrupt lease file; "
5105 						   "expecting semicolon.");
5106 				}
5107 				break;
5108 
5109 				/* Lease expiration time. */
5110 			      case ENDS:
5111 				end_time = parse_date(cfile);
5112 				break;
5113 
5114 				/* Lease binding scopes. */
5115 			      case TOKEN_SET:
5116 				token = next_token(&val, NULL, cfile);
5117 				if ((token != NAME) &&
5118 				    (token != NUMBER_OR_NAME)) {
5119 					parse_warn(cfile, "%s is not a valid "
5120 							  "variable name",
5121 						   val);
5122 					skip_to_semi(cfile);
5123 					continue;
5124 				}
5125 
5126 				if (scope != NULL)
5127 					bnd = find_binding(scope, val);
5128 				else {
5129 					if (!binding_scope_allocate(&scope,
5130 								    MDL)) {
5131 						log_fatal("Out of memory for "
5132 							  "lease binding "
5133 							  "scope.");
5134 					}
5135 
5136 					bnd = NULL;
5137 				}
5138 
5139 				if (bnd == NULL) {
5140 					bnd = dmalloc(sizeof(*bnd),
5141 							  MDL);
5142 					if (bnd == NULL) {
5143 						log_fatal("No memory for "
5144 							  "lease binding.");
5145 					}
5146 
5147 					bnd->name = dmalloc(strlen(val) + 1,
5148 							    MDL);
5149 					if (bnd->name == NULL) {
5150 						log_fatal("No memory for "
5151 							  "binding name.");
5152 					}
5153 					strcpy(bnd->name, val);
5154 
5155 					newbinding = ISC_TRUE;
5156 				} else {
5157 					newbinding = ISC_FALSE;
5158 				}
5159 
5160 				if (!binding_value_allocate(&nv, MDL)) {
5161 					log_fatal("no memory for binding "
5162 						  "value.");
5163 				}
5164 
5165 				token = next_token(NULL, NULL, cfile);
5166 				if (token != EQUAL) {
5167 					parse_warn(cfile, "expecting '=' in "
5168 							  "set statement.");
5169 					goto binding_err;
5170 				}
5171 
5172 				if (!parse_binding_value(cfile, nv)) {
5173 				      binding_err:
5174 					binding_value_dereference(&nv, MDL);
5175 					binding_scope_dereference(&scope, MDL);
5176 					return;
5177 				}
5178 
5179 				if (newbinding) {
5180 					binding_value_reference(&bnd->value,
5181 								nv, MDL);
5182 					bnd->next = scope->bindings;
5183 					scope->bindings = bnd;
5184 				} else {
5185 					binding_value_dereference(&bnd->value,
5186 								  MDL);
5187 					binding_value_reference(&bnd->value,
5188 								nv, MDL);
5189 				}
5190 
5191 				binding_value_dereference(&nv, MDL);
5192 				parse_semi(cfile);
5193 				break;
5194 
5195 			      case ON:
5196 				lose = 0;
5197 				/*
5198 				 * Depending on the user config we may
5199 				 * have one or two on statements.  We
5200 				 * need to save information about both
5201 				 * of them until we allocate the
5202 				 * iasubopt to hold them.
5203 				 */
5204 				if (on_star[0] == NULL) {
5205 					if (!parse_on_statement (&on_star[0],
5206 								 cfile,
5207 								 &lose)) {
5208 						parse_warn(cfile,
5209 							   "corrupt lease "
5210 							   "file; bad ON "
5211 							   "statement");
5212 						skip_to_rbrace (cfile, 1);
5213 						return;
5214 					}
5215 				} else {
5216 					if (!parse_on_statement (&on_star[1],
5217 								 cfile,
5218 								 &lose)) {
5219 						parse_warn(cfile,
5220 							   "corrupt lease "
5221 							   "file; bad ON "
5222 							   "statement");
5223 						skip_to_rbrace (cfile, 1);
5224 						return;
5225 					}
5226 				}
5227 
5228 				break;
5229 
5230 			      default:
5231 				parse_warn(cfile, "corrupt lease file; "
5232 						  "expecting ia_ta contents, "
5233 						  "got '%s'", val);
5234 				skip_to_semi(cfile);
5235 				continue;
5236 			}
5237 		}
5238 
5239 		if (state == FTS_LAST+1) {
5240 			parse_warn(cfile, "corrupt lease file; "
5241 					  "missing state in iaaddr");
5242 			return;
5243 		}
5244 		if (end_time == -1) {
5245 			parse_warn(cfile, "corrupt lease file; "
5246 					  "missing end time in iaaddr");
5247 			return;
5248 		}
5249 
5250 		iaaddr = NULL;
5251 		if (iasubopt_allocate(&iaaddr, MDL) != ISC_R_SUCCESS) {
5252 			log_fatal("Out of memory.");
5253 		}
5254 		memcpy(&iaaddr->addr, iaddr.iabuf, sizeof(iaaddr->addr));
5255 		iaaddr->plen = 0;
5256 		iaaddr->state = state;
5257 		iaaddr->prefer = prefer;
5258 		iaaddr->valid = valid;
5259 		if (iaaddr->state == FTS_RELEASED)
5260 			iaaddr->hard_lifetime_end_time = end_time;
5261 
5262 		if (scope != NULL) {
5263 			binding_scope_reference(&iaaddr->scope, scope, MDL);
5264 			binding_scope_dereference(&scope, MDL);
5265 		}
5266 
5267 		/*
5268 		 * Check on both on statements.  Because of how we write the
5269 		 * lease file we know which is which if we have two but it's
5270 		 * easier to write the code to be independent.  We do assume
5271 		 * that the statements won't overlap.
5272 		 */
5273 		for (i = 0;
5274 		     (i < 2) && on_star[i] != NULL ;
5275 		     i++) {
5276 			if ((on_star[i]->data.on.evtypes & ON_EXPIRY) &&
5277 			    on_star[i]->data.on.statements) {
5278 				executable_statement_reference
5279 					(&iaaddr->on_star.on_expiry,
5280 					 on_star[i]->data.on.statements, MDL);
5281 			}
5282 			if ((on_star[i]->data.on.evtypes & ON_RELEASE) &&
5283 			    on_star[i]->data.on.statements) {
5284 				executable_statement_reference
5285 					(&iaaddr->on_star.on_release,
5286 					 on_star[i]->data.on.statements, MDL);
5287 			}
5288 			executable_statement_dereference (&on_star[i], MDL);
5289 		}
5290 
5291 		/* find the pool this address is in */
5292 		pool = NULL;
5293 		if (find_ipv6_pool(&pool, D6O_IA_TA,
5294 				   &iaaddr->addr) != ISC_R_SUCCESS) {
5295 			inet_ntop(AF_INET6, &iaaddr->addr,
5296 				  addr_buf, sizeof(addr_buf));
5297 			parse_warn(cfile, "no pool found for address %s",
5298 				   addr_buf);
5299 			return;
5300 		}
5301 
5302 		/* remove old information */
5303 		if (cleanup_lease6(ia_ta_active, pool,
5304 				   iaaddr, ia) != ISC_R_SUCCESS) {
5305 			inet_ntop(AF_INET6, &iaaddr->addr,
5306 				  addr_buf, sizeof(addr_buf));
5307 			parse_warn(cfile, "duplicate ta lease for address %s",
5308 				   addr_buf);
5309 		}
5310 
5311 		/*
5312 		 * if we like the lease we add it to our various structues
5313 		 * otherwise we leave it and it will get cleaned when we
5314 		 * do the iasubopt_dereference.
5315 		 */
5316 		if ((state == FTS_ACTIVE) || (state == FTS_ABANDONED)) {
5317 			ia_add_iasubopt(ia, iaaddr, MDL);
5318 			ia_reference(&iaaddr->ia, ia, MDL);
5319 			add_lease6(pool, iaaddr, end_time);
5320 		}
5321 
5322 		ipv6_pool_dereference(&pool, MDL);
5323 		iasubopt_dereference(&iaaddr, MDL);
5324 	}
5325 
5326 	/*
5327 	 * If we have an existing record for this IA_TA, remove it.
5328 	 */
5329 	old_ia = NULL;
5330 	if (ia_hash_lookup(&old_ia, ia_ta_active,
5331 			   (unsigned char *)ia->iaid_duid.data,
5332 			   ia->iaid_duid.len, MDL)) {
5333 		ia_hash_delete(ia_ta_active,
5334 			       (unsigned char *)ia->iaid_duid.data,
5335 			       ia->iaid_duid.len, MDL);
5336 		ia_dereference(&old_ia, MDL);
5337 	}
5338 
5339 	/*
5340 	 * If we have addresses, add this, otherwise don't bother.
5341 	 */
5342 	if (ia->num_iasubopt > 0) {
5343 		ia_hash_add(ia_ta_active,
5344 			    (unsigned char *)ia->iaid_duid.data,
5345 			    ia->iaid_duid.len, ia, MDL);
5346 	}
5347 	ia_dereference(&ia, MDL);
5348 #endif /* defined(DHCPv6) */
5349 }
5350 
5351 void
5352 parse_ia_pd_declaration(struct parse *cfile) {
5353 #if !defined(DHCPv6)
5354 	parse_warn(cfile, "No DHCPv6 support.");
5355 	skip_to_semi(cfile);
5356 #else /* defined(DHCPv6) */
5357 	enum dhcp_token token;
5358 	struct ia_xx *ia;
5359 	const char *val;
5360 	struct ia_xx *old_ia;
5361 	unsigned int len;
5362 	u_int32_t iaid;
5363 	struct iaddr iaddr;
5364 	u_int8_t plen;
5365 	binding_state_t state;
5366 	u_int32_t prefer;
5367 	u_int32_t valid;
5368 	TIME end_time;
5369 	struct iasubopt *iapref;
5370 	struct ipv6_pool *pool;
5371 	char addr_buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
5372 	isc_boolean_t newbinding;
5373 	struct binding_scope *scope = NULL;
5374 	struct binding *bnd;
5375 	struct binding_value *nv = NULL;
5376 	struct executable_statement *on_star[2] = {NULL, NULL};
5377 	int lose, i;
5378 
5379         if (local_family != AF_INET6) {
5380                 parse_warn(cfile, "IA_PD is only supported in DHCPv6 mode.");
5381                 skip_to_semi(cfile);
5382                 return;
5383         }
5384 
5385 	token = next_token(&val, &len, cfile);
5386 	if (token != STRING) {
5387 		parse_warn(cfile, "corrupt lease file; "
5388 				  "expecting an iaid+ia_pd string");
5389 		skip_to_semi(cfile);
5390 		return;
5391 	}
5392 	if (len < 5) {
5393 		parse_warn(cfile, "corrupt lease file; "
5394 				  "iaid+ia_pd string too short");
5395 		skip_to_semi(cfile);
5396 		return;
5397 	}
5398 
5399 	memcpy(&iaid, val, 4);
5400 	ia = NULL;
5401 	if (ia_allocate(&ia, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) {
5402 		log_fatal("Out of memory.");
5403 	}
5404 	ia->ia_type = D6O_IA_PD;
5405 
5406 	token = next_token(&val, NULL, cfile);
5407 	if (token != LBRACE) {
5408 		parse_warn(cfile, "corrupt lease file; expecting left brace");
5409 		skip_to_semi(cfile);
5410 		return;
5411 	}
5412 
5413 	for (;;) {
5414 		token = next_token(&val, NULL, cfile);
5415 		if (token == RBRACE) break;
5416 
5417 		if (token == CLTT) {
5418 			ia->cltt = parse_date (cfile);
5419 			continue;
5420 		}
5421 
5422 		if (token != IAPREFIX) {
5423 			parse_warn(cfile, "corrupt lease file; expecting "
5424 				   "IAPREFIX or right brace");
5425 			skip_to_semi(cfile);
5426 			return;
5427 		}
5428 
5429 		if (!parse_ip6_prefix(cfile, &iaddr, &plen)) {
5430 			parse_warn(cfile, "corrupt lease file; "
5431 					  "expecting IPv6 prefix");
5432 			skip_to_semi(cfile);
5433 			return;
5434 		}
5435 
5436 		token = next_token(&val, NULL, cfile);
5437 		if (token != LBRACE) {
5438 			parse_warn(cfile, "corrupt lease file; "
5439 					  "expecting left brace");
5440 			skip_to_semi(cfile);
5441 			return;
5442 		}
5443 
5444 		state = FTS_LAST+1;
5445 		prefer = valid = 0;
5446 		end_time = -1;
5447 		for (;;) {
5448 			token = next_token(&val, NULL, cfile);
5449 			if (token == RBRACE) break;
5450 
5451 			switch(token) {
5452 				/* Prefix binding state. */
5453 			     case BINDING:
5454 				token = next_token(&val, NULL, cfile);
5455 				if (token != STATE) {
5456 					parse_warn(cfile, "corrupt lease file; "
5457 							  "expecting state");
5458 					skip_to_semi(cfile);
5459 					return;
5460 				}
5461 				token = next_token(&val, NULL, cfile);
5462 				switch (token) {
5463 					case TOKEN_ABANDONED:
5464 						state = FTS_ABANDONED;
5465 						break;
5466 					case TOKEN_FREE:
5467 						state = FTS_FREE;
5468 						break;
5469 					case TOKEN_ACTIVE:
5470 						state = FTS_ACTIVE;
5471 						break;
5472 					case TOKEN_EXPIRED:
5473 						state = FTS_EXPIRED;
5474 						break;
5475 					case TOKEN_RELEASED:
5476 						state = FTS_RELEASED;
5477 						break;
5478 					default:
5479 						parse_warn(cfile,
5480 							   "corrupt lease "
5481 							   "file; "
5482 					    		   "expecting a "
5483 							   "binding state.");
5484 						skip_to_semi(cfile);
5485 						return;
5486 				}
5487 
5488 				token = next_token(&val, NULL, cfile);
5489 				if (token != SEMI) {
5490 					parse_warn(cfile, "corrupt lease file; "
5491 							  "expecting "
5492 							  "semicolon.");
5493 				}
5494 				break;
5495 
5496 				/* Lease preferred lifetime. */
5497 			      case PREFERRED_LIFE:
5498 				token = next_token(&val, NULL, cfile);
5499 				if (token != NUMBER) {
5500 					parse_warn(cfile, "%s is not a valid "
5501 							  "preferred time",
5502 						   val);
5503 					skip_to_semi(cfile);
5504 					continue;
5505 				}
5506 				prefer = atoi (val);
5507 
5508 				/*
5509 				 * Currently we peek for the semi-colon to
5510 				 * allow processing of older lease files that
5511 				 * don't have the semi-colon.  Eventually we
5512 				 * should remove the peeking code.
5513 				 */
5514 				token = peek_token(&val, NULL, cfile);
5515 				if (token == SEMI) {
5516 					skip_token(&val, NULL, cfile);
5517 				} else {
5518 					parse_warn(cfile,
5519 						   "corrupt lease file; "
5520 						   "expecting semicolon.");
5521 				}
5522 				break;
5523 
5524 				/* Lease valid lifetime. */
5525 			      case MAX_LIFE:
5526 				token = next_token(&val, NULL, cfile);
5527 				if (token != NUMBER) {
5528 					parse_warn(cfile, "%s is not a valid "
5529 							  "max time",
5530 						   val);
5531 					skip_to_semi(cfile);
5532 					continue;
5533 				}
5534 				valid = atoi (val);
5535 
5536 				/*
5537 				 * Currently we peek for the semi-colon to
5538 				 * allow processing of older lease files that
5539 				 * don't have the semi-colon.  Eventually we
5540 				 * should remove the peeking code.
5541 				 */
5542 				token = peek_token(&val, NULL, cfile);
5543 				if (token == SEMI) {
5544 					skip_token(&val, NULL, cfile);
5545 				} else {
5546 					parse_warn(cfile,
5547 						   "corrupt lease file; "
5548 						   "expecting semicolon.");
5549 				}
5550 				break;
5551 
5552 				/* Prefix expiration time. */
5553 			      case ENDS:
5554 				end_time = parse_date(cfile);
5555 				break;
5556 
5557 				/* Prefix binding scopes. */
5558 			      case TOKEN_SET:
5559 				token = next_token(&val, NULL, cfile);
5560 				if ((token != NAME) &&
5561 				    (token != NUMBER_OR_NAME)) {
5562 					parse_warn(cfile, "%s is not a valid "
5563 							  "variable name",
5564 						   val);
5565 					skip_to_semi(cfile);
5566 					continue;
5567 				}
5568 
5569 				if (scope != NULL)
5570 					bnd = find_binding(scope, val);
5571 				else {
5572 					if (!binding_scope_allocate(&scope,
5573 								    MDL)) {
5574 						log_fatal("Out of memory for "
5575 							  "lease binding "
5576 							  "scope.");
5577 					}
5578 
5579 					bnd = NULL;
5580 				}
5581 
5582 				if (bnd == NULL) {
5583 					bnd = dmalloc(sizeof(*bnd),
5584 							  MDL);
5585 					if (bnd == NULL) {
5586 						log_fatal("No memory for "
5587 							  "prefix binding.");
5588 					}
5589 
5590 					bnd->name = dmalloc(strlen(val) + 1,
5591 							    MDL);
5592 					if (bnd->name == NULL) {
5593 						log_fatal("No memory for "
5594 							  "binding name.");
5595 					}
5596 					strcpy(bnd->name, val);
5597 
5598 					newbinding = ISC_TRUE;
5599 				} else {
5600 					newbinding = ISC_FALSE;
5601 				}
5602 
5603 				if (!binding_value_allocate(&nv, MDL)) {
5604 					log_fatal("no memory for binding "
5605 						  "value.");
5606 				}
5607 
5608 				token = next_token(NULL, NULL, cfile);
5609 				if (token != EQUAL) {
5610 					parse_warn(cfile, "expecting '=' in "
5611 							  "set statement.");
5612 					goto binding_err;
5613 				}
5614 
5615 				if (!parse_binding_value(cfile, nv)) {
5616 				      binding_err:
5617 					binding_value_dereference(&nv, MDL);
5618 					binding_scope_dereference(&scope, MDL);
5619 					return;
5620 				}
5621 
5622 				if (newbinding) {
5623 					binding_value_reference(&bnd->value,
5624 								nv, MDL);
5625 					bnd->next = scope->bindings;
5626 					scope->bindings = bnd;
5627 				} else {
5628 					binding_value_dereference(&bnd->value,
5629 								  MDL);
5630 					binding_value_reference(&bnd->value,
5631 								nv, MDL);
5632 				}
5633 
5634 				binding_value_dereference(&nv, MDL);
5635 				parse_semi(cfile);
5636 				break;
5637 
5638 			      case ON:
5639 				lose = 0;
5640 				/*
5641 				 * Depending on the user config we may
5642 				 * have one or two on statements.  We
5643 				 * need to save information about both
5644 				 * of them until we allocate the
5645 				 * iasubopt to hold them.
5646 				 */
5647 				if (on_star[0] == NULL) {
5648 					if (!parse_on_statement (&on_star[0],
5649 								 cfile,
5650 								 &lose)) {
5651 						parse_warn(cfile,
5652 							   "corrupt lease "
5653 							   "file; bad ON "
5654 							   "statement");
5655 						skip_to_rbrace (cfile, 1);
5656 						return;
5657 					}
5658 				} else {
5659 					if (!parse_on_statement (&on_star[1],
5660 								 cfile,
5661 								 &lose)) {
5662 						parse_warn(cfile,
5663 							   "corrupt lease "
5664 							   "file; bad ON "
5665 							   "statement");
5666 						skip_to_rbrace (cfile, 1);
5667 						return;
5668 					}
5669 				}
5670 
5671 				break;
5672 
5673 			      default:
5674 				parse_warn(cfile, "corrupt lease file; "
5675 						  "expecting ia_pd contents, "
5676 						  "got '%s'", val);
5677 				skip_to_semi(cfile);
5678 				continue;
5679 			}
5680 		}
5681 
5682 		if (state == FTS_LAST+1) {
5683 			parse_warn(cfile, "corrupt lease file; "
5684 					  "missing state in iaprefix");
5685 			return;
5686 		}
5687 		if (end_time == -1) {
5688 			parse_warn(cfile, "corrupt lease file; "
5689 					  "missing end time in iaprefix");
5690 			return;
5691 		}
5692 
5693 		iapref = NULL;
5694 		if (iasubopt_allocate(&iapref, MDL) != ISC_R_SUCCESS) {
5695 			log_fatal("Out of memory.");
5696 		}
5697 		memcpy(&iapref->addr, iaddr.iabuf, sizeof(iapref->addr));
5698 		iapref->plen = plen;
5699 		iapref->state = state;
5700 		iapref->prefer = prefer;
5701 		iapref->valid = valid;
5702 		if (iapref->state == FTS_RELEASED)
5703 			iapref->hard_lifetime_end_time = end_time;
5704 
5705 		if (scope != NULL) {
5706 			binding_scope_reference(&iapref->scope, scope, MDL);
5707 			binding_scope_dereference(&scope, MDL);
5708 		}
5709 
5710 		/*
5711 		 * Check on both on statements.  Because of how we write the
5712 		 * lease file we know which is which if we have two but it's
5713 		 * easier to write the code to be independent.  We do assume
5714 		 * that the statements won't overlap.
5715 		 */
5716 		for (i = 0;
5717 		     (i < 2) && on_star[i] != NULL ;
5718 		     i++) {
5719 			if ((on_star[i]->data.on.evtypes & ON_EXPIRY) &&
5720 			    on_star[i]->data.on.statements) {
5721 				executable_statement_reference
5722 					(&iapref->on_star.on_expiry,
5723 					 on_star[i]->data.on.statements, MDL);
5724 			}
5725 			if ((on_star[i]->data.on.evtypes & ON_RELEASE) &&
5726 			    on_star[i]->data.on.statements) {
5727 				executable_statement_reference
5728 					(&iapref->on_star.on_release,
5729 					 on_star[i]->data.on.statements, MDL);
5730 			}
5731 			executable_statement_dereference (&on_star[i], MDL);
5732 		}
5733 
5734 		/* find the pool this address is in */
5735 		pool = NULL;
5736 		if (find_ipv6_pool(&pool, D6O_IA_PD,
5737 				   &iapref->addr) != ISC_R_SUCCESS) {
5738 			inet_ntop(AF_INET6, &iapref->addr,
5739 				  addr_buf, sizeof(addr_buf));
5740 			parse_warn(cfile, "no pool found for address %s",
5741 				   addr_buf);
5742 			return;
5743 		}
5744 
5745 		/* remove old information */
5746 		if (cleanup_lease6(ia_pd_active, pool,
5747 				   iapref, ia) != ISC_R_SUCCESS) {
5748 			inet_ntop(AF_INET6, &iapref->addr,
5749 				  addr_buf, sizeof(addr_buf));
5750 			parse_warn(cfile, "duplicate pd lease for address %s",
5751 				   addr_buf);
5752 		}
5753 
5754 		/*
5755 		 * if we like the lease we add it to our various structues
5756 		 * otherwise we leave it and it will get cleaned when we
5757 		 * do the iasubopt_dereference.
5758 		 */
5759 		if ((state == FTS_ACTIVE) || (state == FTS_ABANDONED)) {
5760 			ia_add_iasubopt(ia, iapref, MDL);
5761 			ia_reference(&iapref->ia, ia, MDL);
5762 			add_lease6(pool, iapref, end_time);
5763 		}
5764 
5765 		ipv6_pool_dereference(&pool, MDL);
5766 		iasubopt_dereference(&iapref, MDL);
5767 	}
5768 
5769 	/*
5770 	 * If we have an existing record for this IA_PD, remove it.
5771 	 */
5772 	old_ia = NULL;
5773 	if (ia_hash_lookup(&old_ia, ia_pd_active,
5774 			   (unsigned char *)ia->iaid_duid.data,
5775 			   ia->iaid_duid.len, MDL)) {
5776 		ia_hash_delete(ia_pd_active,
5777 			       (unsigned char *)ia->iaid_duid.data,
5778 			       ia->iaid_duid.len, MDL);
5779 		ia_dereference(&old_ia, MDL);
5780 	}
5781 
5782 	/*
5783 	 * If we have prefixes, add this, otherwise don't bother.
5784 	 */
5785 	if (ia->num_iasubopt > 0) {
5786 		ia_hash_add(ia_pd_active,
5787 			    (unsigned char *)ia->iaid_duid.data,
5788 			    ia->iaid_duid.len, ia, MDL);
5789 	}
5790 	ia_dereference(&ia, MDL);
5791 #endif /* defined(DHCPv6) */
5792 }
5793 
5794 #ifdef DHCPv6
5795 /*
5796  * When we parse a server-duid statement in a lease file, we are
5797  * looking at the saved server DUID from a previous run. In this case
5798  * we expect it to be followed by the binary representation of the
5799  * DUID stored in a string:
5800  *
5801  * server-duid "\000\001\000\001\015\221\034JRT\000\0224Y";
5802  */
5803 void
5804 parse_server_duid(struct parse *cfile) {
5805 	enum dhcp_token token;
5806 	const char *val;
5807 	unsigned int len;
5808 	struct data_string duid;
5809 
5810 	token = next_token(&val, &len, cfile);
5811 	if (token != STRING) {
5812 		parse_warn(cfile, "corrupt lease file; expecting a DUID");
5813 		skip_to_semi(cfile);
5814 		return;
5815 	}
5816 
5817 	memset(&duid, 0, sizeof(duid));
5818 	duid.len = len;
5819 	if (!buffer_allocate(&duid.buffer, duid.len, MDL)) {
5820 		log_fatal("Out of memory storing DUID");
5821 	}
5822 	duid.data = (unsigned char *)duid.buffer->data;
5823 	memcpy(duid.buffer->data, val, len);
5824 
5825 	set_server_duid(&duid);
5826 
5827 	data_string_forget(&duid, MDL);
5828 
5829 	token = next_token(&val, &len, cfile);
5830 	if (token != SEMI) {
5831 		parse_warn(cfile, "corrupt lease file; expecting a semicolon");
5832 		skip_to_semi(cfile);
5833 		return;
5834 	}
5835 }
5836 
5837 /*
5838  * When we parse a server-duid statement in a config file, we will
5839  * have the type of the server DUID to generate, and possibly the
5840  * actual value defined.
5841  *
5842  * server-duid llt;
5843  * server-duid llt ethernet|ieee802|fddi 213982198 00:16:6F:49:7D:9B;
5844  * server-duid ll;
5845  * server-duid ll ethernet|ieee802|fddi 00:16:6F:49:7D:9B;
5846  * server-duid en 2495 "enterprise-specific-identifier-1234";
5847  */
5848 void
5849 parse_server_duid_conf(struct parse *cfile) {
5850 	enum dhcp_token token;
5851 	const char *val;
5852 	unsigned int len;
5853 	u_int32_t enterprise_number;
5854 	int ll_type;
5855 	struct data_string ll_addr;
5856 	u_int32_t llt_time;
5857 	struct data_string duid;
5858 	int duid_type_num;
5859 
5860 	/*
5861 	 * Consume the SERVER_DUID token.
5862 	 */
5863 	skip_token(NULL, NULL, cfile);
5864 
5865 	/*
5866 	 * Obtain the DUID type.
5867 	 */
5868 	token = next_token(&val, NULL, cfile);
5869 
5870 	/*
5871 	 * Enterprise is the easiest - enterprise number and raw data
5872 	 * are required.
5873 	 */
5874 	if (token == EN) {
5875 		/*
5876 		 * Get enterprise number and identifier.
5877 		 */
5878 		token = next_token(&val, NULL, cfile);
5879 		if (token != NUMBER) {
5880 			parse_warn(cfile, "enterprise number expected");
5881 			skip_to_semi(cfile);
5882 			return;
5883 		}
5884 		enterprise_number = atoi(val);
5885 
5886 		token = next_token(&val, &len, cfile);
5887 		if (token != STRING) {
5888 			parse_warn(cfile, "identifier expected");
5889 			skip_to_semi(cfile);
5890 			return;
5891 		}
5892 
5893 		/*
5894 		 * Save the DUID.
5895 		 */
5896 		memset(&duid, 0, sizeof(duid));
5897         	duid.len = 2 + 4 + len;
5898         	if (!buffer_allocate(&duid.buffer, duid.len, MDL)) {
5899 			log_fatal("Out of memory storing DUID");
5900 		}
5901 		duid.data = (unsigned char *)duid.buffer->data;
5902 		putUShort(duid.buffer->data, DUID_EN);
5903  		putULong(duid.buffer->data + 2, enterprise_number);
5904 		memcpy(duid.buffer->data + 6, val, len);
5905 
5906 		set_server_duid(&duid);
5907 		data_string_forget(&duid, MDL);
5908 	}
5909 
5910 	/*
5911 	 * Next easiest is the link-layer DUID. It consists only of
5912 	 * the LL directive, or optionally the specific value to use.
5913 	 *
5914 	 * If we have LL only, then we set the type. If we have the
5915 	 * value, then we set the actual DUID.
5916 	 */
5917 	else if (token == LL) {
5918 		if (peek_token(NULL, NULL, cfile) == SEMI) {
5919 			set_server_duid_type(DUID_LL);
5920 		} else {
5921 			/*
5922 			 * Get our hardware type and address.
5923 			 */
5924 			token = next_token(NULL, NULL, cfile);
5925 			switch (token) {
5926 			      case ETHERNET:
5927 				ll_type = HTYPE_ETHER;
5928 				break;
5929 			      case TOKEN_RING:
5930 				ll_type = HTYPE_IEEE802;
5931 				break;
5932 			      case TOKEN_FDDI:
5933 				ll_type = HTYPE_FDDI;
5934 				break;
5935 			      default:
5936 				parse_warn(cfile, "hardware type expected");
5937 				skip_to_semi(cfile);
5938 				return;
5939 			}
5940 			memset(&ll_addr, 0, sizeof(ll_addr));
5941 			if (!parse_cshl(&ll_addr, cfile)) {
5942 				return;
5943 			}
5944 
5945 			/*
5946 			 * Save the DUID.
5947 			 */
5948 			memset(&duid, 0, sizeof(duid));
5949 			duid.len = 2 + 2 + ll_addr.len;
5950         		if (!buffer_allocate(&duid.buffer, duid.len, MDL)) {
5951 				log_fatal("Out of memory storing DUID");
5952 			}
5953 			duid.data = (unsigned char *)duid.buffer->data;
5954 			putUShort(duid.buffer->data, DUID_LL);
5955  			putULong(duid.buffer->data + 2, ll_type);
5956 			memcpy(duid.buffer->data + 4,
5957 			       ll_addr.data, ll_addr.len);
5958 
5959 			set_server_duid(&duid);
5960 			data_string_forget(&duid, MDL);
5961 			data_string_forget(&ll_addr, MDL);
5962 		}
5963 	}
5964 
5965 	/*
5966 	 * Finally the link-layer DUID plus time. It consists only of
5967 	 * the LLT directive, or optionally the specific value to use.
5968 	 *
5969 	 * If we have LLT only, then we set the type. If we have the
5970 	 * value, then we set the actual DUID.
5971 	 */
5972 	else if (token == LLT) {
5973 		if (peek_token(NULL, NULL, cfile) == SEMI) {
5974 			set_server_duid_type(DUID_LLT);
5975 		} else {
5976 			/*
5977 			 * Get our hardware type, timestamp, and address.
5978 			 */
5979 			token = next_token(NULL, NULL, cfile);
5980 			switch (token) {
5981 			      case ETHERNET:
5982 				ll_type = HTYPE_ETHER;
5983 				break;
5984 			      case TOKEN_RING:
5985 				ll_type = HTYPE_IEEE802;
5986 				break;
5987 			      case TOKEN_FDDI:
5988 				ll_type = HTYPE_FDDI;
5989 				break;
5990 			      default:
5991 				parse_warn(cfile, "hardware type expected");
5992 				skip_to_semi(cfile);
5993 				return;
5994 			}
5995 
5996 			token = next_token(&val, NULL, cfile);
5997 			if (token != NUMBER) {
5998 				parse_warn(cfile, "timestamp expected");
5999 				skip_to_semi(cfile);
6000 				return;
6001 			}
6002 			llt_time = atoi(val);
6003 
6004 			memset(&ll_addr, 0, sizeof(ll_addr));
6005 			if (!parse_cshl(&ll_addr, cfile)) {
6006 				return;
6007 			}
6008 
6009 			/*
6010 			 * Save the DUID.
6011 			 */
6012 			memset(&duid, 0, sizeof(duid));
6013 			duid.len = 2 + 2 + 4 + ll_addr.len;
6014         		if (!buffer_allocate(&duid.buffer, duid.len, MDL)) {
6015 				log_fatal("Out of memory storing DUID");
6016 			}
6017 			duid.data = (unsigned char *)duid.buffer->data;
6018 			putUShort(duid.buffer->data, DUID_LLT);
6019  			putULong(duid.buffer->data + 2, ll_type);
6020  			putULong(duid.buffer->data + 4, llt_time);
6021 			memcpy(duid.buffer->data + 8,
6022 			       ll_addr.data, ll_addr.len);
6023 
6024 			set_server_duid(&duid);
6025 			data_string_forget(&duid, MDL);
6026 			data_string_forget(&ll_addr, MDL);
6027 		}
6028 	}
6029 
6030 	/*
6031 	 * If users want they can use a number for DUID types.
6032 	 * This is useful for supporting future, not-yet-defined
6033 	 * DUID types.
6034 	 *
6035 	 * In this case, they have to put in the complete value.
6036 	 *
6037 	 * This also works for existing DUID types of course.
6038 	 */
6039 	else if (token == NUMBER) {
6040 		duid_type_num = atoi(val);
6041 
6042 		token = next_token(&val, &len, cfile);
6043 		if (token != STRING) {
6044 			parse_warn(cfile, "identifier expected");
6045 			skip_to_semi(cfile);
6046 			return;
6047 		}
6048 
6049 		/*
6050 		 * Save the DUID.
6051 		 */
6052 		memset(&duid, 0, sizeof(duid));
6053         	duid.len = 2 + len;
6054         	if (!buffer_allocate(&duid.buffer, duid.len, MDL)) {
6055 			log_fatal("Out of memory storing DUID");
6056 		}
6057 		duid.data = (unsigned char *)duid.buffer->data;
6058 		putUShort(duid.buffer->data, duid_type_num);
6059 		memcpy(duid.buffer->data + 2, val, len);
6060 
6061 		set_server_duid(&duid);
6062 		data_string_forget(&duid, MDL);
6063 	}
6064 
6065 	/*
6066 	 * Anything else is an error.
6067 	 */
6068 	else {
6069 		parse_warn(cfile, "DUID type of LLT, EN, or LL expected");
6070 		skip_to_semi(cfile);
6071 		return;
6072 	}
6073 
6074 	/*
6075 	 * Finally consume our trailing semicolon.
6076 	 */
6077 	token = next_token(NULL, NULL, cfile);
6078 	if (token != SEMI) {
6079 		parse_warn(cfile, "semicolon expected");
6080 		skip_to_semi(cfile);
6081 	}
6082 }
6083 
6084 #endif /* DHCPv6 */
6085 
6086