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