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