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