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