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
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
* ``http://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);
505
status = parse_option_name(cfile, 1, &known, &option);
506
if (status != ISC_R_SUCCESS || option == NULL)
509
token = next_token (&val, (unsigned *)0, cfile);
511
parse_warn (cfile, "expecting \"code\" keyword.");
512
skip_to_semi (cfile);
513
option_dereference(&option, MDL);
518
"option definitions may only appear in %s",
519
"the outermost scope.");
520
skip_to_semi (cfile);
521
option_dereference(&option, MDL);
524
parse_option_code_definition(cfile, option);
525
option_dereference(&option, MDL);
529
token = next_token (&val, (unsigned *)0, cfile);
530
parse_string_list (cfile, &config -> media, 1);
534
token = next_token (&val, (unsigned *)0, cfile);
536
parse_hardware_param (cfile, &ip -> hw_address);
538
parse_warn (cfile, "hardware address parameter %s",
539
"not allowed here.");
540
skip_to_semi (cfile);
545
token = next_token (&val, (unsigned *)0, cfile);
546
if (config -> requested_options == default_requested_options)
547
config -> requested_options = NULL;
548
parse_option_list (cfile, &config -> requested_options);
552
token = next_token (&val, (unsigned *)0, cfile);
553
parse_lease_time (cfile, &config -> timeout);
557
token = next_token (&val, (unsigned *)0, cfile);
558
parse_lease_time (cfile, &config -> retry_interval);
562
token = next_token (&val, (unsigned *)0, cfile);
563
parse_lease_time (cfile, &config -> select_interval);
567
token = next_token (&val, (unsigned *)0, cfile);
568
token = next_token (&val, (unsigned *)0, cfile);
571
"unexpected omapi subtype: %s", val);
572
skip_to_semi (cfile);
575
token = next_token (&val, (unsigned *)0, cfile);
576
if (token != NUMBER) {
577
parse_warn (cfile, "invalid port number: `%s'", val);
578
skip_to_semi (cfile);
582
if (tmp < 0 || tmp > 65535)
583
parse_warn (cfile, "invalid omapi port %d.", tmp);
584
else if (config != &top_level_config)
586
"omapi port only works at top level.");
588
config -> omapi_port = tmp;
592
case DO_FORWARD_UPDATE:
593
token = next_token (&val, (unsigned *)0, cfile);
594
token = next_token (&val, (unsigned *)0, cfile);
595
if (!strcasecmp (val, "on") ||
596
!strcasecmp (val, "true"))
597
config -> do_forward_update = 1;
598
else if (!strcasecmp (val, "off") ||
599
!strcasecmp (val, "false"))
600
config -> do_forward_update = 0;
602
parse_warn (cfile, "expecting boolean value.");
603
skip_to_semi (cfile);
610
token = next_token (&val, (unsigned *)0, cfile);
611
parse_lease_time (cfile, &config -> reboot_timeout);
615
token = next_token (&val, (unsigned *)0, cfile);
616
parse_lease_time (cfile, &config -> backoff_cutoff);
619
case INITIAL_INTERVAL:
620
token = next_token (&val, (unsigned *)0, cfile);
621
parse_lease_time (cfile, &config -> initial_interval);
625
token = next_token (&val, (unsigned *)0, cfile);
626
parse_string (cfile, &config -> script_name, (unsigned *)0);
630
token = next_token (&val, (unsigned *)0, cfile);
631
token = next_token (&val, (unsigned *)0, cfile);
632
if (token != OPTION) {
633
parse_warn (cfile, "expecting 'vendor option space'");
634
skip_to_semi (cfile);
637
token = next_token (&val, (unsigned *)0, cfile);
638
if (token != SPACE) {
639
parse_warn (cfile, "expecting 'vendor option space'");
640
skip_to_semi (cfile);
643
token = next_token (&val, (unsigned *)0, cfile);
644
if (!is_identifier (token)) {
645
parse_warn (cfile, "expecting an identifier.");
646
skip_to_semi (cfile);
649
config -> vendor_space_name = dmalloc (strlen (val) + 1, MDL);
650
if (!config -> vendor_space_name)
651
log_fatal ("no memory for vendor option space name.");
652
strcpy (config -> vendor_space_name, val);
653
for (i = 0; i < universe_count; i++)
654
if (!strcmp (universes [i] -> name,
655
config -> vendor_space_name))
657
if (i == universe_count) {
658
log_error ("vendor option space %s not found.",
659
config -> vendor_space_name);
665
token = next_token (&val, (unsigned *)0, cfile);
667
parse_warn (cfile, "nested interface declaration.");
668
parse_interface_declaration (cfile, config, (char *)0);
672
token = next_token (&val, (unsigned *)0, cfile);
673
token = next_token (&val, (unsigned *)0, cfile);
674
name = dmalloc (strlen (val) + 1, MDL);
676
log_fatal ("no memory for pseudo interface name");
678
parse_interface_declaration (cfile, config, name);
682
token = next_token (&val, (unsigned *)0, cfile);
683
parse_client_lease_statement (cfile, 1);
687
token = next_token (&val, (unsigned *)0, cfile);
688
parse_client_lease_statement (cfile, 2);
692
token = next_token (&val, (unsigned *)0, cfile);
693
parse_reject_statement (cfile, config);
698
stmt = (struct executable_statement *)0;
699
if (!parse_executable_statement (&stmt,
700
cfile, &lose, context_any)) {
702
parse_warn (cfile, "expecting a statement.");
703
skip_to_semi (cfile);
706
struct executable_statement **eptr, *sptr;
708
(stmt -> op == send_option_statement ||
709
(stmt -> op == on_statement &&
710
(stmt -> data.on.evtypes & ON_TRANSMISSION)))) {
711
eptr = &config -> on_transmission -> statements;
712
if (stmt -> op == on_statement) {
713
sptr = (struct executable_statement *)0;
714
executable_statement_reference
716
stmt -> data.on.statements, MDL);
717
executable_statement_dereference (&stmt,
719
executable_statement_reference (&stmt,
722
executable_statement_dereference (&sptr,
726
eptr = &config -> on_receipt -> statements;
729
for (; *eptr; eptr = &(*eptr) -> next)
731
executable_statement_reference (eptr,
741
/* option-list :== option_name |
742
option_list COMMA option_name */
745
parse_option_list(struct parse *cfile, struct option ***list)
750
pair p = (pair)0, q = (pair)0, r;
751
struct option *option = NULL;
756
token = peek_token (&val, (unsigned *)0, cfile);
758
token = next_token (&val, (unsigned *)0, cfile);
761
if (!is_identifier (token)) {
762
parse_warn (cfile, "%s: expected option name.", val);
763
token = next_token (&val, (unsigned *)0, cfile);
764
skip_to_semi (cfile);
767
status = parse_option_name(cfile, 0, NULL, &option);
768
if (status != ISC_R_SUCCESS || option == NULL) {
769
parse_warn (cfile, "%s: expected option name.", val);
774
log_fatal ("can't allocate pair for option code.");
775
/* XXX: we should probably carry a reference across this */
776
r->car = (caddr_t)option;
777
option_dereference(&option, MDL);
785
token = next_token (&val, (unsigned *)0, cfile);
786
} while (token == COMMA);
788
parse_warn (cfile, "expecting semicolon.");
789
skip_to_semi (cfile);
792
/* XXX we can't free the list here, because we may have copied
793
XXX it from an outer config state. */
796
*list = dmalloc ((ix + 1) * sizeof(struct option *), MDL);
798
log_error ("no memory for option list.");
801
for (q = p; q; q = q -> cdr)
802
option_reference(&(*list)[ix++],
803
(struct option *)q->car, MDL);
816
/* interface-declaration :==
817
INTERFACE string LBRACE client-declarations RBRACE */
819
void parse_interface_declaration (cfile, outer_config, name)
821
struct client_config *outer_config;
826
struct client_state *client, **cp;
827
struct interface_info *ip = (struct interface_info *)0;
829
token = next_token (&val, (unsigned *)0, cfile);
830
if (token != STRING) {
831
parse_warn (cfile, "expecting interface name (in quotes).");
832
skip_to_semi (cfile);
836
if (!interface_or_dummy (&ip, val))
837
log_fatal ("Can't allocate interface %s.", val);
839
/* If we were given a name, this is a pseudo-interface. */
841
make_client_state (&client);
842
client -> name = name;
843
client -> interface = ip;
844
for (cp = &ip -> client; *cp; cp = &((*cp) -> next))
849
make_client_state (&ip -> client);
850
ip -> client -> interface = ip;
852
client = ip -> client;
855
if (!client -> config)
856
make_client_config (client, outer_config);
858
ip -> flags &= ~INTERFACE_AUTOMATIC;
859
interfaces_requested = 1;
861
token = next_token (&val, (unsigned *)0, cfile);
862
if (token != LBRACE) {
863
parse_warn (cfile, "expecting left brace.");
864
skip_to_semi (cfile);
869
token = peek_token (&val, (unsigned *)0, cfile);
870
if (token == END_OF_FILE) {
872
"unterminated interface declaration.");
877
parse_client_statement (cfile, ip, client -> config);
879
token = next_token (&val, (unsigned *)0, cfile);
882
int interface_or_dummy (struct interface_info **pi, const char *name)
884
struct interface_info *i;
885
struct interface_info *ip = (struct interface_info *)0;
888
/* Find the interface (if any) that matches the name. */
889
for (i = interfaces; i; i = i -> next) {
890
if (!strcmp (i -> name, name)) {
891
interface_reference (&ip, i, MDL);
896
/* If it's not a real interface, see if it's on the dummy list. */
898
for (ip = dummy_interfaces; ip; ip = ip -> next) {
899
if (!strcmp (ip -> name, name)) {
900
interface_reference (&ip, i, MDL);
906
/* If we didn't find an interface, make a dummy interface as
909
if ((status = interface_allocate (&ip, MDL)) != ISC_R_SUCCESS)
910
log_fatal ("Can't record interface %s: %s",
911
name, isc_result_totext (status));
913
if (strlen(name) >= sizeof(ip->name)) {
914
interface_dereference(&ip, MDL);
917
strcpy(ip->name, name);
919
if (dummy_interfaces) {
920
interface_reference (&ip -> next,
921
dummy_interfaces, MDL);
922
interface_dereference (&dummy_interfaces, MDL);
924
interface_reference (&dummy_interfaces, ip, MDL);
927
status = interface_reference (pi, ip, MDL);
929
status = ISC_R_FAILURE;
930
interface_dereference (&ip, MDL);
931
if (status != ISC_R_SUCCESS)
936
void make_client_state (state)
937
struct client_state **state;
939
*state = ((struct client_state *)dmalloc (sizeof **state, MDL));
941
log_fatal ("no memory for client state\n");
942
memset (*state, 0, sizeof **state);
945
void make_client_config (client, config)
946
struct client_state *client;
947
struct client_config *config;
949
client -> config = (((struct client_config *)
950
dmalloc (sizeof (struct client_config), MDL)));
951
if (!client -> config)
952
log_fatal ("no memory for client config\n");
953
memcpy (client -> config, config, sizeof *config);
954
if (!clone_group (&client -> config -> on_receipt,
955
config -> on_receipt, MDL) ||
956
!clone_group (&client -> config -> on_transmission,
957
config -> on_transmission, MDL))
958
log_fatal ("no memory for client state groups.");
961
/* client-lease-statement :==
962
LBRACE client-lease-declarations RBRACE
964
client-lease-declarations :==
966
client-lease-declaration |
967
client-lease-declarations client-lease-declaration */
970
void parse_client_lease_statement (cfile, is_static)
974
struct client_lease *lease, *lp, *pl, *next;
975
struct interface_info *ip = (struct interface_info *)0;
978
struct client_state *client = (struct client_state *)0;
980
token = next_token (&val, (unsigned *)0, cfile);
981
if (token != LBRACE) {
982
parse_warn (cfile, "expecting left brace.");
983
skip_to_semi (cfile);
987
lease = ((struct client_lease *)
988
dmalloc (sizeof (struct client_lease), MDL));
990
log_fatal ("no memory for lease.\n");
991
memset (lease, 0, sizeof *lease);
992
lease -> is_static = is_static;
993
if (!option_state_allocate (&lease -> options, MDL))
994
log_fatal ("no memory for lease options.\n");
997
token = peek_token (&val, (unsigned *)0, cfile);
998
if (token == END_OF_FILE) {
999
parse_warn (cfile, "unterminated lease declaration.");
1002
if (token == RBRACE)
1004
parse_client_lease_declaration (cfile, lease, &ip, &client);
1006
token = next_token (&val, (unsigned *)0, cfile);
1008
/* If the lease declaration didn't include an interface
1009
declaration that we recognized, it's of no use to us. */
1011
destroy_client_lease (lease);
1015
/* Make sure there's a client state structure... */
1016
if (!ip -> client) {
1017
make_client_state (&ip -> client);
1018
ip -> client -> interface = ip;
1021
client = ip -> client;
1023
/* If this is an alias lease, it doesn't need to be sorted in. */
1024
if (is_static == 2) {
1025
ip -> client -> alias = lease;
1029
/* The new lease may supersede a lease that's not the
1030
active lease but is still on the lease list, so scan the
1031
lease list looking for a lease with the same address, and
1032
if we find it, toss it. */
1033
pl = (struct client_lease *)0;
1034
for (lp = client -> leases; lp; lp = next) {
1036
if (lp -> address.len == lease -> address.len &&
1037
!memcmp (lp -> address.iabuf, lease -> address.iabuf,
1038
lease -> address.len)) {
1042
client -> leases = next;
1043
destroy_client_lease (lp);
1049
/* If this is a preloaded lease, just put it on the list of recorded
1050
leases - don't make it the active lease. */
1052
lease -> next = client -> leases;
1053
client -> leases = lease;
1057
/* The last lease in the lease file on a particular interface is
1058
the active lease for that interface. Of course, we don't know
1059
what the last lease in the file is until we've parsed the whole
1060
file, so at this point, we assume that the lease we just parsed
1061
is the active lease for its interface. If there's already
1062
an active lease for the interface, and this lease is for the same
1063
ip address, then we just toss the old active lease and replace
1064
it with this one. If this lease is for a different address,
1065
then if the old active lease has expired, we dump it; if not,
1066
we put it on the list of leases for this interface which are
1067
still valid but no longer active. */
1068
if (client -> active) {
1069
if (client -> active -> expiry < cur_time)
1070
destroy_client_lease (client -> active);
1071
else if (client -> active -> address.len ==
1072
lease -> address.len &&
1073
!memcmp (client -> active -> address.iabuf,
1074
lease -> address.iabuf,
1075
lease -> address.len))
1076
destroy_client_lease (client -> active);
1078
client -> active -> next = client -> leases;
1079
client -> leases = client -> active;
1082
client -> active = lease;
1087
/* client-lease-declaration :==
1090
FIXED_ADDR ip_address |
1092
SERVER_NAME string |
1093
OPTION option-decl |
1099
void parse_client_lease_declaration (cfile, lease, ipp, clientp)
1100
struct parse *cfile;
1101
struct client_lease *lease;
1102
struct interface_info **ipp;
1103
struct client_state **clientp;
1107
struct interface_info *ip;
1108
struct option_cache *oc;
1109
struct client_state *client = (struct client_state *)0;
1111
switch (next_token (&val, (unsigned *)0, cfile)) {
1113
token = next_token (&val, (unsigned *)0, cfile);
1114
if (token != STRING && !is_identifier (token)) {
1115
parse_warn (cfile, "expecting key name.");
1116
skip_to_semi (cfile);
1119
if (omapi_auth_key_lookup_name (&lease -> key, val) !=
1121
parse_warn (cfile, "unknown key %s", val);
1125
lease -> is_bootp = 1;
1129
token = next_token (&val, (unsigned *)0, cfile);
1130
if (token != STRING) {
1132
"expecting interface name (in quotes).");
1133
skip_to_semi (cfile);
1136
if (!interface_or_dummy (ipp, val))
1137
log_fatal ("Can't allocate interface %s.", val);
1141
token = next_token (&val, (unsigned *)0, cfile);
1144
parse_warn (cfile, "state name precedes interface.");
1147
for (client = ip -> client; client; client = client -> next)
1148
if (client -> name && !strcmp (client -> name, val))
1152
"lease specified for unknown pseudo.");
1157
if (!parse_ip_addr (cfile, &lease -> address))
1162
parse_string_list (cfile, &lease -> medium, 0);
1166
parse_string (cfile, &lease -> filename, (unsigned *)0);
1170
parse_string (cfile, &lease -> server_name, (unsigned *)0);
1174
lease -> renewal = parse_date (cfile);
1178
lease -> rebind = parse_date (cfile);
1182
lease -> expiry = parse_date (cfile);
1186
oc = (struct option_cache *)0;
1187
if (parse_option_decl (&oc, cfile)) {
1188
save_option(oc->option->universe, lease->options, oc);
1189
option_cache_dereference (&oc, MDL);
1194
parse_warn (cfile, "expecting lease declaration.");
1195
skip_to_semi (cfile);
1198
token = next_token (&val, (unsigned *)0, cfile);
1199
if (token != SEMI) {
1200
parse_warn (cfile, "expecting semicolon.");
1201
skip_to_semi (cfile);
1205
/* Parse a default-duid ""; statement.
1208
parse_client_default_duid(struct parse *cfile)
1210
struct data_string new_duid;
1211
const char *val = NULL;
1215
memset(&new_duid, 0, sizeof(new_duid));
1217
token = next_token(&val, &len, cfile);
1218
if (token != STRING) {
1219
parse_warn(cfile, "Expected DUID string.");
1220
skip_to_semi(cfile);
1225
parse_warn(cfile, "Invalid DUID contents.");
1226
skip_to_semi(cfile);
1230
if (!buffer_allocate(&new_duid.buffer, len, MDL)) {
1231
parse_warn(cfile, "Out of memory parsing default DUID.");
1232
skip_to_semi(cfile);
1235
new_duid.data = new_duid.buffer->data;
1238
memcpy(new_duid.buffer->data, val, len);
1240
/* Rotate the last entry into place. */
1241
if (default_duid.buffer != NULL)
1242
data_string_forget(&default_duid, MDL);
1243
data_string_copy(&default_duid, &new_duid, MDL);
1244
data_string_forget(&new_duid, MDL);
1249
/* Parse a lease6 {} construct. The v6 client is a little different
1250
* than the v4 client today, in that it only retains one lease, the
1251
* active lease, and discards any less recent information. It may
1252
* be useful in the future to cache additional information, but it
1253
* is not worth the effort for the moment.
1256
parse_client6_lease_statement(struct parse *cfile)
1258
#if !defined(DHCPv6)
1259
parse_warn(cfile, "No DHCPv6 support.");
1260
skip_to_semi(cfile);
1261
#else /* defined(DHCPv6) */
1262
struct option_cache *oc = NULL;
1263
struct dhc6_lease *lease;
1264
struct dhc6_ia **ia;
1265
struct client_state *client = NULL;
1266
struct interface_info *iface = NULL;
1267
struct data_string ds;
1270
int token, has_ia, no_semi, has_name;
1272
token = next_token(NULL, NULL, cfile);
1273
if (token != LBRACE) {
1274
parse_warn(cfile, "Expecting open curly brace.");
1275
skip_to_semi(cfile);
1279
lease = dmalloc(sizeof(*lease), MDL);
1280
if (lease == NULL) {
1281
parse_warn(cfile, "Unable to allocate lease state.");
1282
skip_to_rbrace(cfile, 1);
1286
option_state_allocate(&lease->options, MDL);
1287
if (lease->options == NULL) {
1288
parse_warn(cfile, "Unable to allocate option cache.");
1289
skip_to_rbrace(cfile, 1);
1296
ia = &lease->bindings;
1297
token = next_token(&val, NULL, cfile);
1298
while (token != RBRACE) {
1303
*ia = parse_client6_ia_na_statement(cfile);
1314
*ia = parse_client6_ia_ta_statement(cfile);
1325
*ia = parse_client6_ia_pd_statement(cfile);
1336
if (iface != NULL) {
1337
parse_warn(cfile, "Multiple interface names?");
1338
skip_to_semi(cfile);
1343
token = next_token(&val, &len, cfile);
1344
if (token != STRING) {
1346
parse_warn(cfile, "Expecting a string.");
1347
skip_to_semi(cfile);
1352
for (iface = interfaces ; iface != NULL ;
1353
iface = iface->next) {
1354
if (strcmp(iface->name, val) == 0)
1358
if (iface == NULL) {
1359
parse_warn(cfile, "Unknown interface.");
1368
if (client != NULL) {
1369
parse_warn(cfile, "Multiple state names?");
1370
skip_to_semi(cfile);
1375
if (iface == NULL) {
1376
parse_warn(cfile, "Client name without "
1378
skip_to_semi(cfile);
1383
token = next_token(&val, &len, cfile);
1384
if (token != STRING)
1387
for (client = iface->client ; client != NULL ;
1388
client = client->next) {
1389
if ((client->name != NULL) &&
1390
(strcmp(client->name, val) == 0))
1394
if (client == NULL) {
1395
parse_warn(cfile, "Unknown client state %s.",
1403
if (parse_option_decl(&oc, cfile)) {
1404
save_option(oc->option->universe,
1405
lease->options, oc);
1406
option_cache_dereference(&oc, MDL);
1411
case TOKEN_RELEASED:
1412
case TOKEN_ABANDONED:
1413
lease->released = ISC_TRUE;
1417
parse_warn(cfile, "Unexpected token, %s.", val);
1419
skip_to_semi(cfile);
1426
token = next_token(&val, NULL, cfile);
1428
if (token == END_OF_FILE) {
1429
parse_warn(cfile, "Unexpected end of file.");
1435
log_debug("Lease with no IA's discarded from lease db.");
1436
dhc6_lease_destroy(&lease, MDL);
1441
parse_warn(cfile, "Lease has no interface designation.");
1442
else if (!has_name && (client == NULL)) {
1443
for (client = iface->client ; client != NULL ;
1444
client = client->next) {
1445
if (client->name == NULL)
1450
if (client == NULL) {
1451
parse_warn(cfile, "No matching client state.");
1452
dhc6_lease_destroy(&lease, MDL);
1456
/* Fetch Preference option from option cache. */
1457
memset(&ds, 0, sizeof(ds));
1458
oc = lookup_option(&dhcpv6_universe, lease->options, D6O_PREFERENCE);
1460
evaluate_option_cache(&ds, NULL, NULL, NULL, lease->options,
1461
NULL, &global_scope, oc, MDL)) {
1463
log_error("Invalid length of DHCPv6 Preference option "
1464
"(%d != 1)", ds.len);
1465
data_string_forget(&ds, MDL);
1466
dhc6_lease_destroy(&lease, MDL);
1469
lease->pref = ds.data[0];
1471
data_string_forget(&ds, MDL);
1474
/* Fetch server-id option from option cache. */
1475
oc = lookup_option(&dhcpv6_universe, lease->options, D6O_SERVERID);
1477
!evaluate_option_cache(&lease->server_id, NULL, NULL, NULL,
1478
lease->options, NULL, &global_scope, oc,
1480
(lease->server_id.len == 0)) {
1481
/* This should be impossible... */
1482
log_error("Invalid SERVERID option cache.");
1483
dhc6_lease_destroy(&lease, MDL);
1487
if (client->active_lease != NULL)
1488
dhc6_lease_destroy(&client->active_lease, MDL);
1490
client->active_lease = lease;
1491
#endif /* defined(DHCPv6) */
1494
/* Parse an ia_na object from the client lease.
1497
static struct dhc6_ia *
1498
parse_client6_ia_na_statement(struct parse *cfile)
1500
struct data_string id;
1501
struct option_cache *oc = NULL;
1503
struct dhc6_addr **addr;
1507
ia = dmalloc(sizeof(*ia), MDL);
1509
parse_warn(cfile, "Out of memory allocating IA_NA state.");
1510
skip_to_semi(cfile);
1513
ia->ia_type = D6O_IA_NA;
1516
memset(&id, 0, sizeof(id));
1517
if (parse_cshl(&id, cfile)) {
1519
memcpy(ia->iaid, id.data, 4);
1521
parse_warn(cfile, "Expecting IAID of length 4, got %d.",
1523
skip_to_semi(cfile);
1527
data_string_forget(&id, MDL);
1529
parse_warn(cfile, "Expecting IAID.");
1530
skip_to_semi(cfile);
1535
token = next_token(NULL, NULL, cfile);
1536
if (token != LBRACE) {
1537
parse_warn(cfile, "Expecting open curly brace.");
1538
skip_to_semi(cfile);
1543
option_state_allocate(&ia->options, MDL);
1544
if (ia->options == NULL) {
1545
parse_warn(cfile, "Unable to allocate option state.");
1546
skip_to_rbrace(cfile, 1);
1552
token = next_token(&val, NULL, cfile);
1553
while (token != RBRACE) {
1558
token = next_token(&val, NULL, cfile);
1559
if (token == NUMBER) {
1560
ia->starts = atoi(val);
1562
parse_warn(cfile, "Expecting a number.");
1563
skip_to_semi(cfile);
1569
token = next_token(&val, NULL, cfile);
1570
if (token == NUMBER) {
1571
ia->renew = atoi(val);
1573
parse_warn(cfile, "Expecting a number.");
1574
skip_to_semi(cfile);
1580
token = next_token(&val, NULL, cfile);
1581
if (token == NUMBER) {
1582
ia->rebind = atoi(val);
1584
parse_warn(cfile, "Expecting a number.");
1585
skip_to_semi(cfile);
1591
*addr = parse_client6_iaaddr_statement(cfile);
1594
addr = &(*addr)->next;
1601
if (parse_option_decl(&oc, cfile)) {
1602
save_option(oc->option->universe,
1604
option_cache_dereference(&oc, MDL);
1610
parse_warn(cfile, "Unexpected token.");
1612
skip_to_semi(cfile);
1619
token = next_token(&val, NULL, cfile);
1621
if (token == END_OF_FILE) {
1622
parse_warn(cfile, "Unexpected end of file.");
1631
/* Parse an ia_ta object from the client lease.
1634
static struct dhc6_ia *
1635
parse_client6_ia_ta_statement(struct parse *cfile)
1637
struct data_string id;
1638
struct option_cache *oc = NULL;
1640
struct dhc6_addr **addr;
1644
ia = dmalloc(sizeof(*ia), MDL);
1646
parse_warn(cfile, "Out of memory allocating IA_TA state.");
1647
skip_to_semi(cfile);
1650
ia->ia_type = D6O_IA_TA;
1653
memset(&id, 0, sizeof(id));
1654
if (parse_cshl(&id, cfile)) {
1656
memcpy(ia->iaid, id.data, 4);
1658
parse_warn(cfile, "Expecting IAID of length 4, got %d.",
1660
skip_to_semi(cfile);
1664
data_string_forget(&id, MDL);
1666
parse_warn(cfile, "Expecting IAID.");
1667
skip_to_semi(cfile);
1672
token = next_token(NULL, NULL, cfile);
1673
if (token != LBRACE) {
1674
parse_warn(cfile, "Expecting open curly brace.");
1675
skip_to_semi(cfile);
1680
option_state_allocate(&ia->options, MDL);
1681
if (ia->options == NULL) {
1682
parse_warn(cfile, "Unable to allocate option state.");
1683
skip_to_rbrace(cfile, 1);
1689
token = next_token(&val, NULL, cfile);
1690
while (token != RBRACE) {
1695
token = next_token(&val, NULL, cfile);
1696
if (token == NUMBER) {
1697
ia->starts = atoi(val);
1699
parse_warn(cfile, "Expecting a number.");
1700
skip_to_semi(cfile);
1705
/* No RENEW or REBIND */
1708
*addr = parse_client6_iaaddr_statement(cfile);
1711
addr = &(*addr)->next;
1718
if (parse_option_decl(&oc, cfile)) {
1719
save_option(oc->option->universe,
1721
option_cache_dereference(&oc, MDL);
1727
parse_warn(cfile, "Unexpected token.");
1729
skip_to_semi(cfile);
1736
token = next_token(&val, NULL, cfile);
1738
if (token == END_OF_FILE) {
1739
parse_warn(cfile, "Unexpected end of file.");
1748
/* Parse an ia_pd object from the client lease.
1751
static struct dhc6_ia *
1752
parse_client6_ia_pd_statement(struct parse *cfile)
1754
struct data_string id;
1755
struct option_cache *oc = NULL;
1757
struct dhc6_addr **pref;
1761
ia = dmalloc(sizeof(*ia), MDL);
1763
parse_warn(cfile, "Out of memory allocating IA_PD state.");
1764
skip_to_semi(cfile);
1767
ia->ia_type = D6O_IA_PD;
1770
memset(&id, 0, sizeof(id));
1771
if (parse_cshl(&id, cfile)) {
1773
memcpy(ia->iaid, id.data, 4);
1775
parse_warn(cfile, "Expecting IAID of length 4, got %d.",
1777
skip_to_semi(cfile);
1781
data_string_forget(&id, MDL);
1783
parse_warn(cfile, "Expecting IAID.");
1784
skip_to_semi(cfile);
1789
token = next_token(NULL, NULL, cfile);
1790
if (token != LBRACE) {
1791
parse_warn(cfile, "Expecting open curly brace.");
1792
skip_to_semi(cfile);
1797
option_state_allocate(&ia->options, MDL);
1798
if (ia->options == NULL) {
1799
parse_warn(cfile, "Unable to allocate option state.");
1800
skip_to_rbrace(cfile, 1);
1806
token = next_token(&val, NULL, cfile);
1807
while (token != RBRACE) {
1812
token = next_token(&val, NULL, cfile);
1813
if (token == NUMBER) {
1814
ia->starts = atoi(val);
1816
parse_warn(cfile, "Expecting a number.");
1817
skip_to_semi(cfile);
1823
token = next_token(&val, NULL, cfile);
1824
if (token == NUMBER) {
1825
ia->renew = atoi(val);
1827
parse_warn(cfile, "Expecting a number.");
1828
skip_to_semi(cfile);
1834
token = next_token(&val, NULL, cfile);
1835
if (token == NUMBER) {
1836
ia->rebind = atoi(val);
1838
parse_warn(cfile, "Expecting a number.");
1839
skip_to_semi(cfile);
1845
*pref = parse_client6_iaprefix_statement(cfile);
1848
pref = &(*pref)->next;
1855
if (parse_option_decl(&oc, cfile)) {
1856
save_option(oc->option->universe,
1858
option_cache_dereference(&oc, MDL);
1864
parse_warn(cfile, "Unexpected token.");
1866
skip_to_semi(cfile);
1873
token = next_token(&val, NULL, cfile);
1875
if (token == END_OF_FILE) {
1876
parse_warn(cfile, "Unexpected end of file.");
1885
/* Parse an iaaddr {} structure. */
1887
static struct dhc6_addr *
1888
parse_client6_iaaddr_statement(struct parse *cfile)
1890
struct option_cache *oc = NULL;
1891
struct dhc6_addr *addr;
1895
addr = dmalloc(sizeof(*addr), MDL);
1897
parse_warn(cfile, "Unable to allocate IAADDR state.");
1898
skip_to_semi(cfile);
1902
/* Get IP address. */
1903
if (!parse_ip6_addr(cfile, &addr->address)) {
1904
skip_to_semi(cfile);
1909
token = next_token(NULL, NULL, cfile);
1910
if (token != LBRACE) {
1911
parse_warn(cfile, "Expecting open curly bracket.");
1912
skip_to_semi(cfile);
1917
option_state_allocate(&addr->options, MDL);
1918
if (addr->options == NULL) {
1919
parse_warn(cfile, "Unable to allocate option state.");
1920
skip_to_semi(cfile);
1925
token = next_token(&val, NULL, cfile);
1926
while (token != RBRACE) {
1931
token = next_token(&val, NULL, cfile);
1932
if (token == NUMBER) {
1933
addr->starts = atoi(val);
1935
parse_warn(cfile, "Expecting a number.");
1936
skip_to_semi(cfile);
1941
case PREFERRED_LIFE:
1942
token = next_token(&val, NULL, cfile);
1943
if (token == NUMBER) {
1944
addr->preferred_life = atoi(val);
1946
parse_warn(cfile, "Expecting a number.");
1947
skip_to_semi(cfile);
1953
token = next_token(&val, NULL, cfile);
1954
if (token == NUMBER) {
1955
addr->max_life = atoi(val);
1957
parse_warn(cfile, "Expecting a number.");
1958
skip_to_semi(cfile);
1964
if (parse_option_decl(&oc, cfile)) {
1965
save_option(oc->option->universe,
1967
option_cache_dereference(&oc, MDL);
1973
parse_warn(cfile, "Unexpected token.");
1974
skip_to_rbrace(cfile, 1);
1982
token = next_token(&val, NULL, cfile);
1983
if (token == END_OF_FILE) {
1984
parse_warn(cfile, "Unexpected end of file.");
1993
/* Parse an iaprefix {} structure. */
1995
static struct dhc6_addr *
1996
parse_client6_iaprefix_statement(struct parse *cfile)
1998
struct option_cache *oc = NULL;
1999
struct dhc6_addr *pref;
2003
pref = dmalloc(sizeof(*pref), MDL);
2005
parse_warn(cfile, "Unable to allocate IAPREFIX state.");
2006
skip_to_semi(cfile);
2010
/* Get IP prefix. */
2011
if (!parse_ip6_prefix(cfile, &pref->address, &pref->plen)) {
2012
skip_to_semi(cfile);
2017
token = next_token(NULL, NULL, cfile);
2018
if (token != LBRACE) {
2019
parse_warn(cfile, "Expecting open curly bracket.");
2020
skip_to_semi(cfile);
2025
option_state_allocate(&pref->options, MDL);
2026
if (pref->options == NULL) {
2027
parse_warn(cfile, "Unable to allocate option state.");
2028
skip_to_semi(cfile);
2033
token = next_token(&val, NULL, cfile);
2034
while (token != RBRACE) {
2039
token = next_token(&val, NULL, cfile);
2040
if (token == NUMBER) {
2041
pref->starts = atoi(val);
2043
parse_warn(cfile, "Expecting a number.");
2044
skip_to_semi(cfile);
2049
case PREFERRED_LIFE:
2050
token = next_token(&val, NULL, cfile);
2051
if (token == NUMBER) {
2052
pref->preferred_life = atoi(val);
2054
parse_warn(cfile, "Expecting a number.");
2055
skip_to_semi(cfile);
2061
token = next_token(&val, NULL, cfile);
2062
if (token == NUMBER) {
2063
pref->max_life = atoi(val);
2065
parse_warn(cfile, "Expecting a number.");
2066
skip_to_semi(cfile);
2072
if (parse_option_decl(&oc, cfile)) {
2073
save_option(oc->option->universe,
2075
option_cache_dereference(&oc, MDL);
2081
parse_warn(cfile, "Unexpected token.");
2082
skip_to_rbrace(cfile, 1);
2090
token = next_token(&val, NULL, cfile);
2091
if (token == END_OF_FILE) {
2092
parse_warn(cfile, "Unexpected end of file.");
2101
void parse_string_list (cfile, lp, multiple)
2102
struct parse *cfile;
2103
struct string_list **lp;
2108
struct string_list *cur, *tmp;
2110
/* Find the last medium in the media list. */
2112
for (cur = *lp; cur -> next; cur = cur -> next)
2115
cur = (struct string_list *)0;
2119
token = next_token (&val, (unsigned *)0, cfile);
2120
if (token != STRING) {
2121
parse_warn (cfile, "Expecting media options.");
2122
skip_to_semi (cfile);
2126
tmp = ((struct string_list *)
2127
dmalloc (strlen (val) + sizeof (struct string_list),
2130
log_fatal ("no memory for string list entry.");
2132
strcpy (tmp -> string, val);
2133
tmp -> next = (struct string_list *)0;
2135
/* Store this medium at the end of the media list. */
2142
token = next_token (&val, (unsigned *)0, cfile);
2143
} while (multiple && token == COMMA);
2145
if (token != SEMI) {
2146
parse_warn (cfile, "expecting semicolon.");
2147
skip_to_semi (cfile);
2151
void parse_reject_statement (cfile, config)
2152
struct parse *cfile;
2153
struct client_config *config;
2157
struct iaddrmatch match;
2158
struct iaddrmatchlist *list;
2162
if (!parse_ip_addr_with_subnet (cfile, &match)) {
2163
/* no warn: parser will have reported what's wrong */
2164
skip_to_semi (cfile);
2168
/* check mask is not all zeros (because that would
2169
* reject EVERY address). This check could be
2170
* simplified if we assume that the mask *always*
2171
* represents a prefix .. but perhaps it might be
2172
* useful to have a mask which is not a proper prefix
2173
* (perhaps for ipv6?). The following is almost as
2174
* efficient as inspection of match.mask.iabuf[0] when
2175
* it IS a true prefix, and is more general when it is
2179
for (i=0 ; i < match.mask.len ; i++) {
2180
if (match.mask.iabuf[i]) {
2185
if (i == match.mask.len) {
2186
/* oops we found all zeros */
2187
parse_warn(cfile, "zero-length prefix is not permitted "
2188
"for reject statement");
2189
skip_to_semi(cfile);
2193
list = dmalloc(sizeof(struct iaddrmatchlist), MDL);
2195
log_fatal ("no memory for reject list!");
2197
list->match = match;
2198
list->next = config->reject_list;
2199
config->reject_list = list;
2201
token = next_token (&val, (unsigned *)0, cfile);
2202
} while (token == COMMA);
2204
if (token != SEMI) {
2205
parse_warn (cfile, "expecting semicolon.");
2206
skip_to_semi (cfile);
2210
/* allow-deny-keyword :== BOOTP
2213
| UNKNOWN_CLIENTS */
2215
int parse_allow_deny (oc, cfile, flag)
2216
struct option_cache **oc;
2217
struct parse *cfile;
2220
parse_warn (cfile, "allow/deny/ignore not permitted here.");
2221
skip_to_semi (cfile);