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