3 Parser for dhclient config and lease files... */
6 * Copyright (c) 2004-2008 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1996-2003 by Internet Software Consortium
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.
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.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
25 * https://www.isc.org/
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
38 struct client_config top_level_config
;
40 #define NUM_DEFAULT_REQUESTED_OPTS 9
41 struct option
*default_requested_options
[NUM_DEFAULT_REQUESTED_OPTS
+ 1];
43 static void parse_client_default_duid(struct parse
*cfile
);
44 static void parse_client6_lease_statement(struct parse
*cfile
);
46 static struct dhc6_ia
*parse_client6_ia_na_statement(struct parse
*cfile
);
47 static struct dhc6_ia
*parse_client6_ia_ta_statement(struct parse
*cfile
);
48 static struct dhc6_ia
*parse_client6_ia_pd_statement(struct parse
*cfile
);
49 static struct dhc6_addr
*parse_client6_iaaddr_statement(struct parse
*cfile
);
50 static struct dhc6_addr
*parse_client6_iaprefix_statement(struct parse
*cfile
);
53 /* client-conf-file :== client-declarations END_OF_FILE
54 client-declarations :== <nil>
56 | client-declarations client-declaration */
58 isc_result_t
read_client_conf ()
60 struct client_config
*config
;
61 struct interface_info
*ip
;
66 /* Initialize the default request list. */
67 memset(default_requested_options
, 0, sizeof(default_requested_options
));
70 code
= DHO_SUBNET_MASK
;
71 option_code_hash_lookup(&default_requested_options
[0],
72 dhcp_universe
.code_hash
, &code
, 0, MDL
);
75 code
= DHO_BROADCAST_ADDRESS
;
76 option_code_hash_lookup(&default_requested_options
[1],
77 dhcp_universe
.code_hash
, &code
, 0, MDL
);
80 code
= DHO_TIME_OFFSET
;
81 option_code_hash_lookup(&default_requested_options
[2],
82 dhcp_universe
.code_hash
, &code
, 0, MDL
);
86 option_code_hash_lookup(&default_requested_options
[3],
87 dhcp_universe
.code_hash
, &code
, 0, MDL
);
90 code
= DHO_DOMAIN_NAME
;
91 option_code_hash_lookup(&default_requested_options
[4],
92 dhcp_universe
.code_hash
, &code
, 0, MDL
);
95 code
= DHO_DOMAIN_NAME_SERVERS
;
96 option_code_hash_lookup(&default_requested_options
[5],
97 dhcp_universe
.code_hash
, &code
, 0, MDL
);
100 code
= DHO_HOST_NAME
;
101 option_code_hash_lookup(&default_requested_options
[6],
102 dhcp_universe
.code_hash
, &code
, 0, MDL
);
105 code
= D6O_NAME_SERVERS
;
106 option_code_hash_lookup(&default_requested_options
[7],
107 dhcpv6_universe
.code_hash
, &code
, 0, MDL
);
110 code
= D6O_DOMAIN_SEARCH
;
111 option_code_hash_lookup(&default_requested_options
[8],
112 dhcpv6_universe
.code_hash
, &code
, 0, MDL
);
114 for (code
= 0 ; code
< NUM_DEFAULT_REQUESTED_OPTS
; code
++) {
115 if (default_requested_options
[code
] == NULL
)
116 log_fatal("Unable to find option definition for "
117 "index %u during default parameter request "
121 /* Initialize the top level client configuration. */
122 memset (&top_level_config
, 0, sizeof top_level_config
);
124 /* Set some defaults... */
125 top_level_config
.timeout
= 60;
126 top_level_config
.select_interval
= 0;
127 top_level_config
.reboot_timeout
= 10;
128 top_level_config
.retry_interval
= 300;
129 top_level_config
.backoff_cutoff
= 15;
130 top_level_config
.initial_interval
= 3;
131 top_level_config
.bootp_policy
= P_ACCEPT
;
132 top_level_config
.script_name
= path_dhclient_script
;
133 top_level_config
.requested_options
= default_requested_options
;
134 top_level_config
.omapi_port
= -1;
135 top_level_config
.do_forward_update
= 1;
136 /* Requested lease time, used by DHCPv6 (DHCPv4 uses the option cache)
138 top_level_config
.requested_lease
= 7200;
140 group_allocate (&top_level_config
.on_receipt
, MDL
);
141 if (!top_level_config
.on_receipt
)
142 log_fatal ("no memory for top-level on_receipt group");
144 group_allocate (&top_level_config
.on_transmission
, MDL
);
145 if (!top_level_config
.on_transmission
)
146 log_fatal ("no memory for top-level on_transmission group");
148 status
= read_client_conf_file (path_dhclient_conf
,
149 (struct interface_info
*)0,
153 if (status
!= ISC_R_SUCCESS
) {
156 /* Set up the standard name service updater routine. */
157 status
= new_parse(&parse
, -1, default_client_config
,
158 sizeof(default_client_config
) - 1,
159 "default client configuration", 0);
160 if (status
!= ISC_R_SUCCESS
)
161 log_fatal ("can't begin default client config!");
166 token
= peek_token(&val
, NULL
, cfile
);
167 if (token
== END_OF_FILE
)
169 parse_client_statement(cfile
, NULL
, &top_level_config
);
175 /* Set up state and config structures for clients that don't
176 have per-interface configuration statements. */
177 config
= (struct client_config
*)0;
178 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
180 ip
-> client
= (struct client_state
*)
181 dmalloc (sizeof (struct client_state
), MDL
);
183 log_fatal ("no memory for client state.");
184 memset (ip
-> client
, 0, sizeof *(ip
-> client
));
185 ip
-> client
-> interface
= ip
;
188 if (!ip
-> client
-> config
) {
190 config
= (struct client_config
*)
191 dmalloc (sizeof (struct client_config
),
194 log_fatal ("no memory for client config.");
195 memcpy (config
, &top_level_config
,
196 sizeof top_level_config
);
198 ip
-> client
-> config
= config
;
204 int read_client_conf_file (const char *name
, struct interface_info
*ip
,
205 struct client_config
*client
)
213 if ((file
= open (name
, O_RDONLY
)) < 0)
214 return uerr2isc (errno
);
217 status
= new_parse(&cfile
, file
, NULL
, 0, path_dhclient_conf
, 0);
218 if (status
!= ISC_R_SUCCESS
|| cfile
== NULL
)
222 token
= peek_token (&val
, (unsigned *)0, cfile
);
223 if (token
== END_OF_FILE
)
225 parse_client_statement (cfile
, ip
, client
);
227 token
= next_token (&val
, (unsigned *)0, cfile
);
228 status
= (cfile
-> warnings_occurred
236 /* lease-file :== client-lease-statements END_OF_FILE
237 client-lease-statements :== <nil>
238 | client-lease-statements LEASE client-lease-statement */
240 void read_client_leases ()
248 /* Open the lease file. If we can't open it, just return -
249 we can safely trust the server to remember our state. */
250 if ((file
= open (path_dhclient_db
, O_RDONLY
)) < 0)
254 status
= new_parse(&cfile
, file
, NULL
, 0, path_dhclient_db
, 0);
255 if (status
!= ISC_R_SUCCESS
|| cfile
== NULL
)
259 token
= next_token (&val
, (unsigned *)0, cfile
);
260 if (token
== END_OF_FILE
)
265 parse_client_default_duid(cfile
);
269 parse_client_lease_statement(cfile
, 0);
273 parse_client6_lease_statement(cfile
);
277 log_error ("Corrupt lease file - possible data loss!");
278 skip_to_semi (cfile
);
286 /* client-declaration :==
288 DEFAULT option-decl |
289 SUPERSEDE option-decl |
290 PREPEND option-decl |
292 hardware-declaration |
293 ALSO REQUEST option-list |
294 ALSO REQUIRE option-list |
295 REQUEST option-list |
296 REQUIRE option-list |
300 SELECT_TIMEOUT number |
302 VENDOR_SPACE string |
303 interface-declaration |
304 LEASE client-lease-statement |
305 ALIAS client-lease-statement |
306 KEY key-definition */
308 void parse_client_statement (cfile
, ip
, config
)
310 struct interface_info
*ip
;
311 struct client_config
*config
;
315 struct option
*option
= NULL
;
316 struct executable_statement
*stmt
;
323 struct option
***append_list
, **new_list
, **cat_list
;
325 switch (peek_token (&val
, (unsigned *)0, cfile
)) {
327 next_token (&val
, (unsigned *)0, cfile
);
328 token
= next_token (&val
, (unsigned *)0, cfile
);
329 if (token
!= STRING
) {
330 parse_warn (cfile
, "filename string expected.");
331 skip_to_semi (cfile
);
333 status
= read_client_conf_file (val
, ip
, config
);
334 if (status
!= ISC_R_SUCCESS
)
335 parse_warn (cfile
, "%s: bad parse.", val
);
341 next_token (&val
, (unsigned *)0, cfile
);
343 /* This may seem arbitrary, but there's a reason for
344 doing it: the authentication key database is not
345 scoped. If we allow the user to declare a key other
346 than in the outer scope, the user is very likely to
347 believe that the key will only be used in that
348 scope. If the user only wants the key to be used on
349 one interface, because it's known that the other
350 interface may be connected to an insecure net and
351 the secret key is considered sensitive, we don't
352 want to lull them into believing they've gotten
353 their way. This is a bit contrived, but people
354 tend not to be entirely rational about security. */
355 parse_warn (cfile
, "key definition not allowed here.");
356 skip_to_semi (cfile
);
364 next_token(&val
, NULL
, cfile
);
366 /* consume type of ALSO list. */
367 token
= next_token(&val
, NULL
, cfile
);
369 if (token
== REQUEST
) {
370 append_list
= &config
->requested_options
;
371 } else if (token
== REQUIRE
) {
372 append_list
= &config
->required_options
;
374 parse_warn(cfile
, "expected REQUEST or REQUIRE list");
379 /* If there is no list, cut the concat short. */
380 if (*append_list
== NULL
) {
381 parse_option_list(cfile
, append_list
);
385 /* Count the length of the existing list. */
386 for (i
= 0 ; (*append_list
)[i
] != NULL
; i
++)
387 ; /* This space intentionally left blank. */
389 /* If there's no codes on the list, cut the concat short. */
391 parse_option_list(cfile
, append_list
);
395 tmp
= parse_option_list(cfile
, &new_list
);
397 if (tmp
== 0 || new_list
== NULL
)
400 /* Allocate 'i + tmp' buckets plus a terminator. */
401 cat_list
= dmalloc(sizeof(struct option
*) * (i
+ tmp
+ 1),
404 if (cat_list
== NULL
) {
405 log_error("Unable to allocate memory for new "
411 for (i
= 0 ; (*append_list
)[i
] != NULL
; i
++)
412 option_reference(&cat_list
[i
], (*append_list
)[i
], MDL
);
416 for (i
= 0 ; new_list
[i
] != 0 ; i
++)
417 option_reference(&cat_list
[tmp
++], new_list
[i
], MDL
);
421 /* XXX: We cannot free the old list, because it may have been
422 * XXX: assigned from an outer configuration scope (or may be
423 * XXX: the static default setting).
425 *append_list
= cat_list
;
429 /* REQUIRE can either start a policy statement or a
430 comma-separated list of names of required options. */
432 next_token (&val
, (unsigned *)0, cfile
);
433 token
= peek_token (&val
, (unsigned *)0, cfile
);
434 if (token
== AUTHENTICATION
) {
438 parse_option_list (cfile
, &config
-> required_options
);
442 next_token (&val
, (unsigned *)0, cfile
);
447 next_token (&val
, (unsigned *)0, cfile
);
452 next_token (&val
, (unsigned *)0, cfile
);
457 next_token (&val
, (unsigned *)0, cfile
);
462 token
= next_token (&val
, (unsigned *)0, cfile
);
463 if (token
== AUTHENTICATION
) {
464 if (policy
!= P_PREFER
&&
465 policy
!= P_REQUIRE
&&
468 "invalid authentication policy.");
469 skip_to_semi (cfile
);
472 config
-> auth_policy
= policy
;
473 } else if (token
!= TOKEN_BOOTP
) {
474 if (policy
!= P_PREFER
&&
475 policy
!= P_IGNORE
&&
476 policy
!= P_ACCEPT
) {
477 parse_warn (cfile
, "invalid bootp policy.");
478 skip_to_semi (cfile
);
481 config
-> bootp_policy
= policy
;
483 parse_warn (cfile
, "expecting a policy type.");
484 skip_to_semi (cfile
);
490 token
= next_token (&val
, (unsigned *)0, cfile
);
492 token
= peek_token (&val
, (unsigned *)0, cfile
);
493 if (token
== SPACE
) {
496 "option space definitions %s",
497 " may not be scoped.");
498 skip_to_semi (cfile
);
501 parse_option_space_decl (cfile
);
506 status
= parse_option_name(cfile
, 1, &known
, &option
);
507 if (status
!= ISC_R_SUCCESS
|| option
== NULL
)
510 token
= next_token (&val
, (unsigned *)0, cfile
);
512 parse_warn (cfile
, "expecting \"code\" keyword.");
513 skip_to_semi (cfile
);
514 option_dereference(&option
, MDL
);
519 "option definitions may only appear in %s",
520 "the outermost scope.");
521 skip_to_semi (cfile
);
522 option_dereference(&option
, MDL
);
527 * If the option was known, remove it from the code and name
528 * hash tables before redefining it.
531 option_name_hash_delete(option
->universe
->name_hash
,
532 option
->name
, 0, MDL
);
533 option_code_hash_delete(option
->universe
->code_hash
,
534 &option
->code
, 0, MDL
);
537 parse_option_code_definition(cfile
, option
);
538 option_dereference(&option
, MDL
);
542 token
= next_token (&val
, (unsigned *)0, cfile
);
543 parse_string_list (cfile
, &config
-> media
, 1);
547 token
= next_token (&val
, (unsigned *)0, cfile
);
549 parse_hardware_param (cfile
, &ip
-> hw_address
);
551 parse_warn (cfile
, "hardware address parameter %s",
552 "not allowed here.");
553 skip_to_semi (cfile
);
558 token
= next_token(&val
, NULL
, cfile
);
560 parse_hardware_param(cfile
, &ip
->anycast_mac_addr
);
562 parse_warn(cfile
, "anycast mac address parameter "
563 "not allowed here.");
564 skip_to_semi (cfile
);
569 token
= next_token (&val
, (unsigned *)0, cfile
);
570 if (config
-> requested_options
== default_requested_options
)
571 config
-> requested_options
= NULL
;
572 parse_option_list (cfile
, &config
-> requested_options
);
576 token
= next_token (&val
, (unsigned *)0, cfile
);
577 parse_lease_time (cfile
, &config
-> timeout
);
581 token
= next_token (&val
, (unsigned *)0, cfile
);
582 parse_lease_time (cfile
, &config
-> retry_interval
);
586 token
= next_token (&val
, (unsigned *)0, cfile
);
587 parse_lease_time (cfile
, &config
-> select_interval
);
591 token
= next_token (&val
, (unsigned *)0, cfile
);
592 token
= next_token (&val
, (unsigned *)0, cfile
);
595 "unexpected omapi subtype: %s", val
);
596 skip_to_semi (cfile
);
599 token
= next_token (&val
, (unsigned *)0, cfile
);
600 if (token
!= NUMBER
) {
601 parse_warn (cfile
, "invalid port number: `%s'", val
);
602 skip_to_semi (cfile
);
606 if (tmp
< 0 || tmp
> 65535)
607 parse_warn (cfile
, "invalid omapi port %d.", tmp
);
608 else if (config
!= &top_level_config
)
610 "omapi port only works at top level.");
612 config
-> omapi_port
= tmp
;
616 case DO_FORWARD_UPDATE
:
617 token
= next_token (&val
, (unsigned *)0, cfile
);
618 token
= next_token (&val
, (unsigned *)0, cfile
);
619 if (!strcasecmp (val
, "on") ||
620 !strcasecmp (val
, "true"))
621 config
-> do_forward_update
= 1;
622 else if (!strcasecmp (val
, "off") ||
623 !strcasecmp (val
, "false"))
624 config
-> do_forward_update
= 0;
626 parse_warn (cfile
, "expecting boolean value.");
627 skip_to_semi (cfile
);
634 token
= next_token (&val
, (unsigned *)0, cfile
);
635 parse_lease_time (cfile
, &config
-> reboot_timeout
);
639 token
= next_token (&val
, (unsigned *)0, cfile
);
640 parse_lease_time (cfile
, &config
-> backoff_cutoff
);
643 case INITIAL_INTERVAL
:
644 token
= next_token (&val
, (unsigned *)0, cfile
);
645 parse_lease_time (cfile
, &config
-> initial_interval
);
649 token
= next_token (&val
, (unsigned *)0, cfile
);
650 parse_string (cfile
, &config
-> script_name
, (unsigned *)0);
654 token
= next_token (&val
, (unsigned *)0, cfile
);
655 token
= next_token (&val
, (unsigned *)0, cfile
);
656 if (token
!= OPTION
) {
657 parse_warn (cfile
, "expecting 'vendor option space'");
658 skip_to_semi (cfile
);
661 token
= next_token (&val
, (unsigned *)0, cfile
);
662 if (token
!= SPACE
) {
663 parse_warn (cfile
, "expecting 'vendor option space'");
664 skip_to_semi (cfile
);
667 token
= next_token (&val
, (unsigned *)0, cfile
);
668 if (!is_identifier (token
)) {
669 parse_warn (cfile
, "expecting an identifier.");
670 skip_to_semi (cfile
);
673 config
-> vendor_space_name
= dmalloc (strlen (val
) + 1, MDL
);
674 if (!config
-> vendor_space_name
)
675 log_fatal ("no memory for vendor option space name.");
676 strcpy (config
-> vendor_space_name
, val
);
677 for (i
= 0; i
< universe_count
; i
++)
678 if (!strcmp (universes
[i
] -> name
,
679 config
-> vendor_space_name
))
681 if (i
== universe_count
) {
682 log_error ("vendor option space %s not found.",
683 config
-> vendor_space_name
);
689 token
= next_token (&val
, (unsigned *)0, cfile
);
691 parse_warn (cfile
, "nested interface declaration.");
692 parse_interface_declaration (cfile
, config
, (char *)0);
696 token
= next_token (&val
, (unsigned *)0, cfile
);
697 token
= next_token (&val
, (unsigned *)0, cfile
);
698 name
= dmalloc (strlen (val
) + 1, MDL
);
700 log_fatal ("no memory for pseudo interface name");
702 parse_interface_declaration (cfile
, config
, name
);
706 token
= next_token (&val
, (unsigned *)0, cfile
);
707 parse_client_lease_statement (cfile
, 1);
711 token
= next_token (&val
, (unsigned *)0, cfile
);
712 parse_client_lease_statement (cfile
, 2);
716 token
= next_token (&val
, (unsigned *)0, cfile
);
717 parse_reject_statement (cfile
, config
);
722 stmt
= (struct executable_statement
*)0;
723 if (!parse_executable_statement (&stmt
,
724 cfile
, &lose
, context_any
)) {
726 parse_warn (cfile
, "expecting a statement.");
727 skip_to_semi (cfile
);
730 struct executable_statement
**eptr
, *sptr
;
732 (stmt
-> op
== send_option_statement
||
733 (stmt
-> op
== on_statement
&&
734 (stmt
-> data
.on
.evtypes
& ON_TRANSMISSION
)))) {
735 eptr
= &config
-> on_transmission
-> statements
;
736 if (stmt
-> op
== on_statement
) {
737 sptr
= (struct executable_statement
*)0;
738 executable_statement_reference
740 stmt
-> data
.on
.statements
, MDL
);
741 executable_statement_dereference (&stmt
,
743 executable_statement_reference (&stmt
,
746 executable_statement_dereference (&sptr
,
750 eptr
= &config
-> on_receipt
-> statements
;
753 for (; *eptr
; eptr
= &(*eptr
) -> next
)
755 executable_statement_reference (eptr
,
765 /* option-list :== option_name |
766 option_list COMMA option_name */
769 parse_option_list(struct parse
*cfile
, struct option
***list
)
774 pair p
= (pair
)0, q
= (pair
)0, r
;
775 struct option
*option
= NULL
;
780 token
= peek_token (&val
, (unsigned *)0, cfile
);
782 token
= next_token (&val
, (unsigned *)0, cfile
);
785 if (!is_identifier (token
)) {
786 parse_warn (cfile
, "%s: expected option name.", val
);
787 token
= next_token (&val
, (unsigned *)0, cfile
);
788 skip_to_semi (cfile
);
791 status
= parse_option_name(cfile
, 0, NULL
, &option
);
792 if (status
!= ISC_R_SUCCESS
|| option
== NULL
) {
793 parse_warn (cfile
, "%s: expected option name.", val
);
798 log_fatal ("can't allocate pair for option code.");
799 /* XXX: we should probably carry a reference across this */
800 r
->car
= (caddr_t
)option
;
801 option_dereference(&option
, MDL
);
809 token
= next_token (&val
, (unsigned *)0, cfile
);
810 } while (token
== COMMA
);
812 parse_warn (cfile
, "expecting semicolon.");
813 skip_to_semi (cfile
);
816 /* XXX we can't free the list here, because we may have copied
817 XXX it from an outer config state. */
820 *list
= dmalloc ((ix
+ 1) * sizeof(struct option
*), MDL
);
822 log_error ("no memory for option list.");
825 for (q
= p
; q
; q
= q
-> cdr
)
826 option_reference(&(*list
)[ix
++],
827 (struct option
*)q
->car
, MDL
);
840 /* interface-declaration :==
841 INTERFACE string LBRACE client-declarations RBRACE */
843 void parse_interface_declaration (cfile
, outer_config
, name
)
845 struct client_config
*outer_config
;
850 struct client_state
*client
, **cp
;
851 struct interface_info
*ip
= (struct interface_info
*)0;
853 token
= next_token (&val
, (unsigned *)0, cfile
);
854 if (token
!= STRING
) {
855 parse_warn (cfile
, "expecting interface name (in quotes).");
856 skip_to_semi (cfile
);
860 if (!interface_or_dummy (&ip
, val
))
861 log_fatal ("Can't allocate interface %s.", val
);
863 /* If we were given a name, this is a pseudo-interface. */
865 make_client_state (&client
);
866 client
-> name
= name
;
867 client
-> interface
= ip
;
868 for (cp
= &ip
-> client
; *cp
; cp
= &((*cp
) -> next
))
873 make_client_state (&ip
-> client
);
874 ip
-> client
-> interface
= ip
;
876 client
= ip
-> client
;
879 if (!client
-> config
)
880 make_client_config (client
, outer_config
);
882 ip
-> flags
&= ~INTERFACE_AUTOMATIC
;
883 interfaces_requested
= 1;
885 token
= next_token (&val
, (unsigned *)0, cfile
);
886 if (token
!= LBRACE
) {
887 parse_warn (cfile
, "expecting left brace.");
888 skip_to_semi (cfile
);
893 token
= peek_token (&val
, (unsigned *)0, cfile
);
894 if (token
== END_OF_FILE
) {
896 "unterminated interface declaration.");
901 parse_client_statement (cfile
, ip
, client
-> config
);
903 token
= next_token (&val
, (unsigned *)0, cfile
);
906 int interface_or_dummy (struct interface_info
**pi
, const char *name
)
908 struct interface_info
*i
;
909 struct interface_info
*ip
= (struct interface_info
*)0;
912 /* Find the interface (if any) that matches the name. */
913 for (i
= interfaces
; i
; i
= i
-> next
) {
914 if (!strcmp (i
-> name
, name
)) {
915 interface_reference (&ip
, i
, MDL
);
920 /* If it's not a real interface, see if it's on the dummy list. */
922 for (ip
= dummy_interfaces
; ip
; ip
= ip
-> next
) {
923 if (!strcmp (ip
-> name
, name
)) {
924 interface_reference (&ip
, i
, MDL
);
930 /* If we didn't find an interface, make a dummy interface as
933 if ((status
= interface_allocate (&ip
, MDL
)) != ISC_R_SUCCESS
)
934 log_fatal ("Can't record interface %s: %s",
935 name
, isc_result_totext (status
));
937 if (strlen(name
) >= sizeof(ip
->name
)) {
938 interface_dereference(&ip
, MDL
);
941 strcpy(ip
->name
, name
);
943 if (dummy_interfaces
) {
944 interface_reference (&ip
-> next
,
945 dummy_interfaces
, MDL
);
946 interface_dereference (&dummy_interfaces
, MDL
);
948 interface_reference (&dummy_interfaces
, ip
, MDL
);
951 status
= interface_reference (pi
, ip
, MDL
);
953 status
= ISC_R_FAILURE
;
954 interface_dereference (&ip
, MDL
);
955 if (status
!= ISC_R_SUCCESS
)
960 void make_client_state (state
)
961 struct client_state
**state
;
963 *state
= ((struct client_state
*)dmalloc (sizeof **state
, MDL
));
965 log_fatal ("no memory for client state\n");
966 memset (*state
, 0, sizeof **state
);
969 void make_client_config (client
, config
)
970 struct client_state
*client
;
971 struct client_config
*config
;
973 client
-> config
= (((struct client_config
*)
974 dmalloc (sizeof (struct client_config
), MDL
)));
975 if (!client
-> config
)
976 log_fatal ("no memory for client config\n");
977 memcpy (client
-> config
, config
, sizeof *config
);
978 if (!clone_group (&client
-> config
-> on_receipt
,
979 config
-> on_receipt
, MDL
) ||
980 !clone_group (&client
-> config
-> on_transmission
,
981 config
-> on_transmission
, MDL
))
982 log_fatal ("no memory for client state groups.");
985 /* client-lease-statement :==
986 LBRACE client-lease-declarations RBRACE
988 client-lease-declarations :==
990 client-lease-declaration |
991 client-lease-declarations client-lease-declaration */
994 void parse_client_lease_statement (cfile
, is_static
)
998 struct client_lease
*lease
, *lp
, *pl
, *next
;
999 struct interface_info
*ip
= (struct interface_info
*)0;
1002 struct client_state
*client
= (struct client_state
*)0;
1004 token
= next_token (&val
, (unsigned *)0, cfile
);
1005 if (token
!= LBRACE
) {
1006 parse_warn (cfile
, "expecting left brace.");
1007 skip_to_semi (cfile
);
1011 lease
= ((struct client_lease
*)
1012 dmalloc (sizeof (struct client_lease
), MDL
));
1014 log_fatal ("no memory for lease.\n");
1015 memset (lease
, 0, sizeof *lease
);
1016 lease
-> is_static
= is_static
;
1017 if (!option_state_allocate (&lease
-> options
, MDL
))
1018 log_fatal ("no memory for lease options.\n");
1021 token
= peek_token (&val
, (unsigned *)0, cfile
);
1022 if (token
== END_OF_FILE
) {
1023 parse_warn (cfile
, "unterminated lease declaration.");
1026 if (token
== RBRACE
)
1028 parse_client_lease_declaration (cfile
, lease
, &ip
, &client
);
1030 token
= next_token (&val
, (unsigned *)0, cfile
);
1032 /* If the lease declaration didn't include an interface
1033 declaration that we recognized, it's of no use to us. */
1035 destroy_client_lease (lease
);
1039 /* Make sure there's a client state structure... */
1040 if (!ip
-> client
) {
1041 make_client_state (&ip
-> client
);
1042 ip
-> client
-> interface
= ip
;
1045 client
= ip
-> client
;
1047 /* If this is an alias lease, it doesn't need to be sorted in. */
1048 if (is_static
== 2) {
1049 ip
-> client
-> alias
= lease
;
1053 /* The new lease may supersede a lease that's not the
1054 active lease but is still on the lease list, so scan the
1055 lease list looking for a lease with the same address, and
1056 if we find it, toss it. */
1057 pl
= (struct client_lease
*)0;
1058 for (lp
= client
-> leases
; lp
; lp
= next
) {
1060 if (lp
-> address
.len
== lease
-> address
.len
&&
1061 !memcmp (lp
-> address
.iabuf
, lease
-> address
.iabuf
,
1062 lease
-> address
.len
)) {
1066 client
-> leases
= next
;
1067 destroy_client_lease (lp
);
1073 /* If this is a preloaded lease, just put it on the list of recorded
1074 leases - don't make it the active lease. */
1076 lease
-> next
= client
-> leases
;
1077 client
-> leases
= lease
;
1081 /* The last lease in the lease file on a particular interface is
1082 the active lease for that interface. Of course, we don't know
1083 what the last lease in the file is until we've parsed the whole
1084 file, so at this point, we assume that the lease we just parsed
1085 is the active lease for its interface. If there's already
1086 an active lease for the interface, and this lease is for the same
1087 ip address, then we just toss the old active lease and replace
1088 it with this one. If this lease is for a different address,
1089 then if the old active lease has expired, we dump it; if not,
1090 we put it on the list of leases for this interface which are
1091 still valid but no longer active. */
1092 if (client
-> active
) {
1093 if (client
-> active
-> expiry
< cur_time
)
1094 destroy_client_lease (client
-> active
);
1095 else if (client
-> active
-> address
.len
==
1096 lease
-> address
.len
&&
1097 !memcmp (client
-> active
-> address
.iabuf
,
1098 lease
-> address
.iabuf
,
1099 lease
-> address
.len
))
1100 destroy_client_lease (client
-> active
);
1102 client
-> active
-> next
= client
-> leases
;
1103 client
-> leases
= client
-> active
;
1106 client
-> active
= lease
;
1111 /* client-lease-declaration :==
1114 FIXED_ADDR ip_address |
1116 SERVER_NAME string |
1117 OPTION option-decl |
1123 void parse_client_lease_declaration (cfile
, lease
, ipp
, clientp
)
1124 struct parse
*cfile
;
1125 struct client_lease
*lease
;
1126 struct interface_info
**ipp
;
1127 struct client_state
**clientp
;
1131 struct interface_info
*ip
;
1132 struct option_cache
*oc
;
1133 struct client_state
*client
= (struct client_state
*)0;
1135 switch (next_token (&val
, (unsigned *)0, cfile
)) {
1137 token
= next_token (&val
, (unsigned *)0, cfile
);
1138 if (token
!= STRING
&& !is_identifier (token
)) {
1139 parse_warn (cfile
, "expecting key name.");
1140 skip_to_semi (cfile
);
1143 if (omapi_auth_key_lookup_name (&lease
-> key
, val
) !=
1145 parse_warn (cfile
, "unknown key %s", val
);
1149 lease
-> is_bootp
= 1;
1153 token
= next_token (&val
, (unsigned *)0, cfile
);
1154 if (token
!= STRING
) {
1156 "expecting interface name (in quotes).");
1157 skip_to_semi (cfile
);
1160 if (!interface_or_dummy (ipp
, val
))
1161 log_fatal ("Can't allocate interface %s.", val
);
1165 token
= next_token (&val
, (unsigned *)0, cfile
);
1168 parse_warn (cfile
, "state name precedes interface.");
1171 for (client
= ip
-> client
; client
; client
= client
-> next
)
1172 if (client
-> name
&& !strcmp (client
-> name
, val
))
1176 "lease specified for unknown pseudo.");
1181 if (!parse_ip_addr (cfile
, &lease
-> address
))
1186 parse_string_list (cfile
, &lease
-> medium
, 0);
1190 parse_string (cfile
, &lease
-> filename
, (unsigned *)0);
1194 parse_string (cfile
, &lease
-> server_name
, (unsigned *)0);
1198 lease
-> renewal
= parse_date (cfile
);
1202 lease
-> rebind
= parse_date (cfile
);
1206 lease
-> expiry
= parse_date (cfile
);
1210 oc
= (struct option_cache
*)0;
1211 if (parse_option_decl (&oc
, cfile
)) {
1212 save_option(oc
->option
->universe
, lease
->options
, oc
);
1213 option_cache_dereference (&oc
, MDL
);
1218 parse_warn (cfile
, "expecting lease declaration.");
1219 skip_to_semi (cfile
);
1222 token
= next_token (&val
, (unsigned *)0, cfile
);
1223 if (token
!= SEMI
) {
1224 parse_warn (cfile
, "expecting semicolon.");
1225 skip_to_semi (cfile
);
1229 /* Parse a default-duid ""; statement.
1232 parse_client_default_duid(struct parse
*cfile
)
1234 struct data_string new_duid
;
1235 const char *val
= NULL
;
1239 memset(&new_duid
, 0, sizeof(new_duid
));
1241 token
= next_token(&val
, &len
, cfile
);
1242 if (token
!= STRING
) {
1243 parse_warn(cfile
, "Expected DUID string.");
1244 skip_to_semi(cfile
);
1249 parse_warn(cfile
, "Invalid DUID contents.");
1250 skip_to_semi(cfile
);
1254 if (!buffer_allocate(&new_duid
.buffer
, len
, MDL
)) {
1255 parse_warn(cfile
, "Out of memory parsing default DUID.");
1256 skip_to_semi(cfile
);
1259 new_duid
.data
= new_duid
.buffer
->data
;
1262 memcpy(new_duid
.buffer
->data
, val
, len
);
1264 /* Rotate the last entry into place. */
1265 if (default_duid
.buffer
!= NULL
)
1266 data_string_forget(&default_duid
, MDL
);
1267 data_string_copy(&default_duid
, &new_duid
, MDL
);
1268 data_string_forget(&new_duid
, MDL
);
1273 /* Parse a lease6 {} construct. The v6 client is a little different
1274 * than the v4 client today, in that it only retains one lease, the
1275 * active lease, and discards any less recent information. It may
1276 * be useful in the future to cache additional information, but it
1277 * is not worth the effort for the moment.
1280 parse_client6_lease_statement(struct parse
*cfile
)
1282 #if !defined(DHCPv6)
1283 parse_warn(cfile
, "No DHCPv6 support.");
1284 skip_to_semi(cfile
);
1285 #else /* defined(DHCPv6) */
1286 struct option_cache
*oc
= NULL
;
1287 struct dhc6_lease
*lease
;
1288 struct dhc6_ia
**ia
;
1289 struct client_state
*client
= NULL
;
1290 struct interface_info
*iface
= NULL
;
1291 struct data_string ds
;
1294 int token
, has_ia
, no_semi
, has_name
;
1296 token
= next_token(NULL
, NULL
, cfile
);
1297 if (token
!= LBRACE
) {
1298 parse_warn(cfile
, "Expecting open curly brace.");
1299 skip_to_semi(cfile
);
1303 lease
= dmalloc(sizeof(*lease
), MDL
);
1304 if (lease
== NULL
) {
1305 parse_warn(cfile
, "Unable to allocate lease state.");
1306 skip_to_rbrace(cfile
, 1);
1310 option_state_allocate(&lease
->options
, MDL
);
1311 if (lease
->options
== NULL
) {
1312 parse_warn(cfile
, "Unable to allocate option cache.");
1313 skip_to_rbrace(cfile
, 1);
1320 ia
= &lease
->bindings
;
1321 token
= next_token(&val
, NULL
, cfile
);
1322 while (token
!= RBRACE
) {
1327 *ia
= parse_client6_ia_na_statement(cfile
);
1338 *ia
= parse_client6_ia_ta_statement(cfile
);
1349 *ia
= parse_client6_ia_pd_statement(cfile
);
1360 if (iface
!= NULL
) {
1361 parse_warn(cfile
, "Multiple interface names?");
1362 skip_to_semi(cfile
);
1367 token
= next_token(&val
, &len
, cfile
);
1368 if (token
!= STRING
) {
1370 parse_warn(cfile
, "Expecting a string.");
1371 skip_to_semi(cfile
);
1376 for (iface
= interfaces
; iface
!= NULL
;
1377 iface
= iface
->next
) {
1378 if (strcmp(iface
->name
, val
) == 0)
1382 if (iface
== NULL
) {
1383 parse_warn(cfile
, "Unknown interface.");
1392 if (client
!= NULL
) {
1393 parse_warn(cfile
, "Multiple state names?");
1394 skip_to_semi(cfile
);
1399 if (iface
== NULL
) {
1400 parse_warn(cfile
, "Client name without "
1402 skip_to_semi(cfile
);
1407 token
= next_token(&val
, &len
, cfile
);
1408 if (token
!= STRING
)
1411 for (client
= iface
->client
; client
!= NULL
;
1412 client
= client
->next
) {
1413 if ((client
->name
!= NULL
) &&
1414 (strcmp(client
->name
, val
) == 0))
1418 if (client
== NULL
) {
1419 parse_warn(cfile
, "Unknown client state %s.",
1427 if (parse_option_decl(&oc
, cfile
)) {
1428 save_option(oc
->option
->universe
,
1429 lease
->options
, oc
);
1430 option_cache_dereference(&oc
, MDL
);
1435 case TOKEN_RELEASED
:
1436 case TOKEN_ABANDONED
:
1437 lease
->released
= ISC_TRUE
;
1441 parse_warn(cfile
, "Unexpected token, %s.", val
);
1443 skip_to_semi(cfile
);
1450 token
= next_token(&val
, NULL
, cfile
);
1452 if (token
== END_OF_FILE
) {
1453 parse_warn(cfile
, "Unexpected end of file.");
1459 log_debug("Lease with no IA's discarded from lease db.");
1460 dhc6_lease_destroy(&lease
, MDL
);
1465 parse_warn(cfile
, "Lease has no interface designation.");
1466 else if (!has_name
&& (client
== NULL
)) {
1467 for (client
= iface
->client
; client
!= NULL
;
1468 client
= client
->next
) {
1469 if (client
->name
== NULL
)
1474 if (client
== NULL
) {
1475 parse_warn(cfile
, "No matching client state.");
1476 dhc6_lease_destroy(&lease
, MDL
);
1480 /* Fetch Preference option from option cache. */
1481 memset(&ds
, 0, sizeof(ds
));
1482 oc
= lookup_option(&dhcpv6_universe
, lease
->options
, D6O_PREFERENCE
);
1484 evaluate_option_cache(&ds
, NULL
, NULL
, NULL
, lease
->options
,
1485 NULL
, &global_scope
, oc
, MDL
)) {
1487 log_error("Invalid length of DHCPv6 Preference option "
1488 "(%d != 1)", ds
.len
);
1489 data_string_forget(&ds
, MDL
);
1490 dhc6_lease_destroy(&lease
, MDL
);
1493 lease
->pref
= ds
.data
[0];
1495 data_string_forget(&ds
, MDL
);
1498 /* Fetch server-id option from option cache. */
1499 oc
= lookup_option(&dhcpv6_universe
, lease
->options
, D6O_SERVERID
);
1501 !evaluate_option_cache(&lease
->server_id
, NULL
, NULL
, NULL
,
1502 lease
->options
, NULL
, &global_scope
, oc
,
1504 (lease
->server_id
.len
== 0)) {
1505 /* This should be impossible... */
1506 log_error("Invalid SERVERID option cache.");
1507 dhc6_lease_destroy(&lease
, MDL
);
1511 if (client
->active_lease
!= NULL
)
1512 dhc6_lease_destroy(&client
->active_lease
, MDL
);
1514 client
->active_lease
= lease
;
1515 #endif /* defined(DHCPv6) */
1518 /* Parse an ia_na object from the client lease.
1521 static struct dhc6_ia
*
1522 parse_client6_ia_na_statement(struct parse
*cfile
)
1524 struct data_string id
;
1525 struct option_cache
*oc
= NULL
;
1527 struct dhc6_addr
**addr
;
1531 ia
= dmalloc(sizeof(*ia
), MDL
);
1533 parse_warn(cfile
, "Out of memory allocating IA_NA state.");
1534 skip_to_semi(cfile
);
1537 ia
->ia_type
= D6O_IA_NA
;
1540 memset(&id
, 0, sizeof(id
));
1541 if (parse_cshl(&id
, cfile
)) {
1543 memcpy(ia
->iaid
, id
.data
, 4);
1545 parse_warn(cfile
, "Expecting IAID of length 4, got %d.",
1547 skip_to_semi(cfile
);
1551 data_string_forget(&id
, MDL
);
1553 parse_warn(cfile
, "Expecting IAID.");
1554 skip_to_semi(cfile
);
1559 token
= next_token(NULL
, NULL
, cfile
);
1560 if (token
!= LBRACE
) {
1561 parse_warn(cfile
, "Expecting open curly brace.");
1562 skip_to_semi(cfile
);
1567 option_state_allocate(&ia
->options
, MDL
);
1568 if (ia
->options
== NULL
) {
1569 parse_warn(cfile
, "Unable to allocate option state.");
1570 skip_to_rbrace(cfile
, 1);
1576 token
= next_token(&val
, NULL
, cfile
);
1577 while (token
!= RBRACE
) {
1582 token
= next_token(&val
, NULL
, cfile
);
1583 if (token
== NUMBER
) {
1584 ia
->starts
= atoi(val
);
1586 parse_warn(cfile
, "Expecting a number.");
1587 skip_to_semi(cfile
);
1593 token
= next_token(&val
, NULL
, cfile
);
1594 if (token
== NUMBER
) {
1595 ia
->renew
= atoi(val
);
1597 parse_warn(cfile
, "Expecting a number.");
1598 skip_to_semi(cfile
);
1604 token
= next_token(&val
, NULL
, cfile
);
1605 if (token
== NUMBER
) {
1606 ia
->rebind
= atoi(val
);
1608 parse_warn(cfile
, "Expecting a number.");
1609 skip_to_semi(cfile
);
1615 *addr
= parse_client6_iaaddr_statement(cfile
);
1618 addr
= &(*addr
)->next
;
1625 if (parse_option_decl(&oc
, cfile
)) {
1626 save_option(oc
->option
->universe
,
1628 option_cache_dereference(&oc
, MDL
);
1634 parse_warn(cfile
, "Unexpected token.");
1636 skip_to_semi(cfile
);
1643 token
= next_token(&val
, NULL
, cfile
);
1645 if (token
== END_OF_FILE
) {
1646 parse_warn(cfile
, "Unexpected end of file.");
1655 /* Parse an ia_ta object from the client lease.
1658 static struct dhc6_ia
*
1659 parse_client6_ia_ta_statement(struct parse
*cfile
)
1661 struct data_string id
;
1662 struct option_cache
*oc
= NULL
;
1664 struct dhc6_addr
**addr
;
1668 ia
= dmalloc(sizeof(*ia
), MDL
);
1670 parse_warn(cfile
, "Out of memory allocating IA_TA state.");
1671 skip_to_semi(cfile
);
1674 ia
->ia_type
= D6O_IA_TA
;
1677 memset(&id
, 0, sizeof(id
));
1678 if (parse_cshl(&id
, cfile
)) {
1680 memcpy(ia
->iaid
, id
.data
, 4);
1682 parse_warn(cfile
, "Expecting IAID of length 4, got %d.",
1684 skip_to_semi(cfile
);
1688 data_string_forget(&id
, MDL
);
1690 parse_warn(cfile
, "Expecting IAID.");
1691 skip_to_semi(cfile
);
1696 token
= next_token(NULL
, NULL
, cfile
);
1697 if (token
!= LBRACE
) {
1698 parse_warn(cfile
, "Expecting open curly brace.");
1699 skip_to_semi(cfile
);
1704 option_state_allocate(&ia
->options
, MDL
);
1705 if (ia
->options
== NULL
) {
1706 parse_warn(cfile
, "Unable to allocate option state.");
1707 skip_to_rbrace(cfile
, 1);
1713 token
= next_token(&val
, NULL
, cfile
);
1714 while (token
!= RBRACE
) {
1719 token
= next_token(&val
, NULL
, cfile
);
1720 if (token
== NUMBER
) {
1721 ia
->starts
= atoi(val
);
1723 parse_warn(cfile
, "Expecting a number.");
1724 skip_to_semi(cfile
);
1729 /* No RENEW or REBIND */
1732 *addr
= parse_client6_iaaddr_statement(cfile
);
1735 addr
= &(*addr
)->next
;
1742 if (parse_option_decl(&oc
, cfile
)) {
1743 save_option(oc
->option
->universe
,
1745 option_cache_dereference(&oc
, MDL
);
1751 parse_warn(cfile
, "Unexpected token.");
1753 skip_to_semi(cfile
);
1760 token
= next_token(&val
, NULL
, cfile
);
1762 if (token
== END_OF_FILE
) {
1763 parse_warn(cfile
, "Unexpected end of file.");
1772 /* Parse an ia_pd object from the client lease.
1775 static struct dhc6_ia
*
1776 parse_client6_ia_pd_statement(struct parse
*cfile
)
1778 struct data_string id
;
1779 struct option_cache
*oc
= NULL
;
1781 struct dhc6_addr
**pref
;
1785 ia
= dmalloc(sizeof(*ia
), MDL
);
1787 parse_warn(cfile
, "Out of memory allocating IA_PD state.");
1788 skip_to_semi(cfile
);
1791 ia
->ia_type
= D6O_IA_PD
;
1794 memset(&id
, 0, sizeof(id
));
1795 if (parse_cshl(&id
, cfile
)) {
1797 memcpy(ia
->iaid
, id
.data
, 4);
1799 parse_warn(cfile
, "Expecting IAID of length 4, got %d.",
1801 skip_to_semi(cfile
);
1805 data_string_forget(&id
, MDL
);
1807 parse_warn(cfile
, "Expecting IAID.");
1808 skip_to_semi(cfile
);
1813 token
= next_token(NULL
, NULL
, cfile
);
1814 if (token
!= LBRACE
) {
1815 parse_warn(cfile
, "Expecting open curly brace.");
1816 skip_to_semi(cfile
);
1821 option_state_allocate(&ia
->options
, MDL
);
1822 if (ia
->options
== NULL
) {
1823 parse_warn(cfile
, "Unable to allocate option state.");
1824 skip_to_rbrace(cfile
, 1);
1830 token
= next_token(&val
, NULL
, cfile
);
1831 while (token
!= RBRACE
) {
1836 token
= next_token(&val
, NULL
, cfile
);
1837 if (token
== NUMBER
) {
1838 ia
->starts
= atoi(val
);
1840 parse_warn(cfile
, "Expecting a number.");
1841 skip_to_semi(cfile
);
1847 token
= next_token(&val
, NULL
, cfile
);
1848 if (token
== NUMBER
) {
1849 ia
->renew
= atoi(val
);
1851 parse_warn(cfile
, "Expecting a number.");
1852 skip_to_semi(cfile
);
1858 token
= next_token(&val
, NULL
, cfile
);
1859 if (token
== NUMBER
) {
1860 ia
->rebind
= atoi(val
);
1862 parse_warn(cfile
, "Expecting a number.");
1863 skip_to_semi(cfile
);
1869 *pref
= parse_client6_iaprefix_statement(cfile
);
1872 pref
= &(*pref
)->next
;
1879 if (parse_option_decl(&oc
, cfile
)) {
1880 save_option(oc
->option
->universe
,
1882 option_cache_dereference(&oc
, MDL
);
1888 parse_warn(cfile
, "Unexpected token.");
1890 skip_to_semi(cfile
);
1897 token
= next_token(&val
, NULL
, cfile
);
1899 if (token
== END_OF_FILE
) {
1900 parse_warn(cfile
, "Unexpected end of file.");
1909 /* Parse an iaaddr {} structure. */
1911 static struct dhc6_addr
*
1912 parse_client6_iaaddr_statement(struct parse
*cfile
)
1914 struct option_cache
*oc
= NULL
;
1915 struct dhc6_addr
*addr
;
1919 addr
= dmalloc(sizeof(*addr
), MDL
);
1921 parse_warn(cfile
, "Unable to allocate IAADDR state.");
1922 skip_to_semi(cfile
);
1926 /* Get IP address. */
1927 if (!parse_ip6_addr(cfile
, &addr
->address
)) {
1928 skip_to_semi(cfile
);
1933 token
= next_token(NULL
, NULL
, cfile
);
1934 if (token
!= LBRACE
) {
1935 parse_warn(cfile
, "Expecting open curly bracket.");
1936 skip_to_semi(cfile
);
1941 option_state_allocate(&addr
->options
, MDL
);
1942 if (addr
->options
== NULL
) {
1943 parse_warn(cfile
, "Unable to allocate option state.");
1944 skip_to_semi(cfile
);
1949 token
= next_token(&val
, NULL
, cfile
);
1950 while (token
!= RBRACE
) {
1955 token
= next_token(&val
, NULL
, cfile
);
1956 if (token
== NUMBER
) {
1957 addr
->starts
= atoi(val
);
1959 parse_warn(cfile
, "Expecting a number.");
1960 skip_to_semi(cfile
);
1965 case PREFERRED_LIFE
:
1966 token
= next_token(&val
, NULL
, cfile
);
1967 if (token
== NUMBER
) {
1968 addr
->preferred_life
= atoi(val
);
1970 parse_warn(cfile
, "Expecting a number.");
1971 skip_to_semi(cfile
);
1977 token
= next_token(&val
, NULL
, cfile
);
1978 if (token
== NUMBER
) {
1979 addr
->max_life
= atoi(val
);
1981 parse_warn(cfile
, "Expecting a number.");
1982 skip_to_semi(cfile
);
1988 if (parse_option_decl(&oc
, cfile
)) {
1989 save_option(oc
->option
->universe
,
1991 option_cache_dereference(&oc
, MDL
);
1997 parse_warn(cfile
, "Unexpected token.");
1998 skip_to_rbrace(cfile
, 1);
2006 token
= next_token(&val
, NULL
, cfile
);
2007 if (token
== END_OF_FILE
) {
2008 parse_warn(cfile
, "Unexpected end of file.");
2017 /* Parse an iaprefix {} structure. */
2019 static struct dhc6_addr
*
2020 parse_client6_iaprefix_statement(struct parse
*cfile
)
2022 struct option_cache
*oc
= NULL
;
2023 struct dhc6_addr
*pref
;
2027 pref
= dmalloc(sizeof(*pref
), MDL
);
2029 parse_warn(cfile
, "Unable to allocate IAPREFIX state.");
2030 skip_to_semi(cfile
);
2034 /* Get IP prefix. */
2035 if (!parse_ip6_prefix(cfile
, &pref
->address
, &pref
->plen
)) {
2036 skip_to_semi(cfile
);
2041 token
= next_token(NULL
, NULL
, cfile
);
2042 if (token
!= LBRACE
) {
2043 parse_warn(cfile
, "Expecting open curly bracket.");
2044 skip_to_semi(cfile
);
2049 option_state_allocate(&pref
->options
, MDL
);
2050 if (pref
->options
== NULL
) {
2051 parse_warn(cfile
, "Unable to allocate option state.");
2052 skip_to_semi(cfile
);
2057 token
= next_token(&val
, NULL
, cfile
);
2058 while (token
!= RBRACE
) {
2063 token
= next_token(&val
, NULL
, cfile
);
2064 if (token
== NUMBER
) {
2065 pref
->starts
= atoi(val
);
2067 parse_warn(cfile
, "Expecting a number.");
2068 skip_to_semi(cfile
);
2073 case PREFERRED_LIFE
:
2074 token
= next_token(&val
, NULL
, cfile
);
2075 if (token
== NUMBER
) {
2076 pref
->preferred_life
= atoi(val
);
2078 parse_warn(cfile
, "Expecting a number.");
2079 skip_to_semi(cfile
);
2085 token
= next_token(&val
, NULL
, cfile
);
2086 if (token
== NUMBER
) {
2087 pref
->max_life
= atoi(val
);
2089 parse_warn(cfile
, "Expecting a number.");
2090 skip_to_semi(cfile
);
2096 if (parse_option_decl(&oc
, cfile
)) {
2097 save_option(oc
->option
->universe
,
2099 option_cache_dereference(&oc
, MDL
);
2105 parse_warn(cfile
, "Unexpected token.");
2106 skip_to_rbrace(cfile
, 1);
2114 token
= next_token(&val
, NULL
, cfile
);
2115 if (token
== END_OF_FILE
) {
2116 parse_warn(cfile
, "Unexpected end of file.");
2125 void parse_string_list (cfile
, lp
, multiple
)
2126 struct parse
*cfile
;
2127 struct string_list
**lp
;
2132 struct string_list
*cur
, *tmp
;
2134 /* Find the last medium in the media list. */
2136 for (cur
= *lp
; cur
-> next
; cur
= cur
-> next
)
2139 cur
= (struct string_list
*)0;
2143 token
= next_token (&val
, (unsigned *)0, cfile
);
2144 if (token
!= STRING
) {
2145 parse_warn (cfile
, "Expecting media options.");
2146 skip_to_semi (cfile
);
2150 tmp
= ((struct string_list
*)
2151 dmalloc (strlen (val
) + sizeof (struct string_list
),
2154 log_fatal ("no memory for string list entry.");
2156 strcpy (tmp
-> string
, val
);
2157 tmp
-> next
= (struct string_list
*)0;
2159 /* Store this medium at the end of the media list. */
2166 token
= next_token (&val
, (unsigned *)0, cfile
);
2167 } while (multiple
&& token
== COMMA
);
2169 if (token
!= SEMI
) {
2170 parse_warn (cfile
, "expecting semicolon.");
2171 skip_to_semi (cfile
);
2175 void parse_reject_statement (cfile
, config
)
2176 struct parse
*cfile
;
2177 struct client_config
*config
;
2181 struct iaddrmatch match
;
2182 struct iaddrmatchlist
*list
;
2186 if (!parse_ip_addr_with_subnet (cfile
, &match
)) {
2187 /* no warn: parser will have reported what's wrong */
2188 skip_to_semi (cfile
);
2192 /* check mask is not all zeros (because that would
2193 * reject EVERY address). This check could be
2194 * simplified if we assume that the mask *always*
2195 * represents a prefix .. but perhaps it might be
2196 * useful to have a mask which is not a proper prefix
2197 * (perhaps for ipv6?). The following is almost as
2198 * efficient as inspection of match.mask.iabuf[0] when
2199 * it IS a true prefix, and is more general when it is
2203 for (i
=0 ; i
< match
.mask
.len
; i
++) {
2204 if (match
.mask
.iabuf
[i
]) {
2209 if (i
== match
.mask
.len
) {
2210 /* oops we found all zeros */
2211 parse_warn(cfile
, "zero-length prefix is not permitted "
2212 "for reject statement");
2213 skip_to_semi(cfile
);
2217 list
= dmalloc(sizeof(struct iaddrmatchlist
), MDL
);
2219 log_fatal ("no memory for reject list!");
2221 list
->match
= match
;
2222 list
->next
= config
->reject_list
;
2223 config
->reject_list
= list
;
2225 token
= next_token (&val
, (unsigned *)0, cfile
);
2226 } while (token
== COMMA
);
2228 if (token
!= SEMI
) {
2229 parse_warn (cfile
, "expecting semicolon.");
2230 skip_to_semi (cfile
);
2234 /* allow-deny-keyword :== BOOTP
2237 | UNKNOWN_CLIENTS */
2239 int parse_allow_deny (oc
, cfile
, flag
)
2240 struct option_cache
**oc
;
2241 struct parse
*cfile
;
2244 parse_warn (cfile
, "allow/deny/ignore not permitted here.");
2245 skip_to_semi (cfile
);