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