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