1 /* options.c
2 
3    DHCP options parsing and reassembly. */
4 
5 /*
6  * Copyright (c) 2004-2019 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1995-2003 by Internet Software Consortium
8  *
9  * This Source Code Form is subject to the terms of the Mozilla Public
10  * License, v. 2.0. If a copy of the MPL was not distributed with this
11  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  *   Internet Systems Consortium, Inc.
22  *   950 Charter Street
23  *   Redwood City, CA 94063
24  *   <info@isc.org>
25  *   https://www.isc.org/
26  *
27  */
28 
29 #define DHCP_OPTION_DATA
30 #include "dhcpd.h"
31 #include <omapip/omapip_p.h>
32 #include <limits.h>
33 
34 struct option *vendor_cfg_option;
35 
36 static int pretty_text(char **, char *, const unsigned char **,
37 			 const unsigned char *, int);
38 static int pretty_dname(char **, char *, const unsigned char *,
39 			 const unsigned char *);
40 static int pretty_domain(char **, char *, const unsigned char **,
41 			 const unsigned char *);
42 static int prepare_option_buffer(struct universe *universe, struct buffer *bp,
43 				 unsigned char *buffer, unsigned length,
44 				 unsigned code, int terminatep,
45 				 struct option_cache **opp);
46 
47 /* Parse all available options out of the specified packet. */
48 /* Note, the caller is responsible for allocating packet->options. */
parse_options(packet)49 int parse_options (packet)
50 	struct packet *packet;
51 {
52 	struct option_cache *op = NULL;
53 
54 	/* If we don't see the magic cookie, there's nothing to parse. */
55 	if (memcmp (packet -> raw -> options, DHCP_OPTIONS_COOKIE, 4)) {
56 		packet -> options_valid = 0;
57 		return 1;
58 	}
59 
60 	/* Go through the options field, up to the end of the packet
61 	   or the End field. */
62 	if (!parse_option_buffer (packet -> options,
63 				  &packet -> raw -> options [4],
64 				  (packet -> packet_length -
65 				   DHCP_FIXED_NON_UDP - 4),
66 				  &dhcp_universe)) {
67 
68 		/* STSN servers have a bug where they send a mangled
69 		   domain-name option, and whatever is beyond that in
70 		   the packet is junk.   Microsoft clients accept this,
71 		   which is probably why whoever implemented the STSN
72 		   server isn't aware of the problem yet.   To work around
73 		   this, we will accept corrupt packets from the server if
74 		   they contain a valid DHCP_MESSAGE_TYPE option, but
75 		   will not accept any corrupt client packets (the ISC DHCP
76 		   server is sufficiently widely used that it is probably
77 		   beneficial for it to be picky) and will not accept
78 		   packets whose type can't be determined. */
79 
80 		if ((op = lookup_option (&dhcp_universe, packet -> options,
81 					 DHO_DHCP_MESSAGE_TYPE))) {
82 			if (!op -> data.data ||
83 			    (op -> data.data [0] != DHCPOFFER &&
84 			     op -> data.data [0] != DHCPACK &&
85 			     op -> data.data [0] != DHCPNAK))
86 				return 0;
87 		} else
88 			return 0;
89 	}
90 
91 	/* If we parsed a DHCP Option Overload option, parse more
92 	   options out of the buffer(s) containing them. */
93 	if ((op = lookup_option (&dhcp_universe, packet -> options,
94 				 DHO_DHCP_OPTION_OVERLOAD))) {
95 		if (op -> data.data [0] & 1) {
96 			if (!parse_option_buffer
97 			    (packet -> options,
98 			     (unsigned char *)packet -> raw -> file,
99 			     sizeof packet -> raw -> file,
100 			     &dhcp_universe))
101 				return 0;
102 		}
103 		if (op -> data.data [0] & 2) {
104 			if (!parse_option_buffer
105 			    (packet -> options,
106 			     (unsigned char *)packet -> raw -> sname,
107 			     sizeof packet -> raw -> sname,
108 			     &dhcp_universe))
109 				return 0;
110 		}
111 	}
112 	packet -> options_valid = 1;
113 	return 1;
114 }
115 
116 /* Parse options out of the specified buffer, storing addresses of option
117  * values in packet->options.
118  */
parse_option_buffer(options,buffer,length,universe)119 int parse_option_buffer (options, buffer, length, universe)
120 	struct option_state *options;
121 	const unsigned char *buffer;
122 	unsigned length;
123 	struct universe *universe;
124 {
125 	unsigned len, offset;
126 	unsigned code;
127 	struct option_cache *op = NULL, *nop = NULL;
128 	struct buffer *bp = (struct buffer *)0;
129 	struct option *option = NULL;
130 	char *reason = "general failure";
131 
132 	if (!buffer_allocate (&bp, length, MDL)) {
133 		log_error ("no memory for option buffer.");
134 		return 0;
135 	}
136 	memcpy (bp -> data, buffer, length);
137 
138 	for (offset = 0;
139 	     (offset + universe->tag_size) <= length &&
140 	     (code = universe->get_tag(buffer + offset)) != universe->end; ) {
141 		offset += universe->tag_size;
142 
143 		/* Pad options don't have a length - just skip them. */
144 		if (code == DHO_PAD)
145 			continue;
146 
147 		/* Don't look for length if the buffer isn't that big. */
148 		if ((offset + universe->length_size) > length) {
149 			reason = "code tag at end of buffer - missing "
150 				 "length field";
151 			goto bogus;
152 		}
153 
154 		/* All other fields (except PAD and END handled above)
155 		 * have a length field, unless it's a DHCPv6 zero-length
156 		 * options space (eg any of the enterprise-id'd options).
157 		 *
158 		 * Zero-length-size option spaces basically consume the
159 		 * entire options buffer, so have at it.
160 		 */
161 		if (universe->get_length != NULL)
162 			len = universe->get_length(buffer + offset);
163 		else if (universe->length_size == 0)
164 			len = length - universe->tag_size;
165 		else {
166 			log_fatal("Improperly configured option space(%s): "
167 				  "may not have a nonzero length size "
168 				  "AND a NULL get_length function.",
169 				  universe->name);
170 
171 			/* Silence compiler warnings. */
172 			return 0;
173 		}
174 
175 		offset += universe->length_size;
176 
177 		option_code_hash_lookup(&option, universe->code_hash, &code,
178 					0, MDL);
179 
180 		/* If the length is outrageous, the options are bad. */
181 		if (offset + len > length) {
182 			/* Avoid reference count overflow */
183 			option_dereference(&option, MDL);
184 			reason = "option length exceeds option buffer length";
185 		      bogus:
186 			log_error("parse_option_buffer: malformed option "
187 				  "%s.%s (code %u): %s.", universe->name,
188 				  option ? option->name : "<unknown>",
189 				  code, reason);
190 			buffer_dereference (&bp, MDL);
191 			return 0;
192 		}
193 
194 		/* If the option contains an encapsulation, parse it.  In
195 		   any case keep the raw data as well.  (Previous to 4.4.0
196 		   we only kept the raw data if the parse failed, the option
197 		   wasn't an encapsulation (by far the most common case), or
198 		   the option wasn't entirely an encapsulation
199 		*/
200 
201 		if (option &&
202 		    (option->format[0] == 'e' || option->format[0] == 'E')) {
203 			(void) parse_encapsulated_suboptions(options, option,
204 							     bp->data + offset,
205 							     len,
206 							     universe, NULL);
207 		}
208 
209 		if (universe == &dhcp_universe && code == DHO_HOST_NAME &&
210 		    len == 0) {
211 			/* non-compliant clients can send it
212 			 * we'll just drop it and go on */
213 			log_debug ("Ignoring empty DHO_HOST_NAME option");
214 			option_dereference(&option, MDL);
215 			offset += len;
216 			continue;
217 		}
218 
219 		op = lookup_option(universe, options, code);
220 		if (op == NULL) {
221 			/* If we don't have an option create one */
222 			if (save_option_buffer(universe, options, bp,
223 					       bp->data + offset, len,
224 					       code, 1) == 0) {
225 				log_error("parse_option_buffer: "
226 					  "save_option_buffer failed");
227 				buffer_dereference(&bp, MDL);
228 				option_dereference(&option, MDL);
229 				return (0);
230 			}
231 		} else if (universe->concat_duplicates) {
232 			/* If we do have an option either concat with
233 			   what is there ...*/
234 			struct data_string new;
235 			memset(&new, 0, sizeof new);
236 			if (!buffer_allocate(&new.buffer, op->data.len + len,
237 					     MDL)) {
238 				log_error("parse_option_buffer: No memory.");
239 				buffer_dereference(&bp, MDL);
240 				option_dereference(&option, MDL);
241 				return (0);
242 			}
243 			/* Copy old option to new data object. */
244 			memcpy(new.buffer->data, op->data.data,
245 			       op->data.len);
246 			/* Concat new option behind old. */
247 			memcpy(new.buffer->data + op->data.len,
248 			       bp->data + offset, len);
249 			new.len = op->data.len + len;
250 			new.data = new.buffer->data;
251 			/* Save new concat'd object. */
252 			data_string_forget(&op->data, MDL);
253 			data_string_copy(&op->data, &new, MDL);
254 			data_string_forget(&new, MDL);
255 		} else  {
256 			/* ... or we must append this statement onto the
257 			 * end of the list.
258 			 */
259 			while (op->next != NULL)
260 				op = op->next;
261 
262 			if (!option_cache_allocate(&nop, MDL)) {
263 				log_error("parse_option_buffer: No memory.");
264 				buffer_dereference(&bp, MDL);
265 				option_dereference(&option, MDL);
266 				return (0);
267 			}
268 
269 			option_reference(&nop->option, op->option, MDL);
270 
271 			nop->data.buffer = NULL;
272 			buffer_reference(&nop->data.buffer, bp, MDL);
273 			nop->data.data = bp->data + offset;
274 			nop->data.len = len;
275 
276 			option_cache_reference(&op->next, nop, MDL);
277 			option_cache_dereference(&nop, MDL);
278 		}
279 
280 		option_dereference(&option, MDL);
281 		offset += len;
282 	}
283 	buffer_dereference (&bp, MDL);
284 	return (1);
285 }
286 
287 /* If an option in an option buffer turns out to be an encapsulation,
288    figure out what to do.   If we don't know how to de-encapsulate it,
289    or it's not well-formed, return zero; otherwise, return 1, indicating
290    that we succeeded in de-encapsulating it. */
291 
find_option_universe(struct option * eopt,const char * uname)292 struct universe *find_option_universe (struct option *eopt, const char *uname)
293 {
294 	int i;
295 	char *s, *t;
296 	struct universe *universe = (struct universe *)0;
297 
298 	/* Look for the E option in the option format. */
299 	s = strchr (eopt -> format, 'E');
300 	if (!s) {
301 		log_error ("internal encapsulation format error 1.");
302 		return 0;
303 	}
304 	/* Look for the universe name in the option format. */
305 	t = strchr (++s, '.');
306 	/* If there was no trailing '.', or there's something after the
307 	   trailing '.', the option is bogus and we can't use it. */
308 	if (!t || t [1]) {
309 		log_error ("internal encapsulation format error 2.");
310 		return 0;
311 	}
312 	if (t == s && uname) {
313 		for (i = 0; i < universe_count; i++) {
314 			if (!strcmp (universes [i] -> name, uname)) {
315 				universe = universes [i];
316 				break;
317 			}
318 		}
319 	} else if (t != s) {
320 		for (i = 0; i < universe_count; i++) {
321 			if (strlen (universes [i] -> name) == t - s &&
322 			    !memcmp (universes [i] -> name,
323 				     s, (unsigned)(t - s))) {
324 				universe = universes [i];
325 				break;
326 			}
327 		}
328 	}
329 	return universe;
330 }
331 
332 /* If an option in an option buffer turns out to be an encapsulation,
333    figure out what to do.   If we don't know how to de-encapsulate it,
334    or it's not well-formed, return zero; otherwise, return 1, indicating
335    that we succeeded in de-encapsulating it. */
336 
parse_encapsulated_suboptions(struct option_state * options,struct option * eopt,const unsigned char * buffer,unsigned len,struct universe * eu,const char * uname)337 int parse_encapsulated_suboptions (struct option_state *options,
338 				   struct option *eopt,
339 				   const unsigned char *buffer,
340 				   unsigned len, struct universe *eu,
341 				   const char *uname)
342 {
343 	int i;
344 	struct universe *universe = find_option_universe (eopt, uname);
345 
346 	/* If we didn't find the universe, we can't do anything with it
347 	   right now (e.g., we can't decode vendor options until we've
348 	   decoded the packet and executed the scopes that it matches). */
349 	if (!universe)
350 		return 0;
351 
352 	/* If we don't have a decoding function for it, we can't decode
353 	   it. */
354 	if (!universe -> decode)
355 		return 0;
356 
357 	i = (*universe -> decode) (options, buffer, len, universe);
358 
359 	/* If there is stuff before the suboptions, we have to keep it. */
360 	if (eopt -> format [0] != 'E')
361 		return 0;
362 	/* Otherwise, return the status of the decode function. */
363 	return i;
364 }
365 
fqdn_universe_decode(struct option_state * options,const unsigned char * buffer,unsigned length,struct universe * u)366 int fqdn_universe_decode (struct option_state *options,
367 			  const unsigned char *buffer,
368 			  unsigned length, struct universe *u)
369 {
370 	struct buffer *bp = (struct buffer *)0;
371 
372 	/* FQDN options have to be at least four bytes long. */
373 	if (length < 3)
374 		return 0;
375 
376 	/* Save the contents of the option in a buffer. */
377 	if (!buffer_allocate (&bp, length + 4, MDL)) {
378 		log_error ("no memory for option buffer.");
379 		return 0;
380 	}
381 	memcpy (&bp -> data [3], buffer + 1, length - 1);
382 
383 	if (buffer [0] & 4)	/* encoded */
384 		bp -> data [0] = 1;
385 	else
386 		bp -> data [0] = 0;
387 	if (!save_option_buffer(&fqdn_universe, options, bp,
388 				bp->data, 1, FQDN_ENCODED, 0)) {
389 	      bad:
390 		buffer_dereference (&bp, MDL);
391 		return 0;
392 	}
393 
394 	if (buffer [0] & 1)	/* server-update */
395 		bp -> data [2] = 1;
396 	else
397 		bp -> data [2] = 0;
398 	if (buffer [0] & 2)	/* no-client-update */
399 		bp -> data [1] = 1;
400 	else
401 		bp -> data [1] = 0;
402 
403 	/* XXX Ideally we should store the name in DNS format, so if the
404 	   XXX label isn't in DNS format, we convert it to DNS format,
405 	   XXX rather than converting labels specified in DNS format to
406 	   XXX the plain ASCII representation.   But that's hard, so
407 	   XXX not now. */
408 
409 	/* Not encoded using DNS format? */
410 	if (!bp -> data [0]) {
411 		unsigned i;
412 
413 		/* Some broken clients NUL-terminate this option. */
414 		if (buffer [length - 1] == 0) {
415 			--length;
416 			bp -> data [1] = 1;
417 		}
418 
419 		/* Determine the length of the hostname component of the
420 		   name.  If the name contains no '.' character, it
421 		   represents a non-qualified label. */
422 		for (i = 3; i < length && buffer [i] != '.'; i++);
423 		i -= 3;
424 
425 		/* Note: If the client sends a FQDN, the first '.' will
426 		   be used as a NUL terminator for the hostname. */
427 		if (i && (!save_option_buffer(&fqdn_universe, options, bp,
428 					      &bp->data[5], i,
429 					      FQDN_HOSTNAME, 0)))
430 			goto bad;
431 		/* Note: If the client sends a single label, the
432 		   FQDN_DOMAINNAME option won't be set. */
433 		if (length > 4 + i &&
434 		    (!save_option_buffer(&fqdn_universe, options, bp,
435 					 &bp -> data[6 + i], length - 4 - i,
436 					 FQDN_DOMAINNAME, 1)))
437 			goto bad;
438 		/* Also save the whole name. */
439 		if (length > 3) {
440 			if (!save_option_buffer(&fqdn_universe, options, bp,
441 						&bp -> data [5], length - 3,
442 						FQDN_FQDN, 1))
443 				goto bad;
444 		}
445 	} else {
446 		unsigned len;
447 		unsigned total_len = 0;
448 		unsigned first_len = 0;
449 		int terminated = 0;
450 		unsigned char *s;
451 
452 		s = &bp -> data[5];
453 
454 		while (s < &bp -> data[0] + length + 2) {
455 			len = *s;
456 			if (len > 63) {
457 				log_info ("fancy bits in fqdn option");
458 				return 0;
459 			}
460 			if (len == 0) {
461 				terminated = 1;
462 				break;
463 			}
464 			if (s + len > &bp -> data [0] + length + 3) {
465 				log_info ("fqdn tag longer than buffer");
466 				return 0;
467 			}
468 
469 			if (first_len == 0) {
470 				first_len = len;
471 			}
472 
473 			*s = '.';
474 			s += len + 1;
475 			total_len += len + 1;
476 		}
477 
478 		/* We wind up with a length that's one too many because
479 		   we shouldn't increment for the last label, but there's
480 		   no way to tell we're at the last label until we exit
481 		   the loop.   :'*/
482 		if (total_len > 0)
483 			total_len--;
484 
485 		if (!terminated) {
486 			first_len = total_len;
487 		}
488 
489 		if (first_len > 0 &&
490 		    !save_option_buffer(&fqdn_universe, options, bp,
491 					&bp -> data[6], first_len,
492 					FQDN_HOSTNAME, 0))
493 			goto bad;
494 		if (total_len > 0 && first_len != total_len) {
495 			if (!save_option_buffer(&fqdn_universe, options, bp,
496 						&bp->data[6 + first_len],
497 						total_len - first_len,
498 						FQDN_DOMAINNAME, 1))
499 				goto bad;
500 		}
501 		if (total_len > 0)
502 			if (!save_option_buffer (&fqdn_universe, options, bp,
503 						 &bp -> data [6], total_len,
504 						 FQDN_FQDN, 1))
505 				goto bad;
506 	}
507 
508 	if (!save_option_buffer (&fqdn_universe, options, bp,
509 				 &bp -> data [1], 1,
510 				 FQDN_NO_CLIENT_UPDATE, 0))
511 	    goto bad;
512 	if (!save_option_buffer (&fqdn_universe, options, bp,
513 				 &bp -> data [2], 1,
514 				 FQDN_SERVER_UPDATE, 0))
515 		goto bad;
516 
517 	if (!save_option_buffer (&fqdn_universe, options, bp,
518 				 &bp -> data [3], 1,
519 				 FQDN_RCODE1, 0))
520 		goto bad;
521 	if (!save_option_buffer (&fqdn_universe, options, bp,
522 				 &bp -> data [4], 1,
523 				 FQDN_RCODE2, 0))
524 		goto bad;
525 
526 	buffer_dereference (&bp, MDL);
527 	return 1;
528 }
529 
530 /*
531  * Load all options into a buffer, and then split them out into the three
532  * separate fields in the dhcp packet (options, file, and sname) where
533  * options can be stored.
534  *
535  * returns 0 on error, length of packet on success
536  */
537 int
cons_options(struct packet * inpacket,struct dhcp_packet * outpacket,struct lease * lease,struct client_state * client_state,int mms,struct option_state * in_options,struct option_state * cfg_options,struct binding_scope ** scope,int overload_avail,int terminate,int bootpp,struct data_string * prl,const char * vuname)538 cons_options(struct packet *inpacket, struct dhcp_packet *outpacket,
539 	     struct lease *lease, struct client_state *client_state,
540 	     int mms, struct option_state *in_options,
541 	     struct option_state *cfg_options,
542 	     struct binding_scope **scope,
543 	     int overload_avail, int terminate, int bootpp,
544 	     struct data_string *prl, const char *vuname)
545 {
546 #define PRIORITY_COUNT 300
547 	unsigned priority_list[PRIORITY_COUNT];
548 	int priority_len;
549 	unsigned char buffer[4096], agentopts[1024];
550 	unsigned index = 0;
551 	unsigned mb_size = 0, mb_max = 0;
552 	unsigned option_size = 0, agent_size = 0;
553 	unsigned length;
554 	int i;
555 	struct option_cache *op;
556 	struct data_string ds;
557 	pair pp, *hash;
558 	int overload_used = 0;
559 	int of1 = 0, of2 = 0;
560 
561 	memset(&ds, 0, sizeof ds);
562 
563 	/*
564 	 * If there's a Maximum Message Size option in the incoming packet
565 	 * and no alternate maximum message size has been specified, or
566 	 * if the one specified in the packet is shorter than the
567 	 * alternative, take the one in the packet.
568 	 */
569 
570 	if (inpacket &&
571 	    (op = lookup_option(&dhcp_universe, inpacket->options,
572 				DHO_DHCP_MAX_MESSAGE_SIZE)) &&
573 	    (evaluate_option_cache(&ds, inpacket, lease,
574 				   client_state, in_options,
575 				   cfg_options, scope, op, MDL) != 0)) {
576 		if (ds.len >= sizeof (u_int16_t)) {
577 			i = getUShort(ds.data);
578 			if(!mms || (i < mms))
579 				mms = i;
580 		}
581 		data_string_forget(&ds, MDL);
582 	}
583 
584 	/*
585 	 * If the client has provided a maximum DHCP message size,
586 	 * use that, up to the MTU limit.  Otherwise, if it's BOOTP,
587 	 * only 64 bytes; otherwise use up to the minimum IP MTU size
588 	 * (576 bytes).
589 	 *
590 	 * XXX if a BOOTP client specifies a max message size, we will
591 	 * honor it.
592 	 */
593 	if (mms) {
594 		if (mms < DHCP_MTU_MIN)
595 		        /* Enforce minimum packet size, per RFC 2132 */
596 			mb_size = DHCP_MIN_OPTION_LEN;
597 		else if (mms > DHCP_MTU_MAX)
598 			/*
599 			 * TODO: Packets longer than 1500 bytes really
600 			 * should be allowed, but it requires upstream
601 			 * changes to the way the packet is allocated.  For
602 			 * now, we forbid them.  They won't be needed very
603 			 * often anyway.
604 			 */
605 			mb_size = DHCP_MAX_OPTION_LEN;
606 		else
607 			mb_size = mms - DHCP_FIXED_LEN;
608 	} else if (bootpp) {
609 		mb_size = 64;
610 		if (inpacket != NULL &&
611 		    (inpacket->packet_length >= 64 + DHCP_FIXED_NON_UDP))
612 			mb_size = inpacket->packet_length - DHCP_FIXED_NON_UDP;
613 	} else
614 		mb_size = DHCP_MIN_OPTION_LEN;
615 
616 	/*
617 	 * If answering a client message, see whether any relay agent
618 	 * options were included with the message.  If so, save them
619 	 * to copy back in later, and make space in the main buffer
620 	 * to accommodate them
621 	 */
622 	if (client_state == NULL) {
623 		priority_list[0] = DHO_DHCP_AGENT_OPTIONS;
624 		priority_len = 1;
625 		agent_size = store_options(NULL, agentopts, 0,
626 					   sizeof(agentopts),
627 					   inpacket, lease, client_state,
628 					   in_options, cfg_options, scope,
629 					   priority_list, priority_len,
630 					   0, 0, 0, NULL);
631 
632 		mb_size += agent_size;
633 		if (mb_size > DHCP_MAX_OPTION_LEN)
634 			mb_size = DHCP_MAX_OPTION_LEN;
635 	}
636 
637 	/*
638 	 * Set offsets for buffer data to be copied into filename
639 	 * and servername fields
640 	 */
641 	if (mb_size > agent_size)
642 		mb_max = mb_size - agent_size;
643 	else
644 		mb_max = mb_size;
645 
646 	if (overload_avail & 1) {
647 		of1 = mb_max;
648 		mb_max += DHCP_FILE_LEN;
649 	}
650 
651 	if (overload_avail & 2) {
652 		of2 = mb_max;
653 		mb_max += DHCP_SNAME_LEN;
654 	}
655 
656 	/*
657 	 * Preload the option priority list with protocol-mandatory options.
658 	 * This effectively gives these options the highest priority.
659 	 * This provides the order for any available options, the option
660 	 * must be in the option cache in order to actually be included.
661 	 */
662 	priority_len = 0;
663 	priority_list[priority_len++] = DHO_DHCP_MESSAGE_TYPE;
664 	priority_list[priority_len++] = DHO_DHCP_SERVER_IDENTIFIER;
665 	priority_list[priority_len++] = DHO_DHCP_LEASE_TIME;
666 	priority_list[priority_len++] = DHO_DHCP_RENEWAL_TIME;
667 	priority_list[priority_len++] = DHO_DHCP_REBINDING_TIME;
668 	priority_list[priority_len++] = DHO_DHCP_MESSAGE;
669 	priority_list[priority_len++] = DHO_DHCP_REQUESTED_ADDRESS;
670 	priority_list[priority_len++] = DHO_ASSOCIATED_IP;
671 
672 	if (prl != NULL && prl->len > 0) {
673 		if ((op = lookup_option(&dhcp_universe, cfg_options,
674 					 DHO_SUBNET_SELECTION))) {
675 			if (priority_len < PRIORITY_COUNT)
676 				priority_list[priority_len++] =
677 					DHO_SUBNET_SELECTION;
678 		}
679 
680 		/* If echo-client-id is on, then we add client identifier to
681 		 * the priority_list. This way we'll send it whether or not it
682 		 * is in the PRL. */
683 		if ((inpacket != NULL) && (priority_len < PRIORITY_COUNT) &&
684 		    (inpacket->sv_echo_client_id == ISC_TRUE)) {
685 			priority_list[priority_len++] =
686 				DHO_DHCP_CLIENT_IDENTIFIER;
687 		}
688 
689 		data_string_truncate(prl, (PRIORITY_COUNT - priority_len));
690 
691 		/*
692 		 * Copy the client's PRL onto the priority_list after our high
693 		 * priority header.
694 		 */
695 		for (i = 0; i < prl->len; i++) {
696 			/*
697 			 * Prevent client from changing order of delivery
698 			 * of relay agent information option.
699 			 */
700 			if (prl->data[i] != DHO_DHCP_AGENT_OPTIONS)
701 				priority_list[priority_len++] = prl->data[i];
702 		}
703 
704 		/*
705 		 * If the client doesn't request the FQDN option explicitly,
706 		 * to indicate priority, consider it lowest priority.  Fit
707 		 * in the packet if there is space.  Note that the option
708 		 * may only be included if the client supplied one.
709 		 */
710 		if ((inpacket != NULL) && (priority_len < PRIORITY_COUNT) &&
711 		    (lookup_option(&fqdn_universe, inpacket->options,
712 				   FQDN_ENCODED) != NULL))
713 			priority_list[priority_len++] = DHO_FQDN;
714 
715 		/*
716 		 * Some DHCP Servers will give the subnet-mask option if
717 		 * it is not on the parameter request list - so some client
718 		 * implementations have come to rely on this - so we will
719 		 * also make sure we supply this, at lowest priority.
720 		 *
721 		 * This is only done in response to DHCPDISCOVER or
722 		 * DHCPREQUEST messages, to avoid providing the option on
723 		 * DHCPINFORM or DHCPLEASEQUERY responses (if the client
724 		 * didn't request it).
725 		 */
726 		if ((inpacket != NULL) && (priority_len < PRIORITY_COUNT) &&
727 		    ((inpacket->packet_type == DHCPDISCOVER) ||
728 		     (inpacket->packet_type == DHCPREQUEST)))
729 			priority_list[priority_len++] = DHO_SUBNET_MASK;
730 	} else {
731 		/*
732 		 * First, hardcode some more options that ought to be
733 		 * sent first...these are high priority to have in the
734 		 * packet.
735 		 */
736 		priority_list[priority_len++] = DHO_SUBNET_MASK;
737 		priority_list[priority_len++] = DHO_ROUTERS;
738 		priority_list[priority_len++] = DHO_DOMAIN_NAME_SERVERS;
739 		priority_list[priority_len++] = DHO_HOST_NAME;
740 		priority_list[priority_len++] = DHO_FQDN;
741 
742 		/*
743 		 * Append a list of the standard DHCP options from the
744 		 * standard DHCP option space.  Actually, if a site
745 		 * option space hasn't been specified, we wind up
746 		 * treating the dhcp option space as the site option
747 		 * space, and the first for loop is skipped, because
748 		 * it's slightly more general to do it this way,
749 		 * taking the 1Q99 DHCP futures work into account.
750 		 */
751 		if (cfg_options->site_code_min) {
752 		    for (i = 0; i < OPTION_HASH_SIZE; i++) {
753 			hash = cfg_options->universes[dhcp_universe.index];
754 			if (hash) {
755 			    for (pp = hash[i]; pp; pp = pp->cdr) {
756 				op = (struct option_cache *)(pp->car);
757 				if (op->option->code <
758 				     cfg_options->site_code_min &&
759 				    priority_len < PRIORITY_COUNT &&
760 				    op->option->code != DHO_DHCP_AGENT_OPTIONS)
761 					priority_list[priority_len++] =
762 						op->option->code;
763 			    }
764 			}
765 		    }
766 		}
767 
768 		/*
769 		 * Now cycle through the site option space, or if there
770 		 * is no site option space, we'll be cycling through the
771 		 * dhcp option space.
772 		 */
773 		for (i = 0; i < OPTION_HASH_SIZE; i++) {
774 		    hash = cfg_options->universes[cfg_options->site_universe];
775 		    if (hash != NULL)
776 			for (pp = hash[i]; pp; pp = pp->cdr) {
777 				op = (struct option_cache *)(pp->car);
778 				if (op->option->code >=
779 				     cfg_options->site_code_min &&
780 				    priority_len < PRIORITY_COUNT &&
781 				    op->option->code != DHO_DHCP_AGENT_OPTIONS)
782 					priority_list[priority_len++] =
783 						op->option->code;
784 			}
785 		}
786 
787 		/*
788 		 * Put any spaces that are encapsulated on the list,
789 		 * sort out whether they contain values later.
790 		 */
791 		for (i = 0; i < cfg_options->universe_count; i++) {
792 		    if (universes[i]->enc_opt &&
793 			priority_len < PRIORITY_COUNT &&
794 			universes[i]->enc_opt->universe == &dhcp_universe) {
795 			    if (universes[i]->enc_opt->code !=
796 				DHO_DHCP_AGENT_OPTIONS)
797 				    priority_list[priority_len++] =
798 					    universes[i]->enc_opt->code;
799 		    }
800 		}
801 
802 		/*
803 		 * The vendor option space can't stand on its own, so always
804 		 * add it to the list.
805 		 */
806 		if (priority_len < PRIORITY_COUNT)
807 			priority_list[priority_len++] =
808 				DHO_VENDOR_ENCAPSULATED_OPTIONS;
809 	}
810 
811 	/* Put the cookie up front... */
812 	memcpy(buffer, DHCP_OPTIONS_COOKIE, 4);
813 	index += 4;
814 
815 	/* Copy the options into the big buffer... */
816 	option_size = store_options(&overload_used, buffer, index, mb_max,
817 				    inpacket, lease, client_state,
818 				    in_options, cfg_options, scope,
819 				    priority_list, priority_len,
820 				    of1, of2, terminate, vuname);
821 
822 	/* If store_options() failed */
823 	if (option_size == 0)
824 		return 0;
825 
826 	/* How much was stored in the main buffer? */
827 	index += option_size;
828 
829 	/*
830 	 * If we're going to have to overload, store the overload
831 	 * option first.
832 	 */
833 	if (overload_used) {
834 		if (mb_size - agent_size - index < 3)
835 			return 0;
836 
837 		buffer[index++] = DHO_DHCP_OPTION_OVERLOAD;
838 		buffer[index++] = 1;
839 		buffer[index++] = overload_used;
840 
841 		if (overload_used & 1)
842 			memcpy(outpacket->file, &buffer[of1], DHCP_FILE_LEN);
843 
844 		if (overload_used & 2)
845 			memcpy(outpacket->sname, &buffer[of2], DHCP_SNAME_LEN);
846 	}
847 
848 	/* Now copy in preserved agent options, if any */
849 	if (agent_size) {
850 		if (mb_size - index >= agent_size) {
851 			memcpy(&buffer[index], agentopts, agent_size);
852 			index += agent_size;
853 		} else
854 			log_error("Unable to store relay agent information "
855 				  "in reply packet.");
856 	}
857 
858 	/* Tack a DHO_END option onto the packet if we need to. */
859 	if (index < mb_size)
860 		buffer[index++] = DHO_END;
861 
862 	/* Copy main buffer into the options buffer of the packet */
863 	memcpy(outpacket->options, buffer, index);
864 
865 	/* Figure out the length. */
866 	length = DHCP_FIXED_NON_UDP + index;
867 	return length;
868 }
869 
870 /*
871  * XXX: We currently special case collecting VSIO options.
872  *      We should be able to handle this in a more generic fashion, by
873  *      including any encapsulated options that are present and desired.
874  *      This will look something like the VSIO handling VSIO code.
875  *      We may also consider handling the ORO-like options within
876  *      encapsulated spaces.
877  */
878 
879 struct vsio_state {
880 	char *buf;
881 	int buflen;
882 	int bufpos;
883 };
884 
885 static void
vsio_options(struct option_cache * oc,struct packet * packet,struct lease * dummy_lease,struct client_state * dummy_client_state,struct option_state * dummy_opt_state,struct option_state * opt_state,struct binding_scope ** dummy_binding_scope,struct universe * universe,void * void_vsio_state)886 vsio_options(struct option_cache *oc,
887 	     struct packet *packet,
888 	     struct lease *dummy_lease,
889 	     struct client_state *dummy_client_state,
890 	     struct option_state *dummy_opt_state,
891 	     struct option_state *opt_state,
892 	     struct binding_scope **dummy_binding_scope,
893 	     struct universe *universe,
894 	     void *void_vsio_state) {
895 	struct vsio_state *vs = (struct vsio_state *)void_vsio_state;
896 	struct data_string ds;
897 	int total_len;
898 
899 	memset(&ds, 0, sizeof(ds));
900 	if (evaluate_option_cache(&ds, packet, NULL,
901 				  NULL, opt_state, NULL,
902 				  &global_scope, oc, MDL)) {
903 		total_len = ds.len + universe->tag_size + universe->length_size;
904 		if (total_len <= (vs->buflen - vs->bufpos)) {
905 			if (universe->tag_size == 1) {
906 				vs->buf[vs->bufpos++] = oc->option->code;
907 			} else if (universe->tag_size == 2) {
908 				putUShort((unsigned char *)vs->buf+vs->bufpos,
909 					  oc->option->code);
910 				vs->bufpos += 2;
911 			} else if (universe->tag_size == 4) {
912 				putULong((unsigned char *)vs->buf+vs->bufpos,
913 					 oc->option->code);
914 				vs->bufpos += 4;
915 			}
916 			if (universe->length_size == 1) {
917 				vs->buf[vs->bufpos++] = ds.len;
918 			} else if (universe->length_size == 2) {
919 				putUShort((unsigned char *)vs->buf+vs->bufpos,
920 					  ds.len);
921 				vs->bufpos += 2;
922 			} else if (universe->length_size == 4) {
923 				putULong((unsigned char *)vs->buf+vs->bufpos,
924 					 ds.len);
925 				vs->bufpos += 4;
926 			}
927 			memcpy(vs->buf + vs->bufpos, ds.data, ds.len);
928 			vs->bufpos += ds.len;
929 		} else {
930 			log_debug("No space for option %d in VSIO space %s.",
931 		  		oc->option->code, universe->name);
932 		}
933 		data_string_forget(&ds, MDL);
934 	} else {
935 		log_error("Error evaluating option %d in VSIO space %s.",
936 		  	oc->option->code, universe->name);
937 	}
938 }
939 
940 /*!
941  *
942  * \brief Add a v6 option to the buffer
943  *
944  * Put the requested v6 option including tag, length and value
945  * into the specified buffer.  If there isn't enough space for
946  * the entire option it is skipped.
947  *
948  * \param buf    buffer to put the option
949  * \param buflen total length of buffer
950  * \param bufpos on input where to start putting the option
951  *               on output the starting point for the next option
952  * \param code   the option code number
953  * \param ds     the string to put into the option
954  *
955  * \return void
956  */
957 static void
add_option6_data(char * buf,int buflen,int * bufpos,uint16_t code,struct data_string * ds)958 add_option6_data(char *buf, int buflen, int* bufpos, uint16_t code,
959 		struct data_string* ds) {
960 	if ((ds->len + 4) > (buflen - *bufpos)) {
961 		log_debug("No space for option %d", code);
962 	} else {
963 		unsigned char* tmp = (unsigned char *)buf + *bufpos;
964 		/* option tag */
965 		putUShort(tmp, code);
966 		/* option length */
967 		putUShort(tmp+2, ds->len);
968 		/* option data */
969 		memcpy(tmp+4, ds->data, ds->len);
970 		/* update position */
971 		*bufpos += 4 + ds->len;
972 	}
973 }
974 
975 /*!
976  *
977  * \brief Add a v6 encapsulated option to a buffer
978  *
979  * Find the universe for the requested option and if it exists
980  * call it's encapsualtion routine to produce a data string which
981  * can then be added to the current buffer.
982  *
983  * Note 1: currently we only do simple encapsulations, where the
984  * entire value of the option is in the option universe.  This is
985  * the 'E' format, we don't handle the 'e' format as we haven't
986  * defined any such universes yet.  This means that if there is
987  * a simple value for the option store_options6 should handle it
988  * directly and not call this routine.
989  *
990  * \param buf    buffer to put the option
991  * \param buflen total length of buffer
992  * \param bufpos on input where to start putting the option
993  *               on output the starting point for the next option
994  * \param opt_state information about option values to use
995  * \param packet    structure containing what we know about the packet
996  * \param encap_opt information about the structure of the option
997  * \param code      the option code number
998  *
999  * \return void
1000  */
1001 static void
store_encap6(char * buf,int buflen,int * bufpos,struct option_state * opt_state,struct packet * packet,struct option * encap_opt,uint16_t code)1002 store_encap6 (char *buf, int buflen, int* bufpos,
1003 	      struct option_state *opt_state, struct packet *packet,
1004 	      struct option* encap_opt, uint16_t code) {
1005 	/* We need to extract the name of the universe
1006 	 * to use for this option.  We expect a format string
1007 	 * of the form "Ename.".  If we don't find a name we bail. */
1008 	struct data_string ds;
1009 	struct data_string name;
1010 	char* s = (char*)encap_opt->format;
1011 	char* t;
1012 	if ((s == NULL) || (*s != 'E') || (strlen(s) <= 2)) {
1013 		return;
1014 	}
1015 
1016 	t = strchr(++s, '.');
1017 	if ((t == NULL) || (t == s)) {
1018 		return;
1019 	}
1020 
1021 	memset(&ds, 0, sizeof(ds));
1022 	memset(&name, 0, sizeof(name));
1023 	name.data = (unsigned char *)s;
1024 	name.len = t - s;
1025 
1026 	/* Now we call the routine to find and encapsulate the requested
1027 	 * option/universe.  A return of 0 means no option information was
1028 	 * available and nothing is added to the buffer */
1029 	if (option_space_encapsulate(&ds, packet, NULL, NULL, NULL, opt_state,
1030 				     &global_scope, &name) != 0) {
1031 		add_option6_data(buf, buflen, bufpos, code, &ds);
1032 		data_string_forget(&ds, MDL);
1033 	}
1034 }
1035 
1036 /*
1037  * Stores the options from the DHCPv6 universe into the buffer given.
1038  *
1039  * Required options are given as a 0-terminated list of option codes.
1040  * Once those are added, the ORO is consulted.
1041  */
1042 
1043 int
store_options6(char * buf,int buflen,struct option_state * opt_state,struct packet * packet,const int * required_opts,struct data_string * oro)1044 store_options6(char *buf, int buflen,
1045 	       struct option_state *opt_state,
1046 	       struct packet *packet,
1047 	       const int *required_opts,
1048 	       struct data_string *oro) {
1049 	int i, j;
1050 	struct option_cache *oc;
1051 	struct option *o;
1052 	struct data_string ds;
1053 	int bufpos;
1054 	int oro_size;
1055 	u_int16_t code;
1056 	int in_required_opts;
1057 	int vsio_option_code;
1058 	int vsio_wanted;
1059 	struct vsio_state vs;
1060 	unsigned char *tmp;
1061 
1062 	bufpos = 0;
1063 	vsio_wanted = 0;
1064 
1065 	/*
1066 	 * Find the option code for the VSIO universe.
1067 	 */
1068 	vsio_option_code = 0;
1069 	o = vsio_universe.enc_opt;
1070 	while (o != NULL) {
1071 		if (o->universe == &dhcpv6_universe) {
1072 			vsio_option_code = o->code;
1073 			break;
1074 		}
1075 		o = o->universe->enc_opt;
1076 	}
1077 	if (vsio_option_code == 0) {
1078 		log_fatal("No VSIO option code found.");
1079 	}
1080 
1081 	if (required_opts != NULL) {
1082 		for (i=0; required_opts[i] != 0; i++) {
1083 			if (required_opts[i] == vsio_option_code) {
1084 				vsio_wanted = 1;
1085 			}
1086 
1087 			oc = lookup_option(&dhcpv6_universe,
1088 					   opt_state, required_opts[i]);
1089 			if (oc == NULL) {
1090 				continue;
1091 			}
1092 			memset(&ds, 0, sizeof(ds));
1093 			for (; oc != NULL ; oc = oc->next) {
1094 				if (evaluate_option_cache(&ds, packet, NULL,
1095 							  NULL, opt_state,
1096 							  NULL, &global_scope,
1097 							  oc, MDL)) {
1098 					add_option6_data(buf, buflen, &bufpos,
1099 							 (uint16_t)required_opts[i], &ds);
1100 					data_string_forget(&ds, MDL);
1101 				} else {
1102 					log_error("Error evaluating option %d",
1103 					  	required_opts[i]);
1104 				}
1105 			}
1106 		}
1107 	}
1108 
1109 	if (oro == NULL) {
1110 		oro_size = 0;
1111 	} else {
1112 		oro_size = oro->len / 2;
1113 	}
1114 	for (i=0; i<oro_size; i++) {
1115 		memcpy(&code, oro->data+(i*2), 2);
1116 		code = ntohs(code);
1117 
1118 		/*
1119 		 * See if we've already included this option because
1120 		 * it is required.
1121 		 */
1122 		in_required_opts = 0;
1123 		if (required_opts != NULL) {
1124 			for (j=0; required_opts[j] != 0; j++) {
1125 				if (required_opts[j] == code) {
1126 					in_required_opts = 1;
1127 					break;
1128 				}
1129 			}
1130 		}
1131 		if (in_required_opts) {
1132 			continue;
1133 		}
1134 
1135 		/*
1136 		 * If this is the VSIO option flag it so we'll know to
1137 		 * check the vsio space later on.  However we still need
1138 		 * to check for the existence of any defined via
1139 		 * dhcp6.vendor-opts. Those are stored as simple values.
1140 		 */
1141 		if (code == vsio_option_code) {
1142 			vsio_wanted = 1;
1143 		}
1144 
1145 		/*
1146 		 * Not already added, find this option.
1147 		 */
1148 		oc = lookup_option(&dhcpv6_universe, opt_state, code);
1149 		memset(&ds, 0, sizeof(ds));
1150 		if (oc != NULL) {
1151 			/* We have a simple value for the option */
1152 			for (; oc != NULL ; oc = oc->next) {
1153 				if (evaluate_option_cache(&ds, packet, NULL,
1154 							  NULL, opt_state, NULL,
1155 							  &global_scope, oc,
1156 							  MDL)) {
1157 					add_option6_data(buf, buflen, &bufpos,
1158 							 code, &ds);
1159 					data_string_forget(&ds, MDL);
1160 				} else {
1161 					log_error("Error evaluating option %d",
1162 						  code);
1163 				}
1164 			}
1165 		} else {
1166 			/*
1167 			 * We don't have a simple value, check to see if we
1168 			 * have an universe to encapsulate into an option.
1169 			 */
1170 			struct option *encap_opt = NULL;
1171 			unsigned int code_int = code;
1172 
1173 			option_code_hash_lookup(&encap_opt,
1174 						dhcpv6_universe.code_hash,
1175 						&code_int, 0, MDL);
1176 			if (encap_opt != NULL) {
1177 				store_encap6(buf, buflen, &bufpos, opt_state,
1178 					     packet, encap_opt, code);
1179 				option_dereference(&encap_opt, MDL);
1180 			}
1181 		}
1182 	}
1183 
1184 	if (vsio_wanted) {
1185 		for (i=0; i < opt_state->universe_count; i++) {
1186 			if (opt_state->universes[i] != NULL) {
1187 		    		o = universes[i]->enc_opt;
1188 				if ((o != NULL) &&
1189 				    (o->universe == &vsio_universe)) {
1190 					/*
1191 					 * Add the data from this VSIO option.
1192 					 */
1193 					vs.buf = buf;
1194 					vs.buflen = buflen;
1195 					vs.bufpos = bufpos+8;
1196 					option_space_foreach(packet, NULL,
1197 							     NULL,
1198 							     NULL, opt_state,
1199 							     NULL,
1200 							     universes[i],
1201 							     (void *)&vs,
1202 			     				     vsio_options);
1203 
1204 					/*
1205 					 * If there was actually data here,
1206 					 * add the "header".
1207 					 */
1208 					if (vs.bufpos > bufpos+8) {
1209 						tmp = (unsigned char *)buf +
1210 						      bufpos;
1211 						putUShort(tmp,
1212 							  vsio_option_code);
1213 						putUShort(tmp+2,
1214 							  vs.bufpos-bufpos-4);
1215 						putULong(tmp+4, o->code);
1216 
1217 						bufpos = vs.bufpos;
1218 					}
1219 				}
1220 			}
1221 		}
1222 	}
1223 
1224 	return bufpos;
1225 }
1226 
1227 /*
1228  * Store all the requested options into the requested buffer.
1229  * XXX: ought to be static
1230  */
1231 int
store_options(int * ocount,unsigned char * buffer,unsigned index,unsigned buflen,struct packet * packet,struct lease * lease,struct client_state * client_state,struct option_state * in_options,struct option_state * cfg_options,struct binding_scope ** scope,unsigned * priority_list,int priority_len,unsigned first_cutoff,int second_cutoff,int terminate,const char * vuname)1232 store_options(int *ocount,
1233 	      unsigned char *buffer, unsigned index, unsigned buflen,
1234 	      struct packet *packet, struct lease *lease,
1235 	      struct client_state *client_state,
1236 	      struct option_state *in_options,
1237 	      struct option_state *cfg_options,
1238 	      struct binding_scope **scope,
1239 	      unsigned *priority_list, int priority_len,
1240 	      unsigned first_cutoff, int second_cutoff, int terminate,
1241 	      const char *vuname)
1242 {
1243 	int bufix = 0, six = 0, tix = 0;
1244 	int i;
1245 	int ix;
1246 	int tto;
1247 	int bufend, sbufend;
1248 	struct data_string od;
1249 	struct option_cache *oc;
1250 	struct option *option = NULL;
1251 	unsigned code;
1252 
1253 	/*
1254 	 * These arguments are relative to the start of the buffer, so
1255 	 * reduce them by the current buffer index, and advance the
1256 	 * buffer pointer to where we're going to start writing.
1257 	 */
1258 	buffer = &buffer[index];
1259 	buflen -= index;
1260 	if (first_cutoff)
1261 		first_cutoff -= index;
1262 	if (second_cutoff)
1263 		second_cutoff -= index;
1264 
1265 	/* Calculate the start and end of each section of the buffer */
1266 	bufend = sbufend = buflen;
1267 	if (first_cutoff) {
1268 	    if (first_cutoff >= buflen)
1269 		log_fatal("%s:%d:store_options: Invalid first cutoff.", MDL);
1270 	    bufend = first_cutoff;
1271 
1272 	    if (second_cutoff) {
1273 	        if (second_cutoff >= buflen)
1274 		    log_fatal("%s:%d:store_options: Invalid second cutoff.",
1275 			      MDL);
1276 	        sbufend = second_cutoff;
1277 	    }
1278 	} else if (second_cutoff) {
1279 	    if (second_cutoff >= buflen)
1280 		log_fatal("%s:%d:store_options: Invalid second cutoff.", MDL);
1281 	    bufend = second_cutoff;
1282 	}
1283 
1284 	memset (&od, 0, sizeof od);
1285 
1286 	/* Eliminate duplicate options from the parameter request list.
1287 	 * Enforce RFC-mandated ordering of options that are present.
1288 	 */
1289 	for (i = 0; i < priority_len; i++) {
1290 		/* Eliminate duplicates. */
1291 		tto = 0;
1292 		for (ix = i + 1; ix < priority_len + tto; ix++) {
1293 			if (tto)
1294 				priority_list [ix - tto] =
1295 					priority_list [ix];
1296 			if (priority_list [i] == priority_list [ix]) {
1297 				tto++;
1298 				priority_len--;
1299 			}
1300 		}
1301 
1302 		/* Enforce ordering of SUBNET_MASK options, according to
1303 		 * RFC2132 Section 3.3:
1304 		 *
1305 		 *   If both the subnet mask and the router option are
1306 		 *   specified in a DHCP reply, the subnet mask option MUST
1307 		 *   be first.
1308 		 *
1309 		 * This guidance does not specify what to do if the client
1310 		 * PRL explicitly requests the options out of order, it is
1311 		 * a general statement.
1312 		 */
1313 		if (priority_list[i] == DHO_SUBNET_MASK) {
1314 			for (ix = i - 1 ; ix >= 0 ; ix--) {
1315 				if (priority_list[ix] == DHO_ROUTERS) {
1316                                         /* swap */
1317 					priority_list[ix] = DHO_SUBNET_MASK;
1318 					priority_list[i] = DHO_ROUTERS;
1319 					break;
1320 				}
1321 			}
1322 		}
1323 	}
1324 
1325 	/* Copy out the options in the order that they appear in the
1326 	   priority list... */
1327 	for (i = 0; i < priority_len; i++) {
1328 	    /* Number of bytes left to store (some may already
1329 	       have been stored by a previous pass). */
1330 	    unsigned length;
1331 	    int optstart, soptstart, toptstart;
1332 	    struct universe *u;
1333 	    int have_encapsulation = 0;
1334 	    struct data_string encapsulation;
1335 	    int splitup;
1336 
1337 	    memset (&encapsulation, 0, sizeof encapsulation);
1338 	    have_encapsulation = 0;
1339 
1340 	    if (option != NULL)
1341 		option_dereference(&option, MDL);
1342 
1343 	    /* Code for next option to try to store. */
1344 	    code = priority_list [i];
1345 
1346 	    /* Look up the option in the site option space if the code
1347 	       is above the cutoff, otherwise in the DHCP option space. */
1348 	    if (code >= cfg_options -> site_code_min)
1349 		    u = universes [cfg_options -> site_universe];
1350 	    else
1351 		    u = &dhcp_universe;
1352 
1353 	    oc = lookup_option (u, cfg_options, code);
1354 
1355 	    if (oc && oc->option)
1356 		option_reference(&option, oc->option, MDL);
1357 	    else
1358 		option_code_hash_lookup(&option, u->code_hash, &code, 0, MDL);
1359 
1360 	    /* If it's a straight encapsulation, and the user supplied a
1361 	     * value for the entire option, use that.  Otherwise, search
1362 	     * the encapsulated space.
1363 	     *
1364 	     * If it's a limited encapsulation with preceding data, and the
1365 	     * user supplied values for the preceding bytes, search the
1366 	     * encapsulated space.
1367 	     */
1368 	    if ((option != NULL) &&
1369 		(((oc == NULL) && (option->format[0] == 'E')) ||
1370 		 ((oc != NULL) && (option->format[0] == 'e')))) {
1371 		static char *s, *t;
1372 		struct option_cache *tmp;
1373 		struct data_string name;
1374 
1375 		s = strchr (option->format, 'E');
1376 		if (s)
1377 		    t = strchr (++s, '.');
1378 		if (s && t) {
1379 		    memset (&name, 0, sizeof name);
1380 
1381 		    /* A zero-length universe name means the vendor
1382 		       option space, if one is defined. */
1383 		    if (t == s) {
1384 			if (vendor_cfg_option) {
1385 			    tmp = lookup_option (vendor_cfg_option -> universe,
1386 						 cfg_options,
1387 						 vendor_cfg_option -> code);
1388 			    if (tmp)
1389 				/* No need to check the return as we check name.len below */
1390 				(void) evaluate_option_cache (&name, packet, lease,
1391 							      client_state,
1392 							      in_options,
1393 							      cfg_options,
1394 							      scope, tmp, MDL);
1395 			} else if (vuname) {
1396 			    name.data = (unsigned char *)s;
1397 			    name.len = strlen (s);
1398 			}
1399 		    } else {
1400 			name.data = (unsigned char *)s;
1401 			name.len = t - s;
1402 		    }
1403 
1404 		    /* If we found a universe, and there are options configured
1405 		       for that universe, try to encapsulate it. */
1406 		    if (name.len) {
1407 			have_encapsulation =
1408 				(option_space_encapsulate
1409 				 (&encapsulation, packet, lease, client_state,
1410 				  in_options, cfg_options, scope, &name));
1411 		    }
1412 
1413 		    data_string_forget (&name, MDL);
1414 		}
1415 	    }
1416 
1417 	    /* In order to avoid memory leaks, we have to get to here
1418 	       with any option cache that we allocated in tmp not being
1419 	       referenced by tmp, and whatever option cache is referenced
1420 	       by oc being an actual reference.   lookup_option doesn't
1421 	       generate a reference (this needs to be fixed), so the
1422 	       preceding goop ensures that if we *didn't* generate a new
1423 	       option cache, oc still winds up holding an actual reference. */
1424 
1425 	    /* If no data is available for this option, skip it. */
1426 	    if (!oc && !have_encapsulation) {
1427 		    continue;
1428 	    }
1429 
1430 	    /* Find the value of the option... */
1431 	    od.len = 0;
1432 	    if (oc) {
1433 		/* No need to check the return as we check od.len below */
1434 		(void) evaluate_option_cache (&od, packet,
1435 					      lease, client_state, in_options,
1436 					      cfg_options, scope, oc, MDL);
1437 
1438 		/* If we have encapsulation for this option, and an oc
1439 		 * lookup succeeded, but the evaluation failed, it is
1440 		 * either because this is a complex atom (atoms before
1441 		 * E on format list) and the top half of the option is
1442 		 * not configured, or this is a simple encapsulated
1443 		 * space and the evaluator is giving us a NULL.  Prefer
1444 		 * the evaluator's opinion over the subspace.
1445 		 */
1446 		if (!od.len) {
1447 		    data_string_forget (&encapsulation, MDL);
1448 		    data_string_forget (&od, MDL);
1449 		    continue;
1450 		}
1451 	    }
1452 
1453 	    /* We should now have a constant length for the option. */
1454 	    length = od.len;
1455 	    if (have_encapsulation) {
1456 		    length += encapsulation.len;
1457 
1458 		    /* od.len can be nonzero if we got here without an
1459 		     * oc (cache lookup failed), but did have an encapsulated
1460 		     * simple encapsulation space.
1461 		     */
1462 		    if (!od.len) {
1463 			    data_string_copy (&od, &encapsulation, MDL);
1464 			    data_string_forget (&encapsulation, MDL);
1465 		    } else {
1466 			    struct buffer *bp = (struct buffer *)0;
1467 			    if (!buffer_allocate (&bp, length, MDL)) {
1468 				    option_cache_dereference (&oc, MDL);
1469 				    data_string_forget (&od, MDL);
1470 				    data_string_forget (&encapsulation, MDL);
1471 				    continue;
1472 			    }
1473 			    memcpy (&bp -> data [0], od.data, od.len);
1474 			    memcpy (&bp -> data [od.len], encapsulation.data,
1475 				    encapsulation.len);
1476 			    data_string_forget (&od, MDL);
1477 			    data_string_forget (&encapsulation, MDL);
1478 			    od.data = &bp -> data [0];
1479 			    buffer_reference (&od.buffer, bp, MDL);
1480 			    buffer_dereference (&bp, MDL);
1481 			    od.len = length;
1482 			    od.terminated = 0;
1483 		    }
1484 	    }
1485 
1486 	    /* Do we add a NUL? */
1487 	    if (terminate && option && format_has_text(option->format)) {
1488 		    length++;
1489 		    tto = 1;
1490 	    } else {
1491 		    tto = 0;
1492 	    }
1493 
1494 	    /* Try to store the option. */
1495 
1496 	    /* If the option's length is more than 255, we must store it
1497 	       in multiple hunks.   Store 255-byte hunks first.  However,
1498 	       in any case, if the option data will cross a buffer
1499 	       boundary, split it across that boundary. */
1500 
1501 	    if (length > 255)
1502 		splitup = 1;
1503 	    else
1504 		splitup = 0;
1505 
1506 	    ix = 0;
1507 	    optstart = bufix;
1508 	    soptstart = six;
1509 	    toptstart = tix;
1510 	    while (length) {
1511 		    unsigned incr = length;
1512 		    int *pix;
1513 		    unsigned char *base;
1514 
1515 		    /* Try to fit it in the options buffer. */
1516 		    if (!splitup &&
1517 			((!six && !tix && (i == priority_len - 1) &&
1518 			  (bufix + 2 + length < bufend)) ||
1519 			 (bufix + 5 + length < bufend))) {
1520 			base = buffer;
1521 			pix = &bufix;
1522 		    /* Try to fit it in the second buffer. */
1523 		    } else if (!splitup && first_cutoff &&
1524 			       (first_cutoff + six + 3 + length < sbufend)) {
1525 			base = &buffer[first_cutoff];
1526 			pix = &six;
1527 		    /* Try to fit it in the third buffer. */
1528 		    } else if (!splitup && second_cutoff &&
1529 			       (second_cutoff + tix + 3 + length < buflen)) {
1530 			base = &buffer[second_cutoff];
1531 			pix = &tix;
1532 		    /* Split the option up into the remaining space. */
1533 		    } else {
1534 			splitup = 1;
1535 
1536 			/* Use any remaining options space. */
1537 			if (bufix + 6 < bufend) {
1538 			    incr = bufend - bufix - 5;
1539 			    base = buffer;
1540 			    pix = &bufix;
1541 			/* Use any remaining first_cutoff space. */
1542 			} else if (first_cutoff &&
1543 				   (first_cutoff + six + 4 < sbufend)) {
1544 			    incr = sbufend - (first_cutoff + six) - 3;
1545 			    base = &buffer[first_cutoff];
1546 			    pix = &six;
1547 			/* Use any remaining second_cutoff space. */
1548 			} else if (second_cutoff &&
1549 				   (second_cutoff + tix + 4 < buflen)) {
1550 			    incr = buflen - (second_cutoff + tix) - 3;
1551 			    base = &buffer[second_cutoff];
1552 			    pix = &tix;
1553 			/* Give up, roll back this option. */
1554 			} else {
1555 			    bufix = optstart;
1556 			    six = soptstart;
1557 			    tix = toptstart;
1558 			    break;
1559 			}
1560 		    }
1561 
1562 		    if (incr > length)
1563 			incr = length;
1564 		    if (incr > 255)
1565 			incr = 255;
1566 
1567 		    /* Everything looks good - copy it in! */
1568 		    base [*pix] = code;
1569 		    base [*pix + 1] = (unsigned char)incr;
1570 		    if (tto && incr == length) {
1571 			    if (incr > 1)
1572 				memcpy (base + *pix + 2,
1573 					od.data + ix, (unsigned)(incr - 1));
1574 			    base [*pix + 2 + incr - 1] = 0;
1575 		    } else {
1576 			    memcpy (base + *pix + 2,
1577 				    od.data + ix, (unsigned)incr);
1578 		    }
1579 		    length -= incr;
1580 		    ix += incr;
1581 		    *pix += 2 + incr;
1582 	    }
1583 	    data_string_forget (&od, MDL);
1584 	}
1585 
1586 	if (option != NULL)
1587 	    option_dereference(&option, MDL);
1588 
1589 	/* If we can overload, and we have, then PAD and END those spaces. */
1590 	if (first_cutoff && six) {
1591 	    if ((first_cutoff + six + 1) < sbufend)
1592 		memset (&buffer[first_cutoff + six + 1], DHO_PAD,
1593 			sbufend - (first_cutoff + six + 1));
1594 	    else if (first_cutoff + six >= sbufend)
1595 		log_fatal("Second buffer overflow in overloaded options.");
1596 
1597 	    buffer[first_cutoff + six] = DHO_END;
1598 	    if (ocount != NULL)
1599 	    	*ocount |= 1; /* So that caller knows there's data there. */
1600 	}
1601 
1602 	if (second_cutoff && tix) {
1603 	    if (second_cutoff + tix + 1 < buflen) {
1604 		memset (&buffer[second_cutoff + tix + 1], DHO_PAD,
1605 			buflen - (second_cutoff + tix + 1));
1606 	    } else if (second_cutoff + tix >= buflen)
1607 		log_fatal("Third buffer overflow in overloaded options.");
1608 
1609 	    buffer[second_cutoff + tix] = DHO_END;
1610 	    if (ocount != NULL)
1611 	    	*ocount |= 2; /* So that caller knows there's data there. */
1612 	}
1613 
1614 	if ((six || tix) && (bufix + 3 > bufend))
1615 	    log_fatal("Not enough space for option overload option.");
1616 
1617 	return bufix;
1618 }
1619 
1620 /* Return true if the format string has a variable length text option
1621  * ("t"), return false otherwise.
1622  */
1623 
1624 int
format_has_text(format)1625 format_has_text(format)
1626 	const char *format;
1627 {
1628 	const char *p;
1629 
1630 	p = format;
1631 	while (*p != '\0') {
1632 		switch (*p++) {
1633 		    case 't':
1634 		    case 'k':
1635 			return 1;
1636 
1637 			/* These symbols are arbitrary, not fixed or
1638 			 * determinable length...text options with them is
1639 			 * invalid (whatever the case, they are never NULL
1640 			 * terminated).
1641 			 */
1642 		    case 'A':
1643 		    case 'a':
1644 		    case 'X':
1645 		    case 'x':
1646 		    case 'D':
1647 		    case 'd':
1648 			return 0;
1649 
1650 		    case 'c':
1651 			/* 'c' only follows 'D' atoms, and indicates that
1652 			 * compression may be used.  If there was a 'D'
1653 			 * atom already, we would have returned.  So this
1654 			 * is an error, but continue looking for 't' anyway.
1655 			 */
1656 			log_error("format_has_text(%s): 'c' atoms are illegal "
1657 				  "except after 'D' atoms.", format);
1658 			break;
1659 
1660 			/* 'E' is variable length, but not arbitrary...you
1661 			 * can find its length if you can find an END option.
1662 			 * N is (n)-byte in length but trails a name of a
1663 			 * space defining the enumeration values.  So treat
1664 			 * both the same - valid, fixed-length fields.
1665 			 */
1666 		    case 'E':
1667 		    case 'N':
1668 			/* Consume the space name. */
1669 			while ((*p != '\0') && (*p++ != '.'))
1670 				;
1671 			break;
1672 
1673 		    default:
1674 			break;
1675 		}
1676 	}
1677 
1678 	return 0;
1679 }
1680 
1681 /* Determine the minimum length of a DHCP option prior to any variable
1682  * or inconsistent length formats, according to its configured format
1683  * variable (and possibly from supplied option cache contents for variable
1684  * length format symbols).
1685  */
1686 
1687 int
format_min_length(format,oc)1688 format_min_length(format, oc)
1689 	const char *format;
1690 	struct option_cache *oc;
1691 {
1692 	const char *p, *name;
1693 	int min_len = 0;
1694 	int last_size = 0;
1695 	struct enumeration *espace;
1696 
1697 	p = format;
1698 	while (*p != '\0') {
1699 		switch (*p++) {
1700 		    case '6': /* IPv6 Address */
1701 			min_len += 16;
1702 			last_size = 16;
1703 			break;
1704 
1705 		    case 'I': /* IPv4 Address */
1706 		    case 'l': /* int32_t */
1707 		    case 'L': /* uint32_t */
1708 		    case 'T': /* Lease Time, uint32_t equivalent */
1709 			min_len += 4;
1710 			last_size = 4;
1711 			break;
1712 
1713 		    case 's': /* int16_t */
1714 		    case 'S': /* uint16_t */
1715 			min_len += 2;
1716 			last_size = 2;
1717 			break;
1718 
1719 		    case 'N': /* Enumeration value. */
1720 			/* Consume space name. */
1721 			name = p;
1722 			p = strchr(p, '.');
1723 			if (p == NULL)
1724 				log_fatal("Corrupt format: %s", format);
1725 
1726 			espace = find_enumeration(name, p - name);
1727 			if (espace == NULL) {
1728 				log_error("Unknown enumeration: %s", format);
1729 				/* Max is safest value to return. */
1730 				return INT_MAX;
1731 			}
1732 
1733 			min_len += espace->width;
1734 			last_size = espace->width;
1735 			p++;
1736 
1737 			break;
1738 
1739 		    case 'b': /* int8_t */
1740 		    case 'B': /* uint8_t */
1741 		    case 'F': /* Flag that is always true. */
1742 		    case 'f': /* Flag */
1743 			min_len++;
1744 			last_size = 1;
1745 			break;
1746 
1747 		    case 'o': /* Last argument is optional. */
1748 			min_len -= last_size;
1749 
1750 		    /* XXX: It MAY be possible to sense the end of an
1751 		     * encapsulated space, but right now this is too
1752 		     * hard to support.  Return a safe value.
1753 		     */
1754 		    case 'e': /* Encapsulation hint (there is an 'E' later). */
1755 		    case 'E': /* Encapsulated options. */
1756 			return min_len;
1757 
1758 		    case 'd': /* "Domain name" */
1759 		    case 'D': /* "rfc1035 formatted names" */
1760 		    case 't': /* "ASCII Text" */
1761 		    case 'X': /* "ASCII or Hex Conditional */
1762 		    case 'x': /* "Hex" */
1763 		    case 'A': /* Array of all that precedes. */
1764 		    case 'a': /* Array of preceding symbol. */
1765 		    case 'Z': /* nothing. */
1766 		    case 'k': /* key name */
1767 			return min_len;
1768 
1769 		    case 'c': /* Compress flag for D atom. */
1770 			log_error("format_min_length(%s): 'c' atom is illegal "
1771 				  "except after 'D' atom.", format);
1772 			return INT_MAX;
1773 
1774 		    default:
1775 			/* No safe value is known. */
1776 			log_error("format_min_length(%s): No safe value "
1777 				  "for unknown format symbols.", format);
1778 			return INT_MAX;
1779 		}
1780 	}
1781 
1782 	return min_len;
1783 }
1784 
1785 
1786 /* Format the specified option so that a human can easily read it. */
1787 /* Maximum pretty printed size */
1788 #define MAX_OUTPUT_SIZE 32*1024
pretty_print_option(option,data,len,emit_commas,emit_quotes)1789 const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
1790 	struct option *option;
1791 	const unsigned char *data;
1792 	unsigned len;
1793 	int emit_commas;
1794 	int emit_quotes;
1795 {
1796 	/* We add 128 byte pad so we don't have to add checks everywhere. */
1797 	static char optbuf [MAX_OUTPUT_SIZE + 128]; /* XXX */
1798 	static char *endbuf = optbuf + MAX_OUTPUT_SIZE;
1799 	int hunksize = 0;
1800 	int opthunk = 0;
1801 	int hunkinc = 0;
1802 	int numhunk = -1;
1803 	int numelem = 0;
1804 	int count;
1805 	int i, j, k, l;
1806 	char fmtbuf[32] = "";
1807 	struct iaddr iaddr;
1808 	struct enumeration *enumbuf[32]; /* MUST be same as fmtbuf */
1809 	char *op = optbuf;
1810 	const unsigned char *dp = data;
1811 	char comma;
1812 	unsigned long tval;
1813 	isc_boolean_t a_array = ISC_FALSE;
1814 	int len_used;
1815 
1816 	if (emit_commas)
1817 		comma = ',';
1818 	else
1819 		comma = ' ';
1820 
1821 	memset (enumbuf, 0, sizeof enumbuf);
1822 
1823 	/* Figure out the size of the data. */
1824 	for (l = i = 0; option -> format [i]; i++, l++) {
1825 		if (l >= sizeof(fmtbuf) - 1)
1826 			log_fatal("Bounds failure on internal buffer at "
1827 				  "%s:%d", MDL);
1828 
1829 		if (!numhunk) {
1830 			log_error ("%s: Extra codes in format string: %s",
1831 				   option -> name,
1832 				   &(option -> format [i]));
1833 			break;
1834 		}
1835 		numelem++;
1836 		fmtbuf [l] = option -> format [i];
1837 		switch (option -> format [i]) {
1838 		      case 'a':
1839 			a_array = ISC_TRUE;
1840 			/* Fall through */
1841 		      case 'A':
1842 			--numelem;
1843 			fmtbuf [l] = 0;
1844 			numhunk = 0;
1845 			break;
1846 		      case 'E':
1847 			/* Skip the universe name. */
1848 			while (option -> format [i] &&
1849 			       option -> format [i] != '.')
1850 				i++;
1851 			/* Fall Through! */
1852 		      case 'X':
1853 			for (k = 0; k < len; k++) {
1854 				if (!isascii (data [k]) ||
1855 				    !isprint (data [k]))
1856 					break;
1857 			}
1858 			/* If we found no bogus characters, or the bogus
1859 			   character we found is a trailing NUL, it's
1860 			   okay to print this option as text. */
1861 			if (k == len || (k + 1 == len && data [k] == 0)) {
1862 				fmtbuf [l] = 't';
1863 				numhunk = -2;
1864 			} else {
1865 				fmtbuf [l] = 'x';
1866 				hunksize++;
1867 				comma = ':';
1868 				numhunk = 0;
1869 				a_array = ISC_TRUE;
1870 				hunkinc = 1;
1871 			}
1872 			fmtbuf [l + 1] = 0;
1873 			break;
1874 		      case 'c':
1875 			/* The 'c' atom is a 'D' modifier only. */
1876 			log_error("'c' atom not following D atom in format "
1877 				  "string: %s", option->format);
1878 			break;
1879 		      case 'D':
1880 			/*
1881 			 * Skip the 'c' atom, if present.  It does not affect
1882 			 * how we convert wire->text format (if compression is
1883 			 * present either way, we still process it).
1884 			 */
1885 			if (option->format[i+1] == 'c')
1886 				i++;
1887 			fmtbuf[l + 1] = 0;
1888 			numhunk = -2;
1889 			break;
1890 		      case 'd':
1891 			/* Should not be optional, array or compressed */
1892 			if ((option->format[i+1] == 'o') ||
1893 			    (option->format[i+1] == 'a') ||
1894 			    (option->format[i+1] == 'A') ||
1895 			    (option->format[i+1] == 'c')) {
1896 				log_error("%s: Illegal use of domain name: %s",
1897 					  option->name,
1898 					  &(option->format[i-1]));
1899 				fmtbuf[l + 1] = 0;
1900 			}
1901 			k = MRns_name_len(data + len, data + hunksize);
1902 			if (k == -1) {
1903 				log_error("Invalid domain name.");
1904 				return "<error>";
1905 			}
1906 			hunksize += k;
1907 			break;
1908 
1909 		      case 't':
1910 		      case 'k':
1911 			fmtbuf[l + 1] = 0;
1912 			numhunk = -2;
1913 			break;
1914 		      case 'N':
1915 			k = i;
1916 			while (option -> format [i] &&
1917 			       option -> format [i] != '.')
1918 				i++;
1919 			enumbuf [l] =
1920 				find_enumeration (&option -> format [k] + 1,
1921 						  i - k - 1);
1922 			if (enumbuf[l] == NULL) {
1923 				hunksize += 1;
1924 				hunkinc = 1;
1925 			} else {
1926 				hunksize += enumbuf[l]->width;
1927 				hunkinc = enumbuf[l]->width;
1928 			}
1929 			break;
1930 		      case '6':
1931 			hunksize += 16;
1932 			hunkinc = 16;
1933 			break;
1934 		      case 'I':
1935 		      case 'l':
1936 		      case 'L':
1937 		      case 'T':
1938 			hunksize += 4;
1939 			hunkinc = 4;
1940 			break;
1941 		      case 's':
1942 		      case 'S':
1943 			hunksize += 2;
1944 			hunkinc = 2;
1945 			break;
1946 		      case 'b':
1947 		      case 'B':
1948 		      case 'f':
1949 		      case 'F':
1950 			hunksize++;
1951 			hunkinc = 1;
1952 			break;
1953 		      case 'e':
1954 		      case 'Z':
1955 			break;
1956 		      case 'o':
1957 			opthunk += hunkinc;
1958 			break;
1959 		      default:
1960 			log_error ("%s: garbage in format string: %s",
1961 			      option -> name,
1962 			      &(option -> format [i]));
1963 			break;
1964 		}
1965 	}
1966 
1967 	/* Check for too few bytes... */
1968 	if (hunksize - opthunk > len) {
1969 		log_error ("%s: expecting at least %d bytes; got %d",
1970 		      option -> name,
1971 		      hunksize, len);
1972 		return "<error>";
1973 	}
1974 	/* Check for too many bytes... */
1975 	if (numhunk == -1 && hunksize < len)
1976 		log_error ("%s: %d extra bytes",
1977 		      option -> name,
1978 		      len - hunksize);
1979 
1980 	/* If this is an array, compute its size. */
1981 	if (numhunk == 0) {
1982 		if (a_array == ISC_TRUE) {
1983 			/*
1984 			 * It is an 'a' type array - we repeat the
1985 			 * last format type.  A binary string for 'X'
1986 			 * is also like this.  hunkinc is the size
1987 			 * of the last format type and we add 1 to
1988 			 * cover the entire first record.
1989 			 */
1990 
1991 			/* If format string had no valid entries prior to
1992 			 * 'a' hunkinc will be 0. Ex: "a", "oa", "aA" */
1993 			if (hunkinc == 0) {
1994 				log_error ("%s: invalid 'a' format: %s",
1995 					   option->name, option->format);
1996 				return ("<error>");
1997 			}
1998 
1999 			numhunk = ((len - hunksize) / hunkinc) + 1;
2000 			len_used = hunksize + ((numhunk - 1) * hunkinc);
2001 		} else {
2002 			/*
2003 			 * It is an 'A' type array - we repeat the
2004 			 * entire record
2005 			 */
2006 
2007 			/* If format string had no valid entries prior to
2008 			 * 'A' hunksize will be 0. Ex: "A", "oA", "foA" */
2009 			if (hunksize == 0) {
2010 				log_error ("%s: invalid 'A' format: %s",
2011 					   option->name, option->format);
2012 				return ("<error>");
2013 			}
2014 
2015 			numhunk = len / hunksize;
2016 			len_used = numhunk * hunksize;
2017 		}
2018 
2019 		/* See if we got an exact number of hunks. */
2020 		if (len_used < len) {
2021 			log_error ("%s: %d extra bytes at end of array\n",
2022 				   option -> name,
2023 				   len - len_used);
2024 		}
2025 	}
2026 
2027 
2028 	/* A one-hunk array prints the same as a single hunk. */
2029 	if (numhunk < 0)
2030 		numhunk = 1;
2031 
2032 	/* Cycle through the array (or hunk) printing the data. */
2033 	for (i = 0; i < numhunk; i++) {
2034 		if ((a_array == ISC_TRUE) && (i != 0) && (numelem > 0)) {
2035 			/*
2036 			 * For 'a' type of arrays we repeat
2037 			 * only the last format character
2038 			 * We should never hit the case of numelem == 0
2039 			 * but let's include the check to be safe.
2040 			 */
2041 			j = numelem - 1;
2042 		} else {
2043 			/*
2044 			 * for other types of arrays or the first
2045 			 * time through for 'a' types, we go through
2046 			 * the entire set of format characters.
2047 			 */
2048 			j = 0;
2049 		}
2050 
2051 		for (; j < numelem; j++) {
2052 			switch (fmtbuf [j]) {
2053 			      case 't':
2054 			      case 'k':
2055 				/* endbuf-1 leaves room for NULL. */
2056 				k = pretty_text(&op, endbuf - 1, &dp,
2057 						data + len, emit_quotes);
2058 				if (k == -1) {
2059 					log_error("Error printing text.");
2060 					break;
2061 				}
2062 				*op = 0;
2063 				break;
2064 			      case 'd': /* RFC1035 format name */
2065 				k = MRns_name_len(data + len, dp);
2066 				/* Already tested... */
2067 				if (k == -1) {
2068 					log_error("invalid domain name.");
2069 					return "<error>";
2070 				}
2071 				pretty_dname(&op, endbuf-1, dp, data + len);
2072 				/* pretty_dname does not add the nul */
2073 				*op = '\0';
2074 				dp += k;
2075 				break;
2076 			      case 'D': /* RFC1035 format name list */
2077 				for( ; dp < (data + len) ; dp += k) {
2078 					unsigned char nbuff[NS_MAXCDNAME];
2079 					const unsigned char *nbp, *nend;
2080 
2081 					nend = &nbuff[sizeof(nbuff)];
2082 
2083 					/* If this is for ISC DHCP consumption
2084 					 * (emit_quotes), lay it out as a list
2085 					 * of STRING tokens.  Otherwise, it is
2086 					 * a space-separated list of DNS-
2087 					 * escaped names as /etc/resolv.conf
2088 					 * might digest.
2089 					 */
2090 					if (dp != data) {
2091 						if (op + 2 > endbuf)
2092 							break;
2093 
2094 						if (emit_quotes)
2095 							*op++ = ',';
2096 						*op++ = ' ';
2097 					}
2098 
2099 					/* XXX: if fmtbuf[j+1] != 'c', we
2100 					 * should warn if the data was
2101 					 * compressed anyway.
2102 					 */
2103 					k = MRns_name_unpack(data,
2104 							     data + len,
2105 							     dp, nbuff,
2106 							     sizeof(nbuff));
2107 
2108 					if (k == -1) {
2109 						log_error("Invalid domain "
2110 							  "list.");
2111 						break;
2112 					}
2113 
2114 					/* If emit_quotes, then use ISC DHCP
2115 					 * escapes.  Otherwise, rely only on
2116 					 * MRns_name_ntop().
2117 					 */
2118 					if (emit_quotes) {
2119 						nbp = nbuff;
2120 						pretty_domain(&op, endbuf-1,
2121 							      &nbp, nend);
2122 					} else {
2123 						/* MRns_name_ntop() includes
2124 						 * a trailing NUL in its
2125 						 * count.
2126 						 */
2127 						count = MRns_name_ntop(
2128 								nbuff, op,
2129 								(endbuf-op)-1);
2130 
2131 						if (count <= 0) {
2132 							log_error("Invalid "
2133 								"domain name.");
2134 							break;
2135 						}
2136 
2137 						/* Consume all but the trailing
2138 						 * NUL.
2139 						 */
2140 						op += count - 1;
2141 
2142 						/* Replace the trailing NUL
2143 						 * with the implicit root
2144 						 * (in the unlikely event the
2145 						 * domain name /is/ the root).
2146 						 */
2147 						*op++ = '.';
2148 					}
2149 				}
2150 				*op = '\0';
2151 				break;
2152 				/* pretty-printing an array of enums is
2153 				   going to get ugly. */
2154 			      case 'N':
2155 				if (!enumbuf [j]) {
2156 					tval = *dp++;
2157 					goto enum_as_num;
2158 				}
2159 
2160 				switch (enumbuf[j]->width) {
2161 				      case 1:
2162 					tval = getUChar(dp);
2163 					break;
2164 
2165 				     case 2:
2166 					tval = getUShort(dp);
2167 					break;
2168 
2169 				    case 4:
2170 					tval = getULong(dp);
2171 					break;
2172 
2173 				    default:
2174 					log_fatal("Impossible case at %s:%d.",
2175 						  MDL);
2176 					return "<double impossible condition>";
2177 				}
2178 
2179 				for (i = 0; ;i++) {
2180 					if (!enumbuf [j] -> values [i].name)
2181 						goto enum_as_num;
2182 					if (enumbuf [j] -> values [i].value ==
2183 					    tval)
2184 						break;
2185 				}
2186 				strcpy (op, enumbuf [j] -> values [i].name);
2187 				dp += enumbuf[j]->width;
2188 				break;
2189 
2190 			      enum_as_num:
2191 				sprintf(op, "%lu", tval);
2192 				break;
2193 
2194 			      case 'I':
2195 				iaddr.len = 4;
2196 				memcpy(iaddr.iabuf, dp, 4);
2197 				strcpy(op, piaddr(iaddr));
2198 				dp += 4;
2199 				break;
2200 			      case '6':
2201 				iaddr.len = 16;
2202 				memcpy(iaddr.iabuf, dp, 16);
2203 				strcpy(op, piaddr(iaddr));
2204 				dp += 16;
2205 				break;
2206 			      case 'l':
2207 				sprintf (op, "%ld", (long)getLong (dp));
2208 				dp += 4;
2209 				break;
2210 			      case 'T':
2211 				tval = getULong (dp);
2212 				if (tval == -1)
2213 					sprintf (op, "%s", "infinite");
2214 				else
2215 					sprintf(op, "%lu", tval);
2216 				break;
2217 			      case 'L':
2218 				sprintf(op, "%lu",
2219 					(unsigned long)getULong(dp));
2220 				dp += 4;
2221 				break;
2222 			      case 's':
2223 				sprintf (op, "%d", (int)getShort (dp));
2224 				dp += 2;
2225 				break;
2226 			      case 'S':
2227 				sprintf(op, "%u", (unsigned)getUShort(dp));
2228 				dp += 2;
2229 				break;
2230 			      case 'b':
2231 				sprintf (op, "%d", *(const char *)dp++);
2232 				break;
2233 			      case 'B':
2234 				sprintf (op, "%d", *dp++);
2235 				break;
2236 			      case 'X':
2237 			      case 'x':
2238 				sprintf (op, "%x", *dp++);
2239 				break;
2240 			      case 'f':
2241 				strcpy (op, *dp++ ? "true" : "false");
2242 				break;
2243 			      case 'F':
2244 				strcpy (op, "true");
2245 				break;
2246 			      case 'e':
2247 			      case 'Z':
2248 				*op = '\0';
2249 				break;
2250 			      default:
2251 				log_error ("Unexpected format code %c",
2252 					   fmtbuf [j]);
2253 			}
2254 
2255 			op += strlen (op);
2256 			if (op >= endbuf) {
2257 				log_error ("Option data exceeds"
2258 					   " maximum size %d", MAX_OUTPUT_SIZE);
2259 					   return ("<error>");
2260 			}
2261 
2262 			if (dp == data + len)
2263 				break;
2264 			if (j + 1 < numelem && comma != ':')
2265 				*op++ = ' ';
2266 		}
2267 		if (i + 1 < numhunk) {
2268 			*op++ = comma;
2269 		}
2270 		if (dp == data + len)
2271 			break;
2272 	}
2273 	return optbuf;
2274 }
2275 
get_option(result,universe,packet,lease,client_state,in_options,cfg_options,options,scope,code,file,line)2276 int get_option (result, universe, packet, lease, client_state,
2277 		in_options, cfg_options, options, scope, code, file, line)
2278 	struct data_string *result;
2279 	struct universe *universe;
2280 	struct packet *packet;
2281 	struct lease *lease;
2282 	struct client_state *client_state;
2283 	struct option_state *in_options;
2284 	struct option_state *cfg_options;
2285 	struct option_state *options;
2286 	struct binding_scope **scope;
2287 	unsigned code;
2288 	const char *file;
2289 	int line;
2290 {
2291 	struct option_cache *oc;
2292 
2293 	if (!universe -> lookup_func)
2294 		return 0;
2295 	oc = ((*universe -> lookup_func) (universe, options, code));
2296 	if (!oc)
2297 		return 0;
2298 	if (!evaluate_option_cache (result, packet, lease, client_state,
2299 				    in_options, cfg_options, scope, oc,
2300 				    file, line))
2301 		return 0;
2302 	return 1;
2303 }
2304 
2305 /*
2306  * Look for the option and dig out the value assoicated with it.
2307  * Currently this is used for 1 byte integers, it maybe expanded
2308  * in the future to handle other integers at which point it will
2309  * need a size argument.
2310  */
get_option_int(result,universe,packet,lease,client_state,in_options,cfg_options,options,scope,code,file,line)2311 int get_option_int (result, universe, packet, lease, client_state,
2312 		    in_options, cfg_options, options, scope, code, file, line)
2313 	int *result;
2314 	struct universe *universe;
2315 	struct packet *packet;
2316 	struct lease *lease;
2317 	struct client_state *client_state;
2318 	struct option_state *in_options;
2319 	struct option_state *cfg_options;
2320 	struct option_state *options;
2321 	struct binding_scope **scope;
2322 	unsigned code;
2323 	const char *file;
2324 	int line;
2325 {
2326 	struct option_cache *oc;
2327 	struct data_string d1;
2328 	int rcode = 0;
2329 
2330 	/* basic sanity checks */
2331 	if ((options == NULL) || (universe->lookup_func == NULL))
2332 		return (0);
2333 
2334 	/* find the option cache */
2335 	oc = ((*universe->lookup_func)(universe, options, code));
2336 	if (!oc)
2337 		return (0);
2338 
2339 	/* if there is a value get it into the string */
2340 	memset(&d1, 0, sizeof(d1));
2341 	if (!evaluate_option_cache(&d1, packet, lease, client_state,
2342 				   in_options, cfg_options, scope, oc,
2343 				   file, line))
2344 		return (0);
2345 
2346 	/* If the length matches extract the value for the return */
2347 	if (d1.len == 1) {
2348 		*result = d1.data[0];
2349 		rcode = 1;
2350 	}
2351 	data_string_forget(&d1, MDL);
2352 
2353 	return (rcode);
2354 }
2355 
set_option(universe,options,option,op)2356 void set_option (universe, options, option, op)
2357 	struct universe *universe;
2358 	struct option_state *options;
2359 	struct option_cache *option;
2360 	enum statement_op op;
2361 {
2362 	struct option_cache *oc, *noc;
2363 
2364 	switch (op) {
2365 	      case if_statement:
2366 	      case add_statement:
2367 	      case eval_statement:
2368 	      case break_statement:
2369 	      default:
2370 		log_error ("bogus statement type in set_option.");
2371 		break;
2372 
2373 	      case default_option_statement:
2374 		oc = lookup_option (universe, options,
2375 				    option -> option -> code);
2376 		if (oc)
2377 			break;
2378 		save_option (universe, options, option);
2379 		break;
2380 
2381 	      case supersede_option_statement:
2382 	      case send_option_statement:
2383 		/* Install the option, replacing any existing version. */
2384 		save_option (universe, options, option);
2385 		break;
2386 
2387 	      case append_option_statement:
2388 	      case prepend_option_statement:
2389 		oc = lookup_option (universe, options,
2390 				    option -> option -> code);
2391 		if (!oc) {
2392 			save_option (universe, options, option);
2393 			break;
2394 		}
2395 		/* If it's not an expression, make it into one. */
2396 		if (!oc -> expression && oc -> data.len) {
2397 			if (!expression_allocate (&oc -> expression, MDL)) {
2398 				log_error ("Can't allocate const expression.");
2399 				break;
2400 			}
2401 			oc -> expression -> op = expr_const_data;
2402 			data_string_copy
2403 				(&oc -> expression -> data.const_data,
2404 				 &oc -> data, MDL);
2405 			data_string_forget (&oc -> data, MDL);
2406 		}
2407 		noc = (struct option_cache *)0;
2408 		if (!option_cache_allocate (&noc, MDL))
2409 			break;
2410 		if (op == append_option_statement) {
2411 			if (!make_concat (&noc -> expression,
2412 					  oc -> expression,
2413 					  option -> expression)) {
2414 				option_cache_dereference (&noc, MDL);
2415 				break;
2416 			}
2417 		} else {
2418 			if (!make_concat (&noc -> expression,
2419 					  option -> expression,
2420 					  oc -> expression)) {
2421 				option_cache_dereference (&noc, MDL);
2422 				break;
2423 			}
2424 		}
2425 
2426 		/* If we are trying to combine compressed domain-lists then
2427 		 * we need to change the expression opcode.  The lists must
2428 		 * be decompressed, combined, and then recompressed to work
2429 		 * correctly.  You cannot simply add two compressed lists
2430 		 * together. */
2431 		switch (((memcmp(option->option->format, "Dc", 2) == 0) +
2432 			 (memcmp(oc->option->format, "Dc", 2) == 0))) {
2433 			case 1:
2434 				/* Only one is "Dc", this won't work
2435 				 * Not sure if you can make this occur, but just
2436 				 * in case. */
2437 				log_error ("Both options must be Dc format");
2438 				option_cache_dereference (&noc, MDL);
2439 				return;
2440 			case 2:
2441 				/* Both are "Dc", change the code */
2442 				noc->expression->op = expr_concat_dclist;
2443 				break;
2444 			default:
2445 				/* Neither are "Dc", so as you were */
2446 				break;
2447 		}
2448 
2449 		option_reference(&(noc->option), oc->option, MDL);
2450 		save_option (universe, options, noc);
2451 		option_cache_dereference (&noc, MDL);
2452 		break;
2453 	}
2454 }
2455 
lookup_option(universe,options,code)2456 struct option_cache *lookup_option (universe, options, code)
2457 	struct universe *universe;
2458 	struct option_state *options;
2459 	unsigned code;
2460 {
2461 	if (!options)
2462 		return (struct option_cache *)0;
2463 	if (universe -> lookup_func)
2464 		return (*universe -> lookup_func) (universe, options, code);
2465 	else
2466 		log_error ("can't look up options in %s space.",
2467 			   universe -> name);
2468 	return (struct option_cache *)0;
2469 }
2470 
lookup_hashed_option(universe,options,code)2471 struct option_cache *lookup_hashed_option (universe, options, code)
2472 	struct universe *universe;
2473 	struct option_state *options;
2474 	unsigned code;
2475 {
2476 	int hashix;
2477 	pair bptr;
2478 	pair *hash;
2479 
2480 	/* Make sure there's a hash table. */
2481 	if (universe -> index >= options -> universe_count ||
2482 	    !(options -> universes [universe -> index]))
2483 		return (struct option_cache *)0;
2484 
2485 	hash = options -> universes [universe -> index];
2486 
2487 	hashix = compute_option_hash (code);
2488 	for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
2489 		if (((struct option_cache *)(bptr -> car)) -> option -> code ==
2490 		    code)
2491 			return (struct option_cache *)(bptr -> car);
2492 	}
2493 	return (struct option_cache *)0;
2494 }
2495 
2496 /* Save a specified buffer into an option cache. */
2497 int
save_option_buffer(struct universe * universe,struct option_state * options,struct buffer * bp,unsigned char * buffer,unsigned length,unsigned code,int terminatep)2498 save_option_buffer(struct universe *universe, struct option_state *options,
2499 		   struct buffer *bp, unsigned char *buffer, unsigned length,
2500 		   unsigned code, int terminatep)
2501 {
2502 	struct option_cache *op = NULL;
2503 	int status = 1;
2504 
2505 	status = prepare_option_buffer(universe, bp, buffer, length, code,
2506 				       terminatep, &op);
2507 
2508 	if (status == 0)
2509 		goto cleanup;
2510 
2511 	save_option(universe, options, op);
2512 
2513     cleanup:
2514 	if (op != NULL)
2515 		option_cache_dereference(&op, MDL);
2516 
2517 	return status;
2518 }
2519 
2520 /* Append a specified buffer onto the tail of an option cache. */
2521 int
append_option_buffer(struct universe * universe,struct option_state * options,struct buffer * bp,unsigned char * buffer,unsigned length,unsigned code,int terminatep)2522 append_option_buffer(struct universe *universe, struct option_state *options,
2523 		     struct buffer *bp, unsigned char *buffer, unsigned length,
2524 		     unsigned code, int terminatep)
2525 {
2526 	struct option_cache *op = NULL;
2527 	int status = 1;
2528 
2529 	status = prepare_option_buffer(universe, bp, buffer, length, code,
2530 				       terminatep, &op);
2531 
2532 	if (status == 0)
2533 		goto cleanup;
2534 
2535 	also_save_option(universe, options, op);
2536 
2537       cleanup:
2538 	if (op != NULL)
2539 		option_cache_dereference(&op, MDL);
2540 
2541 	return status;
2542 }
2543 
2544 /* Create/copy a buffer into a new option cache. */
2545 static int
prepare_option_buffer(struct universe * universe,struct buffer * bp,unsigned char * buffer,unsigned length,unsigned code,int terminatep,struct option_cache ** opp)2546 prepare_option_buffer(struct universe *universe, struct buffer *bp,
2547 		      unsigned char *buffer, unsigned length, unsigned code,
2548 		      int terminatep, struct option_cache **opp)
2549 {
2550 	struct buffer *lbp = NULL;
2551 	struct option *option = NULL;
2552 	struct option_cache *op;
2553 	int status = 1;
2554 
2555 	/* Code sizes of 8, 16, and 32 bits are allowed. */
2556 	switch(universe->tag_size) {
2557 	      case 1:
2558 		if (code > 0xff)
2559 			return 0;
2560 		break;
2561 	      case 2:
2562 		if (code > 0xffff)
2563 			return 0;
2564 		break;
2565 	      case 4:
2566 		if (code > 0xffffffff)
2567 			return 0;
2568 		break;
2569 
2570 	      default:
2571 		log_fatal("Inconsistent universe tag size at %s:%d.", MDL);
2572 	}
2573 
2574 	option_code_hash_lookup(&option, universe->code_hash, &code, 0, MDL);
2575 
2576 	/* If we created an option structure for each option a client
2577 	 * supplied, it's possible we may create > 2^32 option structures.
2578 	 * That's not feasible.  So by failing to enter these option
2579 	 * structures into the code and name hash tables, references will
2580 	 * never be more than 1 - when the option cache is destroyed, this
2581 	 * will be cleaned up.
2582 	 */
2583 	if (!option) {
2584 		char nbuf[sizeof("unknown-4294967295")];
2585 
2586 		sprintf(nbuf, "unknown-%u", code);
2587 
2588 		option = new_option(nbuf, MDL);
2589 
2590 		if (!option)
2591 			return 0;
2592 
2593 		option->format = default_option_format;
2594 		option->universe = universe;
2595 		option->code = code;
2596 
2597 		/* new_option() doesn't set references, pretend. */
2598 		option->refcnt = 1;
2599 	}
2600 
2601 	if (!option_cache_allocate (opp, MDL)) {
2602 		log_error("No memory for option code %s.%s.",
2603 			  universe->name, option->name);
2604 		status = 0;
2605 		goto cleanup;
2606 	}
2607 
2608 	/* Pointer rather than double pointer makes for less parens. */
2609 	op = *opp;
2610 
2611 	option_reference(&op->option, option, MDL);
2612 
2613 	/* If we weren't passed a buffer in which the data are saved and
2614 	   refcounted, allocate one now. */
2615 	if (!bp) {
2616 		if (!buffer_allocate (&lbp, length + terminatep, MDL)) {
2617 			log_error ("no memory for option buffer.");
2618 
2619 			status = 0;
2620 			goto cleanup;
2621 		}
2622 		memcpy (lbp -> data, buffer, length + terminatep);
2623 		bp = lbp;
2624 		buffer = &bp -> data [0]; /* Refer to saved buffer. */
2625 	}
2626 
2627 	/* Reference buffer copy to option cache. */
2628 	op -> data.buffer = (struct buffer *)0;
2629 	buffer_reference (&op -> data.buffer, bp, MDL);
2630 
2631 	/* Point option cache into buffer. */
2632 	op -> data.data = buffer;
2633 	op -> data.len = length;
2634 
2635 	if (terminatep) {
2636 		/* NUL terminate (we can get away with this because we (or
2637 		   the caller!) allocated one more than the buffer size, and
2638 		   because the byte following the end of an option is always
2639 		   the code of the next option, which the caller is getting
2640 		   out of the *original* buffer. */
2641 		buffer [length] = 0;
2642 		op -> data.terminated = 1;
2643 	} else
2644 		op -> data.terminated = 0;
2645 
2646 	/* If this option is ultimately a text option, null determinate to
2647 	 * comply with RFC2132 section 2.  Mark a flag so this can be sensed
2648 	 * later to echo NULLs back to clients that supplied them (they
2649 	 * probably expect them).
2650 	 */
2651 	if (format_has_text(option->format)) {
2652 		int min_len = format_min_length(option->format, op);
2653 
2654 		while ((op->data.len > min_len) &&
2655 		       (op->data.data[op->data.len-1] == '\0')) {
2656 			op->data.len--;
2657 			op->flags |= OPTION_HAD_NULLS;
2658 		}
2659 	}
2660 
2661 	/* And let go of our references. */
2662       cleanup:
2663 	if (lbp != NULL)
2664 		buffer_dereference(&lbp, MDL);
2665 	option_dereference(&option, MDL);
2666 
2667 	return status;
2668 }
2669 
2670 static void
count_options(struct option_cache * dummy_oc,struct packet * dummy_packet,struct lease * dummy_lease,struct client_state * dummy_client_state,struct option_state * dummy_opt_state,struct option_state * opt_state,struct binding_scope ** dummy_binding_scope,struct universe * dummy_universe,void * void_accumulator)2671 count_options(struct option_cache *dummy_oc,
2672 	      struct packet *dummy_packet,
2673 	      struct lease *dummy_lease,
2674 	      struct client_state *dummy_client_state,
2675 	      struct option_state *dummy_opt_state,
2676 	      struct option_state *opt_state,
2677 	      struct binding_scope **dummy_binding_scope,
2678 	      struct universe *dummy_universe,
2679 	      void *void_accumulator) {
2680 	int *accumulator = (int *)void_accumulator;
2681 
2682 	*accumulator += 1;
2683 }
2684 
2685 static void
collect_oro(struct option_cache * oc,struct packet * dummy_packet,struct lease * dummy_lease,struct client_state * dummy_client_state,struct option_state * dummy_opt_state,struct option_state * opt_state,struct binding_scope ** dummy_binding_scope,struct universe * dummy_universe,void * void_oro)2686 collect_oro(struct option_cache *oc,
2687 	    struct packet *dummy_packet,
2688 	    struct lease *dummy_lease,
2689 	    struct client_state *dummy_client_state,
2690 	    struct option_state *dummy_opt_state,
2691 	    struct option_state *opt_state,
2692 	    struct binding_scope **dummy_binding_scope,
2693 	    struct universe *dummy_universe,
2694 	    void *void_oro) {
2695 	struct data_string *oro = (struct data_string *)void_oro;
2696 
2697 	putUShort(oro->buffer->data + oro->len, oc->option->code);
2698 	oro->len += 2;
2699 }
2700 
2701 /* build_server_oro() is presently unusued, but may be used at a future date
2702  * with support for Reconfigure messages (as a hint to the client about new
2703  * option value contents).
2704  */
2705 void
build_server_oro(struct data_string * server_oro,struct option_state * options,const char * file,int line)2706 build_server_oro(struct data_string *server_oro,
2707 		 struct option_state *options,
2708 		 const char *file, int line) {
2709 	int num_opts;
2710 	int i;
2711 	struct option *o;
2712 
2713 	/*
2714 	 * Count the number of options, so we can allocate enough memory.
2715 	 * We want to mention sub-options too, so check all universes.
2716 	 */
2717 	num_opts = 0;
2718 	option_space_foreach(NULL, NULL, NULL, NULL, options,
2719 			     NULL, &dhcpv6_universe, (void *)&num_opts,
2720 			     count_options);
2721 	for (i=0; i < options->universe_count; i++) {
2722 		if (options->universes[i] != NULL) {
2723 		    	o = universes[i]->enc_opt;
2724 			while (o != NULL) {
2725 				if (o->universe == &dhcpv6_universe) {
2726 					num_opts++;
2727 					break;
2728 				}
2729 				o = o->universe->enc_opt;
2730 			}
2731 		}
2732 	}
2733 
2734 	/*
2735 	 * Allocate space.
2736 	 */
2737 	memset(server_oro, 0, sizeof(*server_oro));
2738 	if (!buffer_allocate(&server_oro->buffer, num_opts * 2, MDL)) {
2739 		log_fatal("no memory to build server ORO");
2740 	}
2741 	server_oro->data = server_oro->buffer->data;
2742 
2743 	/*
2744 	 * Copy the data in.
2745 	 * We want to mention sub-options too, so check all universes.
2746 	 */
2747 	server_oro->len = 0; 	/* gets set in collect_oro */
2748 	option_space_foreach(NULL, NULL, NULL, NULL, options,
2749 			     NULL, &dhcpv6_universe, (void *)server_oro,
2750 			     collect_oro);
2751 	for (i=0; i < options->universe_count; i++) {
2752 		if (options->universes[i] != NULL) {
2753 		    	o = universes[i]->enc_opt;
2754 			while (o != NULL) {
2755 				if (o->universe == &dhcpv6_universe) {
2756 					unsigned char *tmp;
2757 					tmp = server_oro->buffer->data;
2758 					putUShort(tmp + server_oro->len,
2759 						  o->code);
2760 					server_oro->len += 2;
2761 					break;
2762 				}
2763 				o = o->universe->enc_opt;
2764 			}
2765 		}
2766 	}
2767 }
2768 
2769 /* Wrapper function to put an option cache into an option state. */
2770 void
save_option(struct universe * universe,struct option_state * options,struct option_cache * oc)2771 save_option(struct universe *universe, struct option_state *options,
2772 	    struct option_cache *oc)
2773 {
2774 	if (universe->save_func)
2775 		(*universe->save_func)(universe, options, oc, ISC_FALSE);
2776 	else
2777 		log_error("can't store options in %s space.", universe->name);
2778 }
2779 
2780 /* Wrapper function to append an option cache into an option state's list. */
2781 void
also_save_option(struct universe * universe,struct option_state * options,struct option_cache * oc)2782 also_save_option(struct universe *universe, struct option_state *options,
2783 		 struct option_cache *oc)
2784 {
2785 	if (universe->save_func)
2786 		(*universe->save_func)(universe, options, oc, ISC_TRUE);
2787 	else
2788 		log_error("can't store options in %s space.", universe->name);
2789 }
2790 
2791 void
save_hashed_option(struct universe * universe,struct option_state * options,struct option_cache * oc,isc_boolean_t appendp)2792 save_hashed_option(struct universe *universe, struct option_state *options,
2793 		   struct option_cache *oc, isc_boolean_t appendp)
2794 {
2795 	int hashix;
2796 	pair bptr;
2797 	pair *hash = options -> universes [universe -> index];
2798 	struct option_cache **ocloc;
2799 
2800 	if (oc -> refcnt == 0)
2801 		abort ();
2802 
2803 	/* Compute the hash. */
2804 	hashix = compute_option_hash (oc -> option -> code);
2805 
2806 	/* If there's no hash table, make one. */
2807 	if (!hash) {
2808 		hash = (pair *)dmalloc (OPTION_HASH_SIZE * sizeof *hash, MDL);
2809 		if (!hash) {
2810 			log_error ("no memory to store %s.%s",
2811 				   universe -> name, oc -> option -> name);
2812 			return;
2813 		}
2814 		memset (hash, 0, OPTION_HASH_SIZE * sizeof *hash);
2815 		options -> universes [universe -> index] = (void *)hash;
2816 	} else {
2817 		/* Try to find an existing option matching the new one. */
2818 		for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
2819 			if (((struct option_cache *)
2820 			     (bptr -> car)) -> option -> code ==
2821 			    oc -> option -> code)
2822 				break;
2823 		}
2824 
2825 		/* Deal with collisions on the hash list. */
2826 		if (bptr) {
2827 			ocloc = (struct option_cache **)&bptr->car;
2828 
2829 			/*
2830 			 * If appendp is set, append it onto the tail of the
2831 			 * ->next list.  If it is not set, rotate it into
2832 			 * position at the head of the list.
2833 			 */
2834 			if (appendp) {
2835 				do {
2836 					ocloc = &(*ocloc)->next;
2837 				} while (*ocloc != NULL);
2838 			} else {
2839 				option_cache_dereference(ocloc, MDL);
2840 			}
2841 
2842 			option_cache_reference(ocloc, oc, MDL);
2843 			return;
2844 		}
2845 	}
2846 
2847 	/* Otherwise, just put the new one at the head of the list. */
2848 	bptr = new_pair (MDL);
2849 	if (!bptr) {
2850 		log_error ("No memory for option_cache reference.");
2851 		return;
2852 	}
2853 	bptr -> cdr = hash [hashix];
2854 	bptr -> car = 0;
2855 	option_cache_reference ((struct option_cache **)&bptr -> car, oc, MDL);
2856 	hash [hashix] = bptr;
2857 }
2858 
delete_option(universe,options,code)2859 void delete_option (universe, options, code)
2860 	struct universe *universe;
2861 	struct option_state *options;
2862 	int code;
2863 {
2864 	if (universe -> delete_func)
2865 		(*universe -> delete_func) (universe, options, code);
2866 	else
2867 		log_error ("can't delete options from %s space.",
2868 			   universe -> name);
2869 }
2870 
delete_hashed_option(universe,options,code)2871 void delete_hashed_option (universe, options, code)
2872 	struct universe *universe;
2873 	struct option_state *options;
2874 	int code;
2875 {
2876 	int hashix;
2877 	pair bptr, prev = (pair)0;
2878 	pair *hash = options -> universes [universe -> index];
2879 
2880 	/* There may not be any options in this space. */
2881 	if (!hash)
2882 		return;
2883 
2884 	/* Try to find an existing option matching the new one. */
2885 	hashix = compute_option_hash (code);
2886 	for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
2887 		if (((struct option_cache *)(bptr -> car)) -> option -> code
2888 		    == code)
2889 			break;
2890 		prev = bptr;
2891 	}
2892 	/* If we found one, wipe it out... */
2893 	if (bptr) {
2894 		if (prev)
2895 			prev -> cdr = bptr -> cdr;
2896 		else
2897 			hash [hashix] = bptr -> cdr;
2898 		option_cache_dereference
2899 			((struct option_cache **)(&bptr -> car), MDL);
2900 		free_pair (bptr, MDL);
2901 	}
2902 }
2903 
2904 extern struct option_cache *free_option_caches; /* XXX */
2905 
option_cache_dereference(ptr,file,line)2906 int option_cache_dereference (ptr, file, line)
2907 	struct option_cache **ptr;
2908 	const char *file;
2909 	int line;
2910 {
2911 	if (!ptr || !*ptr) {
2912 		log_error ("Null pointer in option_cache_dereference: %s(%d)",
2913 			   file, line);
2914 #if defined (POINTER_DEBUG)
2915 		abort ();
2916 #else
2917 		return 0;
2918 #endif
2919 	}
2920 
2921 	(*ptr) -> refcnt--;
2922 	rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1, RC_MISC);
2923 	if (!(*ptr) -> refcnt) {
2924 		if ((*ptr) -> data.buffer)
2925 			data_string_forget (&(*ptr) -> data, file, line);
2926 		if ((*ptr)->option)
2927 			option_dereference(&(*ptr)->option, MDL);
2928 		if ((*ptr) -> expression)
2929 			expression_dereference (&(*ptr) -> expression,
2930 						file, line);
2931 		if ((*ptr) -> next)
2932 			option_cache_dereference (&((*ptr) -> next),
2933 						  file, line);
2934 		/* Put it back on the free list... */
2935 		(*ptr) -> expression = (struct expression *)free_option_caches;
2936 		free_option_caches = *ptr;
2937 		dmalloc_reuse (free_option_caches, (char *)0, 0, 0);
2938 	}
2939 	if ((*ptr) -> refcnt < 0) {
2940 		log_error ("%s(%d): negative refcnt!", file, line);
2941 #if defined (DEBUG_RC_HISTORY)
2942 		dump_rc_history (*ptr);
2943 #endif
2944 #if defined (POINTER_DEBUG)
2945 		abort ();
2946 #else
2947 		*ptr = (struct option_cache *)0;
2948 		return 0;
2949 #endif
2950 	}
2951 	*ptr = (struct option_cache *)0;
2952 	return 1;
2953 
2954 }
2955 
hashed_option_state_dereference(universe,state,file,line)2956 int hashed_option_state_dereference (universe, state, file, line)
2957 	struct universe *universe;
2958 	struct option_state *state;
2959 	const char *file;
2960 	int line;
2961 {
2962 	pair *heads;
2963 	pair cp, next;
2964 	int i;
2965 
2966 	/* Get the pointer to the array of hash table bucket heads. */
2967 	heads = (pair *)(state -> universes [universe -> index]);
2968 	if (!heads)
2969 		return 0;
2970 
2971 	/* For each non-null head, loop through all the buckets dereferencing
2972 	   the attached option cache structures and freeing the buckets. */
2973 	for (i = 0; i < OPTION_HASH_SIZE; i++) {
2974 		for (cp = heads [i]; cp; cp = next) {
2975 			next = cp -> cdr;
2976 			option_cache_dereference
2977 				((struct option_cache **)&cp -> car,
2978 				 file, line);
2979 			free_pair (cp, file, line);
2980 		}
2981 	}
2982 
2983 	dfree (heads, file, line);
2984 	state -> universes [universe -> index] = (void *)0;
2985 	return 1;
2986 }
2987 
2988 /* The 'data_string' primitive doesn't have an appension mechanism.
2989  * This function must then append a new option onto an existing buffer
2990  * by first duplicating the original buffer and appending the desired
2991  * values, followed by coping the new value into place.
2992  */
2993 int
append_option(struct data_string * dst,struct universe * universe,struct option * option,struct data_string * src)2994 append_option(struct data_string *dst, struct universe *universe,
2995 	      struct option *option, struct data_string *src)
2996 {
2997 	struct data_string tmp;
2998 
2999 	if (src->len == 0 && option->format[0] != 'Z')
3000 		return 0;
3001 
3002 	memset(&tmp, 0, sizeof(tmp));
3003 
3004 	/* Allocate a buffer to hold existing data, the current option's
3005 	 * tag and length, and the option's content.
3006 	 */
3007 	if (!buffer_allocate(&tmp.buffer,
3008 			     (dst->len + universe->length_size +
3009 			      universe->tag_size + src->len), MDL)) {
3010 		/* XXX: This kills all options presently stored in the
3011 		 * destination buffer.  This is the way the original code
3012 		 * worked, and assumes an 'all or nothing' approach to
3013 		 * eg encapsulated option spaces.  It may or may not be
3014 		 * desirable.
3015 		 */
3016 		data_string_forget(dst, MDL);
3017 		return 0;
3018 	}
3019 	tmp.data = tmp.buffer->data;
3020 
3021 	/* Copy the existing data off the destination. */
3022 	if (dst->len != 0)
3023 		memcpy(tmp.buffer->data, dst->data, dst->len);
3024 	tmp.len = dst->len;
3025 
3026 	/* Place the new option tag and length. */
3027 	(*universe->store_tag)(tmp.buffer->data + tmp.len, option->code);
3028 	tmp.len += universe->tag_size;
3029 	(*universe->store_length)(tmp.buffer->data + tmp.len, src->len);
3030 	tmp.len += universe->length_size;
3031 
3032 	/* Copy the option contents onto the end. */
3033 	memcpy(tmp.buffer->data + tmp.len, src->data, src->len);
3034 	tmp.len += src->len;
3035 
3036 	/* Play the shell game. */
3037 	data_string_forget(dst, MDL);
3038 	data_string_copy(dst, &tmp, MDL);
3039 	data_string_forget(&tmp, MDL);
3040 	return 1;
3041 }
3042 
3043 int
store_option(struct data_string * result,struct universe * universe,struct packet * packet,struct lease * lease,struct client_state * client_state,struct option_state * in_options,struct option_state * cfg_options,struct binding_scope ** scope,struct option_cache * oc)3044 store_option(struct data_string *result, struct universe *universe,
3045 	     struct packet *packet, struct lease *lease,
3046 	     struct client_state *client_state,
3047 	     struct option_state *in_options, struct option_state *cfg_options,
3048 	     struct binding_scope **scope, struct option_cache *oc)
3049 {
3050 	struct data_string tmp;
3051 	struct universe *subu=NULL;
3052 	int status;
3053 	char *start, *end;
3054 
3055 	memset(&tmp, 0, sizeof(tmp));
3056 
3057 	if (evaluate_option_cache(&tmp, packet, lease, client_state,
3058 				  in_options, cfg_options, scope, oc, MDL)) {
3059 		/* If the option is an extended 'e'ncapsulation (not a
3060 		 * direct 'E'ncapsulation), append the encapsulated space
3061 		 * onto the currently prepared value.
3062 		 */
3063 		do {
3064 			if (oc->option->format &&
3065 			    oc->option->format[0] == 'e') {
3066 				/* Skip forward to the universe name. */
3067 				start = strchr(oc->option->format, 'E');
3068 				if (start == NULL)
3069 					break;
3070 
3071 				/* Locate the name-terminating '.'. */
3072 				end = strchr(++start, '.');
3073 
3074 				/* A zero-length name is not allowed in
3075 				 * these kinds of encapsulations.
3076 				 */
3077 				if (end == NULL || start == end)
3078 					break;
3079 
3080 				universe_hash_lookup(&subu, universe_hash,
3081 						     start, end - start, MDL);
3082 
3083 				if (subu == NULL) {
3084 					log_error("store_option: option %d "
3085 						  "refers to unknown "
3086 						  "option space '%.*s'.",
3087 						  oc->option->code,
3088 						  (int)(end - start), start);
3089 					break;
3090 				}
3091 
3092 				/* Append encapsulations, if any.  We
3093 				 * already have the prepended values, so
3094 				 * we send those even if there are no
3095 				 * encapsulated options (and ->encapsulate()
3096 				 * returns zero).
3097 				 */
3098 				subu->encapsulate(&tmp, packet, lease,
3099 						  client_state, in_options,
3100 						  cfg_options, scope, subu);
3101 				subu = NULL;
3102 			}
3103 		} while (ISC_FALSE);
3104 
3105 		status = append_option(result, universe, oc->option, &tmp);
3106 		data_string_forget(&tmp, MDL);
3107 
3108 		return status;
3109 	}
3110 
3111 	return 0;
3112 }
3113 
option_space_encapsulate(result,packet,lease,client_state,in_options,cfg_options,scope,name)3114 int option_space_encapsulate (result, packet, lease, client_state,
3115 			      in_options, cfg_options, scope, name)
3116 	struct data_string *result;
3117 	struct packet *packet;
3118 	struct lease *lease;
3119 	struct client_state *client_state;
3120 	struct option_state *in_options;
3121 	struct option_state *cfg_options;
3122 	struct binding_scope **scope;
3123 	struct data_string *name;
3124 {
3125 	struct universe *u = NULL;
3126 	int status = 0;
3127 
3128 	universe_hash_lookup(&u, universe_hash,
3129 			     (const char *)name->data, name->len, MDL);
3130 	if (u == NULL) {
3131 		log_error("option_space_encapsulate: option space '%.*s' does "
3132 			  "not exist, but is configured.",
3133 			  (int)name->len, name->data);
3134 		return status;
3135 	}
3136 
3137 	if (u->encapsulate != NULL) {
3138 		if (u->encapsulate(result, packet, lease, client_state,
3139 				   in_options, cfg_options, scope, u))
3140 			status = 1;
3141 	} else
3142 		log_error("encapsulation requested for '%s' with no support.",
3143 			  name->data);
3144 
3145 	return status;
3146 }
3147 
3148 /* Attempt to store any 'E'ncapsulated options that have not yet been
3149  * placed on the option buffer by the above (configuring a value in
3150  * the space over-rides any values in the child universe).
3151  *
3152  * Note that there are far fewer universes than there will ever be
3153  * options in any universe.  So it is faster to traverse the
3154  * configured universes, checking if each is encapsulated in the
3155  * current universe, and if so attempting to do so.
3156  *
3157  * For each configured universe for this configuration option space,
3158  * which is encapsulated within the current universe, can not be found
3159  * by the lookup function (the universe-specific encapsulation
3160  * functions would already have stored such a value), and encapsulates
3161  * at least one option, append it.
3162  */
3163 static int
search_subencapsulation(struct data_string * result,struct packet * packet,struct lease * lease,struct client_state * client_state,struct option_state * in_options,struct option_state * cfg_options,struct binding_scope ** scope,struct universe * universe)3164 search_subencapsulation(struct data_string *result, struct packet *packet,
3165 			struct lease *lease, struct client_state *client_state,
3166 			struct option_state *in_options,
3167 			struct option_state *cfg_options,
3168 			struct binding_scope **scope,
3169 			struct universe *universe)
3170 {
3171 	struct data_string sub;
3172 	struct universe *subu;
3173 	int i, status = 0;
3174 
3175 	memset(&sub, 0, sizeof(sub));
3176 	for (i = 0 ; i < cfg_options->universe_count ; i++) {
3177 		subu = universes[i];
3178 
3179 		if (subu == NULL)
3180 			log_fatal("Impossible condition at %s:%d.", MDL);
3181 
3182 		if (subu->enc_opt != NULL &&
3183 		    subu->enc_opt->universe == universe &&
3184 		    subu->enc_opt->format != NULL &&
3185 		    subu->enc_opt->format[0] == 'E' &&
3186 		    lookup_option(universe, cfg_options,
3187 				  subu->enc_opt->code) == NULL &&
3188 		    subu->encapsulate(&sub, packet, lease, client_state,
3189 				      in_options, cfg_options,
3190 				      scope, subu)) {
3191 			if (append_option(result, universe,
3192 					  subu->enc_opt, &sub))
3193 				status = 1;
3194 
3195 			data_string_forget(&sub, MDL);
3196 		}
3197 	}
3198 
3199 	return status;
3200 }
3201 
hashed_option_space_encapsulate(result,packet,lease,client_state,in_options,cfg_options,scope,universe)3202 int hashed_option_space_encapsulate (result, packet, lease, client_state,
3203 				     in_options, cfg_options, scope, universe)
3204 	struct data_string *result;
3205 	struct packet *packet;
3206 	struct lease *lease;
3207 	struct client_state *client_state;
3208 	struct option_state *in_options;
3209 	struct option_state *cfg_options;
3210 	struct binding_scope **scope;
3211 	struct universe *universe;
3212 {
3213 	pair p, *hash;
3214 	int status;
3215 	int i;
3216 
3217 	if (universe -> index >= cfg_options -> universe_count)
3218 		return 0;
3219 
3220 	hash = cfg_options -> universes [universe -> index];
3221 	if (!hash)
3222 		return 0;
3223 
3224 	/* For each hash bucket, and each configured option cache within
3225 	 * that bucket, append the option onto the buffer in encapsulated
3226 	 * format appropriate to the universe.
3227 	 */
3228 	status = 0;
3229 	for (i = 0; i < OPTION_HASH_SIZE; i++) {
3230 		for (p = hash [i]; p; p = p -> cdr) {
3231 			if (store_option(result, universe, packet, lease,
3232 					 client_state, in_options, cfg_options,
3233 					 scope, (struct option_cache *)p->car))
3234 				status = 1;
3235 		}
3236 	}
3237 
3238 	if (search_subencapsulation(result, packet, lease, client_state,
3239 				    in_options, cfg_options, scope, universe))
3240 		status = 1;
3241 
3242 	return status;
3243 }
3244 
nwip_option_space_encapsulate(result,packet,lease,client_state,in_options,cfg_options,scope,universe)3245 int nwip_option_space_encapsulate (result, packet, lease, client_state,
3246 				   in_options, cfg_options, scope, universe)
3247 	struct data_string *result;
3248 	struct packet *packet;
3249 	struct lease *lease;
3250 	struct client_state *client_state;
3251 	struct option_state *in_options;
3252 	struct option_state *cfg_options;
3253 	struct binding_scope **scope;
3254 	struct universe *universe;
3255 {
3256 	pair ocp;
3257 	int status;
3258 	static struct option_cache *no_nwip;
3259 	struct data_string ds;
3260 	struct option_chain_head *head;
3261 
3262 	if (universe -> index >= cfg_options -> universe_count)
3263 		return 0;
3264 	head = ((struct option_chain_head *)
3265 		cfg_options -> universes [nwip_universe.index]);
3266 	if (!head)
3267 		return 0;
3268 
3269 	status = 0;
3270 	for (ocp = head -> first; ocp; ocp = ocp -> cdr) {
3271 		if (store_option (result, universe, packet,
3272 				  lease, client_state, in_options,
3273 				  cfg_options, scope,
3274 				  (struct option_cache *)ocp -> car))
3275 			status = 1;
3276 	}
3277 
3278 	/* If there's no data, the nwip suboption is supposed to contain
3279 	   a suboption saying there's no data. */
3280 	if (!status) {
3281 		if (!no_nwip) {
3282 			unsigned one = 1;
3283 			static unsigned char nni [] = { 1, 0 };
3284 
3285 			memset (&ds, 0, sizeof ds);
3286 			ds.data = nni;
3287 			ds.len = 2;
3288 			if (option_cache_allocate (&no_nwip, MDL))
3289 				data_string_copy (&no_nwip -> data, &ds, MDL);
3290 			if (!option_code_hash_lookup(&no_nwip->option,
3291 						     nwip_universe.code_hash,
3292 						     &one, 0, MDL))
3293 				log_fatal("Nwip option hash does not contain "
3294 					  "1 (%s:%d).", MDL);
3295 		}
3296 		if (no_nwip) {
3297 			if (store_option (result, universe, packet, lease,
3298 					  client_state, in_options,
3299 					  cfg_options, scope, no_nwip))
3300 				status = 1;
3301 		}
3302 	} else {
3303 		memset (&ds, 0, sizeof ds);
3304 
3305 		/* If we have nwip options, the first one has to be the
3306 		   nwip-exists-in-option-area option. */
3307 		if (!buffer_allocate (&ds.buffer, result -> len + 2, MDL)) {
3308 			data_string_forget (result, MDL);
3309 			return 0;
3310 		}
3311 		ds.data = &ds.buffer -> data [0];
3312 		ds.buffer -> data [0] = 2;
3313 		ds.buffer -> data [1] = 0;
3314 		memcpy (&ds.buffer -> data [2], result -> data, result -> len);
3315 		data_string_forget (result, MDL);
3316 		data_string_copy (result, &ds, MDL);
3317 		data_string_forget (&ds, MDL);
3318 	}
3319 
3320 	return status;
3321 }
3322 
3323 /* We don't want to use MRns_name_pton()...it doesn't tell us how many bytes
3324  * it has consumed, and it plays havoc with our escapes.
3325  *
3326  * So this function does DNS encoding, and returns either the number of
3327  * octects consumed (on success), or -1 on failure.
3328  */
3329 static int
fqdn_encode(unsigned char * dst,int dstlen,const unsigned char * src,int srclen)3330 fqdn_encode(unsigned char *dst, int dstlen, const unsigned char *src,
3331 	    int srclen)
3332 {
3333 	unsigned char *out;
3334 	int i, j, len, outlen=0;
3335 
3336 	out = dst;
3337 	for (i = 0, j = 0 ; i < srclen ; i = j) {
3338 		while ((j < srclen) && (src[j] != '.') && (src[j] != '\0'))
3339 			j++;
3340 
3341 		len = j - i;
3342 		if ((outlen + 1 + len) > dstlen)
3343 			return -1;
3344 
3345 		*out++ = len;
3346 		outlen++;
3347 
3348 		/* We only do one FQDN, ending in one root label. */
3349 		if (len == 0)
3350 			return outlen;
3351 
3352 		memcpy(out, src + i, len);
3353 		out += len;
3354 		outlen += len;
3355 
3356 		/* Advance past the root label. */
3357 		j++;
3358 	}
3359 
3360 	if ((outlen + 1) > dstlen)
3361 		return -1;
3362 
3363 	/* Place the root label. */
3364 	*out++ = 0;
3365 	outlen++;
3366 
3367 	return outlen;
3368 }
3369 
fqdn_option_space_encapsulate(result,packet,lease,client_state,in_options,cfg_options,scope,universe)3370 int fqdn_option_space_encapsulate (result, packet, lease, client_state,
3371 				   in_options, cfg_options, scope, universe)
3372 	struct data_string *result;
3373 	struct packet *packet;
3374 	struct lease *lease;
3375 	struct client_state *client_state;
3376 	struct option_state *in_options;
3377 	struct option_state *cfg_options;
3378 	struct binding_scope **scope;
3379 	struct universe *universe;
3380 {
3381 	pair ocp;
3382 	struct data_string results [FQDN_SUBOPTION_COUNT + 1];
3383 	int status = 1;
3384 	int i;
3385 	unsigned len;
3386 	struct buffer *bp = (struct buffer *)0;
3387 	struct option_chain_head *head;
3388 
3389 	/* If there's no FQDN universe, don't encapsulate. */
3390 	if (fqdn_universe.index >= cfg_options -> universe_count)
3391 		return 0;
3392 	head = ((struct option_chain_head *)
3393 		cfg_options -> universes [fqdn_universe.index]);
3394 	if (!head)
3395 		return 0;
3396 
3397 	/* Figure out the values of all the suboptions. */
3398 	memset (results, 0, sizeof results);
3399 	for (ocp = head -> first; ocp; ocp = ocp -> cdr) {
3400 		struct option_cache *oc = (struct option_cache *)(ocp -> car);
3401 		if (oc -> option -> code > FQDN_SUBOPTION_COUNT)
3402 			continue;
3403 		/* No need to check the return code, we check the length later */
3404 		(void) evaluate_option_cache (&results[oc->option->code],
3405 					      packet, lease, client_state,
3406 					      in_options, cfg_options, scope,
3407 					      oc, MDL);
3408 	}
3409 	/* We add a byte for the flags field.
3410 	 * We add two bytes for the two RCODE fields.
3411 	 * We add a byte because we will prepend a label count.
3412 	 * We add a byte because the input len doesn't count null termination,
3413 	 * and we will add a root label.
3414 	 */
3415 	len = 5 + results [FQDN_FQDN].len;
3416 	/* Save the contents of the option in a buffer. */
3417 	if (!buffer_allocate (&bp, len, MDL)) {
3418 		log_error ("no memory for option buffer.");
3419 		status = 0;
3420 		goto exit;
3421 	}
3422 	buffer_reference (&result -> buffer, bp, MDL);
3423 	result -> len = 3;
3424 	result -> data = &bp -> data [0];
3425 
3426 	memset (&bp -> data [0], 0, len);
3427 	/* XXX: The server should set bit 4 (yes, 4, not 3) to 1 if it is
3428 	 * not going to perform any ddns updates.  The client should set the
3429 	 * bit if it doesn't want the server to perform any updates.
3430 	 * The problem is at this layer of abstraction we have no idea if
3431 	 * the caller is a client or server.
3432 	 *
3433 	 * See RFC4702, Section 3.1, 'The "N" bit'.
3434 	 *
3435 	 * if (?)
3436 	 *	bp->data[0] |= 8;
3437 	 */
3438 	if (results [FQDN_NO_CLIENT_UPDATE].len &&
3439 	    results [FQDN_NO_CLIENT_UPDATE].data [0])
3440 		bp -> data [0] |= 2;
3441 	if (results [FQDN_SERVER_UPDATE].len &&
3442 	    results [FQDN_SERVER_UPDATE].data [0])
3443 		bp -> data [0] |= 1;
3444 	if (results [FQDN_RCODE1].len)
3445 		bp -> data [1] = results [FQDN_RCODE1].data [0];
3446 	if (results [FQDN_RCODE2].len)
3447 		bp -> data [2] = results [FQDN_RCODE2].data [0];
3448 
3449 	if (results [FQDN_ENCODED].len &&
3450 	    results [FQDN_ENCODED].data [0]) {
3451 		bp->data[0] |= 4;
3452 		if (results [FQDN_FQDN].len) {
3453 			i = fqdn_encode(&bp->data[3], len - 3,
3454 					results[FQDN_FQDN].data,
3455 					results[FQDN_FQDN].len);
3456 
3457 			if (i < 0) {
3458 				status = 0;
3459 				goto exit;
3460 			}
3461 
3462 			result->len += i;
3463 			result->terminated = 0;
3464 		}
3465 	} else {
3466 		if (results [FQDN_FQDN].len) {
3467 			memcpy (&bp -> data [3], results [FQDN_FQDN].data,
3468 				results [FQDN_FQDN].len);
3469 			result -> len += results [FQDN_FQDN].len;
3470 			result -> terminated = 0;
3471 		}
3472 	}
3473       exit:
3474 	for (i = 1; i <= FQDN_SUBOPTION_COUNT; i++) {
3475 		data_string_forget (&results[i], MDL);
3476 	}
3477 	buffer_dereference (&bp, MDL);
3478 	if (!status)
3479 		data_string_forget(result, MDL);
3480 	return status;
3481 }
3482 
3483 /*
3484  * Trap invalid attempts to inspect FQND6 contents.
3485  */
3486 struct option_cache *
lookup_fqdn6_option(struct universe * universe,struct option_state * options,unsigned code)3487 lookup_fqdn6_option(struct universe *universe, struct option_state *options,
3488 		    unsigned code)
3489 {
3490 	log_fatal("Impossible condition at %s:%d.", MDL);
3491 	return NULL;
3492 }
3493 
3494 /*
3495  * Trap invalid attempts to save options directly to FQDN6 rather than FQDN.
3496  */
3497 void
save_fqdn6_option(struct universe * universe,struct option_state * options,struct option_cache * oc,isc_boolean_t appendp)3498 save_fqdn6_option(struct universe *universe, struct option_state *options,
3499 		  struct option_cache *oc, isc_boolean_t appendp)
3500 {
3501 	log_fatal("Impossible condition at %s:%d.", MDL);
3502 }
3503 
3504 /*
3505  * Trap invalid attempts to delete an option out of the FQDN6 universe.
3506  */
3507 void
delete_fqdn6_option(struct universe * universe,struct option_state * options,int code)3508 delete_fqdn6_option(struct universe *universe, struct option_state *options,
3509 		    int code)
3510 {
3511 	log_fatal("Impossible condition at %s:%d.", MDL);
3512 }
3513 
3514 /* Shill to the DHCPv4 fqdn option cache any attempts to traverse the
3515  * V6's option cache entry.
3516  *
3517  * This function is called speculatively by dhclient to setup
3518  * environment variables.  But it would have already called the
3519  * foreach on the normal fqdn universe, so this is superfluous.
3520  */
3521 void
fqdn6_option_space_foreach(struct packet * packet,struct lease * lease,struct client_state * client_state,struct option_state * in_options,struct option_state * cfg_options,struct binding_scope ** scope,struct universe * u,void * stuff,void (* func)(struct option_cache *,struct packet *,struct lease *,struct client_state *,struct option_state *,struct option_state *,struct binding_scope **,struct universe *,void *))3522 fqdn6_option_space_foreach(struct packet *packet, struct lease *lease,
3523 			   struct client_state *client_state,
3524 			   struct option_state *in_options,
3525 			   struct option_state *cfg_options,
3526 			   struct binding_scope **scope,
3527 			   struct universe *u, void *stuff,
3528 			   void (*func)(struct option_cache *,
3529 					struct packet *,
3530 					struct lease *,
3531 					struct client_state *,
3532 					struct option_state *,
3533 					struct option_state *,
3534 					struct binding_scope **,
3535 					struct universe *, void *))
3536 {
3537 	/* Pretend it is empty. */
3538 	return;
3539 }
3540 
3541 /* Turn the FQDN option space into a DHCPv6 FQDN option buffer.
3542  */
3543 int
fqdn6_option_space_encapsulate(struct data_string * result,struct packet * packet,struct lease * lease,struct client_state * client_state,struct option_state * in_options,struct option_state * cfg_options,struct binding_scope ** scope,struct universe * universe)3544 fqdn6_option_space_encapsulate(struct data_string *result,
3545 			       struct packet *packet, struct lease *lease,
3546 			       struct client_state *client_state,
3547 			       struct option_state *in_options,
3548 			       struct option_state *cfg_options,
3549 			       struct binding_scope **scope,
3550 			       struct universe *universe)
3551 {
3552 	pair ocp;
3553 	struct option_chain_head *head;
3554 	struct option_cache *oc;
3555 	unsigned char *data;
3556 	int i, len, rval = 0, count;
3557 	struct data_string results[FQDN_SUBOPTION_COUNT + 1];
3558 
3559 	if (fqdn_universe.index >= cfg_options->universe_count)
3560 		return 0;
3561 	head = ((struct option_chain_head *)
3562 		cfg_options->universes[fqdn_universe.index]);
3563 	if (head == NULL)
3564 		return 0;
3565 
3566 	memset(results, 0, sizeof(results));
3567 	for (ocp = head->first ; ocp != NULL ; ocp = ocp->cdr) {
3568 		oc = (struct option_cache *)(ocp->car);
3569 		if (oc->option->code > FQDN_SUBOPTION_COUNT)
3570 			log_fatal("Impossible condition at %s:%d.", MDL);
3571 		/* No need to check the return code, we check the length later */
3572 		(void) evaluate_option_cache(&results[oc->option->code], packet,
3573 					     lease, client_state, in_options,
3574 					     cfg_options, scope, oc, MDL);
3575 	}
3576 
3577 	/* We add a byte for the flags field at the start of the option.
3578 	 * We add a byte because we will prepend a label count.
3579 	 * We add a byte because the input length doesn't include a trailing
3580 	 * NULL, and we will add a root label.
3581 	 */
3582 	len = results[FQDN_FQDN].len + 3;
3583 	if (!buffer_allocate(&result->buffer, len, MDL)) {
3584 		log_error("No memory for virtual option buffer.");
3585 		goto exit;
3586 	}
3587 	data = result->buffer->data;
3588 	result->data = data;
3589 
3590 	/* The first byte is the flags field. */
3591 	result->len = 1;
3592 	data[0] = 0;
3593 	/* XXX: The server should set bit 3 (yes, 3, not 4) to 1 if we
3594 	 * are not going to perform any DNS updates.  The problem is
3595 	 * that at this layer of abstraction, we do not know if the caller
3596 	 * is the client or the server.
3597 	 *
3598 	 * See RFC4704 Section 4.1, 'The "N" bit'.
3599 	 *
3600 	 * if (?)
3601 	 *	data[0] |= 4;
3602 	 */
3603 	if (results[FQDN_NO_CLIENT_UPDATE].len &&
3604 	    results[FQDN_NO_CLIENT_UPDATE].data[0])
3605 		data[0] |= 2;
3606 	if (results[FQDN_SERVER_UPDATE].len &&
3607 	    results[FQDN_SERVER_UPDATE].data[0])
3608 		data[0] |= 1;
3609 
3610 	/* If there is no name, we're done. */
3611 	if (results[FQDN_FQDN].len == 0) {
3612 		rval = 1;
3613 		goto exit;
3614 	}
3615 
3616 	/* Convert textual representation to DNS format. */
3617 	count = fqdn_encode(data + 1, len - 1,
3618 			    results[FQDN_FQDN].data, results[FQDN_FQDN].len);
3619 
3620 	if (count < 0) {
3621 		rval = 0;
3622 		data_string_forget(result, MDL);
3623 		goto exit;
3624 	}
3625 
3626 	result->len += count;
3627 	result->terminated = 0;
3628 
3629 	/* Success! */
3630 	rval = 1;
3631 
3632       exit:
3633 	for (i = 1 ; i <= FQDN_SUBOPTION_COUNT ; i++) {
3634 		data_string_forget(&results[i], MDL);
3635 	}
3636 
3637 	return rval;
3638 }
3639 
3640 /* Read the DHCPv6 FQDN option's contents into the FQDN virtual space.
3641  */
3642 int
fqdn6_universe_decode(struct option_state * options,const unsigned char * buffer,unsigned length,struct universe * u)3643 fqdn6_universe_decode(struct option_state *options,
3644 		      const unsigned char *buffer, unsigned length,
3645 		      struct universe *u)
3646 {
3647 	struct buffer *bp = NULL;
3648 	unsigned char *first_dot;
3649 	int len, hlen, dlen;
3650 
3651 	/* The FQDN option has to be at least 1 byte long. */
3652 	if (length < 1)
3653 		return 0;
3654 
3655 	/* Save the contents of the option in a buffer.  There are 3
3656 	 * one-byte values we record from the packet. The input is
3657 	 * DNS encoded and to be safe we'll assume that each character
3658 	 * is non-printable and will be converted to an escaped number:
3659 	 * "\\nnn".  Yes, we'll have dead space pretty much all the time
3660 	 * but the alternative is to basically dry run the conversion
3661 	 * first to calculate the precise size or reallocate to a smaller
3662 	 * buffer later, either of which is a bigger performance hit than
3663 	 * just doing a generous allocation. */
3664 	unsigned bp_size = 3 + (length * 4);
3665 
3666 	if (!buffer_allocate(&bp, bp_size, MDL)) {
3667 		log_error("No memory for dhcp6.fqdn option buffer.");
3668 		return 0;
3669 	}
3670 
3671 	/* The v6 FQDN is always 'encoded' per DNS. */
3672 	bp->data[0] = 1;
3673 	if (!save_option_buffer(&fqdn_universe, options, bp,
3674 				bp->data, 1, FQDN_ENCODED, 0))
3675 		goto error;
3676 
3677 	/* XXX: We need to process 'The "N" bit'. */
3678 	if (buffer[0] & 1) /* server-update. */
3679 		bp->data[2] = 1;
3680 	else
3681 		bp->data[2] = 0;
3682 
3683 	if (!save_option_buffer(&fqdn_universe, options, bp, bp->data + 2, 1,
3684 				FQDN_SERVER_UPDATE, 0))
3685 		goto error;
3686 
3687 	if (buffer[0] & 2) /* no-client-update. */
3688 		bp->data[1] = 1;
3689 	else
3690 		bp->data[1] = 0;
3691 
3692 	if (!save_option_buffer(&fqdn_universe, options, bp, bp->data + 1, 1,
3693 				FQDN_NO_CLIENT_UPDATE, 0))
3694 		goto error;
3695 
3696 	/* Convert the domain name to textual representation for config. */
3697 	len = MRns_name_ntop(buffer + 1, (char *)bp->data + 3, bp_size - 3);
3698 	if (len == -1) {
3699 		log_error("Unable to convert dhcp6.fqdn domain name to "
3700 			  "printable form.");
3701 		goto error;
3702 	}
3703 
3704 	/* Save the domain name. */
3705 	if (len > 0) {
3706 		unsigned char *fqdn_start = bp->data + 3;
3707 
3708 		if (!save_option_buffer(&fqdn_universe, options, bp,
3709 					fqdn_start, len, FQDN_FQDN, 1))
3710 			goto error;
3711 
3712 		first_dot = (unsigned char *)strchr((char *)fqdn_start, '.');
3713 
3714 		if (first_dot != NULL) {
3715 			hlen = first_dot - fqdn_start;
3716 			dlen = len - hlen;
3717 		} else {
3718 			hlen = len;
3719 			dlen = 0;
3720 		}
3721 
3722 		if (!save_option_buffer(&fqdn_universe, options, bp,
3723 					fqdn_start, len, FQDN_FQDN, 1) ||
3724 		    ((hlen > 0) &&
3725 		     !save_option_buffer(&fqdn_universe, options, bp,
3726 					 fqdn_start, hlen,
3727 					 FQDN_HOSTNAME, 0)) ||
3728 		    ((dlen > 0) &&
3729 		     !save_option_buffer(&fqdn_universe, options, bp,
3730 					 first_dot, dlen, FQDN_DOMAINNAME, 0)))
3731 				goto error;
3732 	}
3733 
3734 	buffer_dereference(&bp, MDL);
3735 	return 1;
3736 
3737       error:
3738 	buffer_dereference(&bp, MDL);
3739 	return 0;
3740 }
3741 
option_space_foreach(struct packet * packet,struct lease * lease,struct client_state * client_state,struct option_state * in_options,struct option_state * cfg_options,struct binding_scope ** scope,struct universe * u,void * stuff,void (* func)(struct option_cache *,struct packet *,struct lease *,struct client_state *,struct option_state *,struct option_state *,struct binding_scope **,struct universe *,void *))3742 void option_space_foreach (struct packet *packet, struct lease *lease,
3743 			   struct client_state *client_state,
3744 			   struct option_state *in_options,
3745 			   struct option_state *cfg_options,
3746 			   struct binding_scope **scope,
3747 			   struct universe *u, void *stuff,
3748 			   void (*func) (struct option_cache *,
3749 					 struct packet *,
3750 					 struct lease *, struct client_state *,
3751 					 struct option_state *,
3752 					 struct option_state *,
3753 					 struct binding_scope **,
3754 					 struct universe *, void *))
3755 {
3756 	if (u -> foreach)
3757 		(*u -> foreach) (packet, lease, client_state, in_options,
3758 				 cfg_options, scope, u, stuff, func);
3759 }
3760 
suboption_foreach(struct packet * packet,struct lease * lease,struct client_state * client_state,struct option_state * in_options,struct option_state * cfg_options,struct binding_scope ** scope,struct universe * u,void * stuff,void (* func)(struct option_cache *,struct packet *,struct lease *,struct client_state *,struct option_state *,struct option_state *,struct binding_scope **,struct universe *,void *),struct option_cache * oc,const char * vsname)3761 void suboption_foreach (struct packet *packet, struct lease *lease,
3762 			struct client_state *client_state,
3763 			struct option_state *in_options,
3764 			struct option_state *cfg_options,
3765 			struct binding_scope **scope,
3766 			struct universe *u, void *stuff,
3767 			void (*func) (struct option_cache *,
3768 				      struct packet *,
3769 				      struct lease *, struct client_state *,
3770 				      struct option_state *,
3771 				      struct option_state *,
3772 				      struct binding_scope **,
3773 				      struct universe *, void *),
3774 			struct option_cache *oc,
3775 			const char *vsname)
3776 {
3777 	struct universe *universe = find_option_universe (oc -> option,
3778 							  vsname);
3779 	if (universe -> foreach)
3780 		(*universe -> foreach) (packet, lease, client_state,
3781 					in_options, cfg_options,
3782 					scope, universe, stuff, func);
3783 }
3784 
hashed_option_space_foreach(struct packet * packet,struct lease * lease,struct client_state * client_state,struct option_state * in_options,struct option_state * cfg_options,struct binding_scope ** scope,struct universe * u,void * stuff,void (* func)(struct option_cache *,struct packet *,struct lease *,struct client_state *,struct option_state *,struct option_state *,struct binding_scope **,struct universe *,void *))3785 void hashed_option_space_foreach (struct packet *packet, struct lease *lease,
3786 				  struct client_state *client_state,
3787 				  struct option_state *in_options,
3788 				  struct option_state *cfg_options,
3789 				  struct binding_scope **scope,
3790 				  struct universe *u, void *stuff,
3791 				  void (*func) (struct option_cache *,
3792 						struct packet *,
3793 						struct lease *,
3794 						struct client_state *,
3795 						struct option_state *,
3796 						struct option_state *,
3797 						struct binding_scope **,
3798 						struct universe *, void *))
3799 {
3800 	pair *hash;
3801 	int i;
3802 	struct option_cache *oc;
3803 
3804 	if (cfg_options -> universe_count <= u -> index)
3805 		return;
3806 
3807 	hash = cfg_options -> universes [u -> index];
3808 	if (!hash)
3809 		return;
3810 	for (i = 0; i < OPTION_HASH_SIZE; i++) {
3811 		pair p;
3812 		/* XXX save _all_ options! XXX */
3813 		for (p = hash [i]; p; p = p -> cdr) {
3814 			oc = (struct option_cache *)p -> car;
3815 			(*func) (oc, packet, lease, client_state,
3816 				 in_options, cfg_options, scope, u, stuff);
3817 		}
3818 	}
3819 }
3820 
3821 void
save_linked_option(struct universe * universe,struct option_state * options,struct option_cache * oc,isc_boolean_t appendp)3822 save_linked_option(struct universe *universe, struct option_state *options,
3823 		   struct option_cache *oc, isc_boolean_t appendp)
3824 {
3825 	pair *tail;
3826 	struct option_chain_head *head;
3827 	struct option_cache **ocloc;
3828 
3829 	if (universe -> index >= options -> universe_count)
3830 		return;
3831 	head = ((struct option_chain_head *)
3832 		options -> universes [universe -> index]);
3833 	if (!head) {
3834 		if (!option_chain_head_allocate (((struct option_chain_head **)
3835 						  &options -> universes
3836 						  [universe -> index]), MDL))
3837 			return;
3838 		head = ((struct option_chain_head *)
3839 			options -> universes [universe -> index]);
3840 	}
3841 
3842 	/* Find the tail of the list. */
3843 	for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) {
3844 		ocloc = (struct option_cache **)&(*tail)->car;
3845 
3846 		if (oc->option->code == (*ocloc)->option->code) {
3847 			if (appendp) {
3848 				do {
3849 					ocloc = &(*ocloc)->next;
3850 				} while (*ocloc != NULL);
3851 			} else {
3852 				option_cache_dereference(ocloc, MDL);
3853 			}
3854 			option_cache_reference(ocloc, oc, MDL);
3855 			return;
3856 		}
3857 	}
3858 
3859 	*tail = cons (0, 0);
3860 	if (*tail) {
3861 		option_cache_reference ((struct option_cache **)
3862 					(&(*tail) -> car), oc, MDL);
3863 	}
3864 }
3865 
linked_option_space_encapsulate(result,packet,lease,client_state,in_options,cfg_options,scope,universe)3866 int linked_option_space_encapsulate (result, packet, lease, client_state,
3867 				    in_options, cfg_options, scope, universe)
3868 	struct data_string *result;
3869 	struct packet *packet;
3870 	struct lease *lease;
3871 	struct client_state *client_state;
3872 	struct option_state *in_options;
3873 	struct option_state *cfg_options;
3874 	struct binding_scope **scope;
3875 	struct universe *universe;
3876 {
3877 	int status = 0;
3878 	pair oc;
3879 	struct option_chain_head *head;
3880 
3881 	if (universe -> index >= cfg_options -> universe_count)
3882 		return status;
3883 	head = ((struct option_chain_head *)
3884 		cfg_options -> universes [universe -> index]);
3885 	if (!head)
3886 		return status;
3887 
3888 	for (oc = head -> first; oc; oc = oc -> cdr) {
3889 		if (store_option (result, universe, packet,
3890 				  lease, client_state, in_options, cfg_options,
3891 				  scope, (struct option_cache *)(oc -> car)))
3892 			status = 1;
3893 	}
3894 
3895 	if (search_subencapsulation(result, packet, lease, client_state,
3896 				    in_options, cfg_options, scope, universe))
3897 		status = 1;
3898 
3899 	return status;
3900 }
3901 
delete_linked_option(universe,options,code)3902 void delete_linked_option (universe, options, code)
3903 	struct universe *universe;
3904 	struct option_state *options;
3905 	int code;
3906 {
3907 	pair *tail, tmp = (pair)0;
3908 	struct option_chain_head *head;
3909 
3910 	if (universe -> index >= options -> universe_count)
3911 		return;
3912 	head = ((struct option_chain_head *)
3913 		options -> universes [universe -> index]);
3914 	if (!head)
3915 		return;
3916 
3917 	for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) {
3918 		if (code ==
3919 		    ((struct option_cache *)(*tail) -> car) -> option -> code)
3920 		{
3921 			tmp = (*tail) -> cdr;
3922 			option_cache_dereference ((struct option_cache **)
3923 						  (&(*tail) -> car), MDL);
3924 			dfree (*tail, MDL);
3925 			(*tail) = tmp;
3926 			break;
3927 		}
3928 	}
3929 }
3930 
lookup_linked_option(universe,options,code)3931 struct option_cache *lookup_linked_option (universe, options, code)
3932 	struct universe *universe;
3933 	struct option_state *options;
3934 	unsigned code;
3935 {
3936 	pair oc;
3937 	struct option_chain_head *head;
3938 
3939 	if (universe -> index >= options -> universe_count)
3940 		return 0;
3941 	head = ((struct option_chain_head *)
3942 		options -> universes [universe -> index]);
3943 	if (!head)
3944 		return 0;
3945 
3946 	for (oc = head -> first; oc; oc = oc -> cdr) {
3947 		if (code ==
3948 		    ((struct option_cache *)(oc -> car)) -> option -> code) {
3949 			return (struct option_cache *)(oc -> car);
3950 		}
3951 	}
3952 
3953 	return (struct option_cache *)0;
3954 }
3955 
linked_option_state_dereference(universe,state,file,line)3956 int linked_option_state_dereference (universe, state, file, line)
3957 	struct universe *universe;
3958 	struct option_state *state;
3959 	const char *file;
3960 	int line;
3961 {
3962 	return (option_chain_head_dereference
3963 		((struct option_chain_head **)
3964 		 (&state -> universes [universe -> index]), MDL));
3965 }
3966 
linked_option_space_foreach(struct packet * packet,struct lease * lease,struct client_state * client_state,struct option_state * in_options,struct option_state * cfg_options,struct binding_scope ** scope,struct universe * u,void * stuff,void (* func)(struct option_cache *,struct packet *,struct lease *,struct client_state *,struct option_state *,struct option_state *,struct binding_scope **,struct universe *,void *))3967 void linked_option_space_foreach (struct packet *packet, struct lease *lease,
3968 				  struct client_state *client_state,
3969 				  struct option_state *in_options,
3970 				  struct option_state *cfg_options,
3971 				  struct binding_scope **scope,
3972 				  struct universe *u, void *stuff,
3973 				  void (*func) (struct option_cache *,
3974 						struct packet *,
3975 						struct lease *,
3976 						struct client_state *,
3977 						struct option_state *,
3978 						struct option_state *,
3979 						struct binding_scope **,
3980 						struct universe *, void *))
3981 {
3982 	pair car;
3983 	struct option_chain_head *head;
3984 
3985 	if (u -> index >= cfg_options -> universe_count)
3986 		return;
3987 	head = ((struct option_chain_head *)
3988 		cfg_options -> universes [u -> index]);
3989 	if (!head)
3990 		return;
3991 	for (car = head -> first; car; car = car -> cdr) {
3992 		(*func) ((struct option_cache *)(car -> car),
3993 			 packet, lease, client_state,
3994 			 in_options, cfg_options, scope, u, stuff);
3995 	}
3996 }
3997 
do_packet(interface,packet,len,from_port,from,hfrom)3998 void do_packet (interface, packet, len, from_port, from, hfrom)
3999 	struct interface_info *interface;
4000 	struct dhcp_packet *packet;
4001 	unsigned len;
4002 	unsigned int from_port;
4003 	struct iaddr from;
4004 	struct hardware *hfrom;
4005 {
4006 	struct option_cache *op;
4007 	struct packet *decoded_packet;
4008 #if defined (DEBUG_MEMORY_LEAKAGE)
4009 	unsigned long previous_outstanding = dmalloc_outstanding;
4010 #endif
4011 
4012 #if defined (TRACING)
4013 	trace_inpacket_stash(interface, packet, len, from_port, from, hfrom);
4014 #endif
4015 
4016 	decoded_packet = NULL;
4017 	if (!packet_allocate(&decoded_packet, MDL)) {
4018 		log_error("do_packet: no memory for incoming packet!");
4019 		return;
4020 	}
4021 	decoded_packet->raw = packet;
4022 	decoded_packet->packet_length = len;
4023 	decoded_packet->client_port = from_port;
4024 	decoded_packet->client_addr = from;
4025 	interface_reference(&decoded_packet->interface, interface, MDL);
4026 	decoded_packet->haddr = hfrom;
4027 
4028 	if (packet->hlen > sizeof packet->chaddr) {
4029 		packet_dereference(&decoded_packet, MDL);
4030 		log_info("Discarding packet with bogus hlen.");
4031 		return;
4032 	}
4033 
4034 	/* Allocate packet->options now so it is non-null for all packets */
4035 	decoded_packet->options_valid = 0;
4036 	if (!option_state_allocate (&decoded_packet->options, MDL)) {
4037 		packet_dereference(&decoded_packet, MDL);
4038 		return;
4039 	}
4040 
4041 	/* If there's an option buffer, try to parse it. */
4042 	if (decoded_packet->packet_length >= DHCP_FIXED_NON_UDP + 4) {
4043 		if (!parse_options(decoded_packet)) {
4044 			packet_dereference (&decoded_packet, MDL);
4045 			return;
4046 		}
4047 
4048 		if (decoded_packet->options_valid &&
4049 		    (op = lookup_option(&dhcp_universe,
4050 					decoded_packet->options,
4051 					DHO_DHCP_MESSAGE_TYPE))) {
4052 			struct data_string dp;
4053 			memset(&dp, 0, sizeof dp);
4054 			evaluate_option_cache(&dp, decoded_packet, NULL, NULL,
4055 					      decoded_packet->options, NULL,
4056 					      NULL, op, MDL);
4057 			if (dp.len > 0)
4058 				decoded_packet->packet_type = dp.data[0];
4059 			else
4060 				decoded_packet->packet_type = 0;
4061 			data_string_forget(&dp, MDL);
4062 		}
4063 	}
4064 
4065 	if (validate_packet(decoded_packet) != 0) {
4066 		if (decoded_packet->packet_type)
4067 			dhcp(decoded_packet);
4068 		else
4069 			bootp(decoded_packet);
4070 	}
4071 
4072 	/* If the caller kept the packet, they'll have upped the refcnt. */
4073 	packet_dereference(&decoded_packet, MDL);
4074 
4075 #if defined (DEBUG_MEMORY_LEAKAGE)
4076 	log_info("generation %ld: %ld new, %ld outstanding, %ld long-term",
4077 		 dmalloc_generation,
4078 		 dmalloc_outstanding - previous_outstanding,
4079 		 dmalloc_outstanding, dmalloc_longterm);
4080 	dmalloc_dump_outstanding();
4081 #endif
4082 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
4083 	dump_rc_history(0);
4084 #endif
4085 }
4086 
4087 int
packet6_len_okay(const char * packet,int len)4088 packet6_len_okay(const char *packet, int len) {
4089 	if (len < 1) {
4090 		return 0;
4091 	}
4092 	if ((packet[0] == DHCPV6_RELAY_FORW) ||
4093 	    (packet[0] == DHCPV6_RELAY_REPL)) {
4094 		if (len >= offsetof(struct dhcpv6_relay_packet, options)) {
4095 			return 1;
4096 		} else {
4097 			return 0;
4098 		}
4099 	} else {
4100 		if (len >= offsetof(struct dhcpv6_packet, options)) {
4101 			return 1;
4102 		} else {
4103 			return 0;
4104 		}
4105 	}
4106 }
4107 
4108 #ifdef DHCPv6
4109 void
do_packet6(struct interface_info * interface,const char * packet,int len,int from_port,const struct iaddr * from,isc_boolean_t was_unicast)4110 do_packet6(struct interface_info *interface, const char *packet,
4111 	   int len, int from_port, const struct iaddr *from,
4112 	   isc_boolean_t was_unicast) {
4113 	unsigned char msg_type;
4114 	const struct dhcpv6_packet *msg;
4115 	const struct dhcpv6_relay_packet *relay;
4116 #ifdef DHCP4o6
4117 	const struct dhcpv4_over_dhcpv6_packet *msg46;
4118 #endif
4119 	struct packet *decoded_packet;
4120 #if defined (DEBUG_MEMORY_LEAKAGE)
4121 	unsigned long previous_outstanding = dmalloc_outstanding;
4122 #endif
4123 
4124 	if (!packet6_len_okay(packet, len)) {
4125 		log_info("do_packet6: "
4126 			 "short packet from %s port %d, len %d, dropped",
4127 			 piaddr(*from), from_port, len);
4128 		return;
4129 	}
4130 
4131 	decoded_packet = NULL;
4132 	if (!packet_allocate(&decoded_packet, MDL)) {
4133 		log_error("do_packet6: no memory for incoming packet.");
4134 		return;
4135 	}
4136 
4137 	if (!option_state_allocate(&decoded_packet->options, MDL)) {
4138 		log_error("do_packet6: no memory for options.");
4139 		packet_dereference(&decoded_packet, MDL);
4140 		return;
4141 	}
4142 
4143 	/* IPv4 information, already set to 0 */
4144 	/* decoded_packet->packet_type = 0; */
4145 	/* memset(&decoded_packet->haddr, 0, sizeof(decoded_packet->haddr)); */
4146 	/* decoded_packet->circuit_id = NULL; */
4147 	/* decoded_packet->circuit_id_len = 0; */
4148 	/* decoded_packet->remote_id = NULL; */
4149 	/* decoded_packet->remote_id_len = 0; */
4150 	decoded_packet->raw = (struct dhcp_packet *)packet;
4151 	decoded_packet->packet_length = (unsigned)len;
4152 	decoded_packet->client_port = from_port;
4153 	decoded_packet->client_addr = *from;
4154 	interface_reference(&decoded_packet->interface, interface, MDL);
4155 
4156 	decoded_packet->unicast = was_unicast;
4157 
4158 	msg_type = packet[0];
4159 	if ((msg_type == DHCPV6_RELAY_FORW) ||
4160 	    (msg_type == DHCPV6_RELAY_REPL)) {
4161 		int relaylen = (int)(offsetof(struct dhcpv6_relay_packet, options));
4162 		relay = (const struct dhcpv6_relay_packet *)packet;
4163 		decoded_packet->dhcpv6_msg_type = relay->msg_type;
4164 
4165 		/* relay-specific data */
4166 		decoded_packet->dhcpv6_hop_count = relay->hop_count;
4167 		memcpy(&decoded_packet->dhcpv6_link_address,
4168 		       relay->link_address, sizeof(relay->link_address));
4169 		memcpy(&decoded_packet->dhcpv6_peer_address,
4170 		       relay->peer_address, sizeof(relay->peer_address));
4171 
4172 		if (!parse_option_buffer(decoded_packet->options,
4173 					 relay->options, len - relaylen,
4174 					 &dhcpv6_universe)) {
4175 			/* no logging here, as parse_option_buffer() logs all
4176 			   cases where it fails */
4177 			packet_dereference(&decoded_packet, MDL);
4178 			return;
4179 		}
4180 #ifdef DHCP4o6
4181 	} else if ((msg_type == DHCPV6_DHCPV4_QUERY) ||
4182 		   (msg_type == DHCPV6_DHCPV4_RESPONSE)) {
4183 		int msglen =
4184 		    (int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options));
4185 		msg46 = (struct dhcpv4_over_dhcpv6_packet *)packet;
4186 		decoded_packet->dhcpv6_msg_type = msg46->msg_type;
4187 
4188 		/* message-specific data */
4189 		memcpy(decoded_packet->dhcp4o6_flags,
4190 		       msg46->flags,
4191 		       sizeof(decoded_packet->dhcp4o6_flags));
4192 
4193 		if (!parse_option_buffer(decoded_packet->options,
4194 					 msg46->options, len - msglen,
4195 					 &dhcpv6_universe)) {
4196 			/* no logging here, as parse_option_buffer() logs all
4197 			   cases where it fails */
4198 			packet_dereference(&decoded_packet, MDL);
4199 			return;
4200 		}
4201 #endif
4202 	} else {
4203 		int msglen = (int)(offsetof(struct dhcpv6_packet, options));
4204 		msg = (const struct dhcpv6_packet *)packet;
4205 		decoded_packet->dhcpv6_msg_type = msg->msg_type;
4206 
4207 		/* message-specific data */
4208 		memcpy(decoded_packet->dhcpv6_transaction_id,
4209 		       msg->transaction_id,
4210 		       sizeof(decoded_packet->dhcpv6_transaction_id));
4211 
4212 		if (!parse_option_buffer(decoded_packet->options,
4213 					 msg->options, len - msglen,
4214 					 &dhcpv6_universe)) {
4215 			/* no logging here, as parse_option_buffer() logs all
4216 			   cases where it fails */
4217 			packet_dereference(&decoded_packet, MDL);
4218 			return;
4219 		}
4220 	}
4221 
4222 	dhcpv6(decoded_packet);
4223 
4224 	packet_dereference(&decoded_packet, MDL);
4225 
4226 #if defined (DEBUG_MEMORY_LEAKAGE)
4227 	log_info("generation %ld: %ld new, %ld outstanding, %ld long-term",
4228 		 dmalloc_generation,
4229 		 dmalloc_outstanding - previous_outstanding,
4230 		 dmalloc_outstanding, dmalloc_longterm);
4231 	dmalloc_dump_outstanding();
4232 #endif
4233 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
4234 	dump_rc_history(0);
4235 #endif
4236 }
4237 #endif /* DHCPv6 */
4238 
4239 int
pretty_escape(char ** dst,char * dend,const unsigned char ** src,const unsigned char * send)4240 pretty_escape(char **dst, char *dend, const unsigned char **src,
4241 	      const unsigned char *send)
4242 {
4243 	int count = 0;
4244 
4245 	/* If there aren't as many bytes left as there are in the source
4246 	 * buffer, don't even bother entering the loop.
4247 	 */
4248 	if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
4249 	    *dst == NULL || *src == NULL || (*dst >= dend) || (*src > send) ||
4250 	    ((send - *src) > (dend - *dst)))
4251 		return -1;
4252 
4253 	for ( ; *src < send ; (*src)++) {
4254 		if (!isascii (**src) || !isprint (**src)) {
4255 			/* Skip trailing NUL. */
4256 			if ((*src + 1) != send || **src != '\0') {
4257 				if (*dst + 4 > dend)
4258 					return -1;
4259 
4260 				sprintf(*dst, "\\%03o",
4261 					**src);
4262 				(*dst) += 4;
4263 				count += 4;
4264 			}
4265 		} else if (**src == '"' || **src == '\'' || **src == '$' ||
4266 			   **src == '`' || **src == '\\' || **src == '|' ||
4267 			   **src == '&') {
4268 			if (*dst + 2 > dend)
4269 				return -1;
4270 
4271 			**dst = '\\';
4272 			(*dst)++;
4273 			**dst = **src;
4274 			(*dst)++;
4275 			count += 2;
4276 		} else {
4277 			if (*dst + 1 > dend)
4278 				return -1;
4279 
4280 			**dst = **src;
4281 			(*dst)++;
4282 			count++;
4283 		}
4284 	}
4285 
4286 	return count;
4287 }
4288 
4289 static int
pretty_text(char ** dst,char * dend,const unsigned char ** src,const unsigned char * send,int emit_quotes)4290 pretty_text(char **dst, char *dend, const unsigned char **src,
4291 	    const unsigned char *send, int emit_quotes)
4292 {
4293 	int count;
4294 
4295 	if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
4296 	    *dst == NULL || *src == NULL ||
4297 	    ((*dst + (emit_quotes ? 2 : 0)) > dend) || (*src > send))
4298 		return -1;
4299 
4300 	if (emit_quotes) {
4301 		**dst = '"';
4302 		(*dst)++;
4303 	}
4304 
4305 	/* dend-1 leaves 1 byte for the closing quote. */
4306 	count = pretty_escape(dst, dend - (emit_quotes ? 1 : 0), src, send);
4307 
4308 	if (count == -1)
4309 		return -1;
4310 
4311 	if (emit_quotes && (*dst < dend)) {
4312 		**dst = '"';
4313 		(*dst)++;
4314 
4315 		/* Includes quote prior to pretty_escape(); */
4316 		count += 2;
4317 	}
4318 
4319 	return count;
4320 }
4321 
4322 static int
pretty_dname(char ** dst,char * dend,const unsigned char * src,const unsigned char * send)4323 pretty_dname(char **dst, char *dend, const unsigned char *src,
4324 	     const unsigned char *send)
4325 {
4326 	const unsigned char *tend;
4327 	const unsigned char *srcp = src;
4328 	int count = 0;
4329 	int tsiz, status;
4330 
4331 	if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
4332 	    *dst == NULL || ((*dst + 1) > dend) || (src >= send))
4333 		return -1;
4334 
4335 	do {
4336 		/* Continue loop until end of src buffer. */
4337 		if (srcp >= send)
4338 			break;
4339 
4340 		/* Consume tag size. */
4341 		tsiz = *srcp;
4342 		srcp++;
4343 
4344 		/* At root, finis. */
4345 		if (tsiz == 0)
4346 			break;
4347 
4348 		tend = srcp + tsiz;
4349 
4350 		/* If the tag exceeds the source buffer, it's illegal.
4351 		 * This should also trap compression pointers (which should
4352 		 * not be in these buffers).
4353 		 */
4354 		if (tend > send)
4355 			return -1;
4356 
4357 		/* dend-1 leaves room for a trailing dot and quote. */
4358 		status = pretty_escape(dst, dend-1, &srcp, tend);
4359 
4360 		if ((status == -1) || ((*dst + 1) > dend))
4361 			return -1;
4362 
4363 		**dst = '.';
4364 		(*dst)++;
4365 		count += status + 1;
4366 	}
4367 	while(1);
4368 
4369 	return count;
4370 }
4371 
4372 static int
pretty_domain(char ** dst,char * dend,const unsigned char ** src,const unsigned char * send)4373 pretty_domain(char **dst, char *dend, const unsigned char **src,
4374 	      const unsigned char *send)
4375 {
4376 	const unsigned char *tend;
4377 	int count = 2;
4378 	int tsiz, status;
4379 
4380 	if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
4381 	    *dst == NULL || *src == NULL ||
4382 	    ((*dst + 2) > dend) || (*src >= send))
4383 		return -1;
4384 
4385 	**dst = '"';
4386 	(*dst)++;
4387 
4388 	do {
4389 		/* Continue loop until end of src buffer. */
4390 		if (*src >= send)
4391 			break;
4392 
4393 		/* Consume tag size. */
4394 		tsiz = **src;
4395 		(*src)++;
4396 
4397 		/* At root, finis. */
4398 		if (tsiz == 0)
4399 			break;
4400 
4401 		tend = (*src) + tsiz;
4402 
4403 		/* If the tag exceeds the source buffer, it's illegal.
4404 		 * This should also trap compression pointers (which should
4405 		 * not be in these buffers).
4406 		 */
4407 		if (tend > send)
4408 			return -1;
4409 
4410 		/* dend-2 leaves room for a trailing dot and quote. */
4411 		status = pretty_escape(dst, dend-2, src, tend);
4412 
4413 		if ((status == -1) || ((*dst + 2) > dend))
4414 			return -1;
4415 
4416 		**dst = '.';
4417 		(*dst)++;
4418 		count += status + 1;
4419 	}
4420 	while(1);
4421 
4422 	**dst = '"';
4423 	(*dst)++;
4424 
4425 	return count;
4426 }
4427 
4428 /*
4429  * Add the option identified with the option number and data to the
4430  * options state.
4431  */
4432 int
add_option(struct option_state * options,unsigned int option_num,void * data,unsigned int data_len)4433 add_option(struct option_state *options,
4434 	   unsigned int option_num,
4435 	   void *data,
4436 	   unsigned int data_len)
4437 {
4438 	struct option_cache *oc;
4439 	struct option *option;
4440 
4441 	/* INSIST(options != NULL); */
4442 	/* INSIST(data != NULL); */
4443 
4444 	option = NULL;
4445 	if (!option_code_hash_lookup(&option, dhcp_universe.code_hash,
4446 				     &option_num, 0, MDL)) {
4447 		log_error("Attempting to add unknown option %d.", option_num);
4448 		return 0;
4449 	}
4450 
4451 	oc = NULL;
4452 	if (!option_cache_allocate(&oc, MDL)) {
4453 		log_error("No memory for option cache adding %s (option %d).",
4454 			  option->name, option_num);
4455 		return 0;
4456 	}
4457 
4458 	if (!make_const_data(&oc->expression,
4459 			     data,
4460 			     data_len,
4461 			     0,
4462 			     0,
4463 			     MDL)) {
4464 		log_error("No memory for constant data adding %s (option %d).",
4465 			  option->name, option_num);
4466 		option_cache_dereference(&oc, MDL);
4467 		return 0;
4468 	}
4469 
4470 	option_reference(&(oc->option), option, MDL);
4471 	save_option(&dhcp_universe, options, oc);
4472 	option_cache_dereference(&oc, MDL);
4473 
4474 	return 1;
4475 }
4476 
4477 /**
4478  *  Checks if received BOOTP/DHCPv4 packet is sane
4479  *
4480  * @param packet received, decoded packet
4481  *
4482  * @return 1 if packet is sane, 0 if it is not
4483  */
validate_packet(struct packet * packet)4484 int validate_packet(struct packet *packet)
4485 {
4486 	struct option_cache *oc = NULL;
4487 
4488 	oc = lookup_option (&dhcp_universe, packet->options,
4489 			    DHO_DHCP_CLIENT_IDENTIFIER);
4490 	if (oc) {
4491 		/* Let's check if client-identifier is sane */
4492 		if (oc->data.len == 0) {
4493 			log_debug("Dropped DHCPv4 packet with zero-length client-id");
4494 			return (0);
4495 
4496 		} else if (oc->data.len == 1) {
4497 			/*
4498 			 * RFC2132, section 9.14 states that minimum length of client-id
4499 			 * is 2.  We will allow single-character client-ids for now (for
4500 			 * backwards compatibility), but warn the user that support for
4501 			 * this is against the standard.
4502 			 */
4503 			log_debug("Accepted DHCPv4 packet with one-character client-id - "
4504 				"a future version of ISC DHCP will reject this");
4505 		}
4506 	} else {
4507 		/*
4508 		 * If hlen is 0 we don't have any identifier, we warn the user
4509 		 * but continue processing the packet as we can.
4510 		 */
4511 		if (packet->raw->hlen == 0) {
4512 			log_debug("Received DHCPv4 packet without client-id"
4513 				  " option and empty hlen field.");
4514 		}
4515 	}
4516 
4517 	/* @todo: Add checks for other received options */
4518 
4519 	return (1);
4520 }
4521 /*!
4522  *
4523  * \brief Parse a vendor option (option 43)
4524  *
4525  * After the server has parsed most of the options and presented the result
4526  * to the user the user can set the proper vendor option space using
4527  * vendor-option-space in the config file and then cause this routine to be
4528  * called via parse-vendor-option in the config file.  This routine will
4529  * then try and find the proper universe for the vendor-option-space and
4530  * parse the vendor option string based on that universe.
4531  *
4532  * If the information isn't available (no vendor space, no universe for the
4533  * vendor space, no vendor option in the options) or the decode fails we
4534  * simply ignore the option and continue processing.
4535  *
4536  * \param packet      - structure to hold information about the packet being
4537  *                      processed
4538  * \param lease       - lease structure
4539  * \param client_state
4540  * \param in_options  - The incoming options, we expect to find the
4541  *                      vendor-option (option 43, containing the string
4542  *                      to parse) there.  We shall attach decoded options
4543  *                      there.
4544  * \param out_options - The options we have added as we process the packet.
4545  *                      We expect to find the vendor-option-space there and
4546  *                      use that to find the name of the vendor universe to use
4547  * \param scope
4548  *
4549  * \return - void as there isn't much we can do about failures.
4550  */
parse_vendor_option(packet,lease,client_state,in_options,out_options,scope)4551 void parse_vendor_option(packet, lease, client_state, in_options,
4552 			 out_options, scope)
4553 	struct packet *packet;
4554 	struct lease *lease;
4555 	struct client_state *client_state;
4556 	struct option_state *in_options;
4557 	struct option_state *out_options;
4558 	struct binding_scope **scope;
4559 {
4560 	struct option_cache *oc = NULL;
4561 	struct data_string name;
4562 	struct option *option = NULL;
4563 	unsigned int code = DHO_VENDOR_ENCAPSULATED_OPTIONS;
4564 
4565 	/* check if we are processing a packet, if not we can return */
4566 	if ((packet == NULL) || (in_options == NULL) || (out_options == NULL))
4567 		return;
4568 
4569 	/* Do we have any vendor option spaces? */
4570 	if (vendor_cfg_option == NULL)
4571 		return;
4572 
4573 	/* See if the admin has set a vendor option space name */
4574 	oc = lookup_option(vendor_cfg_option->universe,
4575 			   out_options, vendor_cfg_option->code);
4576 	if (oc == NULL)
4577 		return;
4578 
4579 	memset(&name, 0, sizeof(name));
4580 	(void) evaluate_option_cache(&name, packet, lease, client_state,
4581 			      in_options, out_options, scope, oc, MDL);
4582 
4583 	/* No name, all done */
4584 	if (name.len == 0) {
4585 		data_string_forget(&name, MDL);
4586 		return;
4587 	}
4588 
4589 	/* Get any vendor option information from the request */
4590 	oc = lookup_option(&dhcp_universe, in_options, code);
4591 
4592 	/* No vendor option, all done */
4593 	if ((oc == NULL) || (oc->data.len == 0)) {
4594 		data_string_forget(&name, MDL);
4595 		return;
4596 	}
4597 
4598 	/* Get the proper option to pass to the parse routine */
4599 	option_code_hash_lookup(&option, dhcp_universe.code_hash,
4600 				&code, 0, MDL);
4601 
4602 	/* Now that we have the data from the vendor option and a vendor
4603 	 * option space try to parse things.  On success the parsed options
4604 	 * will be added to the in_options list for future use.  A return
4605 	 * return of 1 indicates success, but not much we can do on error */
4606 	(void) parse_encapsulated_suboptions(in_options, option,
4607 					     oc->data.data, oc->data.len,
4608 					     &dhcp_universe,
4609 					     (const char *)name.data);
4610 
4611 	/* Lastly clean up any left overs */
4612 	data_string_forget(&name, MDL);
4613 	option_dereference(&option, MDL);
4614 	return;
4615 }
4616