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