3 Parser for dhcpd config file... */
6 * Copyright (c) 1996-1999 Internet Software Consortium.
7 * Use is subject to license terms which appear in the file named
8 * ISC-LICENSE that should have accompanied this file when you
9 * received it. If a file named ISC-LICENSE did not accompany this
10 * file, or you are not sure the one you have is correct, you may
11 * obtain an applicable copy of the license at:
13 * http://www.isc.org/isc-license-1.0.html.
15 * This file is part of the ISC DHCP distribution. The documentation
16 * associated with this file is listed in the file DOCUMENTATION,
17 * included in the top-level directory of this release.
19 * Support and other services are available for ISC products - see
20 * http://www.isc.org for more information.
24 static char copyright
[] =
25 "$Id: confpars.c,v 1.65 1999/03/16 06:37:51 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
31 static TIME parsed_time
;
33 /* conf-file :== parameters declarations EOF
34 parameters :== <nil> | parameter | parameters parameter
35 declarations :== <nil> | declaration | declarations declaration */
41 enum dhcp_token token
;
44 new_parse (path_dhcpd_conf
);
46 /* Set up the initial dhcp option universe. */
47 initialize_universes ();
49 root_group
.authoritative
= 0;
51 if ((cfile
= fopen (path_dhcpd_conf
, "r")) == NULL
)
52 log_fatal ("Can't open %s: %m", path_dhcpd_conf
);
54 token
= peek_token (&val
, cfile
);
57 declaration
= parse_statement (cfile
, &root_group
,
59 (struct host_decl
*)0,
62 token
= next_token (&val
, cfile
); /* Clear the peek buffer */
64 return !warnings_occurred
;
67 /* lease-file :== lease-declarations EOF
68 lease-statments :== <nil>
70 | lease-declarations lease-declaration */
76 enum dhcp_token token
;
78 new_parse (path_dhcpd_db
);
80 /* Open the lease file. If we can't open it, fail. The reason
81 for this is that although on initial startup, the absence of
82 a lease file is perfectly benign, if dhcpd has been running
83 and this file is absent, it means that dhcpd tried and failed
84 to rewrite the lease database. If we proceed and the
85 problem which caused the rewrite to fail has been fixed, but no
86 human has corrected the database problem, then we are left
87 thinking that no leases have been assigned to anybody, which
88 could create severe network chaos. */
89 if ((cfile
= fopen (path_dhcpd_db
, "r")) == NULL
)
90 log_fatal ("Can't open lease database %s: %m -- %s",
92 "check for failed database rewrite attempt!");
94 token
= next_token (&val
, cfile
);
98 log_error ("Corrupt lease file - possible data loss!");
102 lease
= parse_lease_declaration (cfile
);
106 parse_warn ("possibly corrupt lease file");
112 /* statement :== parameter | declaration
114 parameter :== timestamp
115 | DEFAULT_LEASE_TIME lease_time
116 | MAX_LEASE_TIME lease_time
117 | DYNAMIC_BOOTP_LEASE_CUTOFF date
118 | DYNAMIC_BOOTP_LEASE_LENGTH lease_time
119 | BOOT_UNKNOWN_CLIENTS boolean
120 | ONE_LEASE_PER_CLIENT boolean
121 | GET_LEASE_HOSTNAMES boolean
122 | USE_HOST_DECL_NAME boolean
123 | NEXT_SERVER ip-addr-or-hostname SEMI
125 | SERVER-IDENTIFIER ip-addr-or-hostname SEMI
126 | FILENAME string-parameter
127 | SERVER_NAME string-parameter
129 | fixed-address-parameter
130 | ALLOW allow-deny-keyword
131 | DENY allow-deny-keyword
132 | USE_LEASE_ADDR_FOR_DEFAULT_ROUTE boolean
135 | AUTH_KEY key-id key-value
137 declaration :== host-declaration
139 | shared-network-declaration
141 | VENDOR_CLASS class-declaration
142 | USER_CLASS class-declaration
143 | RANGE address-range-declaration */
145 int parse_statement (cfile
, group
, type
, host_decl
, declaration
)
149 struct host_decl
*host_decl
;
152 enum dhcp_token token
;
154 struct shared_network
*share
;
156 struct expression
*expr
;
157 struct data_string data
;
158 struct hardware hardware
;
159 struct executable_statement
*et
, *ep
;
160 struct option
*option
;
161 struct option_cache
*cache
;
163 struct data_string key_id
;
165 switch (peek_token (&val
, cfile
)) {
167 memset (&key_id
, 0, sizeof key_id
);
168 if (parse_auth_key (&key_id
, cfile
)) {
169 if (type
== HOST_DECL
)
170 data_string_copy (&host_decl
-> auth_key_id
,
171 &key_id
, "parse_statement");
172 data_string_forget (&key_id
, "parse_statement");
176 next_token (&val
, cfile
);
177 if (type
!= HOST_DECL
&& type
!= CLASS_DECL
)
178 parse_host_declaration (cfile
, group
);
180 parse_warn ("host declarations not allowed here.");
181 skip_to_semi (cfile
);
186 next_token (&val
, cfile
);
187 if (type
!= HOST_DECL
&& type
!= CLASS_DECL
)
188 parse_group_declaration (cfile
, group
);
190 parse_warn ("host declarations not allowed here.");
191 skip_to_semi (cfile
);
196 next_token (&val
, cfile
);
197 parsed_time
= parse_timestamp (cfile
);
201 next_token (&val
, cfile
);
202 if (type
== SHARED_NET_DECL
||
204 type
== SUBNET_DECL
||
205 type
== CLASS_DECL
) {
206 parse_warn ("shared-network parameters not %s.",
208 skip_to_semi (cfile
);
212 parse_shared_net_declaration (cfile
, group
);
216 next_token (&val
, cfile
);
217 if (type
== HOST_DECL
|| type
== SUBNET_DECL
||
218 type
== CLASS_DECL
) {
219 parse_warn ("subnet declarations not allowed here.");
220 skip_to_semi (cfile
);
224 /* If we're in a subnet declaration, just do the parse. */
225 if (group
-> shared_network
) {
226 parse_subnet_declaration (cfile
,
227 group
-> shared_network
);
231 /* Otherwise, cons up a fake shared network structure
232 and populate it with the lone subnet... */
234 share
= new_shared_network ("parse_statement");
236 log_fatal ("No memory for shared subnet");
237 share
-> group
= clone_group (group
, "parse_statement:subnet");
238 share
-> group
-> shared_network
= share
;
240 parse_subnet_declaration (cfile
, share
);
242 /* share -> subnets is the subnet we just parsed. */
243 if (share
-> subnets
) {
245 share
-> subnets
-> interface
;
247 /* Make the shared network name from network number. */
248 n
= piaddr (share
-> subnets
-> net
);
249 t
= malloc (strlen (n
) + 1);
251 log_fatal ("no memory for subnet name");
255 /* Copy the authoritative parameter from the subnet,
256 since there is no opportunity to declare it here. */
257 share
-> group
-> authoritative
=
258 share
-> subnets
-> group
-> authoritative
;
259 enter_shared_network (share
);
264 next_token (&val
, cfile
);
265 if (type
== CLASS_DECL
) {
266 parse_warn ("class declarations not allowed here.");
267 skip_to_semi (cfile
);
270 parse_class_declaration (cfile
, group
, 0);
274 next_token (&val
, cfile
);
275 if (type
== CLASS_DECL
) {
276 parse_warn ("class declarations not allowed here.");
277 skip_to_semi (cfile
);
280 parse_class_declaration (cfile
, group
, 1);
284 next_token (&val
, cfile
);
285 if (type
== CLASS_DECL
) {
286 parse_warn ("class declarations not allowed here.");
287 skip_to_semi (cfile
);
290 parse_class_declaration (cfile
, group
, 2);
294 next_token (&val
, cfile
);
295 if (type
== CLASS_DECL
) {
296 parse_warn ("class declarations not allowed here.");
297 skip_to_semi (cfile
);
300 parse_class_declaration (cfile
, group
, 3);
304 next_token (&val
, cfile
);
305 parse_hardware_param (cfile
, &hardware
);
307 host_decl
-> interface
= hardware
;
309 parse_warn ("hardware address parameter %s",
310 "not allowed here.");
314 next_token (&val
, cfile
);
315 cache
= (struct option_cache
*)0;
316 parse_fixed_addr_param (&cache
, cfile
);
318 host_decl
-> fixed_addr
= cache
;
320 parse_warn ("fixed-address parameter not %s",
322 option_cache_dereference (&cache
, "parse_statement");
327 next_token (&val
, cfile
);
328 if (type
!= SUBNET_DECL
&& type
!= SHARED_NET_DECL
) {
329 parse_warn ("pool declared outside of network");
331 if (type
== POOL_DECL
) {
332 parse_warn ("pool declared within pool.");
334 parse_pool_statement (cfile
, group
, type
);
338 next_token (&val
, cfile
);
339 if (type
!= SUBNET_DECL
|| !group
-> subnet
) {
340 parse_warn ("range declaration not allowed here.");
341 skip_to_semi (cfile
);
344 parse_address_range (cfile
, group
, type
, (struct pool
*)0);
349 token
= next_token (&val
, cfile
);
350 cache
= (struct option_cache
*)0;
351 if (!parse_allow_deny (&cache
, cfile
,
352 token
== ALLOW
? 1 : 0))
354 et
= (struct executable_statement
*)dmalloc (sizeof *et
,
357 log_fatal ("no memory for %s statement",
358 token
== ALLOW
? "allow" : "deny");
359 memset (et
, 0, sizeof *et
);
360 et
-> op
= supersede_option_statement
;
361 et
-> data
.option
= cache
;
362 goto insert_statement
;
365 token
= next_token (&val
, cfile
);
366 token
= next_token (&val
, cfile
);
369 group
-> authoritative
= 0;
372 parse_warn ("expecting assertion");
373 skip_to_semi (cfile
);
378 token
= next_token (&val
, cfile
);
379 group
-> authoritative
= 1;
381 if (type
== HOST_DECL
)
382 parse_warn ("authority makes no sense here.");
387 token
= next_token (&val
, cfile
);
388 option
= parse_option_name (cfile
);
390 et
= parse_option_statement
392 supersede_option_statement
);
395 goto insert_statement
;
401 #if defined (FAILOVER_PROTOCOL)
403 parse_failover_peer (cfile
, group
, type
);
408 et
= (struct executable_statement
*)0;
409 if (is_identifier (token
)) {
410 option
= ((struct option
*)
411 hash_lookup (server_universe
.hash
,
412 (unsigned char *)val
, 0));
414 token
= next_token (&val
, cfile
);
415 et
= parse_option_statement
417 supersede_option_statement
);
425 et
= parse_executable_statement (cfile
, &lose
);
429 parse_warn ("expecting a %s.",
432 parse_warn ("expecting a%s%s.",
435 skip_to_semi (cfile
);
441 parse_warn ("expecting a %sdeclaration",
442 declaration
? "" : "parameter or ");
446 if (group
-> statements
) {
447 for (ep
= group
-> statements
; ep
-> next
;
453 group
-> statements
= et
;
458 parse_warn ("parameters not allowed after first declaration.");
465 #if defined (FAILOVER_PROTOCOL)
466 void parse_failover_peer (cfile
, group
, type
)
471 enum dhcp_token token
;
473 struct failover_peer
*peer
;
477 if (type
!= SHARED_NET_DECL
&& type
!= ROOT_GROUP
) {
478 parse_warn ("failover peer statements not in shared-network%s"
479 " declaration or at top level.");
480 skip_to_semi (cfile
);
484 token
= next_token (&val
, cfile
);
486 parse_warn ("expecting peer keyword");
487 skip_to_semi (cfile
);
491 token
= next_token (&val
, cfile
);
492 if (is_identifier (token
) || token
== STRING
) {
493 name
= dmalloc (strlen (name
) + 1, "peer name");
495 log_fatal ("no memory for peer name %s", name
);
497 parse_warn ("expecting identifier or left brace");
498 skip_to_semi (cfile
);
502 /* See if there's a peer declaration by this name. */
503 peer
= find_failover_peer (name
);
505 token
= next_token (&val
, cfile
);
507 dfree (name
, "peer name");
508 if (type
!= SHARED_NET_DECL
)
509 parse_warn ("failover peer reference not %s",
510 "in shared-network declaration");
513 parse_warn ("reference to unknown%s%s",
514 " failover peer ", name
);
517 group
-> shared_network
-> failover_peer
=
521 } else if (token
== MY
|| token
== PARTNER
) {
523 parse_warn ("reference to unknown%s%s",
524 " failover peer ", name
);
529 : peer
-> partner_state
) = parse_failover_state (cfile
) ==
531 skip_to_semi (cfile
);
535 } else if (token
!= LBRACE
) {
536 parse_warn ("expecting left brace");
537 skip_to_semi (cfile
);
540 /* Make sure this isn't a redeclaration. */
542 parse_warn ("redeclaration of failover peer %s", name
);
543 skip_to_rbrace (cfile
, 1);
547 peer
= new_failover_peer ("parse_failover_peer");
549 log_fatal ("no memory for %sfailover peer%s%s.",
550 name
? "" : "anonymous", name
? " " : "", name
);
556 token
= next_token (&val
, cfile
);
561 peer
-> i_am
= primary
;
564 peer
-> i_am
= secondary
;
567 if (!parse_ip_addr_or_hostname (&peer
-> address
,
569 skip_to_rbrace (cfile
, 1);
574 token
= next_token (&val
, cfile
);
575 if (token
!= NUMBER
) {
576 parse_warn ("expecting number");
577 skip_to_rbrace (cfile
, 1);
579 peer
-> port
= atoi (val
);
580 if (!parse_semi (cfile
)) {
581 skip_to_rbrace (cfile
, 1);
585 case MAX_TRANSMIT_IDLE
:
586 tp
= &peer
-> max_transmit_idle
;
588 case MAX_RESPONSE_DELAY
:
589 tp
= &peer
-> max_transmit_idle
;
591 token
= next_token (&val
, cfile
);
592 if (token
!= NUMBER
) {
593 parse_warn ("expecting number.");
594 skip_to_rbrace (cfile
, 1);
599 parse_warn ("invalid statement in peer declaration");
600 skip_to_rbrace (cfile
, 1);
603 } while (token
!= RBRACE
);
605 if (type
== SHARED_NET_DECL
) {
606 group
-> shared_network
-> failover_peer
= peer
;
608 enter_failover_peer (peer
);
611 enum failover_state
parse_failover_state (cfile
)
614 enum dhcp_token token
;
617 token
= next_token (&val
, cfile
);
623 case COMMUNICATIONS_INTERRUPTED
:
624 return communications_interrupted
;
625 case POTENTIAL_CONFLICT
:
626 return potential_conflict
;
630 parse_warn ("unknown failover state");
633 return invalid_state
;
635 #endif /* defined (FAILOVER_PROTOCOL) */
637 void parse_pool_statement (cfile
, group
, type
)
642 enum dhcp_token token
;
645 struct pool
*pool
, **p
;
646 struct permit
*permit
;
647 struct permit
**permit_head
;
650 pool
= new_pool ("parse_pool_statement");
652 log_fatal ("no memory for pool.");
654 pool
-> group
= clone_group (group
, "parse_pool_statement");
656 if (!parse_lbrace (cfile
))
659 switch (peek_token (&val
, cfile
)) {
661 next_token (&val
, cfile
);
662 parse_address_range (cfile
, group
, type
, pool
);
665 permit_head
= &pool
-> permit_list
;
667 permit
= new_permit ("parse_pool_statement");
669 log_fatal ("no memory for permit");
670 next_token (&val
, cfile
);
671 token
= next_token (&val
, cfile
);
674 permit
-> type
= permit_unknown_clients
;
676 if (next_token (&val
, cfile
) != CLIENTS
) {
677 parse_warn ("expecting \"clients\"");
678 skip_to_semi (cfile
);
680 "parse_pool_statement");
686 permit
-> type
= permit_known_clients
;
690 permit
-> type
= permit_authenticated_clients
;
693 case UNAUTHENTICATED
:
695 permit_unauthenticated_clients
;
699 permit
-> type
= permit_all_clients
;
704 permit
-> type
= permit_dynamic_bootp_clients
;
705 if (next_token (&val
, cfile
) != BOOTP
) {
706 parse_warn ("expecting \"bootp\"");
707 skip_to_semi (cfile
);
709 "parse_pool_statement");
715 if (next_token (&val
, cfile
) != OF
) {
716 parse_warn ("expecting \"of\"");
717 skip_to_semi (cfile
);
719 "parse_pool_statement");
722 if (next_token (&val
, cfile
) != STRING
) {
723 parse_warn ("expecting class name.");
724 skip_to_semi (cfile
);
726 "parse_pool_statement");
729 permit
-> type
= permit_class
;
730 permit
-> class = find_class (val
);
731 if (!permit
-> class)
732 parse_warn ("no such class: %s", val
);
734 parse_warn ("expecting permit type.");
735 skip_to_semi (cfile
);
739 permit_head
= &((*permit_head
) -> next
);
740 *permit_head
= permit
;
745 permit_head
= &pool
-> prohibit_list
;
749 next_token (&val
, cfile
);
754 declaration
= parse_statement (cfile
, pool
-> group
,
756 (struct host_decl
*)0,
762 if (type
== SUBNET_DECL
)
763 pool
-> shared_network
= group
-> subnet
-> shared_network
;
765 pool
-> shared_network
= group
-> shared_network
;
767 p
= &pool
-> shared_network
-> pools
;
768 for (; *p
; p
= &((*p
) -> next
))
773 /* allow-deny-keyword :== BOOTP
778 int parse_allow_deny (oc
, cfile
, flag
)
779 struct option_cache
**oc
;
783 enum dhcp_token token
;
785 unsigned char rf
= flag
;
786 struct expression
*data
= (struct expression
*)0;
789 if (!make_const_data (&data
, &rf
, 1, 0, 1))
792 token
= next_token (&val
, cfile
);
795 status
= option_cache (oc
, (struct data_string
*)0, data
,
796 &server_options
[SV_ALLOW_BOOTP
]);
800 status
= option_cache (oc
, (struct data_string
*)0, data
,
801 &server_options
[SV_ALLOW_BOOTING
]);
805 status
= option_cache (oc
, (struct data_string
*)0, data
,
806 &server_options
[SV_DYNAMIC_BOOTP
]);
809 case UNKNOWN_CLIENTS
:
810 status
= (option_cache
811 (oc
, (struct data_string
*)0, data
,
812 &server_options
[SV_BOOT_UNKNOWN_CLIENTS
]));
816 parse_warn ("expecting allow/deny key");
817 skip_to_semi (cfile
);
824 /* boolean :== ON SEMI | OFF SEMI | TRUE SEMI | FALSE SEMI */
826 int parse_boolean (cfile
)
829 enum dhcp_token token
;
833 token
= next_token (&val
, cfile
);
834 if (!strcasecmp (val
, "true")
835 || !strcasecmp (val
, "on"))
837 else if (!strcasecmp (val
, "false")
838 || !strcasecmp (val
, "off"))
841 parse_warn ("boolean value (true/false/on/off) expected");
842 skip_to_semi (cfile
);
849 /* Expect a left brace; if there isn't one, skip over the rest of the
850 statement and return zero; otherwise, return 1. */
852 int parse_lbrace (cfile
)
855 enum dhcp_token token
;
858 token
= next_token (&val
, cfile
);
859 if (token
!= LBRACE
) {
860 parse_warn ("expecting left brace.");
861 skip_to_semi (cfile
);
868 /* host-declaration :== hostname RBRACE parameters declarations LBRACE */
870 void parse_host_declaration (cfile
, group
)
875 enum dhcp_token token
;
876 struct host_decl
*host
;
880 token
= peek_token (&val
, cfile
);
881 if (token
!= LBRACE
) {
882 name
= parse_host_name (cfile
);
889 host
= (struct host_decl
*)dmalloc (sizeof (struct host_decl
),
890 "parse_host_declaration");
892 log_fatal ("can't allocate host decl struct %s.", name
);
895 host
-> group
= clone_group (group
, "parse_host_declaration");
897 if (!parse_lbrace (cfile
))
901 token
= peek_token (&val
, cfile
);
902 if (token
== RBRACE
) {
903 token
= next_token (&val
, cfile
);
907 token
= next_token (&val
, cfile
);
908 parse_warn ("unexpected end of file");
911 declaration
= parse_statement (cfile
, host
-> group
,
919 /* class-declaration :== STRING LBRACE parameters declarations RBRACE
922 struct class *parse_class_declaration (cfile
, group
, type
)
928 enum dhcp_token token
;
929 struct class *class = (struct class *)0, *pc
;
932 struct data_string data
;
934 struct executable_statement
*stmt
= (struct executable_statement
*)0;
935 struct expression
*expr
;
938 token
= next_token (&val
, cfile
);
939 if (token
!= STRING
) {
940 parse_warn ("Expecting class name");
941 skip_to_semi (cfile
);
942 return (struct class *)0;
945 /* See if there's already a class with the specified name. */
946 pc
= (struct class *)find_class (val
);
948 /* If this isn't a subclass, we're updating an existing class. */
949 if (pc
&& type
!= 0 && type
!= 1 && type
!= 3) {
952 pc
= (struct class *)0;
955 /* If this _is_ a subclass, there _must_ be a class with the
957 if (!pc
&& (type
== 0 || type
== 1 || type
== 3)) {
958 parse_warn ("no class named %s", val
);
959 skip_to_semi (cfile
);
960 return (struct class *)0;
963 /* The old vendor-class and user-class declarations had an implicit
964 match. We don't do the implicit match anymore. Instead, for
965 backward compatibility, we have an implicit-vendor-class and an
966 implicit-user-class. vendor-class and user-class declarations
967 are turned into subclasses of the implicit classes, and the
968 submatch expression of the implicit classes extracts the contents of
969 the vendor class or user class. */
970 if (type
== 0 || type
== 1) {
971 data
.len
= strlen (val
);
972 data
.buffer
= (struct buffer
*)0;
973 if (!buffer_allocate (&data
.buffer
,
974 data
.len
+ 1, "parse_class_declaration"))
975 log_fatal ("no memoy for class name.");
976 data
.data
= &data
.buffer
-> data
[0];
979 name
= type
? "implicit-vendor-class" : "implicit-user-class";
980 } else if (type
== 2) {
981 if (!(name
= dmalloc (strlen (val
) + 1,
982 "parse_class_declaration")))
983 log_fatal ("No memory for class name %s.", val
);
989 /* If this is a straight subclass, parse the hash string. */
991 token
= peek_token (&val
, cfile
);
992 if (token
== STRING
) {
993 token
= next_token (&val
, cfile
);
994 data
.len
= strlen (val
);
995 data
.buffer
= (struct buffer
*)0;
996 if (!buffer_allocate (&data
.buffer
, data
.len
+ 1,
997 "parse_class_declaration"))
998 return (struct class *)0;
1000 data
.data
= &data
.buffer
-> data
[0];
1001 strcpy ((char *)data
.data
, val
);
1002 } else if (token
== NUMBER_OR_NAME
|| token
== NUMBER
) {
1003 memset (&data
, 0, sizeof data
);
1004 if (!parse_cshl (&data
, cfile
))
1005 return (struct class *)0;
1009 /* See if there's already a class in the hash table matching the
1011 if (type
== 0 || type
== 1 || type
== 3)
1012 class = ((struct class *)
1013 hash_lookup (pc
-> hash
, data
.data
, data
.len
));
1015 /* If we didn't find an existing class, allocate a new one. */
1017 /* Allocate the class structure... */
1018 class = (struct class *)dmalloc (sizeof (struct class),
1019 "parse_class_declaration");
1021 log_fatal ("No memory for class %s.", val
);
1022 memset (class, 0, sizeof *class);
1024 class -> group
= pc
-> group
;
1025 class -> group
= pc
-> group
;
1026 class -> superclass
= pc
;
1027 class -> lease_limit
= pc
-> lease_limit
;
1028 if (class -> lease_limit
) {
1029 class -> billed_leases
=
1030 dmalloc (class -> lease_limit
*
1031 sizeof (struct lease
*),
1032 "check_collection");
1033 if (!class -> billed_leases
)
1034 log_fatal ("no memory for billed leases");
1035 memset (class -> billed_leases
, 0,
1036 (class -> lease_limit
*
1037 sizeof class -> billed_leases
));
1039 data_string_copy (&class -> hash_string
, &data
,
1040 "check_collection");
1042 pc
-> hash
= new_hash ();
1043 add_hash (pc
-> hash
,
1044 class -> hash_string
.data
,
1045 class -> hash_string
.len
,
1046 (unsigned char *)class);
1049 clone_group (group
, "parse_class_declaration");
1052 /* If this is an implicit vendor or user class, add a
1053 statement that causes the vendor or user class ID to
1054 be sent back in the reply. */
1055 if (type
== 0 || type
== 1) {
1056 stmt
= ((struct executable_statement
*)
1057 dmalloc (sizeof (struct executable_statement
),
1058 "implicit user/vendor class"));
1060 log_fatal ("no memory for class statement.");
1061 memset (stmt
, 0, sizeof *stmt
);
1062 stmt
-> op
= supersede_option_statement
;
1063 if (option_cache_allocate (&stmt
-> data
.option
,
1064 "parse_class_statement")) {
1065 stmt
-> data
.option
-> data
= data
;
1066 stmt
-> data
.option
-> option
=
1067 dhcp_universe
.options
1069 ? DHO_DHCP_CLASS_IDENTIFIER
1070 : DHO_DHCP_USER_CLASS_ID
];
1072 class -> statements
= stmt
;
1075 /* Save the name, if there is one. */
1076 class -> name
= name
;
1079 if (type
== 0 || type
== 1 || type
== 3)
1080 data_string_forget (&data
, "check_collection");
1082 /* Spawned classes don't have their own settings. */
1083 if (class -> superclass
) {
1088 if (!parse_lbrace (cfile
))
1089 return (struct class *)0;
1092 token
= peek_token (&val
, cfile
);
1093 if (token
== RBRACE
) {
1094 token
= next_token (&val
, cfile
);
1096 } else if (token
== EOF
) {
1097 token
= next_token (&val
, cfile
);
1098 parse_warn ("unexpected end of file");
1100 } else if (token
== MATCH
) {
1102 parse_warn ("invalid match in subclass.");
1103 skip_to_semi (cfile
);
1106 if (class -> expr
) {
1107 parse_warn ("can't override match.");
1108 skip_to_semi (cfile
);
1111 token
= next_token (&val
, cfile
);
1112 token
= next_token (&val
, cfile
);
1115 parse_boolean_expression (&class -> expr
, cfile
,
1119 #if defined (DEBUG_EXPRESSION_PARSE)
1120 print_expression ("class match", class -> expr
);
1123 } else if (token
== SPAWN
) {
1125 parse_warn ("invalid spawn in subclass.");
1126 skip_to_semi (cfile
);
1129 token
= next_token (&val
, cfile
);
1130 token
= next_token (&val
, cfile
);
1131 if (token
!= WITH
) {
1132 parse_warn ("expecting with after spawn");
1133 skip_to_semi (cfile
);
1136 class -> spawning
= 1;
1138 if (class -> submatch
) {
1139 parse_warn ("can't override existing %s.",
1141 skip_to_semi (cfile
);
1144 parse_data_expression (&class -> submatch
,
1148 #if defined (DEBUG_EXPRESSION_PARSE)
1149 print_expression ("class submatch",
1153 } else if (token
== LEASE
) {
1154 next_token (&val
, cfile
);
1155 token
= next_token (&val
, cfile
);
1156 if (token
!= LIMIT
) {
1157 parse_warn ("expecting \"limit\"");
1159 skip_to_semi (cfile
);
1162 token
= next_token (&val
, cfile
);
1163 if (token
!= NUMBER
) {
1164 parse_warn ("expecting a number");
1166 skip_to_semi (cfile
);
1169 class -> lease_limit
= atoi (val
);
1170 class -> billed_leases
=
1171 dmalloc (class -> lease_limit
*
1172 sizeof (struct lease
*),
1173 "check_collection");
1174 if (!class -> billed_leases
)
1175 log_fatal ("no memory for billed leases.");
1176 memset (class -> billed_leases
, 0,
1177 (class -> lease_limit
*
1178 sizeof class -> billed_leases
));
1179 have_billing_classes
= 1;
1182 declaration
= parse_statement (cfile
, class -> group
,
1184 (struct host_decl
*)0,
1188 if (type
== 2 && new) {
1189 if (!collections
-> classes
)
1190 collections
-> classes
= class;
1193 for (cp
= collections
-> classes
;
1194 cp
-> nic
; cp
= cp
-> nic
)
1202 /* shared-network-declaration :==
1203 hostname LBRACE declarations parameters RBRACE */
1205 void parse_shared_net_declaration (cfile
, group
)
1207 struct group
*group
;
1210 enum dhcp_token token
;
1211 struct shared_network
*share
;
1213 int declaration
= 0;
1215 share
= new_shared_network ("parse_shared_net_declaration");
1217 log_fatal ("No memory for shared subnet");
1218 share
-> pools
= (struct pool
*)0;
1219 share
-> next
= (struct shared_network
*)0;
1220 share
-> interface
= (struct interface_info
*)0;
1221 share
-> group
= clone_group (group
, "parse_shared_net_declaration");
1222 share
-> group
-> shared_network
= share
;
1224 /* Get the name of the shared network... */
1225 token
= peek_token (&val
, cfile
);
1226 if (token
== STRING
) {
1227 token
= next_token (&val
, cfile
);
1230 parse_warn ("zero-length shared network name");
1231 val
= "<no-name-given>";
1233 name
= malloc (strlen (val
) + 1);
1235 log_fatal ("no memory for shared network name");
1238 name
= parse_host_name (cfile
);
1242 share
-> name
= name
;
1244 if (!parse_lbrace (cfile
))
1248 token
= peek_token (&val
, cfile
);
1249 if (token
== RBRACE
) {
1250 token
= next_token (&val
, cfile
);
1251 if (!share
-> subnets
) {
1252 parse_warn ("empty shared-network decl");
1255 enter_shared_network (share
);
1257 } else if (token
== EOF
) {
1258 token
= next_token (&val
, cfile
);
1259 parse_warn ("unexpected end of file");
1263 declaration
= parse_statement (cfile
, share
-> group
,
1265 (struct host_decl
*)0,
1270 /* subnet-declaration :==
1271 net NETMASK netmask RBRACE parameters declarations LBRACE */
1273 void parse_subnet_declaration (cfile
, share
)
1275 struct shared_network
*share
;
1278 enum dhcp_token token
;
1279 struct subnet
*subnet
, *t
, *u
;
1281 unsigned char addr
[4];
1282 int len
= sizeof addr
;
1283 int declaration
= 0;
1285 subnet
= new_subnet ("parse_subnet_declaration");
1287 log_fatal ("No memory for new subnet");
1288 subnet
-> shared_network
= share
;
1289 subnet
-> group
= clone_group (share
-> group
,
1290 "parse_subnet_declaration");
1291 subnet
-> group
-> subnet
= subnet
;
1293 /* Get the network number... */
1294 if (!parse_numeric_aggregate (cfile
, addr
, &len
, DOT
, 10, 8))
1296 memcpy (iaddr
.iabuf
, addr
, len
);
1298 subnet
-> net
= iaddr
;
1300 token
= next_token (&val
, cfile
);
1301 if (token
!= NETMASK
) {
1302 parse_warn ("Expecting netmask");
1303 skip_to_semi (cfile
);
1307 /* Get the netmask... */
1308 if (!parse_numeric_aggregate (cfile
, addr
, &len
, DOT
, 10, 8))
1310 memcpy (iaddr
.iabuf
, addr
, len
);
1312 subnet
-> netmask
= iaddr
;
1314 enter_subnet (subnet
);
1316 if (!parse_lbrace (cfile
))
1320 token
= peek_token (&val
, cfile
);
1321 if (token
== RBRACE
) {
1322 token
= next_token (&val
, cfile
);
1324 } else if (token
== EOF
) {
1325 token
= next_token (&val
, cfile
);
1326 parse_warn ("unexpected end of file");
1329 declaration
= parse_statement (cfile
, subnet
-> group
,
1331 (struct host_decl
*)0,
1335 /* Add the subnet to the list of subnets in this shared net. */
1336 if (!share
-> subnets
)
1337 share
-> subnets
= subnet
;
1339 u
= (struct subnet
*)0;
1340 for (t
= share
-> subnets
;
1341 t
-> next_sibling
; t
= t
-> next_sibling
) {
1342 if (subnet_inner_than (subnet
, t
, 0)) {
1344 u
-> next_sibling
= subnet
;
1346 share
-> subnets
= subnet
;
1347 subnet
-> next_sibling
= t
;
1352 t
-> next_sibling
= subnet
;
1356 /* group-declaration :== RBRACE parameters declarations LBRACE */
1358 void parse_group_declaration (cfile
, group
)
1360 struct group
*group
;
1363 enum dhcp_token token
;
1365 int declaration
= 0;
1367 g
= clone_group (group
, "parse_group_declaration");
1369 if (!parse_lbrace (cfile
))
1373 token
= peek_token (&val
, cfile
);
1374 if (token
== RBRACE
) {
1375 token
= next_token (&val
, cfile
);
1377 } else if (token
== EOF
) {
1378 token
= next_token (&val
, cfile
);
1379 parse_warn ("unexpected end of file");
1382 declaration
= parse_statement (cfile
, g
, GROUP_DECL
,
1383 (struct host_decl
*)0,
1388 /* fixed-addr-parameter :== ip-addrs-or-hostnames SEMI
1389 ip-addrs-or-hostnames :== ip-addr-or-hostname
1390 | ip-addrs-or-hostnames ip-addr-or-hostname */
1392 int parse_fixed_addr_param (oc
, cfile
)
1393 struct option_cache
**oc
;
1397 enum dhcp_token token
;
1398 struct expression
*expr
= (struct expression
*)0;
1399 struct expression
*tmp
, *new;
1403 tmp
= (struct expression
*)0;
1404 if (parse_ip_addr_or_hostname (&tmp
, cfile
, 1)) {
1406 new = (struct expression
*)0;
1407 status
= make_concat (&new, expr
, tmp
);
1408 expression_dereference
1409 (&expr
, "parse_fixed_addr_param");
1410 expression_dereference
1411 (&tmp
, "parse_fixed_addr_param");
1419 expression_dereference
1420 (&expr
, "parse_fixed_addr_param");
1423 token
= peek_token (&val
, cfile
);
1425 token
= next_token (&val
, cfile
);
1426 } while (token
== COMMA
);
1428 if (!parse_semi (cfile
)) {
1430 expression_dereference (&expr
,
1431 "parse_fixed_addr_param");
1434 status
= option_cache (oc
, (struct data_string
*)0, expr
,
1435 (struct option
*)0);
1436 expression_dereference (&expr
, "parse_fixed_addr_param");
1440 /* timestamp :== date
1442 Timestamps are actually not used in dhcpd.conf, which is a static file,
1443 but rather in the database file and the journal file. (Okay, actually
1444 they're not even used there yet). */
1446 TIME
parse_timestamp (cfile
)
1451 rv
= parse_date (cfile
);
1455 /* lease_declaration :== LEASE ip_address LBRACE lease_parameters RBRACE
1457 lease_parameters :== <nil>
1459 | lease_parameters lease_parameter
1461 lease_parameter :== STARTS date
1464 | HARDWARE hardware-parameter
1465 | UID hex_numbers SEMI
1466 | HOSTNAME hostname SEMI
1467 | CLIENT_HOSTNAME hostname SEMI
1468 | CLASS identifier SEMI
1469 | DYNAMIC_BOOTP SEMI */
1471 struct lease
*parse_lease_declaration (cfile
)
1475 enum dhcp_token token
;
1476 unsigned char addr
[4];
1477 int len
= sizeof addr
;
1481 static struct lease lease
;
1483 /* Zap the lease structure... */
1484 memset (&lease
, 0, sizeof lease
);
1486 /* Get the address for which the lease has been issued. */
1487 if (!parse_numeric_aggregate (cfile
, addr
, &len
, DOT
, 10, 8))
1488 return (struct lease
*)0;
1489 memcpy (lease
.ip_addr
.iabuf
, addr
, len
);
1490 lease
.ip_addr
.len
= len
;
1492 if (!parse_lbrace (cfile
))
1493 return (struct lease
*)0;
1496 token
= next_token (&val
, cfile
);
1497 if (token
== RBRACE
)
1499 else if (token
== EOF
) {
1500 parse_warn ("unexpected end of file");
1503 strncpy (tbuf
, val
, sizeof tbuf
);
1504 tbuf
[(sizeof tbuf
) - 1] = 0;
1506 /* Parse any of the times associated with the lease. */
1507 if (token
== STARTS
|| token
== ENDS
|| token
== TIMESTAMP
) {
1509 t
= parse_date (cfile
);
1523 lease
.timestamp
= t
;
1533 /* Colon-seperated hexadecimal octets... */
1536 token
= peek_token (&val
, cfile
);
1537 if (token
== STRING
) {
1538 token
= next_token (&val
, cfile
);
1539 lease
.uid_len
= strlen (val
) + 1;
1540 lease
.uid
= (unsigned char *)
1541 malloc (lease
.uid_len
);
1543 log_error ("no space for uid");
1544 return (struct lease
*)0;
1546 memcpy (lease
.uid
, val
, lease
.uid_len
);
1549 lease
.uid
= parse_numeric_aggregate
1550 (cfile
, (unsigned char *)0,
1551 &lease
.uid_len
, ':', 16, 8);
1553 log_error ("no space for uid");
1554 return (struct lease
*)0;
1556 if (lease
.uid_len
== 0) {
1557 lease
.uid
= (unsigned char *)0;
1558 parse_warn ("zero-length uid");
1564 log_fatal ("No memory for lease uid");
1570 token
= next_token (&val
, cfile
);
1571 if (!is_identifier (token
)) {
1573 skip_to_semi (cfile
);
1574 return (struct lease
*)0;
1576 /* for now, we aren't using this. */
1581 parse_hardware_param (cfile
,
1582 &lease
.hardware_addr
);
1587 lease
.flags
|= BOOTP_LEASE
;
1592 lease
.flags
|= ABANDONED_LEASE
;
1597 token
= peek_token (&val
, cfile
);
1598 if (token
== STRING
)
1599 lease
.hostname
= parse_string (cfile
);
1602 parse_host_name (cfile
);
1603 if (!lease
.hostname
) {
1605 return (struct lease
*)0;
1609 case CLIENT_HOSTNAME
:
1611 token
= peek_token (&val
, cfile
);
1612 if (token
== STRING
)
1613 lease
.client_hostname
=
1614 parse_string (cfile
);
1616 lease
.client_hostname
=
1617 parse_host_name (cfile
);
1622 token
= next_token (&val
, cfile
);
1623 if (token
== CLASS
) {
1624 token
= next_token (&val
, cfile
);
1625 if (token
!= STRING
) {
1627 ("expecting string");
1629 skip_to_semi (cfile
);
1633 lease
.billing_class
= find_class (val
);
1634 if (!lease
.billing_class
)
1635 parse_warn ("unknown class %s",
1638 } else if (token
== SUBCLASS
) {
1639 lease
.billing_class
=
1640 parse_class_declaration
1641 (cfile
, (struct group
*)0, 3);
1643 parse_warn ("expecting \"class\"");
1645 skip_to_semi (cfile
);
1651 skip_to_semi (cfile
);
1653 return (struct lease
*)0;
1656 if (token
!= HARDWARE
&& token
!= STRING
1657 && token
!= BILLING
) {
1658 token
= next_token (&val
, cfile
);
1659 if (token
!= SEMI
) {
1660 parse_warn ("semicolon expected.");
1661 skip_to_semi (cfile
);
1662 return (struct lease
*)0;
1666 if (seenmask
& seenbit
) {
1667 parse_warn ("Too many %s parameters in lease %s\n",
1668 tbuf
, piaddr (lease
.ip_addr
));
1670 seenmask
|= seenbit
;
1676 /* address-range-declaration :== ip-address ip-address SEMI
1677 | DYNAMIC_BOOTP ip-address ip-address SEMI */
1679 void parse_address_range (cfile
, group
, type
, pool
)
1681 struct group
*group
;
1685 struct iaddr low
, high
, net
;
1686 unsigned char addr
[4];
1687 int len
= sizeof addr
;
1688 enum dhcp_token token
;
1691 struct subnet
*subnet
;
1692 struct shared_network
*share
;
1695 if ((token
= peek_token (&val
, cfile
)) == DYNAMIC_BOOTP
) {
1696 token
= next_token (&val
, cfile
);
1700 /* Get the bottom address in the range... */
1701 if (!parse_numeric_aggregate (cfile
, addr
, &len
, DOT
, 10, 8))
1703 memcpy (low
.iabuf
, addr
, len
);
1706 /* Only one address? */
1707 token
= peek_token (&val
, cfile
);
1711 /* Get the top address in the range... */
1712 if (!parse_numeric_aggregate (cfile
, addr
, &len
, DOT
, 10, 8))
1714 memcpy (high
.iabuf
, addr
, len
);
1718 token
= next_token (&val
, cfile
);
1719 if (token
!= SEMI
) {
1720 parse_warn ("semicolon expected.");
1721 skip_to_semi (cfile
);
1725 if (type
== SUBNET_DECL
) {
1726 subnet
= group
-> subnet
;
1727 share
= subnet
-> shared_network
;
1729 share
= group
-> shared_network
;
1730 for (subnet
= share
-> subnets
;
1731 subnet
; subnet
= subnet
-> next_sibling
) {
1732 net
= subnet_number (low
, subnet
-> netmask
);
1733 if (addr_eq (low
, subnet
-> net
))
1737 parse_warn ("address range not on network %s",
1738 group
-> shared_network
-> name
);
1745 /* If we're permitting dynamic bootp for this range,
1746 then look for a pool with an empty prohibit list and
1747 a permit list with one entry which permits dynamic
1749 for (pool
= share
-> pools
; pool
; pool
= pool
-> next
) {
1751 !pool
-> permit_list
&& !pool
-> prohibit_list
) ||
1753 !pool
-> prohibit_list
&&
1754 pool
-> permit_list
&&
1755 !pool
-> permit_list
-> next
&&
1756 (pool
-> permit_list
-> type
==
1757 permit_dynamic_bootp_clients
))) {
1763 /* If we didn't get a pool, make one. */
1765 pool
= new_pool ("parse_address_range");
1767 log_fatal ("no memory for ad-hoc pool.");
1769 pool
-> permit_list
=
1770 new_permit ("parse_address_range");
1771 if (!pool
-> permit_list
)
1772 log_fatal ("no memory for ad-hoc permit.");
1773 pool
-> permit_list
-> type
=
1774 permit_dynamic_bootp_clients
;
1777 last
-> next
= pool
;
1779 share
-> pools
= pool
;
1780 pool
-> shared_network
= share
;
1781 pool
-> group
= clone_group (share
-> group
,
1782 "parse_address_range");
1786 /* Create the new address range... */
1787 new_address_range (low
, high
, subnet
, pool
);