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