1/* $NetBSD: dhclient.c,v 1.5 2022/04/03 01:10:57 christos Exp $ */ 2 3/* dhclient.c 4 5 DHCP Client. */ 6 7/* 8 * Copyright (c) 2004-2022 by Internet Systems Consortium, Inc. ("ISC") 9 * Copyright (c) 1995-2003 by Internet Software Consortium 10 * 11 * This Source Code Form is subject to the terms of the Mozilla Public 12 * License, v. 2.0. If a copy of the MPL was not distributed with this 13 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 * 23 * Internet Systems Consortium, Inc. 24 * PO Box 360 25 * Newmarket, NH 03857 USA 26 * <info@isc.org> 27 * https://www.isc.org/ 28 * 29 * This code is based on the original client state machine that was 30 * written by Elliot Poger. The code has been extensively hacked on 31 * by Ted Lemon since then, so any mistakes you find are probably his 32 * fault and not Elliot's. 33 */ 34 35#include <sys/cdefs.h> 36__RCSID("$NetBSD: dhclient.c,v 1.5 2022/04/03 01:10:57 christos Exp $"); 37 38#include "dhcpd.h" 39#include <isc/util.h> 40#include <isc/file.h> 41#include <dns/result.h> 42#include <syslog.h> 43#include <signal.h> 44#include <errno.h> 45#include <sys/time.h> 46#include <sys/wait.h> 47#include <limits.h> 48 49TIME default_lease_time = 43200; /* 12 hours... */ 50TIME max_lease_time = 86400; /* 24 hours... */ 51 52const char *path_dhclient_conf = _PATH_DHCLIENT_CONF; 53const char *path_dhclient_db = NULL; 54const char *path_dhclient_pid = NULL; 55static char path_dhclient_script_array[] = _PATH_DHCLIENT_SCRIPT; 56char *path_dhclient_script = path_dhclient_script_array; 57const char *path_dhclient_duid = NULL; 58 59static void add_to_tail(struct client_lease** lease_list, struct client_lease* lease); 60 61/* False (default) => we write and use a pid file */ 62isc_boolean_t no_pid_file = ISC_FALSE; 63isc_boolean_t hw_mismatch_drop = ISC_TRUE; 64 65int dhcp_max_agent_option_packet_length = 0; 66 67int interfaces_requested = 0; 68int interfaces_left = 0; 69 70struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } }; 71struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } }; 72struct in_addr inaddr_any; 73struct sockaddr_in sockaddr_broadcast; 74struct in_addr giaddr; 75struct data_string default_duid; 76int duid_type = 0; 77int duid_v4 = 0; 78int std_dhcid = 0; 79 80int decline_wait_time = 10; /* Default to 10 secs per, RFC 2131, 3.1.5 */ 81 82/* ASSERT_STATE() does nothing now; it used to be 83 assert (state_is == state_shouldbe). */ 84#define ASSERT_STATE(state_is, state_shouldbe) {} 85 86#ifndef UNIT_TEST 87static const char copyright[] = "Copyright 2004-2022 Internet Systems Consortium."; 88static const char arr [] = "All rights reserved."; 89static const char message [] = "Internet Systems Consortium DHCP Client"; 90static const char url [] = "For info, please visit https://www.isc.org/software/dhcp/"; 91#endif /* UNIT_TEST */ 92 93extern u_int16_t local_port; 94extern u_int16_t remote_port; 95 96#if defined(DHCPv6) && defined(DHCP4o6) 97int dhcp4o6_state = -1; /* -1 = stopped, 0 = polling, 1 = started */ 98#endif 99int no_daemon = 0; 100int dfd[2] = { -1, -1 }; 101struct string_list *client_env = NULL; 102int client_env_count = 0; 103int onetry = 0; 104int quiet = 1; 105int nowait = 0; 106int stateless = 0; 107int wanted_ia_na = -1; /* the absolute value is the real one. */ 108int wanted_ia_ta = 0; 109int wanted_ia_pd = 0; 110int require_all_ias = 0; /* If the user requires all of the IAs to 111 be available before accepting a lease 112 0 = no, 1 = requries */ 113#if defined(DHCPv6) 114int dad_wait_time = 0; 115int prefix_len_hint = 0; 116#endif 117 118int address_prefix_len = DHCLIENT_DEFAULT_PREFIX_LEN; 119char *mockup_relay = NULL; 120 121libdhcp_callbacks_t dhclient_callbacks = { 122 &local_port, 123 &remote_port, 124 classify, 125 check_collection, 126 dhcp, 127#ifdef DHCPv6 128 dhcpv6, 129#endif /* DHCPv6 */ 130 bootp, 131 find_class, 132 parse_allow_deny, 133 dhcp_set_control_state, 134}; 135 136char *progname = NULL; 137 138void run_stateless(int exit_mode, u_int16_t port); 139 140static isc_result_t write_duid(struct data_string *duid); 141static void add_reject(struct packet *packet); 142 143static int check_domain_name(const char *ptr, size_t len, int dots); 144static int check_domain_name_list(const char *ptr, size_t len, int dots); 145static int check_option_values(struct universe *universe, unsigned int opt, 146 const char *ptr, size_t len); 147 148#if defined(NSUPDATE) 149static void dhclient_ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, 150 char* file, int line); 151#endif /* defined NSUPDATE */ 152 153static void 154setup(void) { 155 isc_result_t status; 156 /* Set up the isc and dns library managers */ 157 status = dhcp_context_create(DHCP_CONTEXT_PRE_DB, NULL, NULL); 158 if (status != ISC_R_SUCCESS) 159 log_fatal("Can't initialize context: %s", 160 isc_result_totext(status)); 161 162 /* Set up the OMAPI. */ 163 status = omapi_init(); 164 if (status != ISC_R_SUCCESS) 165 log_fatal("Can't initialize OMAPI: %s", 166 isc_result_totext(status)); 167 168 /* Set up the OMAPI wrappers for various server database internal 169 objects. */ 170 dhcp_common_objects_setup(); 171 172 dhcp_interface_discovery_hook = dhclient_interface_discovery_hook; 173 dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook; 174 dhcp_interface_startup_hook = dhclient_interface_startup_hook; 175} 176 177static void 178go_daemon(void) 179{ 180 int pid; 181 182 if (pipe(dfd) == -1) 183 log_fatal("Can't get pipe: %m"); 184 if ((pid = fork ()) < 0) 185 log_fatal("Can't fork daemon: %m"); 186 if (pid != 0) { 187 /* Parent: wait for the child to start */ 188 int n; 189 190 (void) close(dfd[1]); 191 do { 192 char buf; 193 194 n = read(dfd[0], &buf, 1); 195 if (n == 1) 196 _exit((int)buf); 197 } while (n == -1 && errno == EINTR); 198 _exit(1); 199 } 200 /* Child */ 201 (void) close(dfd[0]); 202} 203 204static void 205add_interfaces(char **ifaces, int nifaces) 206{ 207 isc_result_t status; 208 209 for (int i = 0; i < nifaces; i++) { 210 struct interface_info *tmp = NULL; 211 status = interface_allocate(&tmp, MDL); 212 if (status != ISC_R_SUCCESS) 213 log_fatal("Can't record interface %s:%s", 214 ifaces[i], isc_result_totext(status)); 215 if (strlen(ifaces[i]) >= sizeof(tmp->name)) 216 log_fatal("%s: interface name too long (is %ld)", 217 ifaces[i], (long)strlen(ifaces[i])); 218 strcpy(tmp->name, ifaces[i]); 219 if (interfaces) { 220 interface_reference(&tmp->next, interfaces, MDL); 221 interface_dereference(&interfaces, MDL); 222 } 223 interface_reference(&interfaces, tmp, MDL); 224 tmp->flags = INTERFACE_REQUESTED; 225 } 226} 227 228/*! 229 * 230 * \brief Print the generic usage message 231 * 232 * If the user has provided an incorrect command line print out 233 * the description of the command line. The arguments provide 234 * a way for the caller to request more specific information about 235 * the error be printed as well. Mostly this will be that some 236 * command doesn't include its argument. 237 * 238 * \param sfmt - The basic string and format for the specific error 239 * \param sarg - Generally the offending argument from the command line. 240 * 241 * \return Nothing 242 */ 243 244#include <sys/cdefs.h> 245__RCSID("$NetBSD: dhclient.c,v 1.5 2022/04/03 01:10:57 christos Exp $"); 246 247#if defined(DHCPv6) && defined(DHCP4o6) 248static void dhcp4o6_poll(void *dummy); 249static void dhcp4o6_resume(void); 250static void recv_dhcpv4_response(struct data_string *raw); 251static int send_dhcpv4_query(struct client_state *client, int broadcast); 252 253static void dhcp4o6_stop(void); 254static void forw_dhcpv4_response(struct packet *packet); 255static void forw_dhcpv4_query(struct data_string *raw); 256#endif 257 258#ifndef UNIT_TEST 259/* These are only used when we call usage() from the main routine 260 * which isn't compiled when building for unit tests 261 */ 262static const char use_noarg[] = "No argument for command: %s"; 263#ifdef DHCPv6 264static const char use_v6command[] = "Command not used for DHCPv4: %s"; 265#endif 266 267#ifdef DHCPv6 268#ifdef DHCP4o6 269#define DHCLIENT_USAGE0 \ 270"[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>] [-p <port>] [-D LL|LLT]\n" \ 271" [--dad-wait-time <seconds>] [--prefix-len-hint <length>]\n" \ 272" [--decline-wait-time <seconds>]\n" \ 273" [--address-prefix-len <length>]\n" 274#else /* DHCP4o6 */ 275#define DHCLIENT_USAGE0 \ 276"[-4|-6] [-SNTPRI1dvrxi] [-nw] [-p <port>] [-D LL|LLT]\n" \ 277" [--dad-wait-time <seconds>] [--prefix-len-hint <length>]\n" \ 278" [--decline-wait-time <seconds>]\n" \ 279" [--address-prefix-len <length>]\n" 280#endif 281#else /* DHCPv6 */ 282#define DHCLIENT_USAGE0 \ 283"[-I1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n" \ 284" [--decline-wait-time <seconds>]\n" 285#endif 286 287#define DHCLIENT_USAGEC \ 288" [-s server-addr] [-cf config-file]\n" \ 289" [-df duid-file] [-lf lease-file]\n" \ 290" [-pf pid-file] [--no-pid] [-e VAR=val]\n" \ 291" [-sf script-file] [interface]*" 292 293#define DHCLIENT_USAGEH "{--version|--help|-h}" 294 295static void 296usage(const char *sfmt, const char *sarg) 297{ 298 log_info("%s %s", message, PACKAGE_VERSION); 299 log_info(copyright); 300 log_info(arr); 301 log_info(url); 302 303 /* If desired print out the specific error message */ 304#ifdef PRINT_SPECIFIC_CL_ERRORS 305 if (sfmt != NULL) 306 log_error(sfmt, sarg); 307#endif 308 309 log_fatal("Usage: %s %s%s\n %s %s", 310 isc_file_basename(progname), 311 DHCLIENT_USAGE0, 312 DHCLIENT_USAGEC, 313 isc_file_basename(progname), 314 DHCLIENT_USAGEH); 315} 316 317extern void initialize_client_option_spaces(void); 318 319int 320main(int argc, char **argv) { 321 int fd; 322 int i; 323 struct interface_info *ip; 324 struct client_state *client; 325 unsigned seed; 326 char *server = NULL; 327 int exit_mode = 0; 328 int release_mode = 0; 329 struct timeval tv; 330 omapi_object_t *listener; 331 isc_result_t result; 332 int persist = 0; 333 int no_dhclient_conf = 0; 334 int no_dhclient_db = 0; 335 int no_dhclient_pid = 0; 336 int no_dhclient_script = 0; 337#ifdef DHCPv6 338 int local_family_set = 0; 339#ifdef DHCP4o6 340 u_int16_t dhcp4o6_port = 0; 341#endif /* DHCP4o6 */ 342#endif /* DHCPv6 */ 343 char *s; 344 char **ifaces; 345 346 libdhcp_callbacks_register(&dhclient_callbacks); 347 348#ifdef OLD_LOG_NAME 349 progname = "dhclient"; 350#else 351 progname = argv[0]; 352#endif 353 /* Initialize client globals. */ 354 memset(&default_duid, 0, sizeof(default_duid)); 355 356 /* Make sure that file descriptors 0 (stdin), 1, (stdout), and 357 2 (stderr) are open. To do this, we assume that when we 358 open a file the lowest available file descriptor is used. */ 359 fd = open("/dev/null", O_RDWR); 360 if (fd == 0) 361 fd = open("/dev/null", O_RDWR); 362 if (fd == 1) 363 fd = open("/dev/null", O_RDWR); 364 if (fd == 2) 365 log_perror = 0; /* No sense logging to /dev/null. */ 366 else if (fd != -1) 367 close(fd); 368 369 openlog(isc_file_basename(progname), DHCP_LOG_OPTIONS, LOG_DAEMON); 370 371#if !(defined(DEBUG) || defined(__CYGWIN32__)) 372 setlogmask(LOG_UPTO(LOG_INFO)); 373#endif 374 375 if ((ifaces = malloc(sizeof(*ifaces) * argc)) == NULL) { 376 log_fatal("Can't allocate memory"); 377 return 1; 378 } 379 380 /* Parse arguments changing no_daemon */ 381 for (i = 1; i < argc; i++) { 382 if (!strcmp(argv[i], "-r")) { 383 no_daemon = 1; 384 } else if (!strcmp(argv[i], "-x")) { 385 no_daemon = 0; 386 } else if (!strcmp(argv[i], "-d")) { 387 no_daemon = 1; 388 } else if (!strcmp(argv[i], "--version")) { 389 const char vstring[] = "isc-dhclient-"; 390 IGNORE_RET(write(STDERR_FILENO, vstring, 391 strlen(vstring))); 392 IGNORE_RET(write(STDERR_FILENO, 393 PACKAGE_VERSION, 394 strlen(PACKAGE_VERSION))); 395 IGNORE_RET(write(STDERR_FILENO, "\n", 1)); 396 exit(0); 397 } else if (!strcmp(argv[i], "--help") || 398 !strcmp(argv[i], "-h")) { 399 const char *pname = isc_file_basename(progname); 400 IGNORE_RET(write(STDERR_FILENO, "Usage: ", 7)); 401 IGNORE_RET(write(STDERR_FILENO, pname, strlen(pname))); 402 IGNORE_RET(write(STDERR_FILENO, " ", 1)); 403 IGNORE_RET(write(STDERR_FILENO, DHCLIENT_USAGE0, 404 strlen(DHCLIENT_USAGE0))); 405 IGNORE_RET(write(STDERR_FILENO, DHCLIENT_USAGEC, 406 strlen(DHCLIENT_USAGEC))); 407 IGNORE_RET(write(STDERR_FILENO, "\n", 1)); 408 IGNORE_RET(write(STDERR_FILENO, " ", 7)); 409 IGNORE_RET(write(STDERR_FILENO, pname, strlen(pname))); 410 IGNORE_RET(write(STDERR_FILENO, " ", 1)); 411 IGNORE_RET(write(STDERR_FILENO, DHCLIENT_USAGEH, 412 strlen(DHCLIENT_USAGEH))); 413 IGNORE_RET(write(STDERR_FILENO, "\n", 1)); 414 exit(0); 415 } 416 } 417 /* When not forbidden prepare to become a daemon */ 418 if (!no_daemon) { 419 go_daemon(); 420 } 421 422 setup(); 423 424 for (i = 1; i < argc; i++) { 425 if (!strcmp(argv[i], "-r")) { 426 release_mode = 1; 427 /* no_daemon = 1; */ 428#ifdef DHCPv6 429 } else if (!strcmp(argv[i], "-4")) { 430 if (local_family_set && local_family != AF_INET) 431 log_fatal("Client can only do v4 or v6, not " 432 "both."); 433 local_family_set = 1; 434 local_family = AF_INET; 435 } else if (!strcmp(argv[i], "-6")) { 436 if (local_family_set && local_family != AF_INET6) 437 log_fatal("Client can only do v4 or v6, not " 438 "both."); 439 local_family_set = 1; 440 local_family = AF_INET6; 441#ifdef DHCP4o6 442 } else if (!strcmp(argv[i], "-4o6")) { 443 if (++i == argc) 444 usage(use_noarg, argv[i-1]); 445 dhcp4o6_port = validate_port_pair(argv[i]); 446 447 log_debug("DHCPv4 over DHCPv6 over ::1 port %d and %d", 448 ntohs(dhcp4o6_port), 449 ntohs(dhcp4o6_port) + 1); 450 dhcpv4_over_dhcpv6 = 1; 451#endif /* DHCP4o6 */ 452#endif /* DHCPv6 */ 453 } else if (!strcmp(argv[i], "-x")) { /* eXit, no release */ 454 release_mode = 0; 455 /* no_daemon = 0; */ 456 exit_mode = 1; 457 } else if (!strcmp(argv[i], "-p")) { 458 if (++i == argc) 459 usage(use_noarg, argv[i-1]); 460 local_port = validate_port(argv[i]); 461 log_debug("binding to user-specified port %d", 462 ntohs(local_port)); 463 } else if (!strcmp(argv[i], "-d")) { 464 /* no_daemon = 1; */ 465 quiet = 0; 466 } else if (!strcmp(argv[i], "-pf")) { 467 if (++i == argc) 468 usage(use_noarg, argv[i-1]); 469 path_dhclient_pid = argv[i]; 470 no_dhclient_pid = 1; 471 } else if (!strcmp(argv[i], "--no-pid")) { 472 no_pid_file = ISC_TRUE; 473 } else if (!strcmp(argv[i], "-cf")) { 474 if (++i == argc) 475 usage(use_noarg, argv[i-1]); 476 path_dhclient_conf = argv[i]; 477 no_dhclient_conf = 1; 478 } else if (!strcmp(argv[i], "-df")) { 479 if (++i == argc) 480 usage(use_noarg, argv[i-1]); 481 path_dhclient_duid = argv[i]; 482 } else if (!strcmp(argv[i], "-lf")) { 483 if (++i == argc) 484 usage(use_noarg, argv[i-1]); 485 path_dhclient_db = argv[i]; 486 no_dhclient_db = 1; 487 } else if (!strcmp(argv[i], "-sf")) { 488 if (++i == argc) 489 usage(use_noarg, argv[i-1]); 490 path_dhclient_script = argv[i]; 491 no_dhclient_script = 1; 492 } else if (!strcmp(argv[i], "-1")) { 493 onetry = 1; 494 } else if (!strcmp(argv[i], "-q")) { 495 quiet = 1; 496 } else if (!strcmp(argv[i], "-s")) { 497 if (++i == argc) 498 usage(use_noarg, argv[i-1]); 499 server = argv[i]; 500 } else if (!strcmp(argv[i], "-g")) { 501 if (++i == argc) 502 usage(use_noarg, argv[i-1]); 503 mockup_relay = argv[i]; 504 } else if (!strcmp(argv[i], "-nw")) { 505 nowait = 1; 506 } else if (!strcmp(argv[i], "-n")) { 507 /* do not start up any interfaces */ 508 interfaces_requested = -1; 509 } else if (!strcmp(argv[i], "-w")) { 510 /* do not exit if there are no broadcast interfaces. */ 511 persist = 1; 512 } else if (!strcmp(argv[i], "-e")) { 513 struct string_list *tmp; 514 if (++i == argc) 515 usage(use_noarg, argv[i-1]); 516 tmp = dmalloc(strlen(argv[i]) + sizeof *tmp, MDL); 517 if (!tmp) 518 log_fatal("No memory for %s", argv[i]); 519 strcpy(tmp->string, argv[i]); 520 tmp->next = client_env; 521 client_env = tmp; 522 client_env_count++; 523#ifdef DHCPv6 524 } else if (!strcmp(argv[i], "-S")) { 525 if (local_family_set && (local_family == AF_INET)) { 526 usage(use_v6command, argv[i]); 527 } 528 local_family_set = 1; 529 local_family = AF_INET6; 530 wanted_ia_na = 0; 531 stateless = 1; 532 } else if (!strcmp(argv[i], "-N")) { 533 if (local_family_set && (local_family == AF_INET)) { 534 usage(use_v6command, argv[i]); 535 } 536 local_family_set = 1; 537 local_family = AF_INET6; 538 if (wanted_ia_na < 0) { 539 wanted_ia_na = 0; 540 } 541 wanted_ia_na++; 542 } else if (!strcmp(argv[i], "-T")) { 543 if (local_family_set && (local_family == AF_INET)) { 544 usage(use_v6command, argv[i]); 545 } 546 local_family_set = 1; 547 local_family = AF_INET6; 548 if (wanted_ia_na < 0) { 549 wanted_ia_na = 0; 550 } 551 wanted_ia_ta++; 552 } else if (!strcmp(argv[i], "-P")) { 553 if (local_family_set && (local_family == AF_INET)) { 554 usage(use_v6command, argv[i]); 555 } 556 local_family_set = 1; 557 local_family = AF_INET6; 558 if (wanted_ia_na < 0) { 559 wanted_ia_na = 0; 560 } 561 wanted_ia_pd++; 562 } else if (!strcmp(argv[i], "-R")) { 563 if (local_family_set && (local_family == AF_INET)) { 564 usage(use_v6command, argv[i]); 565 } 566 local_family_set = 1; 567 local_family = AF_INET6; 568 require_all_ias = 1; 569 } else if (!strcmp(argv[i], "--dad-wait-time")) { 570 if (++i == argc) { 571 usage(use_noarg, argv[i-1]); 572 } 573 errno = 0; 574 dad_wait_time = (int)strtol(argv[i], &s, 10); 575 if (errno || (*s != '\0') || (dad_wait_time < 0)) { 576 usage("Invalid value for --dad-wait-time: %s", 577 argv[i]); 578 } 579 } else if (!strcmp(argv[i], "--prefix-len-hint")) { 580 if (++i == argc) { 581 usage(use_noarg, argv[i-1]); 582 } 583 584 errno = 0; 585 prefix_len_hint = (int)strtol(argv[i], &s, 10); 586 if (errno || (*s != '\0') || (prefix_len_hint < 0)) { 587 usage("Invalid value for --prefix-len-hint: %s", 588 argv[i]); 589 } 590 } else if (!strcmp(argv[i], "--address-prefix-len")) { 591 if (++i == argc) { 592 usage(use_noarg, argv[i-1]); 593 } 594 errno = 0; 595 address_prefix_len = (int)strtol(argv[i], &s, 10); 596 if (errno || (*s != '\0') || 597 (address_prefix_len < 0)) { 598 usage("Invalid value for" 599 " --address-prefix-len: %s", argv[i]); 600 } 601#endif /* DHCPv6 */ 602 } else if (!strcmp(argv[i], "--decline-wait-time")) { 603 if (++i == argc) { 604 usage(use_noarg, argv[i-1]); 605 } 606 607 errno = 0; 608 decline_wait_time = (int)strtol(argv[i], &s, 10); 609 if (errno || (*s != '\0') || 610 (decline_wait_time < 0)) { 611 usage("Invalid value for " 612 "--decline-wait-time: %s", argv[i]); 613 } 614 } else if (!strcmp(argv[i], "-D")) { 615 duid_v4 = 1; 616 if (++i == argc) 617 usage(use_noarg, argv[i-1]); 618 if (!strcasecmp(argv[i], "LL")) { 619 duid_type = DUID_LL; 620 } else if (!strcasecmp(argv[i], "LLT")) { 621 duid_type = DUID_LLT; 622 } else { 623 usage("Unknown argument to -D: %s", argv[i]); 624 } 625 } else if (!strcmp(argv[i], "-i")) { 626 /* enable DUID support for DHCPv4 clients */ 627 duid_v4 = 1; 628 } else if (!strcmp(argv[i], "-I")) { 629 /* enable standard DHCID support for DDNS updates */ 630 std_dhcid = 1; 631 } else if (!strcmp(argv[i], "-m")) { 632 hw_mismatch_drop = ISC_FALSE; 633 } else if (!strcmp(argv[i], "-v")) { 634 quiet = 0; 635 } else if (argv[i][0] == '-') { 636 usage("Unknown command: %s", argv[i]); 637 } else if (interfaces_requested < 0) { 638 usage("No interfaces command -n and " 639 " requested interface %s", argv[i]); 640 } else { 641 ifaces[interfaces_requested++] = argv[i]; 642 } 643 } 644 645 /* 646 * Do this before setup, otherwise if we are using threads things 647 * are not going to work 648 */ 649 if (interfaces_requested > 0) { 650 add_interfaces(ifaces, interfaces_requested); 651 interfaces_left = interfaces_requested; 652 } 653 free(ifaces); 654 655 if (wanted_ia_na < 0) { 656 wanted_ia_na = 1; 657 } 658 659 /* Support only one (requested) interface for Prefix Delegation. */ 660 if (wanted_ia_pd && (interfaces_requested != 1)) { 661 usage("PD %s only supports one requested interface", "-P"); 662 } 663 664#if defined(DHCPv6) && defined(DHCP4o6) 665 if ((local_family == AF_INET6) && dhcpv4_over_dhcpv6 && 666 (exit_mode || release_mode)) 667 log_error("Can't relay DHCPv4-over-DHCPv6 " 668 "without a persistent DHCPv6 client"); 669 if ((local_family == AF_INET) && dhcpv4_over_dhcpv6 && 670 (interfaces_requested != 1)) 671 log_fatal("DHCPv4-over-DHCPv6 requires an explicit " 672 "interface on which to be applied"); 673#endif 674 675 if (!no_dhclient_conf && (s = getenv("PATH_DHCLIENT_CONF"))) { 676 path_dhclient_conf = s; 677 } 678 if (!no_dhclient_db && (s = getenv("PATH_DHCLIENT_DB"))) { 679 path_dhclient_db = s; 680 } 681 if (!no_dhclient_pid && (s = getenv("PATH_DHCLIENT_PID"))) { 682 path_dhclient_pid = s; 683 } 684 if (!no_dhclient_script && (s = getenv("PATH_DHCLIENT_SCRIPT"))) { 685 path_dhclient_script = s; 686 } 687 688 /* Set up the initial dhcp option universe. */ 689 initialize_common_option_spaces(); 690 691 /* Set up the initial client option universe. */ 692 initialize_client_option_spaces(); 693 694 /* Assign v4 or v6 specific running parameters. */ 695 if (local_family == AF_INET) 696 dhcpv4_client_assignments(); 697#ifdef DHCPv6 698 else if (local_family == AF_INET6) 699 dhcpv6_client_assignments(); 700#endif /* DHCPv6 */ 701 else 702 log_fatal("Impossible condition at %s:%d.", MDL); 703 704 /* 705 * convert relative path names to absolute, for files that need 706 * to be reopened after chdir() has been called 707 */ 708 if (path_dhclient_db[0] != '/') { 709 path_dhclient_db = absolute_path(path_dhclient_db); 710 } 711 712 if (path_dhclient_script[0] != '/') { 713 path_dhclient_script = absolute_path(path_dhclient_script); 714 } 715 716 /* 717 * See if we should kill off any currently running client 718 * we don't try to kill it off if the user told us not 719 * to write a pid file - we assume they are controlling 720 * the process in some other fashion. 721 */ 722 if (path_dhclient_pid != NULL && 723 (release_mode || exit_mode) && (no_pid_file == ISC_FALSE)) { 724 FILE *pidfd; 725 pid_t oldpid; 726 long temp; 727 int e; 728 729 if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) { 730 e = fscanf(pidfd, "%ld\n", &temp); 731 oldpid = (pid_t)temp; 732 733 if (e != 0 && e != EOF && oldpid) { 734 if (kill(oldpid, SIGTERM) == 0) { 735 log_info("Killed old client process"); 736 (void) unlink(path_dhclient_pid); 737 /* 738 * wait for the old process to 739 * cleanly terminate. 740 * Note kill() with sig=0 could 741 * detect termination but only 742 * the parent can be signaled... 743 */ 744 sleep(1); 745 } else if (errno == ESRCH) { 746 log_info("Removed stale PID file"); 747 (void) unlink(path_dhclient_pid); 748 } 749 } 750 fclose(pidfd); 751 } 752 } 753 754 if (!quiet) { 755 log_info("%s %s", message, PACKAGE_VERSION); 756 log_info(copyright); 757 log_info(arr); 758 log_info(url); 759 log_info("%s", ""); 760 } else { 761 log_perror = 0; 762 quiet_interface_discovery = 1; 763 } 764 765 /* If we're given a relay agent address to insert, for testing 766 purposes, figure out what it is. */ 767 if (mockup_relay) { 768 if (!inet_aton(mockup_relay, &giaddr)) { 769 struct hostent *he; 770 he = gethostbyname(mockup_relay); 771 if (he) { 772 memcpy(&giaddr, he->h_addr_list[0], 773 sizeof giaddr); 774 } else { 775 log_fatal("%s: no such host", mockup_relay); 776 } 777 } 778 } 779 780 /* Get the current time... */ 781 gettimeofday(&cur_tv, NULL); 782 783 sockaddr_broadcast.sin_family = AF_INET; 784 sockaddr_broadcast.sin_port = remote_port; 785 if (server) { 786 if (!inet_aton(server, &sockaddr_broadcast.sin_addr)) { 787 struct hostent *he; 788 he = gethostbyname(server); 789 if (he) { 790 memcpy(&sockaddr_broadcast.sin_addr, 791 he->h_addr_list[0], 792 sizeof sockaddr_broadcast.sin_addr); 793 } else 794 sockaddr_broadcast.sin_addr.s_addr = 795 INADDR_BROADCAST; 796 } 797 } else { 798 sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST; 799 } 800 801 inaddr_any.s_addr = INADDR_ANY; 802 803 /* Stateless special case. */ 804 if (stateless) { 805 if (release_mode || (wanted_ia_na > 0) || 806 wanted_ia_ta || wanted_ia_pd || 807 (interfaces_requested != 1)) { 808 usage("Stateless command: %s incompatibile with " 809 "other commands", "-S"); 810 } 811#if defined(DHCPv6) && defined(DHCP4o6) 812 run_stateless(exit_mode, dhcp4o6_port); 813#else 814 run_stateless(exit_mode, 0); 815#endif 816 finish(0); 817 } 818 819 /* Discover all the network interfaces. */ 820 discover_interfaces(DISCOVER_UNCONFIGURED); 821 822 /* Parse the dhclient.conf file. */ 823 read_client_conf(); 824 825 /* Parse the lease database. */ 826 read_client_leases(); 827 828 /* If desired parse the secondary lease database for a DUID */ 829 if ((default_duid.len == 0) && (path_dhclient_duid != NULL)) { 830 read_client_duid(); 831 } 832 833 /* Rewrite the lease database... */ 834 rewrite_client_leases(); 835 836 /* XXX */ 837/* config_counter(&snd_counter, &rcv_counter); */ 838 839 /* 840 * If no broadcast interfaces were discovered, call the script 841 * and tell it so. 842 */ 843 if (!interfaces) { 844 /* 845 * Call dhclient-script with the NBI flag, 846 * in case somebody cares. 847 */ 848 script_init(NULL, "NBI", NULL); 849 script_go(NULL); 850 851 /* 852 * If we haven't been asked to persist, waiting for new 853 * interfaces, then just exit. 854 */ 855 if (!persist) { 856 /* Nothing more to do. */ 857 log_info("No broadcast interfaces found - exiting."); 858 finish(0); 859 } 860 } else if (!release_mode && !exit_mode) { 861 /* Call the script with the list of interfaces. */ 862 for (ip = interfaces; ip; ip = ip->next) { 863 /* 864 * If interfaces were specified, don't configure 865 * interfaces that weren't specified! 866 */ 867 if ((interfaces_requested > 0) && 868 ((ip->flags & (INTERFACE_REQUESTED | 869 INTERFACE_AUTOMATIC)) != 870 INTERFACE_REQUESTED)) 871 continue; 872 873 if (local_family == AF_INET6) { 874 script_init(ip->client, "PREINIT6", NULL); 875 } else { 876 script_init(ip->client, "PREINIT", NULL); 877 if (ip->client->alias != NULL) 878 script_write_params(ip->client, 879 "alias_", 880 ip->client->alias); 881 } 882 script_go(ip->client); 883 } 884 } 885 886 /* At this point, all the interfaces that the script thinks 887 are relevant should be running, so now we once again call 888 discover_interfaces(), and this time ask it to actually set 889 up the interfaces. */ 890 discover_interfaces(interfaces_requested != 0 891 ? DISCOVER_REQUESTED 892 : DISCOVER_RUNNING); 893 894 /* PLEASE PREFER the random device: not all systems use random 895 * process identifiers so the alternative can be predictable. */ 896 seed = 0; 897 size_t nrnd = 0; 898#ifdef ISC_PATH_RANDOMDEV 899 FILE *frnd = fopen(ISC_PATH_RANDOMDEV, "r"); 900 if (frnd) { 901 nrnd = fread(&seed, sizeof(seed), 1, frnd); 902 fclose(frnd); 903 } 904#endif 905 /* Please leave the compiler to emit a warning about a constant 906 * condition in the if test. */ 907 if (!nrnd) { 908 /* Make up a seed for the random number generator from current 909 time plus the sum of the last four bytes of each 910 interface's hardware address interpreted as an integer. 911 Not much entropy, but we're booting, so we're not likely to 912 find anything better. */ 913 914 for (ip = interfaces; ip; ip = ip->next) { 915 int junk; 916 memcpy(&junk, 917 &ip->hw_address.hbuf[ip->hw_address.hlen - 918 sizeof seed], sizeof seed); 919 seed += junk; 920 } 921 seed += cur_time + (unsigned)getpid(); 922 } 923 srandom(seed); 924 925 /* 926 * Establish a default DUID. We always do so for v6 and 927 * do so if desired for v4 via the -D or -i options 928 */ 929 if ((local_family == AF_INET6) || 930 ((local_family == AF_INET) && (duid_v4 == 1))) { 931 if (default_duid.len == 0) { 932 if (default_duid.buffer != NULL) 933 data_string_forget(&default_duid, MDL); 934 935 form_duid(&default_duid, MDL); 936 write_duid(&default_duid); 937 } 938 } 939 940#if defined(DHCPv6) && defined(DHCP4o6) 941 if (dhcpv4_over_dhcpv6 && !exit_mode) 942 dhcp4o6_setup(dhcp4o6_port); 943#endif 944 945 /* Start a configuration state machine for each interface. */ 946#ifdef DHCPv6 947 if (local_family == AF_INET6) { 948 for (ip = interfaces ; ip != NULL ; ip = ip->next) { 949 for (client = ip->client ; client != NULL ; 950 client = client->next) { 951 if (release_mode) { 952 start_release6(client); 953 continue; 954 } else if (exit_mode) { 955 unconfigure6(client, "STOP6"); 956 continue; 957 } 958 959 /* If we have a previous binding, Confirm 960 * that we can (or can't) still use it. 961 */ 962 if ((client->active_lease != NULL) && 963 !client->active_lease->released) 964 start_confirm6(client); 965 else 966 start_init6(client); 967 } 968 } 969 } else 970#endif /* DHCPv6 */ 971 { 972 for (ip = interfaces ; ip ; ip = ip->next) { 973 ip->flags |= INTERFACE_RUNNING; 974 for (client = ip->client ; client ; 975 client = client->next) { 976 if (exit_mode) 977 state_stop(client); 978 if (release_mode) 979 do_release(client); 980 else { 981 client->state = S_INIT; 982 983 if (top_level_config.initial_delay>0) 984 { 985 tv.tv_sec = 0; 986 if (top_level_config. 987 initial_delay>1) 988 tv.tv_sec = cur_time 989 + random() 990 % (top_level_config. 991 initial_delay-1); 992 tv.tv_usec = random() 993 % 1000000; 994 /* 995 * this gives better 996 * distribution than just 997 *whole seconds 998 */ 999 add_timeout(&tv, state_reboot, 1000 client, 0, 0); 1001 } else { 1002 state_reboot(client); 1003 } 1004 } 1005 } 1006 } 1007 } 1008 1009 if (exit_mode) 1010 finish(0); 1011 if (release_mode) { 1012#ifndef DHCPv6 1013 finish(0); 1014#else 1015 if ((local_family == AF_INET6) || dhcpv4_over_dhcpv6) { 1016 if (onetry) 1017 finish(0); 1018 } else 1019 finish(0); 1020#endif /* DHCPv6 */ 1021 } 1022 1023 /* Start up a listener for the object management API protocol. */ 1024 if (top_level_config.omapi_port != -1) { 1025 listener = NULL; 1026 result = omapi_generic_new(&listener, MDL); 1027 if (result != ISC_R_SUCCESS) 1028 log_fatal("Can't allocate new generic object: %s\n", 1029 isc_result_totext(result)); 1030 result = omapi_protocol_listen(listener, 1031 (unsigned) 1032 top_level_config.omapi_port, 1033 1); 1034 if (result != ISC_R_SUCCESS) 1035 log_fatal("Can't start OMAPI protocol: %s", 1036 isc_result_totext (result)); 1037 } 1038 1039 /* Set up the bootp packet handler... */ 1040 bootp_packet_handler = do_packet; 1041#ifdef DHCPv6 1042 dhcpv6_packet_handler = do_packet6; 1043#endif /* DHCPv6 */ 1044 1045#if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \ 1046 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT) 1047 dmalloc_cutoff_generation = dmalloc_generation; 1048 dmalloc_longterm = dmalloc_outstanding; 1049 dmalloc_outstanding = 0; 1050#endif 1051 1052#if defined(ENABLE_GENTLE_SHUTDOWN) 1053 /* no signal handlers until we deal with the side effects */ 1054 /* install signal handlers */ 1055 signal(SIGINT, dhcp_signal_handler); /* control-c */ 1056 signal(SIGTERM, dhcp_signal_handler); /* kill */ 1057#endif 1058 1059 /* If we're not supposed to wait before getting the address, 1060 don't. */ 1061 if (nowait) 1062 detach(); 1063 1064 /* If we're not going to daemonize, write the pid file 1065 now. */ 1066 if (no_daemon || nowait) 1067 write_client_pid_file(); 1068 1069 /* Start dispatching packets and timeouts... */ 1070 dispatch(); 1071 1072 /* In fact dispatch() never returns. */ 1073 return 0; 1074} 1075 1076/* 1077 * \brief Run the DHCPv6 stateless client (dhclient -6 -S) 1078 * 1079 * \param exist_mode set to 1 when dhclient was called with -x 1080 * \param port DHCPv4-over-DHCPv6 client inter-process communication 1081 * UDP port pair (port,port+1 with port in network byte order) 1082 */ 1083 1084void run_stateless(int exit_mode, u_int16_t port) 1085{ 1086#ifdef DHCPv6 1087 struct client_state *client; 1088 omapi_object_t *listener; 1089 isc_result_t result; 1090 1091#ifndef DHCP4o6 1092 IGNORE_UNUSED(port); 1093#endif 1094 1095 /* Discover the network interface. */ 1096 discover_interfaces(DISCOVER_REQUESTED); 1097 1098 if (!interfaces) 1099 usage("No interfaces available for stateless command: %s", "-S"); 1100 1101 /* Parse the dhclient.conf file. */ 1102#ifdef DHCP4o6 1103 if (dhcpv4_over_dhcpv6) { 1104 /* Mark we want to request IRT too! */ 1105 dhcpv4_over_dhcpv6++; 1106 } 1107#endif 1108 read_client_conf(); 1109 1110 /* Parse the lease database. */ 1111 read_client_leases(); 1112 1113 /* If desired parse the secondary lease database for a DUID */ 1114 if ((default_duid.len == 0) && (path_dhclient_duid != NULL)) { 1115 read_client_duid(); 1116 } 1117 1118 /* Establish a default DUID. */ 1119 if (default_duid.len == 0) { 1120 if (default_duid.buffer != NULL) 1121 data_string_forget(&default_duid, MDL); 1122 1123 form_duid(&default_duid, MDL); 1124 } 1125 1126#ifdef DHCP4o6 1127 if (dhcpv4_over_dhcpv6 && !exit_mode) 1128 dhcp4o6_setup(port); 1129#endif 1130 1131 /* Start a configuration state machine. */ 1132 for (client = interfaces->client ; 1133 client != NULL ; 1134 client = client->next) { 1135 if (exit_mode) { 1136 unconfigure6(client, "STOP6"); 1137 continue; 1138 } 1139 start_info_request6(client); 1140 } 1141 if (exit_mode) 1142 return; 1143 1144 /* Start up a listener for the object management API protocol. */ 1145 if (top_level_config.omapi_port != -1) { 1146 listener = NULL; 1147 result = omapi_generic_new(&listener, MDL); 1148 if (result != ISC_R_SUCCESS) 1149 log_fatal("Can't allocate new generic object: %s\n", 1150 isc_result_totext(result)); 1151 result = omapi_protocol_listen(listener, 1152 (unsigned) 1153 top_level_config.omapi_port, 1154 1); 1155 if (result != ISC_R_SUCCESS) 1156 log_fatal("Can't start OMAPI protocol: %s", 1157 isc_result_totext(result)); 1158 } 1159 1160 /* Set up the packet handler... */ 1161 dhcpv6_packet_handler = do_packet6; 1162 1163#if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \ 1164 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT) 1165 dmalloc_cutoff_generation = dmalloc_generation; 1166 dmalloc_longterm = dmalloc_outstanding; 1167 dmalloc_outstanding = 0; 1168#endif 1169 1170 /* If we're not supposed to wait before getting the address, 1171 don't. */ 1172 if (nowait) 1173 detach(); 1174 1175 /* If we're not going to daemonize, write the pid file 1176 now. */ 1177 if (no_daemon || nowait) 1178 write_client_pid_file(); 1179 1180 /* Start dispatching packets and timeouts... */ 1181 dispatch(); 1182 1183#endif /* DHCPv6 */ 1184 return; 1185} 1186#endif /* !UNIT_TEST */ 1187 1188isc_result_t find_class (struct class **c, 1189 const char *s, const char *file, int line) 1190{ 1191 return 0; 1192} 1193 1194int check_collection (packet, lease, collection) 1195 struct packet *packet; 1196 struct lease *lease; 1197 struct collection *collection; 1198{ 1199 return 0; 1200} 1201 1202void classify (packet, class) 1203 struct packet *packet; 1204 struct class *class; 1205{ 1206} 1207 1208void unbill_class (lease) 1209 struct lease *lease; 1210{ 1211} 1212 1213int find_subnet (struct subnet **sp, 1214 struct iaddr addr, const char *file, int line) 1215{ 1216 return 0; 1217} 1218 1219/* Individual States: 1220 * 1221 * Each routine is called from the dhclient_state_machine() in one of 1222 * these conditions: 1223 * -> entering INIT state 1224 * -> recvpacket_flag == 0: timeout in this state 1225 * -> otherwise: received a packet in this state 1226 * 1227 * Return conditions as handled by dhclient_state_machine(): 1228 * Returns 1, sendpacket_flag = 1: send packet, reset timer. 1229 * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone). 1230 * Returns 0: finish the nap which was interrupted for no good reason. 1231 * 1232 * Several per-interface variables are used to keep track of the process: 1233 * active_lease: the lease that is being used on the interface 1234 * (null pointer if not configured yet). 1235 * offered_leases: leases corresponding to DHCPOFFER messages that have 1236 * been sent to us by DHCP servers. 1237 * acked_leases: leases corresponding to DHCPACK messages that have been 1238 * sent to us by DHCP servers. 1239 * sendpacket: DHCP packet we're trying to send. 1240 * destination: IP address to send sendpacket to 1241 * In addition, there are several relevant per-lease variables. 1242 * T1_expiry, T2_expiry, lease_expiry: lease milestones 1243 * In the active lease, these control the process of renewing the lease; 1244 * In leases on the acked_leases list, this simply determines when we 1245 * can no longer legitimately use the lease. 1246 */ 1247 1248#include <sys/cdefs.h> 1249__RCSID("$NetBSD: dhclient.c,v 1.5 2022/04/03 01:10:57 christos Exp $"); 1250 1251void state_reboot (cpp) 1252 void *cpp; 1253{ 1254 struct client_state *client = cpp; 1255 1256#if defined(DHCPv6) && defined(DHCP4o6) 1257 if (dhcpv4_over_dhcpv6 && (dhcp4o6_state <= 0)) { 1258 if (dhcp4o6_state < 0) 1259 dhcp4o6_poll(NULL); 1260 client->pending = P_REBOOT; 1261 return; 1262 } 1263#endif 1264 1265 client->pending= P_NONE; 1266 1267 /* If we don't remember an active lease, go straight to INIT. */ 1268 if (!client -> active || 1269 client -> active -> is_bootp || 1270 client -> active -> expiry <= cur_time) { 1271 state_init (client); 1272 return; 1273 } 1274 1275 /* We are in the rebooting state. */ 1276 client -> state = S_REBOOTING; 1277 1278 /* 1279 * make_request doesn't initialize xid because it normally comes 1280 * from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER, 1281 * so pick an xid now. 1282 */ 1283 client -> xid = random (); 1284 1285 /* 1286 * Make a DHCPREQUEST packet, and set 1287 * appropriate per-interface flags. 1288 */ 1289 make_request (client, client -> active); 1290 client -> destination = iaddr_broadcast; 1291 client -> first_sending = cur_time; 1292 client -> interval = client -> config -> initial_interval; 1293 1294 /* Zap the medium list... */ 1295 client -> medium = NULL; 1296 1297 /* Send out the first DHCPREQUEST packet. */ 1298 send_request (client); 1299} 1300 1301/* Called when a lease has completely expired and we've been unable to 1302 renew it. */ 1303 1304void state_init (cpp) 1305 void *cpp; 1306{ 1307 struct client_state *client = cpp; 1308 1309 ASSERT_STATE(state, S_INIT); 1310 1311 /* Make a DHCPDISCOVER packet, and set appropriate per-interface 1312 flags. */ 1313 make_discover (client, client -> active); 1314 client -> xid = client -> packet.xid; 1315 client -> destination = iaddr_broadcast; 1316 client -> state = S_SELECTING; 1317 client -> first_sending = cur_time; 1318 client -> interval = client -> config -> initial_interval; 1319 1320 /* Add an immediate timeout to cause the first DHCPDISCOVER packet 1321 to go out. */ 1322 send_discover (client); 1323} 1324 1325/* check_v6only is called by dhcpoffer and dhcpack. It checks if a 1326 * requested v6-only-preferred option is present and returned the 1327 * V6ONLY_WAIT delay to suspend DHCPv4. */ 1328 1329uint32_t check_v6only(packet, client) 1330 struct packet *packet; 1331 struct client_state *client; 1332{ 1333 int i; 1334 struct option **req; 1335 isc_boolean_t found = ISC_FALSE; 1336 struct option_cache *oc; 1337 struct data_string data; 1338 uint32_t v6only_wait = 0; 1339 1340 /* Check if the v6-only-preferred was requested. */ 1341 req = client->config->requested_options; 1342 1343 if (req == NULL) 1344 return 0; 1345 1346 for (i = 0 ; req[i] != NULL ; i++) { 1347 if ((req[i]->universe == &dhcp_universe) && 1348 (req[i]->code == DHO_V6_ONLY_PREFERRED)) { 1349 found = ISC_TRUE; 1350 break; 1351 } 1352 } 1353 1354 if (found == ISC_FALSE) 1355 return 0; 1356 1357 /* Get the V6ONLY_WAIT timer. */ 1358 oc = lookup_option(&dhcp_universe, packet->options, 1359 DHO_V6_ONLY_PREFERRED); 1360 if (!oc) 1361 return 0; 1362 1363 memset(&data, 0, sizeof(data)); 1364 1365 if (evaluate_option_cache(&data, packet, (struct lease *)0, client, 1366 packet->options, (struct option_state *)0, 1367 &global_scope, oc, MDL)) { 1368 if (data.len == 4) { 1369 v6only_wait = getULong(data.data); 1370 if (v6only_wait < MIN_V6ONLY_WAIT) 1371 v6only_wait = MIN_V6ONLY_WAIT; 1372 } 1373 data_string_forget(&data, MDL); 1374 } 1375 1376 return (v6only_wait); 1377} 1378 1379/* finish_v6only is called when the V6ONLY_WAIT timer expired. */ 1380 1381void finish_v6only(cpp) 1382 void *cpp; 1383{ 1384 struct client_state *client = cpp; 1385 1386 cancel_timeout(finish_v6only, client); 1387 client->state = S_INIT; 1388 state_init(cpp); 1389} 1390 1391/* 1392 * start_v6only is called when a requested v6-only-preferred option was 1393 * returned by the server. */ 1394 1395void start_v6only(client, v6only_wait) 1396 struct client_state *client; 1397 uint32_t v6only_wait; 1398{ 1399 struct timeval tv; 1400 1401 /* Enter V6ONLY state. */ 1402 1403 client->state = S_V6ONLY; 1404 1405 /* Run the client script. */ 1406 script_init(client, "V6ONLY", NULL); 1407 if (client->active) { 1408 script_write_params(client, "old_", client->active); 1409 destroy_client_lease(client->active); 1410 client->active = NULL; 1411 } 1412 script_write_requested(client); 1413 client_envadd(client, "", "v6-only-preferred", "%lu", 1414 (long unsigned)v6only_wait); 1415 script_go(client); 1416 1417 /* Trigger finish_v6only after V6ONLY_WAIT seconds. */ 1418 tv.tv_sec = cur_tv.tv_sec + v6only_wait; 1419 tv.tv_usec = cur_tv.tv_usec; 1420 1421 add_timeout(&tv, finish_v6only, client, 0, 0); 1422} 1423 1424/* 1425 * state_selecting is called when one or more DHCPOFFER packets have been 1426 * received and a configurable period of time has passed. 1427 */ 1428 1429void state_selecting (cpp) 1430 void *cpp; 1431{ 1432 struct client_state *client = cpp; 1433 struct client_lease *lp, *next, *picked; 1434 1435 1436 ASSERT_STATE(state, S_SELECTING); 1437 1438 /* 1439 * Cancel state_selecting and send_discover timeouts, since either 1440 * one could have got us here. 1441 */ 1442 cancel_timeout (state_selecting, client); 1443 cancel_timeout (send_discover, client); 1444 1445 /* 1446 * We have received one or more DHCPOFFER packets. Currently, 1447 * the only criterion by which we judge leases is whether or 1448 * not we get a response when we arp for them. 1449 */ 1450 picked = NULL; 1451 for (lp = client -> offered_leases; lp; lp = next) { 1452 next = lp -> next; 1453 1454 /* 1455 * Check to see if we got an ARPREPLY for the address 1456 * in this particular lease. 1457 */ 1458 if (!picked) { 1459 picked = lp; 1460 picked -> next = NULL; 1461 } else { 1462 destroy_client_lease (lp); 1463 } 1464 } 1465 client -> offered_leases = NULL; 1466 1467 /* 1468 * If we just tossed all the leases we were offered, go back 1469 * to square one. 1470 */ 1471 if (!picked) { 1472 client -> state = S_INIT; 1473 state_init (client); 1474 return; 1475 } 1476 1477 /* If it was a BOOTREPLY, we can just take the address right now. */ 1478 if (picked -> is_bootp) { 1479 client -> new = picked; 1480 1481 /* Make up some lease expiry times 1482 XXX these should be configurable. */ 1483 client -> new -> expiry = cur_time + 12000; 1484 client -> new -> renewal += cur_time + 8000; 1485 client -> new -> rebind += cur_time + 10000; 1486 1487 client -> state = S_REQUESTING; 1488 1489 /* Bind to the address we received. */ 1490 bind_lease (client); 1491 return; 1492 } 1493 1494 /* Go to the REQUESTING state. */ 1495 client -> destination = iaddr_broadcast; 1496 client -> state = S_REQUESTING; 1497 client -> first_sending = cur_time; 1498 client -> interval = client -> config -> initial_interval; 1499 1500 /* Make a DHCPREQUEST packet from the lease we picked. */ 1501 make_request (client, picked); 1502 client -> xid = client -> packet.xid; 1503 1504 /* Toss the lease we picked - we'll get it back in a DHCPACK. */ 1505 destroy_client_lease (picked); 1506 1507 /* Add an immediate timeout to send the first DHCPREQUEST packet. */ 1508 send_request (client); 1509} 1510 1511static isc_boolean_t 1512compare_hw_address(const char *name, struct packet *packet) { 1513 if (packet->interface->hw_address.hlen - 1 != packet->raw->hlen || 1514 memcmp(&packet->interface->hw_address.hbuf[1], 1515 packet->raw->chaddr, packet->raw->hlen)) { 1516 unsigned char *c = packet->raw ->chaddr; 1517 log_error ("%s raw = %d %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", 1518 name, packet->raw->hlen, 1519 c[0], c[1], c[2], c[3], c[4], c[5]); 1520 c = &packet -> interface -> hw_address.hbuf [1]; 1521 log_error ("%s cooked = %d %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", 1522 name, packet->interface->hw_address.hlen - 1, 1523 c[0], c[1], c[2], c[3], c[4], c[5]); 1524 log_error ("%s in wrong transaction (%s ignored).", name, 1525 hw_mismatch_drop ? "packet" : "error"); 1526 return hw_mismatch_drop; 1527 } 1528 return ISC_FALSE; 1529} 1530 1531/* state_requesting is called when we receive a DHCPACK message after 1532 having sent out one or more DHCPREQUEST packets. */ 1533 1534void dhcpack (packet) 1535 struct packet *packet; 1536{ 1537 struct interface_info *ip = packet -> interface; 1538 struct client_state *client; 1539 uint32_t v6only_wait; 1540 struct client_lease *lease; 1541 struct option_cache *oc; 1542 struct data_string ds; 1543 1544 /* If we're not receptive to an offer right now, or if the offer 1545 has an unrecognizable transaction id, then just drop it. */ 1546 for (client = ip -> client; client; client = client -> next) { 1547 if (client -> xid == packet -> raw -> xid) 1548 break; 1549 } 1550 if (!client || compare_hw_address("DHCPACK", packet) == ISC_TRUE) 1551 return; 1552 1553 if (client -> state != S_REBOOTING && 1554 client -> state != S_REQUESTING && 1555 client -> state != S_RENEWING && 1556 client -> state != S_REBINDING) { 1557#if defined (DEBUG) 1558 log_debug ("DHCPACK in wrong state."); 1559#endif 1560 return; 1561 } 1562 1563 log_info ("DHCPACK of %s from %s", 1564 inet_ntoa(packet->raw->yiaddr), 1565 piaddr (packet->client_addr)); 1566 1567 /* Check v6only first. */ 1568 v6only_wait = check_v6only(packet, client); 1569 if (v6only_wait > 0) { 1570 log_info("v6 only preferred for %lu seconds.", 1571 (long unsigned)v6only_wait); 1572 cancel_timeout(send_request, client); 1573 start_v6only(client, v6only_wait); 1574 return; 1575 } 1576 1577 lease = packet_to_lease (packet, client); 1578 if (!lease) { 1579 log_info ("packet_to_lease failed."); 1580 return; 1581 } 1582 1583 client -> new = lease; 1584 1585 /* Stop resending DHCPREQUEST. */ 1586 cancel_timeout (send_request, client); 1587 1588 /* Figure out the lease time. */ 1589 oc = lookup_option (&dhcp_universe, client -> new -> options, 1590 DHO_DHCP_LEASE_TIME); 1591 memset (&ds, 0, sizeof ds); 1592 if (oc && 1593 evaluate_option_cache (&ds, packet, (struct lease *)0, client, 1594 packet -> options, client -> new -> options, 1595 &global_scope, oc, MDL)) { 1596 if (ds.len > 3) 1597 client -> new -> expiry = getULong (ds.data); 1598 else 1599 client -> new -> expiry = 0; 1600 data_string_forget (&ds, MDL); 1601 } else 1602 client -> new -> expiry = 0; 1603 1604 if (client->new->expiry == 0) { 1605 struct timeval tv; 1606 1607 log_error ("no expiry time on offered lease."); 1608 1609 /* Quench this (broken) server. Return to INIT to reselect. */ 1610 add_reject(packet); 1611 1612 /* 1/2 second delay to restart at INIT. */ 1613 tv.tv_sec = cur_tv.tv_sec; 1614 tv.tv_usec = cur_tv.tv_usec + 500000; 1615 1616 if (tv.tv_usec >= 1000000) { 1617 tv.tv_sec++; 1618 tv.tv_usec -= 1000000; 1619 } 1620 1621 add_timeout(&tv, state_init, client, 0, 0); 1622 return; 1623 } 1624 1625 /* 1626 * A number that looks negative here is really just very large, 1627 * because the lease expiry offset is unsigned. 1628 */ 1629 if (client->new->expiry < 0) 1630 client->new->expiry = TIME_MAX; 1631 1632 /* Take the server-provided renewal time if there is one. */ 1633 oc = lookup_option (&dhcp_universe, client -> new -> options, 1634 DHO_DHCP_RENEWAL_TIME); 1635 if (oc && 1636 evaluate_option_cache (&ds, packet, (struct lease *)0, client, 1637 packet -> options, client -> new -> options, 1638 &global_scope, oc, MDL)) { 1639 if (ds.len > 3) 1640 client -> new -> renewal = getULong (ds.data); 1641 else 1642 client -> new -> renewal = 0; 1643 data_string_forget (&ds, MDL); 1644 } else 1645 client -> new -> renewal = 0; 1646 1647 /* If it wasn't specified by the server, calculate it. */ 1648 if (!client -> new -> renewal) 1649 client -> new -> renewal = client -> new -> expiry / 2 + 1; 1650 1651 if (client -> new -> renewal <= 0) 1652 client -> new -> renewal = TIME_MAX; 1653 1654 /* Now introduce some randomness to the renewal time: */ 1655 if (client->new->renewal <= ((TIME_MAX / 3) - 3)) 1656 client->new->renewal = (((client->new->renewal * 3) + 3) / 4) + 1657 (((random() % client->new->renewal) + 3) / 4); 1658 1659 /* Same deal with the rebind time. */ 1660 oc = lookup_option (&dhcp_universe, client -> new -> options, 1661 DHO_DHCP_REBINDING_TIME); 1662 if (oc && 1663 evaluate_option_cache (&ds, packet, (struct lease *)0, client, 1664 packet -> options, client -> new -> options, 1665 &global_scope, oc, MDL)) { 1666 if (ds.len > 3) 1667 client -> new -> rebind = getULong (ds.data); 1668 else 1669 client -> new -> rebind = 0; 1670 data_string_forget (&ds, MDL); 1671 } else 1672 client -> new -> rebind = 0; 1673 1674 if (client -> new -> rebind <= 0) { 1675 if (client -> new -> expiry <= TIME_MAX / 7) 1676 client -> new -> rebind = 1677 client -> new -> expiry * 7 / 8; 1678 else 1679 client -> new -> rebind = 1680 client -> new -> expiry / 8 * 7; 1681 } 1682 1683 /* Make sure our randomness didn't run the renewal time past the 1684 rebind time. */ 1685 if (client -> new -> renewal > client -> new -> rebind) { 1686 if (client -> new -> rebind <= TIME_MAX / 3) 1687 client -> new -> renewal = 1688 client -> new -> rebind * 3 / 4; 1689 else 1690 client -> new -> renewal = 1691 client -> new -> rebind / 4 * 3; 1692 } 1693 1694 client -> new -> expiry += cur_time; 1695 /* Lease lengths can never be negative. */ 1696 if (client -> new -> expiry < cur_time) 1697 client -> new -> expiry = TIME_MAX; 1698 client -> new -> renewal += cur_time; 1699 if (client -> new -> renewal < cur_time) 1700 client -> new -> renewal = TIME_MAX; 1701 client -> new -> rebind += cur_time; 1702 if (client -> new -> rebind < cur_time) 1703 client -> new -> rebind = TIME_MAX; 1704 1705 bind_lease (client); 1706} 1707 1708void bind_lease (client) 1709 struct client_state *client; 1710{ 1711 struct timeval tv; 1712 1713 /* Remember the medium. */ 1714 client->new->medium = client->medium; 1715 1716 /* Run the client script with the new parameters. */ 1717 script_init(client, (client->state == S_REQUESTING ? "BOUND" : 1718 (client->state == S_RENEWING ? "RENEW" : 1719 (client->state == S_REBOOTING ? "REBOOT" : 1720 "REBIND"))), 1721 client->new->medium); 1722 if (client->active && client->state != S_REBOOTING) 1723 script_write_params(client, "old_", client->active); 1724 script_write_params(client, "new_", client->new); 1725 script_write_requested(client); 1726 if (client->alias) 1727 script_write_params(client, "alias_", client->alias); 1728 1729 /* If the BOUND/RENEW code detects another machine using the 1730 offered address, then per our man page it should exit with 1731 a non-zero status, to which we send a DHCPDECLINE and toss 1732 the lease. A return value of less than zero indicates 1733 the script crashed (e.g. segfault) which script_go will log 1734 but we will ignore here. */ 1735 if (script_go(client) > 0) { 1736 make_decline(client, client->new); 1737 send_decline(client); 1738 destroy_client_lease(client->new); 1739 client->new = NULL; 1740 if (onetry) { 1741 if (!quiet) { 1742 log_info("Unable to obtain a lease on first " 1743 "try (declined). Exiting."); 1744 } 1745 1746#if defined (CALL_SCRIPT_ON_ONETRY_FAIL) 1747 /* Let's call a script and we're done */ 1748 script_init(client, "FAIL", (struct string_list *)0); 1749 script_go(client); 1750#endif 1751 finish(2); 1752 } else { 1753 struct timeval tv; 1754 tv.tv_sec = cur_tv.tv_sec + decline_wait_time; 1755 tv.tv_usec = cur_tv.tv_usec; 1756 add_timeout(&tv, state_init, client, 0, 0); 1757 return; 1758 } 1759 } 1760 1761 /* Write out the new lease if it has been long enough. */ 1762 if (!client->last_write || 1763 (cur_time - client->last_write) >= MIN_LEASE_WRITE) 1764 write_client_lease(client, client->new, 0, 1); 1765 1766 /* Replace the old active lease with the new one. */ 1767 if (client->active) { 1768 if (client->active->is_static) { 1769 // We need to preserve the fallback lease in case 1770 // we lose DHCP service again. 1771 add_to_tail(&client->leases, client->active); 1772 } else { 1773 destroy_client_lease(client->active); 1774 } 1775 } 1776 1777 client->active = client->new; 1778 client->new = NULL; 1779 1780 /* Set up a timeout to start the renewal process. */ 1781 tv.tv_sec = client->active->renewal; 1782 tv.tv_usec = ((client->active->renewal - cur_tv.tv_sec) > 1) ? 1783 random() % 1000000 : cur_tv.tv_usec; 1784 add_timeout(&tv, state_bound, client, 0, 0); 1785 1786 log_info("bound to %s -- renewal in %ld seconds.", 1787 piaddr(client->active->address), 1788 (long)(client->active->renewal - cur_time)); 1789 client->state = S_BOUND; 1790 reinitialize_interfaces(); 1791 detach(); 1792#if defined (NSUPDATE) 1793 if (client->config->do_forward_update) 1794 dhclient_schedule_updates(client, &client->active->address, 1); 1795#endif /* defined NSUPDATE */ 1796 1797} 1798 1799/* state_bound is called when we've successfully bound to a particular 1800 lease, but the renewal time on that lease has expired. We are 1801 expected to unicast a DHCPREQUEST to the server that gave us our 1802 original lease. */ 1803 1804void state_bound (cpp) 1805 void *cpp; 1806{ 1807 struct client_state *client = cpp; 1808 struct option_cache *oc; 1809 struct data_string ds; 1810 1811 ASSERT_STATE(state, S_BOUND); 1812 1813 /* T1 has expired. */ 1814 make_request (client, client -> active); 1815 client -> xid = client -> packet.xid; 1816 1817 memset (&ds, 0, sizeof ds); 1818 oc = lookup_option (&dhcp_universe, client -> active -> options, 1819 DHO_DHCP_SERVER_IDENTIFIER); 1820 if (oc && 1821 evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0, 1822 client, (struct option_state *)0, 1823 client -> active -> options, 1824 &global_scope, oc, MDL)) { 1825 if (ds.len > 3) { 1826 memcpy (client -> destination.iabuf, ds.data, 4); 1827 client -> destination.len = 4; 1828 } else 1829 client -> destination = iaddr_broadcast; 1830 1831 data_string_forget (&ds, MDL); 1832 } else 1833 client -> destination = iaddr_broadcast; 1834 1835 client -> first_sending = cur_time; 1836 client -> interval = client -> config -> initial_interval; 1837 client -> state = S_RENEWING; 1838 1839 /* Send the first packet immediately. */ 1840 send_request (client); 1841} 1842 1843/* state_stop is called when we've been told to shut down. We unconfigure 1844 the interfaces, and then stop operating until told otherwise. */ 1845 1846void state_stop (cpp) 1847 void *cpp; 1848{ 1849 struct client_state *client = cpp; 1850 1851 client->pending = P_NONE; 1852 1853 /* Cancel all timeouts. */ 1854 cancel_timeout(state_selecting, client); 1855 cancel_timeout(send_discover, client); 1856 cancel_timeout(send_request, client); 1857 cancel_timeout(state_bound, client); 1858 cancel_timeout(finish_v6only, client); 1859 1860 /* If we have an address, unconfigure it. */ 1861 if (client->active) { 1862 script_init(client, "STOP", client->active->medium); 1863 script_write_params(client, "old_", client->active); 1864 script_write_requested(client); 1865 if (client->alias) 1866 script_write_params(client, "alias_", client->alias); 1867 script_go(client); 1868 } 1869} 1870 1871int commit_leases () 1872{ 1873 return 0; 1874} 1875 1876int write_lease (lease) 1877 struct lease *lease; 1878{ 1879 return 0; 1880} 1881 1882int write_host (host) 1883 struct host_decl *host; 1884{ 1885 return 0; 1886} 1887 1888void db_startup (testp) 1889 int testp; 1890{ 1891} 1892 1893void bootp (packet) 1894 struct packet *packet; 1895{ 1896 struct iaddrmatchlist *ap; 1897 char addrbuf[4*16]; 1898 char maskbuf[4*16]; 1899 1900 if (packet -> raw -> op != BOOTREPLY) 1901 return; 1902 1903 /* If there's a reject list, make sure this packet's sender isn't 1904 on it. */ 1905 for (ap = packet -> interface -> client -> config -> reject_list; 1906 ap; ap = ap -> next) { 1907 if (addr_match(&packet->client_addr, &ap->match)) { 1908 1909 /* piaddr() returns its result in a static 1910 buffer sized 4*16 (see common/inet.c). */ 1911 1912 strcpy(addrbuf, piaddr(ap->match.addr)); 1913 strcpy(maskbuf, piaddr(ap->match.mask)); 1914 1915 log_info("BOOTREPLY from %s rejected by rule %s " 1916 "mask %s.", piaddr(packet->client_addr), 1917 addrbuf, maskbuf); 1918 return; 1919 } 1920 } 1921 1922 dhcpoffer (packet); 1923 1924} 1925 1926void dhcp (packet) 1927 struct packet *packet; 1928{ 1929 struct iaddrmatchlist *ap; 1930 void (*handler) (struct packet *); 1931 const char *type; 1932 char addrbuf[4*16]; 1933 char maskbuf[4*16]; 1934 1935 switch (packet -> packet_type) { 1936 case DHCPOFFER: 1937 handler = dhcpoffer; 1938 type = "DHCPOFFER"; 1939 break; 1940 1941 case DHCPNAK: 1942 handler = dhcpnak; 1943 type = "DHCPNACK"; 1944 break; 1945 1946 case DHCPACK: 1947 handler = dhcpack; 1948 type = "DHCPACK"; 1949 break; 1950 1951 default: 1952 return; 1953 } 1954 1955 /* If there's a reject list, make sure this packet's sender isn't 1956 on it. */ 1957 for (ap = packet -> interface -> client -> config -> reject_list; 1958 ap; ap = ap -> next) { 1959 if (addr_match(&packet->client_addr, &ap->match)) { 1960 1961 /* piaddr() returns its result in a static 1962 buffer sized 4*16 (see common/inet.c). */ 1963 1964 strcpy(addrbuf, piaddr(ap->match.addr)); 1965 strcpy(maskbuf, piaddr(ap->match.mask)); 1966 1967 log_info("%s from %s rejected by rule %s mask %s.", 1968 type, piaddr(packet->client_addr), 1969 addrbuf, maskbuf); 1970 return; 1971 } 1972 } 1973 (*handler) (packet); 1974} 1975 1976#ifdef DHCPv6 1977void 1978dhcpv6(struct packet *packet) { 1979 struct iaddrmatchlist *ap; 1980 struct client_state *client; 1981 char addrbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]; 1982 1983 /* Silently drop bogus messages. */ 1984 if (packet->dhcpv6_msg_type >= dhcpv6_type_name_max) 1985 return; 1986 1987 /* Discard, with log, packets from quenched sources. */ 1988 for (ap = packet->interface->client->config->reject_list ; 1989 ap ; ap = ap->next) { 1990 if (addr_match(&packet->client_addr, &ap->match)) { 1991 strcpy(addrbuf, piaddr(packet->client_addr)); 1992 log_info("%s from %s rejected by rule %s", 1993 dhcpv6_type_names[packet->dhcpv6_msg_type], 1994 addrbuf, 1995 piaddrmask(&ap->match.addr, &ap->match.mask)); 1996 return; 1997 } 1998 } 1999 2000 /* Screen out nonsensical messages. */ 2001 switch(packet->dhcpv6_msg_type) { 2002#ifdef DHCP4o6 2003 case DHCPV6_DHCPV4_RESPONSE: 2004 if (dhcpv4_over_dhcpv6) { 2005 log_info("RCV: %s message on %s from %s.", 2006 dhcpv6_type_names[packet->dhcpv6_msg_type], 2007 packet->interface->name, 2008 piaddr(packet->client_addr)); 2009 forw_dhcpv4_response(packet); 2010 } 2011 return; 2012#endif 2013 case DHCPV6_ADVERTISE: 2014 case DHCPV6_RECONFIGURE: 2015 if (stateless) 2016 return; 2017 /* Falls through */ 2018 case DHCPV6_REPLY: 2019 log_info("RCV: %s message on %s from %s.", 2020 dhcpv6_type_names[packet->dhcpv6_msg_type], 2021 packet->interface->name, piaddr(packet->client_addr)); 2022 break; 2023 2024 default: 2025 return; 2026 } 2027 2028 /* Find a client state that matches the incoming XID. */ 2029 for (client = packet->interface->client ; client ; 2030 client = client->next) { 2031 if (memcmp(&client->dhcpv6_transaction_id, 2032 packet->dhcpv6_transaction_id, 3) == 0) { 2033 client->v6_handler(packet, client); 2034 return; 2035 } 2036 } 2037 2038 /* XXX: temporary log for debugging */ 2039 log_info("Packet received, but nothing done with it."); 2040} 2041 2042#ifdef DHCP4o6 2043/* 2044 * \brief Forward a DHCPv4-response to the DHCPv4 client. 2045 * (DHCPv6 client function) 2046 * 2047 * The DHCPv6 client receives a DHCPv4-response which is forwarded 2048 * to the DHCPv4 client. 2049 * Format: address:16 + DHCPv4 message content 2050 * (we have no state to keep the address so it is transported in 2051 * DHCPv6 <-> DHCPv6 inter-process messages) 2052 * 2053 * \param packet the DHCPv4-response packet 2054 */ 2055static void forw_dhcpv4_response(struct packet *packet) 2056{ 2057 struct option_cache *oc; 2058 struct data_string enc_opt_data; 2059 struct data_string ds; 2060 int cc; 2061 2062 /* 2063 * Discard if relay is not ready. 2064 */ 2065 if (dhcp4o6_state == -1) { 2066 log_info("forw_dhcpv4_response: not ready."); 2067 return; 2068 } 2069 2070 if (packet->client_addr.len != 16) { 2071 log_error("forw_dhcpv4_response: bad address"); 2072 return; 2073 } 2074 2075 /* 2076 * Get our encapsulated DHCPv4 message. 2077 */ 2078 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_DHCPV4_MSG); 2079 if (oc == NULL) { 2080 log_info("DHCPv4-response from %s missing " 2081 "DHCPv4 Message option.", 2082 piaddr(packet->client_addr)); 2083 return; 2084 } 2085 2086 memset(&enc_opt_data, 0, sizeof(enc_opt_data)); 2087 if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL, 2088 NULL, NULL, &global_scope, oc, MDL)) { 2089 log_error("forw_dhcpv4_response: error evaluating " 2090 "DHCPv4 message."); 2091 data_string_forget(&enc_opt_data, MDL); 2092 return; 2093 } 2094 2095 if (enc_opt_data.len < DHCP_FIXED_NON_UDP) { 2096 log_error("forw_dhcpv4_response: " 2097 "no memory for encapsulated packet."); 2098 data_string_forget(&enc_opt_data, MDL); 2099 return; 2100 } 2101 2102 /* 2103 * Append address. 2104 */ 2105 memset(&ds, 0, sizeof(ds)); 2106 if (!buffer_allocate(&ds.buffer, enc_opt_data.len + 16, MDL)) { 2107 log_error("forw_dhcpv4_response: no memory buffer."); 2108 data_string_forget(&enc_opt_data, MDL); 2109 return; 2110 } 2111 ds.data = ds.buffer->data; 2112 ds.len = enc_opt_data.len + 16; 2113 memcpy(ds.buffer->data, enc_opt_data.data, enc_opt_data.len); 2114 memcpy(ds.buffer->data + enc_opt_data.len, 2115 packet->client_addr.iabuf, 16); 2116 data_string_forget(&enc_opt_data, MDL); 2117 2118 /* 2119 * Forward them. 2120 */ 2121 cc = send(dhcp4o6_fd, ds.data, ds.len, 0); 2122 if (cc < 0) 2123 log_error("forw_dhcpv4_response: send(): %m"); 2124 2125 data_string_forget(&ds, MDL); 2126} 2127 2128/* 2129 * \brief Receive a DHCPv4-response from the DHCPv6 client. 2130 * (DHCPv4 client function) 2131 * 2132 * The DHCPv4 client receives a DHCPv4-response forwarded 2133 * by the DHCPv6 client (using \ref forw_dhcpv4_response()) 2134 * 2135 * \param raw the DHCPv4-response raw packet 2136 */ 2137static void recv_dhcpv4_response(struct data_string *raw) 2138{ 2139 struct packet *packet; 2140 struct iaddr from; 2141 2142 if (interfaces == NULL) { 2143 log_error("recv_dhcpv4_response: no interfaces."); 2144 return; 2145 } 2146 2147 from.len = 16; 2148 memcpy(from.iabuf, raw->data + (raw->len - 16), 16); 2149 2150 /* 2151 * Build a packet structure. 2152 */ 2153 packet = NULL; 2154 if (!packet_allocate(&packet, MDL)) { 2155 log_error("recv_dhcpv4_response: no memory for packet."); 2156 return; 2157 } 2158 2159 packet->raw = (struct dhcp_packet *) raw->data; 2160 packet->packet_length = raw->len - 16; 2161 packet->client_port = remote_port; 2162 packet->client_addr = from; 2163 interface_reference(&packet->interface, interfaces, MDL); 2164 2165 /* Allocate packet->options now so it is non-null for all packets */ 2166 if (!option_state_allocate (&packet->options, MDL)) { 2167 log_error("recv_dhcpv4_response: no memory for options."); 2168 packet_dereference (&packet, MDL); 2169 return; 2170 } 2171 2172 /* If there's an option buffer, try to parse it. */ 2173 if (packet->packet_length >= DHCP_FIXED_NON_UDP + 4) { 2174 struct option_cache *op; 2175 if (!parse_options(packet)) { 2176 if (packet->options) 2177 option_state_dereference 2178 (&packet->options, MDL); 2179 packet_dereference (&packet, MDL); 2180 return; 2181 } 2182 2183 if (packet->options_valid && 2184 (op = lookup_option(&dhcp_universe, 2185 packet->options, 2186 DHO_DHCP_MESSAGE_TYPE))) { 2187 struct data_string dp; 2188 memset(&dp, 0, sizeof dp); 2189 evaluate_option_cache(&dp, packet, NULL, NULL, 2190 packet->options, NULL, 2191 NULL, op, MDL); 2192 if (dp.len > 0) 2193 packet->packet_type = dp.data[0]; 2194 else 2195 packet->packet_type = 0; 2196 data_string_forget(&dp, MDL); 2197 } 2198 } 2199 2200 if (validate_packet(packet) != 0) { 2201 if (packet->packet_type) 2202 dhcp(packet); 2203 else 2204 bootp(packet); 2205 } 2206 2207 /* If the caller kept the packet, they'll have upped the refcnt. */ 2208 packet_dereference(&packet, MDL); 2209} 2210#endif /* DHCP4o6 */ 2211#endif /* DHCPv6 */ 2212 2213void dhcpoffer (packet) 2214 struct packet *packet; 2215{ 2216 struct interface_info *ip = packet -> interface; 2217 struct client_state *client; 2218 uint32_t v6only_wait; 2219 struct client_lease *lease, *lp; 2220 struct option **req; 2221 int i; 2222 int stop_selecting; 2223 const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY"; 2224 char obuf [1024]; 2225 struct timeval tv; 2226 2227#ifdef DEBUG_PACKET 2228 dump_packet (packet); 2229#endif 2230 2231 /* Find a client state that matches the xid... */ 2232 for (client = ip -> client; client; client = client -> next) 2233 if (client -> xid == packet -> raw -> xid) 2234 break; 2235 2236 /* If we're not receptive to an offer right now, or if the offer 2237 has an unrecognizable transaction id, then just drop it. */ 2238 if (!client || client -> state != S_SELECTING || 2239 compare_hw_address(name, packet) == ISC_TRUE) 2240 return; 2241 2242 sprintf (obuf, "%s of %s from %s", name, 2243 inet_ntoa(packet->raw->yiaddr), 2244 piaddr(packet->client_addr)); 2245 2246 /* Check v6only first. */ 2247 v6only_wait = check_v6only(packet, client); 2248 if (v6only_wait > 0) { 2249 log_info("%s: v6 only preferred for %lu.", obuf, 2250 (long unsigned)v6only_wait); 2251 cancel_timeout(send_discover, client); 2252 start_v6only(client, v6only_wait); 2253 return; 2254 } 2255 2256 /* If this lease doesn't supply the minimum required DHCPv4 parameters, 2257 * ignore it. 2258 */ 2259 req = client->config->required_options; 2260 if (req != NULL) { 2261 for (i = 0 ; req[i] != NULL ; i++) { 2262 if ((req[i]->universe == &dhcp_universe) && 2263 !lookup_option(&dhcp_universe, packet->options, 2264 req[i]->code)) { 2265 struct option *option = NULL; 2266 unsigned code = req[i]->code; 2267 2268 option_code_hash_lookup(&option, 2269 dhcp_universe.code_hash, 2270 &code, 0, MDL); 2271 2272 if (option) 2273 log_info("%s: no %s option.", obuf, 2274 option->name); 2275 else 2276 log_info("%s: no unknown-%u option.", 2277 obuf, code); 2278 2279 option_dereference(&option, MDL); 2280 2281 return; 2282 } 2283 } 2284 } 2285 2286 /* If we've already seen this lease, don't record it again. */ 2287 for (lease = client -> offered_leases; lease; lease = lease -> next) { 2288 if (lease -> address.len == sizeof packet -> raw -> yiaddr && 2289 !memcmp (lease -> address.iabuf, 2290 &packet -> raw -> yiaddr, lease -> address.len)) { 2291 log_debug ("%s: already seen.", obuf); 2292 return; 2293 } 2294 } 2295 2296 lease = packet_to_lease (packet, client); 2297 if (!lease) { 2298 log_info ("%s: packet_to_lease failed.", obuf); 2299 return; 2300 } 2301 2302 /* log it now, so it emits before the request goes out */ 2303 log_info("%s", obuf); 2304 2305 /* If this lease was acquired through a BOOTREPLY, record that 2306 fact. */ 2307 if (!packet -> options_valid || !packet -> packet_type) 2308 lease -> is_bootp = 1; 2309 2310 /* Record the medium under which this lease was offered. */ 2311 lease -> medium = client -> medium; 2312 2313 /* Figure out when we're supposed to stop selecting. */ 2314 stop_selecting = (client -> first_sending + 2315 client -> config -> select_interval); 2316 2317 /* If this is the lease we asked for, put it at the head of the 2318 list, and don't mess with the arp request timeout. */ 2319 if (lease -> address.len == client -> requested_address.len && 2320 !memcmp (lease -> address.iabuf, 2321 client -> requested_address.iabuf, 2322 client -> requested_address.len)) { 2323 lease -> next = client -> offered_leases; 2324 client -> offered_leases = lease; 2325 } else { 2326 /* Put the lease at the end of the list. */ 2327 lease -> next = (struct client_lease *)0; 2328 if (!client -> offered_leases) 2329 client -> offered_leases = lease; 2330 else { 2331 for (lp = client -> offered_leases; lp -> next; 2332 lp = lp -> next) 2333 ; 2334 lp -> next = lease; 2335 } 2336 } 2337 2338 /* If the selecting interval has expired, go immediately to 2339 state_selecting(). Otherwise, time out into 2340 state_selecting at the select interval. */ 2341 if (stop_selecting <= cur_tv.tv_sec) 2342 state_selecting (client); 2343 else { 2344 tv.tv_sec = stop_selecting; 2345 tv.tv_usec = cur_tv.tv_usec; 2346 add_timeout(&tv, state_selecting, client, 0, 0); 2347 cancel_timeout(send_discover, client); 2348 } 2349} 2350 2351/* Allocate a client_lease structure and initialize it from the parameters 2352 in the specified packet. */ 2353 2354struct client_lease *packet_to_lease (packet, client) 2355 struct packet *packet; 2356 struct client_state *client; 2357{ 2358 struct client_lease *lease; 2359 unsigned i; 2360 struct option_cache *oc; 2361 struct option *option = NULL; 2362 struct data_string data; 2363 2364 lease = (struct client_lease *)new_client_lease (MDL); 2365 2366 if (!lease) { 2367 log_error("packet_to_lease: no memory to record lease.\n"); 2368 return NULL; 2369 } 2370 2371 memset(lease, 0, sizeof(*lease)); 2372 2373 /* Copy the lease options. */ 2374 option_state_reference(&lease->options, packet->options, MDL); 2375 2376 lease->address.len = sizeof(packet->raw->yiaddr); 2377 memcpy(lease->address.iabuf, &packet->raw->yiaddr, 2378 lease->address.len); 2379 2380 lease->next_srv_addr.len = sizeof(packet->raw->siaddr); 2381 memcpy(lease->next_srv_addr.iabuf, &packet->raw->siaddr, 2382 lease->next_srv_addr.len); 2383 2384 memset(&data, 0, sizeof(data)); 2385 2386 if (client -> config -> vendor_space_name) { 2387 i = DHO_VENDOR_ENCAPSULATED_OPTIONS; 2388 2389 /* See if there was a vendor encapsulation option. */ 2390 oc = lookup_option (&dhcp_universe, lease -> options, i); 2391 if (oc && 2392 client -> config -> vendor_space_name && 2393 evaluate_option_cache (&data, packet, 2394 (struct lease *)0, client, 2395 packet -> options, lease -> options, 2396 &global_scope, oc, MDL)) { 2397 if (data.len) { 2398 if (!option_code_hash_lookup(&option, 2399 dhcp_universe.code_hash, 2400 &i, 0, MDL)) 2401 log_fatal("Unable to find VENDOR " 2402 "option (%s:%d).", MDL); 2403 parse_encapsulated_suboptions 2404 (packet -> options, option, 2405 data.data, data.len, &dhcp_universe, 2406 client -> config -> vendor_space_name 2407 ); 2408 2409 option_dereference(&option, MDL); 2410 } 2411 data_string_forget (&data, MDL); 2412 } 2413 } else 2414 i = 0; 2415 2416 /* Figure out the overload flag. */ 2417 oc = lookup_option (&dhcp_universe, lease -> options, 2418 DHO_DHCP_OPTION_OVERLOAD); 2419 if (oc && 2420 evaluate_option_cache (&data, packet, (struct lease *)0, client, 2421 packet -> options, lease -> options, 2422 &global_scope, oc, MDL)) { 2423 if (data.len > 0) 2424 i = data.data [0]; 2425 else 2426 i = 0; 2427 data_string_forget (&data, MDL); 2428 } else 2429 i = 0; 2430 2431 /* If the server name was filled out, copy it. */ 2432 if (!(i & 2) && packet -> raw -> sname [0]) { 2433 unsigned len; 2434 /* Don't count on the NUL terminator. */ 2435 for (len = 0; len < DHCP_SNAME_LEN; len++) 2436 if (!packet -> raw -> sname [len]) 2437 break; 2438 lease -> server_name = dmalloc (len + 1, MDL); 2439 if (!lease -> server_name) { 2440 log_error ("dhcpoffer: no memory for server name.\n"); 2441 destroy_client_lease (lease); 2442 return (struct client_lease *)0; 2443 } else { 2444 memcpy (lease -> server_name, 2445 packet -> raw -> sname, len); 2446 lease -> server_name [len] = 0; 2447 } 2448 } 2449 2450 /* Ditto for the filename. */ 2451 if (!(i & 1) && packet -> raw -> file [0]) { 2452 unsigned len; 2453 /* Don't count on the NUL terminator. */ 2454 for (len = 0; len < DHCP_FILE_LEN; len++) 2455 if (!packet -> raw -> file [len]) 2456 break; 2457 lease -> filename = dmalloc (len + 1, MDL); 2458 if (!lease -> filename) { 2459 log_error ("dhcpoffer: no memory for filename.\n"); 2460 destroy_client_lease (lease); 2461 return (struct client_lease *)0; 2462 } else { 2463 memcpy (lease -> filename, 2464 packet -> raw -> file, len); 2465 lease -> filename [len] = 0; 2466 } 2467 } 2468 2469 execute_statements_in_scope(NULL, (struct packet *)packet, NULL, 2470 client, lease->options, lease->options, 2471 &global_scope, client->config->on_receipt, 2472 NULL, NULL); 2473 2474 return lease; 2475} 2476 2477void dhcpnak (packet) 2478 struct packet *packet; 2479{ 2480 struct interface_info *ip = packet -> interface; 2481 struct client_state *client; 2482 2483 /* Find a client state that matches the xid... */ 2484 for (client = ip -> client; client; client = client -> next) 2485 if (client -> xid == packet -> raw -> xid) 2486 break; 2487 2488 /* If we're not receptive to an offer right now, or if the offer 2489 has an unrecognizable transaction id, then just drop it. */ 2490 if (!client || compare_hw_address("DHCPNAK", packet) == ISC_TRUE) 2491 return; 2492 2493 if (client -> state != S_REBOOTING && 2494 client -> state != S_REQUESTING && 2495 client -> state != S_RENEWING && 2496 client -> state != S_REBINDING) { 2497#if defined (DEBUG) 2498 log_debug ("DHCPNAK in wrong state."); 2499#endif 2500 return; 2501 } 2502 2503 log_info ("DHCPNAK from %s", piaddr (packet -> client_addr)); 2504 2505 if (!client -> active) { 2506#if defined (DEBUG) 2507 log_info ("DHCPNAK with no active lease.\n"); 2508#endif 2509 return; 2510 } 2511 2512 /* If we get a DHCPNAK, we use the EXPIRE dhclient-script state 2513 * to indicate that we want all old bindings to be removed. (It 2514 * is possible that we may get a NAK while in the RENEW state, 2515 * so we might have bindings active at that time) 2516 */ 2517 script_init(client, "EXPIRE", NULL); 2518 script_write_params(client, "old_", client->active); 2519 script_write_requested(client); 2520 if (client->alias) 2521 script_write_params(client, "alias_", client->alias); 2522 script_go(client); 2523 2524 destroy_client_lease (client -> active); 2525 client -> active = (struct client_lease *)0; 2526 2527 /* Stop sending DHCPREQUEST packets... */ 2528 cancel_timeout (send_request, client); 2529 2530 /* On some scripts, 'EXPIRE' causes the interface to be ifconfig'd 2531 * down (this expunges any routes and arp cache). This makes the 2532 * interface unusable by state_init(), which we call next. So, we 2533 * need to 'PREINIT' the interface to bring it back up. 2534 */ 2535 script_init(client, "PREINIT", NULL); 2536 if (client->alias) 2537 script_write_params(client, "alias_", client->alias); 2538 script_go(client); 2539 2540 client -> state = S_INIT; 2541 state_init (client); 2542} 2543 2544/* Send out a DHCPDISCOVER packet, and set a timeout to send out another 2545 one after the right interval has expired. If we don't get an offer by 2546 the time we reach the panic interval, call the panic function. */ 2547 2548void send_discover (cpp) 2549 void *cpp; 2550{ 2551 struct client_state *client = cpp; 2552 2553 int result; 2554 int interval; 2555 int increase = 1; 2556 struct timeval tv; 2557 2558 /* Figure out how long it's been since we started transmitting. */ 2559 interval = cur_time - client -> first_sending; 2560 2561 /* If we're past the panic timeout, call the script and tell it 2562 we haven't found anything for this interface yet. */ 2563 if (interval > client -> config -> timeout) { 2564 state_panic (client); 2565 return; 2566 } 2567 2568 /* If we're selecting media, try the whole list before doing 2569 the exponential backoff, but if we've already received an 2570 offer, stop looping, because we obviously have it right. */ 2571 if (!client -> offered_leases && 2572 client -> config -> media) { 2573 int fail = 0; 2574 again: 2575 if (client -> medium) { 2576 client -> medium = client -> medium -> next; 2577 increase = 0; 2578 } 2579 if (!client -> medium) { 2580 if (fail) 2581 log_fatal ("No valid media types for %s!", 2582 client -> interface -> name); 2583 client -> medium = 2584 client -> config -> media; 2585 increase = 1; 2586 } 2587 2588 log_info ("Trying medium \"%s\" %d", 2589 client -> medium -> string, increase); 2590 script_init(client, "MEDIUM", client -> medium); 2591 if (script_go(client)) { 2592 fail = 1; 2593 goto again; 2594 } 2595 } 2596 2597 /* If we're supposed to increase the interval, do so. If it's 2598 currently zero (i.e., we haven't sent any packets yet), set 2599 it to initial_interval; otherwise, add to it a random number 2600 between zero and two times itself. On average, this means 2601 that it will double with every transmission. */ 2602 if (increase) { 2603 if (!client->interval) 2604 client->interval = client->config->initial_interval; 2605 else 2606 client->interval += random() % (2 * client->interval); 2607 2608 /* Don't backoff past cutoff. */ 2609 if (client->interval > client->config->backoff_cutoff) 2610 client->interval = (client->config->backoff_cutoff / 2) 2611 + (random() % client->config->backoff_cutoff); 2612 } else if (!client->interval) 2613 client->interval = client->config->initial_interval; 2614 2615 /* If the backoff would take us to the panic timeout, just use that 2616 as the interval. */ 2617 if (cur_time + client -> interval > 2618 client -> first_sending + client -> config -> timeout) 2619 client -> interval = 2620 (client -> first_sending + 2621 client -> config -> timeout) - cur_time + 1; 2622 2623 /* Record the number of seconds since we started sending. */ 2624 if (interval < 65536) 2625 client -> packet.secs = htons (interval); 2626 else 2627 client -> packet.secs = htons (65535); 2628 client -> secs = client -> packet.secs; 2629 2630#if defined(DHCPv6) && defined(DHCP4o6) 2631 if (dhcpv4_over_dhcpv6) { 2632 log_info ("DHCPDISCOVER interval %ld", 2633 (long)(client -> interval)); 2634 } else 2635#endif 2636 log_info ("DHCPDISCOVER on %s to %s port %d interval %ld", 2637 client -> name ? client -> name : client -> interface -> name, 2638 inet_ntoa (sockaddr_broadcast.sin_addr), 2639 ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval)); 2640 2641 /* Send out a packet. */ 2642#if defined(DHCPv6) && defined(DHCP4o6) 2643 if (dhcpv4_over_dhcpv6) { 2644 result = send_dhcpv4_query(client, 1); 2645 } else 2646#endif 2647 result = send_packet(client->interface, NULL, &client->packet, 2648 client->packet_length, inaddr_any, 2649 &sockaddr_broadcast, NULL); 2650 if (result < 0) { 2651#if defined(DHCPv6) && defined(DHCP4o6) 2652 if (dhcpv4_over_dhcpv6) { 2653 log_error("%s:%d: Failed to send %d byte long packet.", 2654 MDL, client->packet_length); 2655 } else 2656#endif 2657 log_error("%s:%d: Failed to send %d byte long packet over %s " 2658 "interface.", MDL, client->packet_length, 2659 client->interface->name); 2660 } 2661 2662 /* 2663 * If we used 0 microseconds here, and there were other clients on the 2664 * same network with a synchronized local clock (ntp), and a similar 2665 * zero-microsecond-scheduler behavior, then we could be participating 2666 * in a sub-second DOS ttck. 2667 */ 2668 tv.tv_sec = cur_tv.tv_sec + client->interval; 2669 tv.tv_usec = client->interval > 1 ? random() % 1000000 : cur_tv.tv_usec; 2670 add_timeout(&tv, send_discover, client, 0, 0); 2671} 2672 2673 2674/* 2675 * \brief Remove leases from a list of leases which duplicate a given lease 2676 * 2677 * Searches through a linked-list of leases, remove the first one matches the 2678 * given lease's address and value of is_static. The latter test is done 2679 * so we only remove leases that are from the same source (i.e server/lease file 2680 * vs config file). This ensures we do not discard "fallback" config file leases 2681 * that happen to match non-config file leases. 2682 * 2683 * \param lease_list list of leases to clean 2684 * \param lease lease for which duplicates should be removed 2685 */ 2686extern void discard_duplicate (struct client_lease** lease_list, 2687 struct client_lease* lease); 2688void discard_duplicate (struct client_lease** lease_list, struct client_lease* lease) { 2689 struct client_lease *cur, *prev, *next; 2690 2691 if (!lease_list || !lease) { 2692 return; 2693 } 2694 2695 prev = (struct client_lease *)0; 2696 for (cur = *lease_list; cur; cur = next) { 2697 next = cur->next; 2698 if ((cur->is_static == lease->is_static) && 2699 (cur->address.len == lease->address.len && 2700 !memcmp (cur->address.iabuf, lease->address.iabuf, 2701 lease->address.len))) { 2702 if (prev) 2703 prev->next = next; 2704 else 2705 *lease_list = next; 2706 2707 destroy_client_lease (cur); 2708 break; 2709 } else { 2710 prev = cur; 2711 } 2712 } 2713} 2714 2715/* 2716 * \brief Add a given lease to the end of list of leases 2717 * 2718 * Searches through a linked-list of leases, removing any that match the 2719 * given lease's address and value of is_static. The latter test is done 2720 * so we only remove leases that are from the same source (i.e server/lease file 2721 * vs config file). This ensures we do not discard "fallback" config file leases 2722 * that happen to match non-config file leases. 2723 * 2724 * \param lease_list list of leases to clean 2725 * \param lease lease for which duplicates should be removed 2726 */ 2727void add_to_tail(struct client_lease** lease_list, 2728 struct client_lease* lease) 2729{ 2730 if (!lease_list || !lease) { 2731 return; 2732 } 2733 2734 /* If there is already a lease for this address and 2735 * is_static value, toss discard it. This ensures 2736 * we only keep one dynamic and/or one static lease 2737 * for a given address. */ 2738 discard_duplicate(lease_list, lease); 2739 2740 /* Find the tail */ 2741 struct client_lease* tail; 2742 for (tail = *lease_list; tail && tail->next; tail = tail->next){}; 2743 2744 /* Ensure the tail points nowhere. */ 2745 lease->next = NULL; 2746 2747 /* Add to the tail. */ 2748 if (!tail) { 2749 *lease_list = lease; 2750 } else { 2751 tail->next = lease; 2752 } 2753} 2754 2755#if 0 2756void dbg_print_lease(char *text, struct client_lease* lease) { 2757 if (!lease) { 2758 log_debug("%s, lease is null", text); 2759 } else { 2760 log_debug ("%s: %p addr:%s expires:%ld :is_static? %d", 2761 text, lease, piaddr (lease->address), 2762 (lease->expiry - cur_time), 2763 lease->is_static); 2764 } 2765} 2766#endif 2767 2768/* state_panic gets called if we haven't received any offers in a preset 2769 amount of time. When this happens, we try to use existing leases that 2770 haven't yet expired, and failing that, we call the client script and 2771 hope it can do something. */ 2772 2773void state_panic (cpp) 2774 void *cpp; 2775{ 2776 struct client_state *client = cpp; 2777 struct client_lease *loop; 2778 struct client_lease *lp; 2779 struct timeval tv; 2780 2781 loop = lp = client -> active; 2782 2783 log_info ("No DHCPOFFERS received."); 2784 2785 /* We may not have an active lease, but we may have some 2786 predefined leases that we can try. */ 2787 if (!client -> active && client -> leases) 2788 goto activate_next; 2789 2790 /* Run through the list of leases and see if one can be used. */ 2791 while (client -> active) { 2792 if (client -> active -> expiry > cur_time) { 2793 log_info ("Trying %s lease %s", 2794 (client -> active -> is_static 2795 ? "fallback" : "recorded"), 2796 piaddr (client -> active -> address)); 2797 /* Run the client script with the existing 2798 parameters. */ 2799 script_init(client, "TIMEOUT", 2800 client -> active -> medium); 2801 script_write_params(client, "new_", client -> active); 2802 script_write_requested(client); 2803 if (client -> alias) 2804 script_write_params(client, "alias_", 2805 client -> alias); 2806 2807 /* If the old lease is still good and doesn't 2808 yet need renewal, go into BOUND state and 2809 timeout at the renewal time. */ 2810 if (!script_go(client)) { 2811 if (cur_time < client -> active -> renewal) { 2812 client -> state = S_BOUND; 2813 log_info ("bound: renewal in %ld %s.", 2814 (long)(client -> active -> renewal - 2815 cur_time), "seconds"); 2816 tv.tv_sec = client->active->renewal; 2817 tv.tv_usec = ((client->active->renewal - 2818 cur_time) > 1) ? 2819 random() % 1000000 : 2820 cur_tv.tv_usec; 2821 add_timeout(&tv, state_bound, client, 0, 0); 2822 } else { 2823 client -> state = S_BOUND; 2824 log_info ("bound: immediate renewal."); 2825 state_bound (client); 2826 } 2827 reinitialize_interfaces (); 2828 detach (); 2829 return; 2830 } 2831 } 2832 2833 /* If there are no other leases, give up. */ 2834 if (!client -> leases) { 2835 client -> leases = client -> active; 2836 client -> active = (struct client_lease *)0; 2837 break; 2838 } 2839 2840 activate_next: 2841 /* Otherwise, put the active lease at the end of the 2842 lease list, and try another lease.. */ 2843 add_to_tail(&client->leases, client->active); 2844 2845 client -> active = client -> leases; 2846 client -> leases = client -> leases -> next; 2847 2848 /* If we already tried this lease, we've exhausted the 2849 set of leases, so we might as well give up for 2850 now. */ 2851 if (client -> active == loop) 2852 break; 2853 else if (!loop) 2854 loop = client -> active; 2855 } 2856 2857 /* No leases were available, or what was available didn't work, so 2858 tell the shell script that we failed to allocate an address, 2859 and try again later. */ 2860 if (onetry) { 2861 if (!quiet) { 2862 log_info ("Unable to obtain a lease on first try.%s", 2863 " Exiting."); 2864 } 2865 2866#if defined (CALL_SCRIPT_ON_ONETRY_FAIL) 2867 /* Let's call a script and we're done */ 2868 script_init(client, "FAIL", (struct string_list *)0); 2869 script_go(client); 2870#endif 2871 finish(2); 2872 } 2873 2874 log_info ("No working leases in persistent database - sleeping."); 2875 script_init(client, "FAIL", (struct string_list *)0); 2876 if (client -> alias) 2877 script_write_params(client, "alias_", client -> alias); 2878 script_go(client); 2879 client -> state = S_INIT; 2880 tv.tv_sec = cur_tv.tv_sec + ((client->config->retry_interval + 1) / 2 + 2881 (random() % client->config->retry_interval)); 2882 tv.tv_usec = ((tv.tv_sec - cur_tv.tv_sec) > 1) ? 2883 random() % 1000000 : cur_tv.tv_usec; 2884 add_timeout(&tv, state_init, client, 0, 0); 2885 detach (); 2886} 2887 2888void send_request (cpp) 2889 void *cpp; 2890{ 2891 struct client_state *client = cpp; 2892 2893 int result; 2894 int interval; 2895 struct sockaddr_in destination; 2896 struct in_addr from; 2897 struct timeval tv; 2898 char rip_buf[128]; 2899 const char* rip_str = ""; 2900 2901 /* Figure out how long it's been since we started transmitting. */ 2902 interval = cur_time - client -> first_sending; 2903 2904 /* If we're in the INIT-REBOOT or REQUESTING state and we're 2905 past the reboot timeout, go to INIT and see if we can 2906 DISCOVER an address... */ 2907 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it 2908 means either that we're on a network with no DHCP server, 2909 or that our server is down. In the latter case, assuming 2910 that there is a backup DHCP server, DHCPDISCOVER will get 2911 us a new address, but we could also have successfully 2912 reused our old address. In the former case, we're hosed 2913 anyway. This is not a win-prone situation. */ 2914 if ((client -> state == S_REBOOTING || 2915 client -> state == S_REQUESTING) && 2916 interval > client -> config -> reboot_timeout) { 2917 cancel: 2918 client -> state = S_INIT; 2919 cancel_timeout (send_request, client); 2920 state_init (client); 2921 return; 2922 } 2923 2924 /* If we're in the reboot state, make sure the media is set up 2925 correctly. */ 2926 if (client -> state == S_REBOOTING && 2927 !client -> medium && 2928 client -> active -> medium ) { 2929 script_init(client, "MEDIUM", client -> active -> medium); 2930 2931 /* If the medium we chose won't fly, go to INIT state. */ 2932 if (script_go(client)) 2933 goto cancel; 2934 2935 /* Record the medium. */ 2936 client -> medium = client -> active -> medium; 2937 } 2938 2939 /* If the lease has expired, relinquish the address and go back 2940 to the INIT state. */ 2941 if (client -> state != S_REQUESTING && 2942 cur_time > client -> active -> expiry) { 2943 /* Run the client script with the new parameters. */ 2944 script_init(client, "EXPIRE", (struct string_list *)0); 2945 script_write_params(client, "old_", client -> active); 2946 script_write_requested(client); 2947 if (client -> alias) 2948 script_write_params(client, "alias_", 2949 client -> alias); 2950 script_go(client); 2951 2952 /* Now do a preinit on the interface so that we can 2953 discover a new address. */ 2954 script_init(client, "PREINIT", (struct string_list *)0); 2955 if (client -> alias) 2956 script_write_params(client, "alias_", 2957 client -> alias); 2958 script_go(client); 2959 2960 client -> state = S_INIT; 2961 state_init (client); 2962 return; 2963 } 2964 2965 /* Do the exponential backoff... */ 2966 if (!client -> interval) 2967 client -> interval = client -> config -> initial_interval; 2968 else { 2969 client -> interval += ((random () >> 2) % 2970 (2 * client -> interval)); 2971 } 2972 2973 /* Don't backoff past cutoff. */ 2974 if (client -> interval > 2975 client -> config -> backoff_cutoff) 2976 client -> interval = 2977 ((client -> config -> backoff_cutoff / 2) 2978 + ((random () >> 2) % 2979 client -> config -> backoff_cutoff)); 2980 2981 /* If the backoff would take us to the expiry time, just set the 2982 timeout to the expiry time. */ 2983 if (client -> state != S_REQUESTING && 2984 cur_time + client -> interval > client -> active -> expiry) 2985 client -> interval = 2986 client -> active -> expiry - cur_time + 1; 2987 2988 /* If the lease T2 time has elapsed, or if we're not yet bound, 2989 broadcast the DHCPREQUEST rather than unicasting. */ 2990 if (client -> state == S_REQUESTING || 2991 client -> state == S_REBOOTING || 2992 cur_time > client -> active -> rebind) 2993 destination.sin_addr = sockaddr_broadcast.sin_addr; 2994 else 2995 memcpy (&destination.sin_addr.s_addr, 2996 client -> destination.iabuf, 2997 sizeof destination.sin_addr.s_addr); 2998 destination.sin_port = remote_port; 2999 destination.sin_family = AF_INET; 3000#ifdef HAVE_SA_LEN 3001 destination.sin_len = sizeof destination; 3002#endif 3003 3004 if (client -> state == S_RENEWING || 3005 client -> state == S_REBINDING) 3006 memcpy (&from, client -> active -> address.iabuf, 3007 sizeof from); 3008 else 3009 from.s_addr = INADDR_ANY; 3010 3011 /* Record the number of seconds since we started sending. */ 3012 if (client -> state == S_REQUESTING) 3013 client -> packet.secs = client -> secs; 3014 else { 3015 if (interval < 65536) 3016 client -> packet.secs = htons (interval); 3017 else 3018 client -> packet.secs = htons (65535); 3019 } 3020 3021#if defined(DHCPv6) && defined(DHCP4o6) 3022 if (dhcpv4_over_dhcpv6) { 3023 log_info ("DHCPREQUEST"); 3024 } else 3025#endif 3026 memset(rip_buf, 0x0, sizeof(rip_buf)); 3027 if (client->state == S_BOUND || client->state == S_RENEWING || 3028 client->state == S_REBINDING) { 3029 rip_str = inet_ntoa(client->packet.ciaddr); 3030 } else { 3031 rip_str = piaddr(client->requested_address); 3032 } 3033 3034 strncpy(rip_buf, rip_str, sizeof(rip_buf)-1); 3035 log_info ("DHCPREQUEST for %s on %s to %s port %d", rip_buf, 3036 client->name ? client->name : client->interface->name, 3037 inet_ntoa(destination.sin_addr), 3038 ntohs (destination.sin_port)); 3039 3040#if defined(DHCPv6) && defined(DHCP4o6) 3041 if (dhcpv4_over_dhcpv6) { 3042 int broadcast = 0; 3043 if (destination.sin_addr.s_addr == INADDR_BROADCAST) 3044 broadcast = 1; 3045 result = send_dhcpv4_query(client, broadcast); 3046 if (result < 0) { 3047 log_error("%s:%d: Failed to send %d byte long packet.", 3048 MDL, client->packet_length); 3049 } 3050 } else 3051#endif 3052 if (destination.sin_addr.s_addr != INADDR_BROADCAST && 3053 fallback_interface) { 3054 result = send_packet(fallback_interface, NULL, &client->packet, 3055 client->packet_length, from, &destination, 3056 NULL); 3057 if (result < 0) { 3058 log_error("%s:%d: Failed to send %d byte long packet " 3059 "over %s interface.", MDL, 3060 client->packet_length, 3061 fallback_interface->name); 3062 } 3063 } 3064 else { 3065 /* Send out a packet. */ 3066 result = send_packet(client->interface, NULL, &client->packet, 3067 client->packet_length, from, &destination, 3068 NULL); 3069 if (result < 0) { 3070 log_error("%s:%d: Failed to send %d byte long packet" 3071 " over %s interface.", MDL, 3072 client->packet_length, 3073 client->interface->name); 3074 } 3075 } 3076 3077 tv.tv_sec = cur_tv.tv_sec + client->interval; 3078 tv.tv_usec = ((tv.tv_sec - cur_tv.tv_sec) > 1) ? 3079 random() % 1000000 : cur_tv.tv_usec; 3080 add_timeout(&tv, send_request, client, 0, 0); 3081} 3082 3083void send_decline (cpp) 3084 void *cpp; 3085{ 3086 struct client_state *client = cpp; 3087 3088 int result; 3089 3090#if defined(DHCPv6) && defined(DHCP4o6) 3091 if (dhcpv4_over_dhcpv6) { 3092 log_info ("DHCPDECLINE"); 3093 } else 3094#endif 3095 log_info ("DHCPDECLINE of %s on %s to %s port %d", 3096 piaddr(client->requested_address), 3097 (client->name ? client->name : client->interface->name), 3098 inet_ntoa(sockaddr_broadcast.sin_addr), 3099 ntohs(sockaddr_broadcast.sin_port)); 3100 3101 /* Send out a packet. */ 3102#if defined(DHCPv6) && defined(DHCP4o6) 3103 if (dhcpv4_over_dhcpv6) { 3104 result = send_dhcpv4_query(client, 1); 3105 } else 3106#endif 3107 result = send_packet(client->interface, NULL, &client->packet, 3108 client->packet_length, inaddr_any, 3109 &sockaddr_broadcast, NULL); 3110 if (result < 0) { 3111#if defined(DHCPv6) && defined(DHCP4o6) 3112 if (dhcpv4_over_dhcpv6) { 3113 log_error("%s:%d: Failed to send %d byte long packet.", 3114 MDL, client->packet_length); 3115 } else 3116#endif 3117 log_error("%s:%d: Failed to send %d byte long packet over %s" 3118 " interface.", MDL, client->packet_length, 3119 client->interface->name); 3120 } 3121} 3122 3123void send_release (cpp) 3124 void *cpp; 3125{ 3126 struct client_state *client = cpp; 3127 3128 int result; 3129 struct sockaddr_in destination; 3130 struct in_addr from; 3131 3132 memcpy (&from, client -> active -> address.iabuf, 3133 sizeof from); 3134 memcpy (&destination.sin_addr.s_addr, 3135 client -> destination.iabuf, 3136 sizeof destination.sin_addr.s_addr); 3137 destination.sin_port = remote_port; 3138 destination.sin_family = AF_INET; 3139#ifdef HAVE_SA_LEN 3140 destination.sin_len = sizeof destination; 3141#endif 3142 3143 /* Set the lease to end now, so that we don't accidentally 3144 reuse it if we restart before the old expiry time. */ 3145 client -> active -> expiry = 3146 client -> active -> renewal = 3147 client -> active -> rebind = cur_time; 3148 if (!write_client_lease (client, client -> active, 1, 1)) { 3149 log_error ("Can't release lease: lease write failed."); 3150 return; 3151 } 3152 3153#if defined(DHCPv6) && defined(DHCP4o6) 3154 if (dhcpv4_over_dhcpv6) { 3155 log_info ("DHCPRELEASE"); 3156 } else 3157#endif 3158 log_info ("DHCPRELEASE of %s on %s to %s port %d", 3159 piaddr(client->active->address), 3160 client->name ? client->name : client->interface->name, 3161 inet_ntoa (destination.sin_addr), 3162 ntohs (destination.sin_port)); 3163 3164#if defined(DHCPv6) && defined(DHCP4o6) 3165 if (dhcpv4_over_dhcpv6) { 3166 int broadcast = 0; 3167 if (destination.sin_addr.s_addr == INADDR_BROADCAST) 3168 broadcast = 1; 3169 result = send_dhcpv4_query(client, broadcast); 3170 if (result < 0) { 3171 log_error("%s:%d: Failed to send %d byte long packet.", 3172 MDL, client->packet_length); 3173 } 3174 } else 3175#endif 3176 if (fallback_interface) { 3177 result = send_packet(fallback_interface, NULL, &client->packet, 3178 client->packet_length, from, &destination, 3179 NULL); 3180 if (result < 0) { 3181 log_error("%s:%d: Failed to send %d byte long packet" 3182 " over %s interface.", MDL, 3183 client->packet_length, 3184 fallback_interface->name); 3185 } 3186 } else { 3187 /* Send out a packet. */ 3188 result = send_packet(client->interface, NULL, &client->packet, 3189 client->packet_length, from, &destination, 3190 NULL); 3191 if (result < 0) { 3192 log_error ("%s:%d: Failed to send %d byte long packet" 3193 " over %s interface.", MDL, 3194 client->packet_length, 3195 client->interface->name); 3196 } 3197 3198 } 3199} 3200 3201#if defined(DHCPv6) && defined(DHCP4o6) 3202/* 3203 * \brief Send a DHCPv4-query to the DHCPv6 client 3204 * (DHCPv4 client function) 3205 * 3206 * The DHCPv4 client sends a DHCPv4-query to the DHCPv6 client over 3207 * the inter-process communication socket. 3208 * 3209 * \param client the DHCPv4 client state 3210 * \param broadcast the broadcast flag 3211 * \return the sent byte count (-1 on error) 3212 */ 3213static int send_dhcpv4_query(struct client_state *client, int broadcast) { 3214 struct data_string ds; 3215 struct dhcpv4_over_dhcpv6_packet *query; 3216 int ofs, len, cc; 3217 3218 if (dhcp4o6_state <= 0) { 3219 log_info("send_dhcpv4_query: not ready."); 3220 return -1; 3221 } 3222 3223 /* 3224 * Compute buffer length and allocate it. 3225 */ 3226 len = ofs = (int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options)); 3227 len += dhcpv6_universe.tag_size + dhcpv6_universe.length_size; 3228 len += client->packet_length; 3229 memset(&ds, 0, sizeof(ds)); 3230 if (!buffer_allocate(&ds.buffer, len, MDL)) { 3231 log_error("Unable to allocate memory for DHCPv4-query."); 3232 return -1; 3233 } 3234 ds.data = ds.buffer->data; 3235 ds.len = len; 3236 3237 /* 3238 * Fill header. 3239 */ 3240 query = (struct dhcpv4_over_dhcpv6_packet *)ds.data; 3241 query->msg_type = DHCPV6_DHCPV4_QUERY; 3242 query->flags[0] = query->flags[1] = query->flags[2] = 0; 3243 if (!broadcast) 3244 query->flags[0] |= DHCP4O6_QUERY_UNICAST; 3245 3246 /* 3247 * Append DHCPv4 message. 3248 */ 3249 dhcpv6_universe.store_tag(ds.buffer->data + ofs, D6O_DHCPV4_MSG); 3250 ofs += dhcpv6_universe.tag_size; 3251 dhcpv6_universe.store_length(ds.buffer->data + ofs, 3252 client->packet_length); 3253 ofs += dhcpv6_universe.length_size; 3254 memcpy(ds.buffer->data + ofs, &client->packet, client->packet_length); 3255 3256 /* 3257 * Send DHCPv6 message. 3258 */ 3259 cc = send(dhcp4o6_fd, ds.data, ds.len, 0); 3260 if (cc < 0) 3261 log_error("send_dhcpv4_query: send(): %m"); 3262 3263 data_string_forget(&ds, MDL); 3264 3265 return cc; 3266} 3267 3268/* 3269 * \brief Forward a DHCPv4-query to all DHCPv4 over DHCPv6 server addresses. 3270 * (DHCPv6 client function) 3271 * 3272 * \param raw the DHCPv6 DHCPv4-query message raw content 3273 */ 3274static void forw_dhcpv4_query(struct data_string *raw) { 3275 struct interface_info *ip; 3276 struct client_state *client; 3277 struct dhc6_lease *lease; 3278 struct option_cache *oc; 3279 struct data_string addrs; 3280 struct sockaddr_in6 sin6; 3281 int i, send_ret, attempt, success; 3282 3283 attempt = success = 0; 3284 memset(&sin6, 0, sizeof(sin6)); 3285 sin6.sin6_family = AF_INET6; 3286 sin6.sin6_port = remote_port; 3287#ifdef HAVE_SA_LEN 3288 sin6.sin6_len = sizeof(sin6); 3289#endif 3290 memset(&addrs, 0, sizeof(addrs)); 3291 for (ip = interfaces; ip != NULL; ip = ip->next) { 3292 for (client = ip->client; client != NULL; 3293 client = client->next) { 3294 if ((client->state != S_BOUND) && 3295 (client->state != S_RENEWING) && 3296 (client->state != S_REBINDING)) 3297 continue; 3298 lease = client->active_lease; 3299 if ((lease == NULL) || lease->released) 3300 continue; 3301 oc = lookup_option(&dhcpv6_universe, 3302 lease->options, 3303 D6O_DHCP4_O_DHCP6_SERVER); 3304 if ((oc == NULL) || 3305 !evaluate_option_cache(&addrs, NULL, NULL, NULL, 3306 lease->options, NULL, 3307 &global_scope, oc, MDL) || 3308 ((addrs.len % sizeof(sin6.sin6_addr)) != 0)) { 3309 data_string_forget(&addrs, MDL); 3310 continue; 3311 } 3312 if (addrs.len == 0) { 3313 /* note there is nothing to forget */ 3314 inet_pton(AF_INET6, 3315 All_DHCP_Relay_Agents_and_Servers, 3316 &sin6.sin6_addr); 3317 attempt++; 3318 send_ret = send_packet6(ip, raw->data, 3319 raw->len, &sin6); 3320 if (send_ret == raw->len) 3321 success++; 3322 continue; 3323 } 3324 for (i = 0; i < addrs.len; 3325 i += sizeof(sin6.sin6_addr)) { 3326 memcpy(&sin6.sin6_addr, addrs.data + i, 3327 sizeof(sin6.sin6_addr)); 3328 attempt++; 3329 send_ret = send_packet6(ip, raw->data, 3330 raw->len, &sin6); 3331 if (send_ret == raw->len) 3332 success++; 3333 } 3334 data_string_forget(&addrs, MDL); 3335 } 3336 } 3337 3338 log_info("forw_dhcpv4_query: sent(%d): %d/%d", 3339 raw->len, success, attempt); 3340 3341 if (attempt == 0) 3342 dhcp4o6_stop(); 3343} 3344#endif 3345 3346void 3347make_client_options(struct client_state *client, struct client_lease *lease, 3348 u_int8_t *type, struct option_cache *sid, 3349 struct iaddr *rip, struct option **prl, 3350 struct option_state **op) 3351{ 3352 unsigned i; 3353 struct option_cache *oc; 3354 struct option *option = NULL; 3355 struct buffer *bp = NULL; 3356 3357 /* If there are any leftover options, get rid of them. */ 3358 if (*op) 3359 option_state_dereference(op, MDL); 3360 3361 /* Allocate space for options. */ 3362 option_state_allocate(op, MDL); 3363 3364 /* Send the server identifier if provided. */ 3365 if (sid) 3366 save_option(&dhcp_universe, *op, sid); 3367 3368 oc = NULL; 3369 3370 /* Send the requested address if provided. */ 3371 if (rip) { 3372 client->requested_address = *rip; 3373 i = DHO_DHCP_REQUESTED_ADDRESS; 3374 if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash, 3375 &i, 0, MDL) && 3376 make_const_option_cache(&oc, NULL, rip->iabuf, rip->len, 3377 option, MDL))) 3378 log_error ("can't make requested address cache."); 3379 else { 3380 save_option(&dhcp_universe, *op, oc); 3381 option_cache_dereference(&oc, MDL); 3382 } 3383 option_dereference(&option, MDL); 3384 } else { 3385 client->requested_address.len = 0; 3386 } 3387 3388 i = DHO_DHCP_MESSAGE_TYPE; 3389 if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash, &i, 0, 3390 MDL) && 3391 make_const_option_cache(&oc, NULL, type, 1, option, MDL))) 3392 log_error("can't make message type."); 3393 else { 3394 save_option(&dhcp_universe, *op, oc); 3395 option_cache_dereference(&oc, MDL); 3396 } 3397 option_dereference(&option, MDL); 3398 3399 if (prl) { 3400 int len; 3401 3402 /* Probe the length of the list. */ 3403 len = 0; 3404 for (i = 0 ; prl[i] != NULL ; i++) 3405 if (prl[i]->universe == &dhcp_universe) 3406 len++; 3407 3408 if (!buffer_allocate(&bp, len, MDL)) 3409 log_error("can't make parameter list buffer."); 3410 else { 3411 unsigned code = DHO_DHCP_PARAMETER_REQUEST_LIST; 3412 3413 len = 0; 3414 for (i = 0 ; prl[i] != NULL ; i++) 3415 if (prl[i]->universe == &dhcp_universe) 3416 bp->data[len++] = prl[i]->code; 3417 3418 if (!(option_code_hash_lookup(&option, 3419 dhcp_universe.code_hash, 3420 &code, 0, MDL) && 3421 make_const_option_cache(&oc, &bp, NULL, len, 3422 option, MDL))) { 3423 if (bp != NULL) 3424 buffer_dereference(&bp, MDL); 3425 log_error ("can't make option cache"); 3426 } else { 3427 save_option(&dhcp_universe, *op, oc); 3428 option_cache_dereference(&oc, MDL); 3429 } 3430 option_dereference(&option, MDL); 3431 } 3432 } 3433 3434 /* 3435 * If requested (duid_v4 == 1) add an RFC4361 compliant client-identifier 3436 * This can be overridden by including a client id in the configuration 3437 * file. 3438 */ 3439 if (duid_v4 == 1) { 3440 struct data_string client_identifier; 3441 int hw_idx, hw_len; 3442 3443 memset(&client_identifier, 0, sizeof(client_identifier)); 3444 client_identifier.len = 1 + 4 + default_duid.len; 3445 if (!buffer_allocate(&client_identifier.buffer, 3446 client_identifier.len, MDL)) 3447 log_fatal("no memory for default DUID!"); 3448 client_identifier.data = client_identifier.buffer->data; 3449 3450 i = DHO_DHCP_CLIENT_IDENTIFIER; 3451 3452 /* Client-identifier type : 1 byte */ 3453 *client_identifier.buffer->data = 255; 3454 3455 /* IAID : 4 bytes 3456 * we use the low 4 bytes from the interface address 3457 */ 3458 if (client->interface->hw_address.hlen > 4) { 3459 hw_idx = client->interface->hw_address.hlen - 4; 3460 hw_len = 4; 3461 } else { 3462 hw_idx = 0; 3463 hw_len = client->interface->hw_address.hlen; 3464 } 3465 memcpy(client_identifier.buffer->data + 5 - hw_len, 3466 client->interface->hw_address.hbuf + hw_idx, 3467 hw_len); 3468 3469 /* Add the default duid */ 3470 memcpy(client_identifier.buffer->data + (1 + 4), 3471 default_duid.data, default_duid.len); 3472 3473 /* And save the option */ 3474 if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash, 3475 &i, 0, MDL) && 3476 make_const_option_cache(&oc, NULL, 3477 (u_int8_t *)client_identifier.data, 3478 client_identifier.len, 3479 option, MDL))) 3480 log_error ("can't make requested client id cache.."); 3481 else { 3482 save_option (&dhcp_universe, *op, oc); 3483 option_cache_dereference (&oc, MDL); 3484 } 3485 option_dereference(&option, MDL); 3486 } 3487 3488 /* Run statements that need to be run on transmission. */ 3489 if (client->config->on_transmission) 3490 execute_statements_in_scope(NULL, NULL, NULL, client, 3491 (lease ? lease->options : NULL), 3492 *op, &global_scope, 3493 client->config->on_transmission, 3494 NULL, NULL); 3495} 3496 3497void make_discover (client, lease) 3498 struct client_state *client; 3499 struct client_lease *lease; 3500{ 3501 unsigned char discover = DHCPDISCOVER; 3502 struct option_state *options = (struct option_state *)0; 3503 3504 memset (&client -> packet, 0, sizeof (client -> packet)); 3505 3506 make_client_options (client, 3507 lease, &discover, (struct option_cache *)0, 3508 lease ? &lease -> address : (struct iaddr *)0, 3509 client -> config -> requested_options, 3510 &options); 3511 3512 /* Set up the option buffer... */ 3513 client -> packet_length = 3514 cons_options ((struct packet *)0, &client -> packet, 3515 (struct lease *)0, client, 3516 /* maximum packet size */1500, 3517 (struct option_state *)0, 3518 options, 3519 /* scope */ &global_scope, 3520 /* overload */ 0, 3521 /* terminate */0, 3522 /* bootpp */0, 3523 (struct data_string *)0, 3524 client -> config -> vendor_space_name); 3525 3526 option_state_dereference (&options, MDL); 3527 if (client -> packet_length < BOOTP_MIN_LEN) 3528 client -> packet_length = BOOTP_MIN_LEN; 3529 3530 client -> packet.op = BOOTREQUEST; 3531 client -> packet.htype = client -> interface -> hw_address.hbuf [0]; 3532 /* Assumes hw_address is known, otherwise a random value may result */ 3533 client -> packet.hlen = client -> interface -> hw_address.hlen - 1; 3534 client -> packet.hops = 0; 3535 client -> packet.xid = random (); 3536 client -> packet.secs = 0; /* filled in by send_discover. */ 3537 3538 if (can_receive_unicast_unconfigured (client -> interface)) 3539 client -> packet.flags = 0; 3540 else 3541 client -> packet.flags = htons (BOOTP_BROADCAST); 3542 3543 memset (&(client -> packet.ciaddr), 3544 0, sizeof client -> packet.ciaddr); 3545 memset (&(client -> packet.yiaddr), 3546 0, sizeof client -> packet.yiaddr); 3547 memset (&(client -> packet.siaddr), 3548 0, sizeof client -> packet.siaddr); 3549 client -> packet.giaddr = giaddr; 3550 if (client -> interface -> hw_address.hlen > 0) 3551 memcpy (client -> packet.chaddr, 3552 &client -> interface -> hw_address.hbuf [1], 3553 (unsigned)(client -> interface -> hw_address.hlen - 1)); 3554 3555#ifdef DEBUG_PACKET 3556 dump_raw ((unsigned char *)&client -> packet, client -> packet_length); 3557#endif 3558} 3559 3560 3561void make_request (client, lease) 3562 struct client_state *client; 3563 struct client_lease *lease; 3564{ 3565 unsigned char request = DHCPREQUEST; 3566 struct option_cache *oc; 3567 3568 memset (&client -> packet, 0, sizeof (client -> packet)); 3569 3570 if (client -> state == S_REQUESTING) 3571 oc = lookup_option (&dhcp_universe, lease -> options, 3572 DHO_DHCP_SERVER_IDENTIFIER); 3573 else 3574 oc = (struct option_cache *)0; 3575 3576 if (client -> sent_options) 3577 option_state_dereference (&client -> sent_options, MDL); 3578 3579 make_client_options (client, lease, &request, oc, 3580 ((client -> state == S_REQUESTING || 3581 client -> state == S_REBOOTING) 3582 ? &lease -> address 3583 : (struct iaddr *)0), 3584 client -> config -> requested_options, 3585 &client -> sent_options); 3586 3587 /* Set up the option buffer... */ 3588 client -> packet_length = 3589 cons_options ((struct packet *)0, &client -> packet, 3590 (struct lease *)0, client, 3591 /* maximum packet size */1500, 3592 (struct option_state *)0, 3593 client -> sent_options, 3594 /* scope */ &global_scope, 3595 /* overload */ 0, 3596 /* terminate */0, 3597 /* bootpp */0, 3598 (struct data_string *)0, 3599 client -> config -> vendor_space_name); 3600 3601 if (client -> packet_length < BOOTP_MIN_LEN) 3602 client -> packet_length = BOOTP_MIN_LEN; 3603 3604 client -> packet.op = BOOTREQUEST; 3605 client -> packet.htype = client -> interface -> hw_address.hbuf [0]; 3606 /* Assumes hw_address is known, otherwise a random value may result */ 3607 client -> packet.hlen = client -> interface -> hw_address.hlen - 1; 3608 client -> packet.hops = 0; 3609 client -> packet.xid = client -> xid; 3610 client -> packet.secs = 0; /* Filled in by send_request. */ 3611 3612 /* If we own the address we're requesting, put it in ciaddr; 3613 otherwise set ciaddr to zero. */ 3614 if (client -> state == S_BOUND || 3615 client -> state == S_RENEWING || 3616 client -> state == S_REBINDING) { 3617 memcpy (&client -> packet.ciaddr, 3618 lease -> address.iabuf, lease -> address.len); 3619 client -> packet.flags = 0; 3620 } else { 3621 memset (&client -> packet.ciaddr, 0, 3622 sizeof client -> packet.ciaddr); 3623 if (can_receive_unicast_unconfigured (client -> interface)) 3624 client -> packet.flags = 0; 3625 else 3626 client -> packet.flags = htons (BOOTP_BROADCAST); 3627 } 3628 3629 memset (&client -> packet.yiaddr, 0, 3630 sizeof client -> packet.yiaddr); 3631 memset (&client -> packet.siaddr, 0, 3632 sizeof client -> packet.siaddr); 3633 if (client -> state != S_BOUND && 3634 client -> state != S_RENEWING) 3635 client -> packet.giaddr = giaddr; 3636 else 3637 memset (&client -> packet.giaddr, 0, 3638 sizeof client -> packet.giaddr); 3639 if (client -> interface -> hw_address.hlen > 0) 3640 memcpy (client -> packet.chaddr, 3641 &client -> interface -> hw_address.hbuf [1], 3642 (unsigned)(client -> interface -> hw_address.hlen - 1)); 3643 3644#ifdef DEBUG_PACKET 3645 dump_raw ((unsigned char *)&client -> packet, client -> packet_length); 3646#endif 3647} 3648 3649void make_decline (client, lease) 3650 struct client_state *client; 3651 struct client_lease *lease; 3652{ 3653 unsigned char decline = DHCPDECLINE; 3654 struct option_cache *oc; 3655 3656 struct option_state *options = (struct option_state *)0; 3657 3658 /* Create the options cache. */ 3659 oc = lookup_option (&dhcp_universe, lease -> options, 3660 DHO_DHCP_SERVER_IDENTIFIER); 3661 make_client_options(client, lease, &decline, oc, &lease->address, 3662 NULL, &options); 3663 3664 /* Consume the options cache into the option buffer. */ 3665 memset (&client -> packet, 0, sizeof (client -> packet)); 3666 client -> packet_length = 3667 cons_options ((struct packet *)0, &client -> packet, 3668 (struct lease *)0, client, 0, 3669 (struct option_state *)0, options, 3670 &global_scope, 0, 0, 0, (struct data_string *)0, 3671 client -> config -> vendor_space_name); 3672 3673 /* Destroy the options cache. */ 3674 option_state_dereference (&options, MDL); 3675 3676 if (client -> packet_length < BOOTP_MIN_LEN) 3677 client -> packet_length = BOOTP_MIN_LEN; 3678 3679 client -> packet.op = BOOTREQUEST; 3680 client -> packet.htype = client -> interface -> hw_address.hbuf [0]; 3681 /* Assumes hw_address is known, otherwise a random value may result */ 3682 client -> packet.hlen = client -> interface -> hw_address.hlen - 1; 3683 client -> packet.hops = 0; 3684 client -> packet.xid = client -> xid; 3685 client -> packet.secs = 0; /* Filled in by send_request. */ 3686 if (can_receive_unicast_unconfigured (client -> interface)) 3687 client -> packet.flags = 0; 3688 else 3689 client -> packet.flags = htons (BOOTP_BROADCAST); 3690 3691 /* ciaddr must always be zero. */ 3692 memset (&client -> packet.ciaddr, 0, 3693 sizeof client -> packet.ciaddr); 3694 memset (&client -> packet.yiaddr, 0, 3695 sizeof client -> packet.yiaddr); 3696 memset (&client -> packet.siaddr, 0, 3697 sizeof client -> packet.siaddr); 3698 client -> packet.giaddr = giaddr; 3699 memcpy (client -> packet.chaddr, 3700 &client -> interface -> hw_address.hbuf [1], 3701 client -> interface -> hw_address.hlen); 3702 3703#ifdef DEBUG_PACKET 3704 dump_raw ((unsigned char *)&client -> packet, client -> packet_length); 3705#endif 3706} 3707 3708void make_release (client, lease) 3709 struct client_state *client; 3710 struct client_lease *lease; 3711{ 3712 unsigned char request = DHCPRELEASE; 3713 struct option_cache *oc; 3714 3715 struct option_state *options = (struct option_state *)0; 3716 3717 memset (&client -> packet, 0, sizeof (client -> packet)); 3718 3719 oc = lookup_option (&dhcp_universe, lease -> options, 3720 DHO_DHCP_SERVER_IDENTIFIER); 3721 make_client_options(client, lease, &request, oc, NULL, NULL, &options); 3722 3723 /* Set up the option buffer... */ 3724 client -> packet_length = 3725 cons_options ((struct packet *)0, &client -> packet, 3726 (struct lease *)0, client, 3727 /* maximum packet size */1500, 3728 (struct option_state *)0, 3729 options, 3730 /* scope */ &global_scope, 3731 /* overload */ 0, 3732 /* terminate */0, 3733 /* bootpp */0, 3734 (struct data_string *)0, 3735 client -> config -> vendor_space_name); 3736 3737 if (client -> packet_length < BOOTP_MIN_LEN) 3738 client -> packet_length = BOOTP_MIN_LEN; 3739 option_state_dereference (&options, MDL); 3740 3741 client -> packet.op = BOOTREQUEST; 3742 client -> packet.htype = client -> interface -> hw_address.hbuf [0]; 3743 /* Assumes hw_address is known, otherwise a random value may result */ 3744 client -> packet.hlen = client -> interface -> hw_address.hlen - 1; 3745 client -> packet.hops = 0; 3746 client -> packet.xid = random (); 3747 client -> packet.secs = 0; 3748 client -> packet.flags = 0; 3749 memcpy (&client -> packet.ciaddr, 3750 lease -> address.iabuf, lease -> address.len); 3751 memset (&client -> packet.yiaddr, 0, 3752 sizeof client -> packet.yiaddr); 3753 memset (&client -> packet.siaddr, 0, 3754 sizeof client -> packet.siaddr); 3755 client -> packet.giaddr = giaddr; 3756 memcpy (client -> packet.chaddr, 3757 &client -> interface -> hw_address.hbuf [1], 3758 client -> interface -> hw_address.hlen); 3759 3760#ifdef DEBUG_PACKET 3761 dump_raw ((unsigned char *)&client -> packet, client -> packet_length); 3762#endif 3763} 3764 3765void destroy_client_lease (lease) 3766 struct client_lease *lease; 3767{ 3768 if (lease -> server_name) 3769 dfree (lease -> server_name, MDL); 3770 if (lease -> filename) 3771 dfree (lease -> filename, MDL); 3772 option_state_dereference (&lease -> options, MDL); 3773 free_client_lease (lease, MDL); 3774} 3775 3776FILE *leaseFile = NULL; 3777int leases_written = 0; 3778 3779void rewrite_client_leases () 3780{ 3781 struct interface_info *ip; 3782 struct client_state *client; 3783 struct client_lease *lp; 3784 3785 if (leaseFile != NULL) 3786 fclose (leaseFile); 3787 leaseFile = fopen (path_dhclient_db, "w"); 3788 if (leaseFile == NULL) { 3789 log_error ("can't create %s: %m", path_dhclient_db); 3790 return; 3791 } 3792 3793 /* If there is a default duid, write it out. */ 3794 if (default_duid.len != 0) 3795 write_duid(&default_duid); 3796 3797 /* Write out all the leases attached to configured interfaces that 3798 we know about. */ 3799 for (ip = interfaces; ip; ip = ip -> next) { 3800 for (client = ip -> client; client; client = client -> next) { 3801 for (lp = client -> leases; lp; lp = lp -> next) { 3802 write_client_lease (client, lp, 1, 0); 3803 } 3804 if (client -> active) 3805 write_client_lease (client, 3806 client -> active, 1, 0); 3807 3808 if (client->active_lease != NULL) 3809 write_client6_lease(client, 3810 client->active_lease, 3811 1, 0); 3812 3813 /* Reset last_write after rewrites. */ 3814 client->last_write = 0; 3815 } 3816 } 3817 3818 /* Write out any leases that are attached to interfaces that aren't 3819 currently configured. */ 3820 for (ip = dummy_interfaces; ip; ip = ip -> next) { 3821 for (client = ip -> client; client; client = client -> next) { 3822 for (lp = client -> leases; lp; lp = lp -> next) { 3823 write_client_lease (client, lp, 1, 0); 3824 } 3825 if (client -> active) 3826 write_client_lease (client, 3827 client -> active, 1, 0); 3828 3829 if (client->active_lease != NULL) 3830 write_client6_lease(client, 3831 client->active_lease, 3832 1, 0); 3833 3834 /* Reset last_write after rewrites. */ 3835 client->last_write = 0; 3836 } 3837 } 3838 fflush (leaseFile); 3839} 3840 3841void write_lease_option (struct option_cache *oc, 3842 struct packet *packet, struct lease *lease, 3843 struct client_state *client_state, 3844 struct option_state *in_options, 3845 struct option_state *cfg_options, 3846 struct binding_scope **scope, 3847 struct universe *u, void *stuff) 3848{ 3849 const char *name, *dot; 3850 struct data_string ds; 3851 char *preamble = stuff; 3852 3853 memset (&ds, 0, sizeof ds); 3854 3855 if (u != &dhcp_universe) { 3856 name = u -> name; 3857 dot = "."; 3858 } else { 3859 name = ""; 3860 dot = ""; 3861 } 3862 if (evaluate_option_cache (&ds, packet, lease, client_state, 3863 in_options, cfg_options, scope, oc, MDL)) { 3864 /* The option name */ 3865 fprintf(leaseFile, "%soption %s%s%s", preamble, 3866 name, dot, oc->option->name); 3867 3868 /* The option value if there is one */ 3869 if ((oc->option->format == NULL) || 3870 (oc->option->format[0] != 'Z')) { 3871 fprintf(leaseFile, " %s", 3872 pretty_print_option(oc->option, ds.data, 3873 ds.len, 1, 1)); 3874 } 3875 3876 /* The closing semi-colon and newline */ 3877 fprintf(leaseFile, ";\n"); 3878 3879 data_string_forget (&ds, MDL); 3880 } 3881} 3882 3883/* Write an option cache to the lease store. */ 3884static void 3885write_options(struct client_state *client, struct option_state *options, 3886 const char *preamble) 3887{ 3888 int i; 3889 3890 for (i = 0; i < options->universe_count; i++) { 3891 option_space_foreach(NULL, NULL, client, NULL, options, 3892 &global_scope, universes[i], 3893 (char *)preamble, write_lease_option); 3894 } 3895} 3896 3897/* 3898 * The "best" default DUID, since we cannot predict any information 3899 * about the system (such as whether or not the hardware addresses are 3900 * integrated into the motherboard or similar), is the "LLT", link local 3901 * plus time, DUID. For real stateless "LL" is better. 3902 * 3903 * Once generated, this duid is stored into the state database, and 3904 * retained across restarts. 3905 * 3906 * For the time being, there is probably a different state database for 3907 * every daemon, so this winds up being a per-interface identifier...which 3908 * is not how it is intended. Upcoming rearchitecting the client should 3909 * address this "one daemon model." 3910 */ 3911void 3912form_duid(struct data_string *duid, const char *file, int line) 3913{ 3914 struct interface_info *ip; 3915 int len; 3916 char *str; 3917 3918 /* For now, just use the first interface on the list. */ 3919 ip = interfaces; 3920 3921 if (ip == NULL) 3922 log_fatal("Impossible condition at %s:%d.", MDL); 3923 3924 if ((ip->hw_address.hlen == 0) || 3925 (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf))) 3926 log_fatal("Impossible hardware address length at %s:%d.", MDL); 3927 3928 if (duid_type == 0) 3929 duid_type = stateless ? DUID_LL : DUID_LLT; 3930 3931 /* 3932 * 2 bytes for the 'duid type' field. 3933 * 2 bytes for the 'htype' field. 3934 * (DUID_LLT) 4 bytes for the 'current time'. 3935 * enough bytes for the hardware address (note that hw_address has 3936 * the 'htype' on byte zero). 3937 */ 3938 len = 4 + (ip->hw_address.hlen - 1); 3939 if (duid_type == DUID_LLT) 3940 len += 4; 3941 if (!buffer_allocate(&duid->buffer, len, MDL)) 3942 log_fatal("no memory for default DUID!"); 3943 duid->data = duid->buffer->data; 3944 duid->len = len; 3945 3946 /* Basic Link Local Address type of DUID. */ 3947 if (duid_type == DUID_LLT) { 3948 putUShort(duid->buffer->data, DUID_LLT); 3949 putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]); 3950 putULong(duid->buffer->data + 4, cur_time - DUID_TIME_EPOCH); 3951 memcpy(duid->buffer->data + 8, ip->hw_address.hbuf + 1, 3952 ip->hw_address.hlen - 1); 3953 } else { 3954 putUShort(duid->buffer->data, DUID_LL); 3955 putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]); 3956 memcpy(duid->buffer->data + 4, ip->hw_address.hbuf + 1, 3957 ip->hw_address.hlen - 1); 3958 } 3959 3960 /* Now format the output based on lease-id-format */ 3961 str = format_lease_id(duid->data, duid->len, 3962 top_level_config.lease_id_format, MDL); 3963 if (str == NULL) { 3964 log_info("form_duid: Couldn't allocate memory to log duid!"); 3965 } else { 3966 log_info("Created duid %s.", str); 3967 dfree(str, MDL); 3968 } 3969} 3970 3971/* Write the default DUID to the lease store. */ 3972static isc_result_t 3973write_duid(struct data_string *duid) 3974{ 3975 char *str; 3976 int stat; 3977 3978 if ((duid == NULL) || (duid->len <= 2)) 3979 return DHCP_R_INVALIDARG; 3980 3981 if (leaseFile == NULL) { /* XXX? */ 3982 leaseFile = fopen(path_dhclient_db, "w"); 3983 if (leaseFile == NULL) { 3984 log_error("can't create %s: %m", path_dhclient_db); 3985 return ISC_R_IOERROR; 3986 } 3987 } 3988 3989 /* Generate a formatted duid string per lease-id-format */ 3990 str = format_lease_id(duid->data, duid->len, 3991 top_level_config.lease_id_format, MDL); 3992 if (str == NULL) 3993 return ISC_R_NOMEMORY; 3994 3995 stat = fprintf(leaseFile, "default-duid %s;\n", str); 3996 dfree(str, MDL); 3997 if (stat <= 0) 3998 return ISC_R_IOERROR; 3999 4000 if (fflush(leaseFile) != 0) 4001 return ISC_R_IOERROR; 4002 4003 return ISC_R_SUCCESS; 4004} 4005 4006/* Write a DHCPv6 lease to the store. */ 4007isc_result_t 4008write_client6_lease(struct client_state *client, struct dhc6_lease *lease, 4009 int rewrite, int sync) 4010{ 4011 struct dhc6_ia *ia; 4012 struct dhc6_addr *addr; 4013 int stat; 4014 const char *ianame; 4015 4016 /* This should include the current lease. */ 4017 if (!rewrite && (leases_written++ > 20)) { 4018 rewrite_client_leases(); 4019 leases_written = 0; 4020 return ISC_R_SUCCESS; 4021 } 4022 4023 if (client == NULL || lease == NULL) 4024 return DHCP_R_INVALIDARG; 4025 4026 if (leaseFile == NULL) { /* XXX? */ 4027 leaseFile = fopen(path_dhclient_db, "w"); 4028 if (leaseFile == NULL) { 4029 log_error("can't create %s: %m", path_dhclient_db); 4030 return ISC_R_IOERROR; 4031 } 4032 } 4033 4034 stat = fprintf(leaseFile, "lease6 {\n"); 4035 if (stat <= 0) 4036 return ISC_R_IOERROR; 4037 4038 stat = fprintf(leaseFile, " interface \"%s\";\n", 4039 client->interface->name); 4040 if (stat <= 0) 4041 return ISC_R_IOERROR; 4042 4043 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) { 4044 switch (ia->ia_type) { 4045 case D6O_IA_NA: 4046 default: 4047 ianame = "ia-na"; 4048 break; 4049 case D6O_IA_TA: 4050 ianame = "ia-ta"; 4051 break; 4052 case D6O_IA_PD: 4053 ianame = "ia-pd"; 4054 break; 4055 } 4056 4057 /* For some reason IAID was never octal or hex, but string or 4058 * hex. Go figure. So for compatibilty's sake we will either 4059 * do hex or "legacy" i.e string rather than octal. What a 4060 * cluster. */ 4061 switch(top_level_config.lease_id_format) { 4062 case TOKEN_HEX: { 4063 char* iaid_str = format_lease_id( 4064 (const unsigned char *) &ia->iaid, 4, 4065 top_level_config.lease_id_format, MDL); 4066 4067 if (!iaid_str) { 4068 log_error("Can't format iaid"); 4069 return ISC_R_IOERROR; 4070 } 4071 4072 stat = fprintf(leaseFile, " %s %s {\n", 4073 ianame, iaid_str); 4074 dfree(iaid_str, MDL); 4075 break; 4076 } 4077 4078 case TOKEN_OCTAL: 4079 default: 4080 stat = fprintf(leaseFile, " %s %s {\n", ianame, 4081 print_hex_1(4, ia->iaid, 12)); 4082 break; 4083 } 4084 4085 if (stat <= 0) 4086 return ISC_R_IOERROR; 4087 4088 if (ia->ia_type != D6O_IA_TA) 4089 stat = fprintf(leaseFile, " starts %d;\n" 4090 " renew %u;\n" 4091 " rebind %u;\n", 4092 (int)ia->starts, ia->renew, ia->rebind); 4093 else 4094 stat = fprintf(leaseFile, " starts %d;\n", 4095 (int)ia->starts); 4096 if (stat <= 0) 4097 return ISC_R_IOERROR; 4098 4099 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 4100 if (ia->ia_type != D6O_IA_PD) 4101 stat = fprintf(leaseFile, 4102 " iaaddr %s {\n", 4103 piaddr(addr->address)); 4104 else 4105 stat = fprintf(leaseFile, 4106 " iaprefix %s/%d {\n", 4107 piaddr(addr->address), 4108 (int)addr->plen); 4109 if (stat <= 0) 4110 return ISC_R_IOERROR; 4111 4112 stat = fprintf(leaseFile, " starts %d;\n" 4113 " preferred-life %u;\n" 4114 " max-life %u;\n", 4115 (int)addr->starts, addr->preferred_life, 4116 addr->max_life); 4117 if (stat <= 0) 4118 return ISC_R_IOERROR; 4119 4120 if (addr->options != NULL) 4121 write_options(client, addr->options, " "); 4122 4123 stat = fprintf(leaseFile, " }\n"); 4124 if (stat <= 0) 4125 return ISC_R_IOERROR; 4126 } 4127 4128 if (ia->options != NULL) 4129 write_options(client, ia->options, " "); 4130 4131 stat = fprintf(leaseFile, " }\n"); 4132 if (stat <= 0) 4133 return ISC_R_IOERROR; 4134 } 4135 4136 if (lease->released) { 4137 stat = fprintf(leaseFile, " released;\n"); 4138 if (stat <= 0) 4139 return ISC_R_IOERROR; 4140 } 4141 4142 if (lease->options != NULL) 4143 write_options(client, lease->options, " "); 4144 4145 stat = fprintf(leaseFile, "}\n"); 4146 if (stat <= 0) 4147 return ISC_R_IOERROR; 4148 4149 if (fflush(leaseFile) != 0) 4150 return ISC_R_IOERROR; 4151 4152 if (sync) { 4153 if (fsync(fileno(leaseFile)) < 0) { 4154 log_error("write_client_lease: fsync(): %m"); 4155 return ISC_R_IOERROR; 4156 } 4157 } 4158 4159 return ISC_R_SUCCESS; 4160} 4161 4162int write_client_lease (client, lease, rewrite, makesure) 4163 struct client_state *client; 4164 struct client_lease *lease; 4165 int rewrite; 4166 int makesure; 4167{ 4168 struct data_string ds; 4169 int errors = 0; 4170 char *s; 4171 const char *tval; 4172 4173 if (!rewrite) { 4174 if (leases_written++ > 20) { 4175 rewrite_client_leases (); 4176 leases_written = 0; 4177 } 4178 } 4179 4180 /* If the lease came from the config file, we don't need to stash 4181 a copy in the lease database. */ 4182 if (lease -> is_static) 4183 return 1; 4184 4185 if (leaseFile == NULL) { /* XXX */ 4186 leaseFile = fopen (path_dhclient_db, "w"); 4187 if (leaseFile == NULL) { 4188 log_error ("can't create %s: %m", path_dhclient_db); 4189 return 0; 4190 } 4191 } 4192 4193 errno = 0; 4194 fprintf (leaseFile, "lease {\n"); 4195 if (lease -> is_bootp) { 4196 fprintf (leaseFile, " bootp;\n"); 4197 if (errno) { 4198 ++errors; 4199 errno = 0; 4200 } 4201 } 4202 fprintf (leaseFile, " interface \"%s\";\n", 4203 client -> interface -> name); 4204 if (errno) { 4205 ++errors; 4206 errno = 0; 4207 } 4208 if (client -> name) { 4209 fprintf (leaseFile, " name \"%s\";\n", client -> name); 4210 if (errno) { 4211 ++errors; 4212 errno = 0; 4213 } 4214 } 4215 fprintf (leaseFile, " fixed-address %s;\n", 4216 piaddr (lease -> address)); 4217 if (errno) { 4218 ++errors; 4219 errno = 0; 4220 } 4221 if (lease -> filename) { 4222 s = quotify_string (lease -> filename, MDL); 4223 if (s) { 4224 fprintf (leaseFile, " filename \"%s\";\n", s); 4225 if (errno) { 4226 ++errors; 4227 errno = 0; 4228 } 4229 dfree (s, MDL); 4230 } else 4231 errors++; 4232 4233 } 4234 if (lease->server_name != NULL) { 4235 s = quotify_string(lease->server_name, MDL); 4236 if (s != NULL) { 4237 fprintf(leaseFile, " server-name \"%s\";\n", s); 4238 if (errno) { 4239 ++errors; 4240 errno = 0; 4241 } 4242 dfree(s, MDL); 4243 } else 4244 ++errors; 4245 } 4246 if (lease -> medium) { 4247 s = quotify_string (lease -> medium -> string, MDL); 4248 if (s) { 4249 fprintf (leaseFile, " medium \"%s\";\n", s); 4250 if (errno) { 4251 ++errors; 4252 errno = 0; 4253 } 4254 dfree (s, MDL); 4255 } else 4256 errors++; 4257 } 4258 if (errno != 0) { 4259 errors++; 4260 errno = 0; 4261 } 4262 4263 memset (&ds, 0, sizeof ds); 4264 4265 write_options(client, lease->options, " "); 4266 4267 tval = print_time(lease->renewal); 4268 if (tval == NULL || 4269 fprintf(leaseFile, " renew %s\n", tval) < 0) 4270 errors++; 4271 4272 tval = print_time(lease->rebind); 4273 if (tval == NULL || 4274 fprintf(leaseFile, " rebind %s\n", tval) < 0) 4275 errors++; 4276 4277 tval = print_time(lease->expiry); 4278 if (tval == NULL || 4279 fprintf(leaseFile, " expire %s\n", tval) < 0) 4280 errors++; 4281 4282 if (fprintf(leaseFile, "}\n") < 0) 4283 errors++; 4284 4285 if (fflush(leaseFile) != 0) 4286 errors++; 4287 4288 client->last_write = cur_time; 4289 4290 if (!errors && makesure) { 4291 if (fsync (fileno (leaseFile)) < 0) { 4292 log_info ("write_client_lease: %m"); 4293 return 0; 4294 } 4295 } 4296 4297 return errors ? 0 : 1; 4298} 4299 4300/* Variables holding name of script and file pointer for writing to 4301 script. Needless to say, this is not reentrant - only one script 4302 can be invoked at a time. */ 4303char scriptName [256]; 4304FILE *scriptFile; 4305 4306/** 4307 * @brief Initializes basic variables for a script 4308 * 4309 * This function is called as an initial preparation for calling a script. 4310 * It sets up a number of common env. variables that will be passed to 4311 * the script. For actual script calling, see @ref script_go . 4312 * 4313 * @param client variables will be stored here (if null, the whole function 4314 * is no-op) 4315 * @param reason specified the reason for calling a script (must be non-null) 4316 * @param medium if specified, defines medium type (may be null) 4317 */ 4318void script_init(struct client_state *client, const char *reason, 4319 struct string_list *medium) 4320{ 4321 struct string_list *sl, *next; 4322 4323 if (client) { 4324 for (sl = client -> env; sl; sl = next) { 4325 next = sl -> next; 4326 dfree (sl, MDL); 4327 } 4328 client -> env = (struct string_list *)0; 4329 client -> envc = 0; 4330 4331 if (client -> interface) { 4332 client_envadd (client, "", "interface", "%s", 4333 client -> interface -> name); 4334 } 4335 if (client -> name) 4336 client_envadd (client, 4337 "", "client", "%s", client -> name); 4338 if (medium) 4339 client_envadd (client, 4340 "", "medium", "%s", medium -> string); 4341 4342 client_envadd (client, "", "reason", "%s", reason); 4343 client_envadd (client, "", "pid", "%ld", (long int)getpid ()); 4344#if defined(DHCPv6) 4345 client_envadd (client, "", "dad_wait_time", "%ld", 4346 (long int)dad_wait_time); 4347#endif 4348 } 4349} 4350 4351void client_option_envadd (struct option_cache *oc, 4352 struct packet *packet, struct lease *lease, 4353 struct client_state *client_state, 4354 struct option_state *in_options, 4355 struct option_state *cfg_options, 4356 struct binding_scope **scope, 4357 struct universe *u, void *stuff) 4358{ 4359 struct envadd_state *es = stuff; 4360 struct data_string data; 4361 memset (&data, 0, sizeof data); 4362 4363 if (evaluate_option_cache (&data, packet, lease, client_state, 4364 in_options, cfg_options, scope, oc, MDL)) { 4365 if (data.len) { 4366 char name [256]; 4367 if (dhcp_option_ev_name (name, sizeof name, 4368 oc->option)) { 4369 const char *value; 4370 size_t length; 4371 value = pretty_print_option(oc->option, 4372 data.data, 4373 data.len, 0, 0); 4374 length = strlen(value); 4375 4376 if (check_option_values(oc->option->universe, 4377 oc->option->code, 4378 value, length) == 0) { 4379 client_envadd(es->client, es->prefix, 4380 name, "%s", value); 4381 } else { 4382 log_error("suspect value in %s " 4383 "option - discarded", 4384 name); 4385 } 4386 } 4387 } 4388 4389 data_string_forget (&data, MDL); 4390 } 4391} 4392 4393/** 4394 * @brief Adds parameters to environment variables for a script 4395 * 4396 * This function add details of specified lease to a list of env. variables 4397 * to be passed to a script. The lease details will be prepended with 4398 * specified prefix (e.g. "old_") and added to the list stored in client. 4399 * Following variables may be set: 4400 * - ip_address 4401 * - next_server 4402 * - network_number 4403 * - broadcast_address 4404 * - filename 4405 * - server_name 4406 * - expiry 4407 * 4408 * @param client env. variables will be stored here 4409 * @param prefix textual prefix to be added to each variable (e.g. "old_") 4410 * @param lease lease details will be extracted from here 4411 */ 4412void script_write_params(struct client_state *client, const char *prefix, 4413 struct client_lease *lease) 4414{ 4415 int i; 4416 struct data_string data; 4417 struct option_cache *oc; 4418 struct envadd_state es; 4419 4420 es.client = client; 4421 es.prefix = prefix; 4422 4423 client_envadd (client, 4424 prefix, "ip_address", "%s", piaddr (lease -> address)); 4425 4426 /* If we've set the next server address in the lease structure 4427 put it into an environment variable for the script */ 4428 if (lease->next_srv_addr.len != 0) { 4429 client_envadd(client, prefix, "next_server", "%s", 4430 piaddr(lease->next_srv_addr)); 4431 } 4432 4433 /* For the benefit of Linux (and operating systems which may 4434 have similar needs), compute the network address based on 4435 the supplied ip address and netmask, if provided. Also 4436 compute the broadcast address (the host address all ones 4437 broadcast address, not the host address all zeroes 4438 broadcast address). */ 4439 4440 memset (&data, 0, sizeof data); 4441 oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK); 4442 if (oc && evaluate_option_cache (&data, (struct packet *)0, 4443 (struct lease *)0, client, 4444 (struct option_state *)0, 4445 lease -> options, 4446 &global_scope, oc, MDL)) { 4447 if (data.len > 3) { 4448 struct iaddr netmask, subnet, broadcast; 4449 4450 /* 4451 * No matter the length of the subnet-mask option, 4452 * use only the first four octets. Note that 4453 * subnet-mask options longer than 4 octets are not 4454 * in conformance with RFC 2132, but servers with this 4455 * flaw do exist. 4456 */ 4457 memcpy(netmask.iabuf, data.data, 4); 4458 netmask.len = 4; 4459 data_string_forget (&data, MDL); 4460 4461 subnet = subnet_number (lease -> address, netmask); 4462 if (subnet.len) { 4463 client_envadd (client, prefix, "network_number", 4464 "%s", piaddr (subnet)); 4465 4466 oc = lookup_option (&dhcp_universe, 4467 lease -> options, 4468 DHO_BROADCAST_ADDRESS); 4469 if (!oc || 4470 !(evaluate_option_cache 4471 (&data, (struct packet *)0, 4472 (struct lease *)0, client, 4473 (struct option_state *)0, 4474 lease -> options, 4475 &global_scope, oc, MDL))) { 4476 broadcast = broadcast_addr (subnet, netmask); 4477 if (broadcast.len) { 4478 client_envadd (client, 4479 prefix, "broadcast_address", 4480 "%s", piaddr (broadcast)); 4481 } 4482 } 4483 } 4484 } 4485 data_string_forget (&data, MDL); 4486 } 4487 4488 if (lease->filename) { 4489 if (check_option_values(NULL, DHO_ROOT_PATH, 4490 lease->filename, 4491 strlen(lease->filename)) == 0) { 4492 client_envadd(client, prefix, "filename", 4493 "%s", lease->filename); 4494 } else { 4495 log_error("suspect value in %s " 4496 "option - discarded", 4497 lease->filename); 4498 } 4499 } 4500 4501 if (lease->server_name) { 4502 if (check_option_values(NULL, DHO_HOST_NAME, 4503 lease->server_name, 4504 strlen(lease->server_name)) == 0 ) { 4505 client_envadd (client, prefix, "server_name", 4506 "%s", lease->server_name); 4507 } else { 4508 log_error("suspect value in %s " 4509 "option - discarded", 4510 lease->server_name); 4511 } 4512 } 4513 4514 for (i = 0; i < lease -> options -> universe_count; i++) { 4515 option_space_foreach ((struct packet *)0, (struct lease *)0, 4516 client, (struct option_state *)0, 4517 lease -> options, &global_scope, 4518 universes [i], 4519 &es, client_option_envadd); 4520 } 4521 4522 client_envadd (client, prefix, "expiry", "%lu", 4523 (unsigned long)(lease -> expiry)); 4524} 4525 4526/** 4527 * @brief Write out the environent variable the client requested. 4528 * Write out the environment variables for the objects that the 4529 * client requested. If the object was requested the variable will be: 4530 * requested_<option_name>=1 4531 * If it wasn't requested there won't be a variable. 4532 * 4533 * @param client client structure 4534 */ 4535void script_write_requested(struct client_state *client) 4536{ 4537 int i; 4538 struct option **req; 4539 char name[256]; 4540 req = client->config->requested_options; 4541 4542 if (req == NULL) 4543 return; 4544 4545 for (i = 0 ; req[i] != NULL ; i++) { 4546 if ((req[i]->universe == &dhcp_universe) && 4547 dhcp_option_ev_name(name, sizeof(name), req[i])) { 4548 client_envadd(client, "requested_", name, "%d", 1); 4549 } 4550 } 4551} 4552 4553/** 4554 * @brief Calls external script. 4555 * 4556 * External script is specified either using -sf command line or 4557 * script parameter in the configuration file. 4558 * 4559 * @param client specifies client information (environment variables, 4560 * and other parameters will be extracted and passed to the script. 4561 * @return If positive, it contains exit code of the process running script. 4562 * If negative, returns the signal number that cause the script process 4563 * to terminate. 4564 */ 4565int script_go(struct client_state *client) 4566{ 4567 char *scriptName; 4568 char *argv [2]; 4569 char **envp; 4570 char reason [] = "REASON=NBI"; 4571 static char client_path [] = CLIENT_PATH; 4572 int i; 4573 struct string_list *sp, *next; 4574 int pid, wpid, wstatus; 4575 4576 if (client) 4577 scriptName = client -> config -> script_name; 4578 else 4579 scriptName = top_level_config.script_name; 4580 4581 envp = dmalloc (((client ? client -> envc : 2) + 4582 client_env_count + 2) * sizeof (char *), MDL); 4583 if (!envp) { 4584 log_error ("No memory for client script environment."); 4585 return 0; 4586 } 4587 i = 0; 4588 /* Copy out the environment specified on the command line, 4589 if any. */ 4590 for (sp = client_env; sp; sp = sp -> next) { 4591 envp [i++] = sp -> string; 4592 } 4593 /* Copy out the environment specified by dhclient. */ 4594 if (client) { 4595 for (sp = client -> env; sp; sp = sp -> next) { 4596 envp [i++] = sp -> string; 4597 } 4598 } else { 4599 envp [i++] = reason; 4600 } 4601 /* Set $PATH. */ 4602 envp [i++] = client_path; 4603 envp [i] = (char *)0; 4604 4605 argv [0] = scriptName; 4606 argv [1] = (char *)0; 4607 4608 pid = fork (); 4609 if (pid < 0) { 4610 log_error ("fork: %m"); 4611 wstatus = 0; 4612 } else if (pid) { 4613 do { 4614 wpid = wait (&wstatus); 4615 } while (wpid != pid && wpid > 0); 4616 if (wpid < 0) { 4617 log_error ("wait: %m"); 4618 wstatus = 0; 4619 } 4620 } else { 4621 /* We don't want to pass an open file descriptor for 4622 * dhclient.leases when executing dhclient-script. 4623 */ 4624 if (leaseFile != NULL) 4625 fclose(leaseFile); 4626 execve (scriptName, argv, envp); 4627 log_error ("execve (%s, ...): %m", scriptName); 4628 exit (0); 4629 } 4630 4631 if (client) { 4632 for (sp = client -> env; sp; sp = next) { 4633 next = sp -> next; 4634 dfree (sp, MDL); 4635 } 4636 client -> env = (struct string_list *)0; 4637 client -> envc = 0; 4638 } 4639 dfree (envp, MDL); 4640 gettimeofday(&cur_tv, NULL); 4641 4642 if (!WIFEXITED(wstatus)) { 4643 int sigval = WTERMSIG(wstatus); 4644 log_error ("script_go script: %s was terminated by signal %d", scriptName, sigval); 4645 return (-sigval); 4646 } 4647 4648 return (WEXITSTATUS(wstatus)); 4649} 4650 4651void client_envadd (struct client_state *client, 4652 const char *prefix, const char *name, const char *fmt, ...) 4653{ 4654 char spbuf [1024]; 4655 char *s; 4656 unsigned len; 4657 struct string_list *val; 4658 va_list list; 4659 4660 va_start (list, fmt); 4661 len = vsnprintf (spbuf, sizeof spbuf, fmt, list); 4662 va_end (list); 4663 4664 val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ + 4665 len + sizeof *val, MDL); 4666 if (!val) { 4667 log_error ("client_envadd: cannot allocate space for variable"); 4668 return; 4669 } 4670 4671 s = val -> string; 4672 strcpy (s, prefix); 4673 strcat (s, name); 4674 s += strlen (s); 4675 *s++ = '='; 4676 if (len >= sizeof spbuf) { 4677 va_start (list, fmt); 4678 vsnprintf (s, len + 1, fmt, list); 4679 va_end (list); 4680 } else { 4681 strcpy (s, spbuf); 4682 } 4683 4684 val -> next = client -> env; 4685 client -> env = val; 4686 client -> envc++; 4687} 4688 4689int dhcp_option_ev_name (buf, buflen, option) 4690 char *buf; 4691 size_t buflen; 4692 struct option *option; 4693{ 4694 int i, j; 4695 const char *s; 4696 4697 j = 0; 4698 if (option -> universe != &dhcp_universe) { 4699 s = option -> universe -> name; 4700 i = 0; 4701 } else { 4702 s = option -> name; 4703 i = 1; 4704 } 4705 4706 do { 4707 while (*s) { 4708 if (j + 1 == buflen) 4709 return 0; 4710 if (*s == '-') 4711 buf [j++] = '_'; 4712 else 4713 buf [j++] = *s; 4714 ++s; 4715 } 4716 if (!i) { 4717 s = option -> name; 4718 if (j + 1 == buflen) 4719 return 0; 4720 buf [j++] = '_'; 4721 } 4722 ++i; 4723 } while (i != 2); 4724 4725 buf [j] = 0; 4726 return 1; 4727} 4728 4729void finish (char ret) 4730{ 4731 if (no_daemon || dfd[0] == -1 || dfd[1] == -1) 4732 exit((int)ret); 4733 if (write(dfd[1], &ret, 1) != 1) 4734 log_fatal("write to parent: %m"); 4735 (void) close(dfd[1]); 4736 dfd[0] = dfd[1] = -1; 4737 exit((int)ret); 4738} 4739 4740void detach () 4741{ 4742 char buf = 0; 4743 4744 if (no_daemon) 4745 return; 4746 4747 if (interfaces_left && --interfaces_left) 4748 return; 4749 4750 /* Only do it once. */ 4751 if (dfd[0] == -1 || dfd[1] == -1) 4752 return; 4753 4754 /* Signal parent we started successfully. */ 4755 if (write(dfd[1], &buf, 1) != 1) 4756 log_fatal("write to parent: %m"); 4757 (void) close(dfd[1]); 4758 dfd[0] = dfd[1] = -1; 4759 4760 /* Stop logging to stderr... */ 4761 log_perror = 0; 4762 4763 /* Become session leader and get pid... */ 4764 (void) setsid(); 4765 4766 /* Close standard I/O descriptors. */ 4767 (void) close(0); 4768 (void) close(1); 4769 (void) close(2); 4770 4771 /* Reopen them on /dev/null. */ 4772 (void) open("/dev/null", O_RDWR); 4773 (void) open("/dev/null", O_RDWR); 4774 (void) open("/dev/null", O_RDWR); 4775 4776 write_client_pid_file (); 4777 4778 IGNORE_RET (chdir("/")); 4779 4780} 4781 4782void write_client_pid_file () 4783{ 4784 FILE *pf; 4785 int pfdesc; 4786 4787 /* nothing to do if the user doesn't want a pid file */ 4788 if (path_dhclient_pid == NULL || no_pid_file == ISC_TRUE) { 4789 return; 4790 } 4791 4792 pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644); 4793 4794 if (pfdesc < 0) { 4795 log_error ("Can't create %s: %m", path_dhclient_pid); 4796 return; 4797 } 4798 4799 pf = fdopen (pfdesc, "w"); 4800 if (!pf) { 4801 close(pfdesc); 4802 log_error ("Can't fdopen %s: %m", path_dhclient_pid); 4803 } else { 4804 fprintf (pf, "%ld\n", (long)getpid ()); 4805 fclose (pf); 4806 } 4807} 4808 4809void client_location_changed () 4810{ 4811 struct interface_info *ip; 4812 struct client_state *client; 4813 4814 for (ip = interfaces; ip; ip = ip -> next) { 4815 for (client = ip -> client; client; client = client -> next) { 4816 switch (client -> state) { 4817 case S_SELECTING: 4818 cancel_timeout (send_discover, client); 4819 break; 4820 4821 case S_BOUND: 4822 cancel_timeout (state_bound, client); 4823 break; 4824 4825 case S_REBOOTING: 4826 case S_REQUESTING: 4827 case S_RENEWING: 4828 cancel_timeout (send_request, client); 4829 break; 4830 4831 case S_INIT: 4832 case S_REBINDING: 4833 case S_STOPPED: 4834 case S_DECLINING: 4835 case S_V6ONLY: 4836 break; 4837 } 4838 client -> state = S_INIT; 4839 state_reboot (client); 4840 } 4841 } 4842} 4843 4844void do_release(client) 4845 struct client_state *client; 4846{ 4847 struct data_string ds; 4848 struct option_cache *oc; 4849 4850#if defined(DHCPv6) && defined(DHCP4o6) 4851 if (dhcpv4_over_dhcpv6 && (dhcp4o6_state <= 0)) { 4852 if (dhcp4o6_state < 0) 4853 dhcp4o6_poll(NULL); 4854 client->pending = P_RELEASE; 4855 return; 4856 } 4857#endif 4858 4859 /* Pick a random xid. */ 4860 client -> xid = random (); 4861 4862 /* is there even a lease to release? */ 4863 if (client -> active) { 4864 /* Make a DHCPRELEASE packet, and set appropriate per-interface 4865 flags. */ 4866 make_release (client, client -> active); 4867 4868 memset (&ds, 0, sizeof ds); 4869 oc = lookup_option (&dhcp_universe, 4870 client -> active -> options, 4871 DHO_DHCP_SERVER_IDENTIFIER); 4872 if (oc && 4873 evaluate_option_cache (&ds, (struct packet *)0, 4874 (struct lease *)0, client, 4875 (struct option_state *)0, 4876 client -> active -> options, 4877 &global_scope, oc, MDL)) { 4878 if (ds.len > 3) { 4879 memcpy (client -> destination.iabuf, 4880 ds.data, 4); 4881 client -> destination.len = 4; 4882 } else 4883 client -> destination = iaddr_broadcast; 4884 4885 data_string_forget (&ds, MDL); 4886 } else 4887 client -> destination = iaddr_broadcast; 4888 client -> first_sending = cur_time; 4889 client -> interval = client -> config -> initial_interval; 4890 4891 /* Zap the medium list... */ 4892 client -> medium = (struct string_list *)0; 4893 4894 /* Send out the first and only DHCPRELEASE packet. */ 4895 send_release (client); 4896 4897 /* Do the client script RELEASE operation. */ 4898 script_init (client, 4899 "RELEASE", (struct string_list *)0); 4900 if (client -> alias) 4901 script_write_params(client, "alias_", 4902 client -> alias); 4903 script_write_params(client, "old_", client -> active); 4904 script_write_requested(client); 4905 script_go(client); 4906 } 4907 4908 /* Cancel any timeouts. */ 4909 cancel_timeout (state_bound, client); 4910 cancel_timeout (send_discover, client); 4911 cancel_timeout (state_init, client); 4912 cancel_timeout (send_request, client); 4913 cancel_timeout (state_reboot, client); 4914 cancel_timeout (finish_v6only, client); 4915 client -> state = S_STOPPED; 4916 4917#if defined(DHCPv6) && defined(DHCP4o6) 4918 if (dhcpv4_over_dhcpv6) 4919 finish(0); 4920#endif 4921} 4922 4923int dhclient_interface_shutdown_hook (struct interface_info *interface) 4924{ 4925 do_release (interface -> client); 4926 4927 return 1; 4928} 4929 4930int dhclient_interface_discovery_hook (struct interface_info *tmp) 4931{ 4932 struct interface_info *last, *ip; 4933 /* See if we can find the client from dummy_interfaces */ 4934 last = 0; 4935 for (ip = dummy_interfaces; ip; ip = ip -> next) { 4936 if (!strcmp (ip -> name, tmp -> name)) { 4937 /* Remove from dummy_interfaces */ 4938 if (last) { 4939 ip = (struct interface_info *)0; 4940 interface_reference (&ip, last -> next, MDL); 4941 interface_dereference (&last -> next, MDL); 4942 if (ip -> next) { 4943 interface_reference (&last -> next, 4944 ip -> next, MDL); 4945 interface_dereference (&ip -> next, 4946 MDL); 4947 } 4948 } else { 4949 ip = (struct interface_info *)0; 4950 interface_reference (&ip, 4951 dummy_interfaces, MDL); 4952 interface_dereference (&dummy_interfaces, MDL); 4953 if (ip -> next) { 4954 interface_reference (&dummy_interfaces, 4955 ip -> next, MDL); 4956 interface_dereference (&ip -> next, 4957 MDL); 4958 } 4959 } 4960 /* Copy "client" to tmp */ 4961 if (ip -> client) { 4962 tmp -> client = ip -> client; 4963 tmp -> client -> interface = tmp; 4964 } 4965 interface_dereference (&ip, MDL); 4966 break; 4967 } 4968 last = ip; 4969 } 4970 return 1; 4971} 4972 4973isc_result_t dhclient_interface_startup_hook (struct interface_info *interface) 4974{ 4975 struct interface_info *ip; 4976 struct client_state *client; 4977 4978 /* This code needs some rethinking. It doesn't test against 4979 a signal name, and it just kind of bulls into doing something 4980 that may or may not be appropriate. */ 4981 4982 if (interfaces) { 4983 interface_reference (&interface -> next, interfaces, MDL); 4984 interface_dereference (&interfaces, MDL); 4985 } 4986 interface_reference (&interfaces, interface, MDL); 4987 4988 discover_interfaces (DISCOVER_UNCONFIGURED); 4989 4990 for (ip = interfaces; ip; ip = ip -> next) { 4991 /* If interfaces were specified, don't configure 4992 interfaces that weren't specified! */ 4993 if (ip -> flags & INTERFACE_RUNNING || 4994 (ip -> flags & (INTERFACE_REQUESTED | 4995 INTERFACE_AUTOMATIC)) != 4996 INTERFACE_REQUESTED) 4997 continue; 4998 script_init (ip -> client, 4999 "PREINIT", (struct string_list *)0); 5000 if (ip -> client -> alias) 5001 script_write_params(ip -> client, "alias_", 5002 ip -> client -> alias); 5003 script_go(ip -> client); 5004 } 5005 5006 discover_interfaces (interfaces_requested != 0 5007 ? DISCOVER_REQUESTED 5008 : DISCOVER_RUNNING); 5009 5010 for (ip = interfaces; ip; ip = ip -> next) { 5011 if (ip -> flags & INTERFACE_RUNNING) 5012 continue; 5013 ip -> flags |= INTERFACE_RUNNING; 5014 for (client = ip->client ; client ; client = client->next) { 5015 client->state = S_INIT; 5016 state_reboot(client); 5017 } 5018 } 5019 return ISC_R_SUCCESS; 5020} 5021 5022/* The client should never receive a relay agent information option, 5023 so if it does, log it and discard it. */ 5024 5025int parse_agent_information_option (packet, len, data) 5026 struct packet *packet; 5027 int len; 5028 u_int8_t *data; 5029{ 5030 return 1; 5031} 5032 5033/* The client never sends relay agent information options. */ 5034 5035unsigned cons_agent_information_options (cfg_options, outpacket, 5036 agentix, length) 5037 struct option_state *cfg_options; 5038 struct dhcp_packet *outpacket; 5039 unsigned agentix; 5040 unsigned length; 5041{ 5042 return length; 5043} 5044 5045static void shutdown_exit (void *foo) 5046{ 5047 /* get rid of the pid if we can */ 5048 if (no_pid_file == ISC_FALSE) 5049 (void) unlink(path_dhclient_pid); 5050 finish(0); 5051} 5052 5053#if defined (NSUPDATE) 5054/* 5055 * If the first query fails, the updater MUST NOT delete the DNS name. It 5056 * may be that the host whose lease on the server has expired has moved 5057 * to another network and obtained a lease from a different server, 5058 * which has caused the client's A RR to be replaced. It may also be 5059 * that some other client has been configured with a name that matches 5060 * the name of the DHCP client, and the policy was that the last client 5061 * to specify the name would get the name. In this case, the DHCID RR 5062 * will no longer match the updater's notion of the client-identity of 5063 * the host pointed to by the DNS name. 5064 * -- "Interaction between DHCP and DNS" 5065 */ 5066 5067/* The first and second stages are pretty similar so we combine them */ 5068static void 5069client_dns_remove_action(dhcp_ddns_cb_t *ddns_cb, 5070 isc_result_t eresult) 5071{ 5072 5073 isc_result_t result; 5074 5075 if ((eresult == ISC_R_SUCCESS) && 5076 (ddns_cb->state == DDNS_STATE_REM_FW_YXDHCID)) { 5077 /* Do the second stage of the FWD removal */ 5078 ddns_cb->state = DDNS_STATE_REM_FW_NXRR; 5079 5080 result = ddns_modify_fwd(ddns_cb, MDL); 5081 if (result == ISC_R_SUCCESS) { 5082 return; 5083 } 5084 } 5085 5086 /* If we are done or have an error clean up */ 5087 dhclient_ddns_cb_free(ddns_cb, MDL); 5088 return; 5089} 5090 5091void 5092client_dns_remove(struct client_state *client, 5093 struct iaddr *addr) 5094{ 5095 dhcp_ddns_cb_t *ddns_cb; 5096 isc_result_t result; 5097 5098 /* if we have an old ddns request for this client, cancel it */ 5099 if (client->ddns_cb != NULL) { 5100 ddns_cancel(client->ddns_cb, MDL); 5101 client->ddns_cb = NULL; 5102 } 5103 5104 ddns_cb = ddns_cb_alloc(MDL); 5105 if (ddns_cb != NULL) { 5106 ddns_cb->address = *addr; 5107 ddns_cb->timeout = 0; 5108 5109 ddns_cb->state = DDNS_STATE_REM_FW_YXDHCID; 5110 ddns_cb->flags = DDNS_UPDATE_ADDR; 5111 ddns_cb->cur_func = client_dns_remove_action; 5112 5113 result = client_dns_update(client, ddns_cb); 5114 5115 if (result != ISC_R_TIMEDOUT) { 5116 dhclient_ddns_cb_free(ddns_cb, MDL); 5117 } 5118 } 5119} 5120#endif /* defined NSUPDATE */ 5121 5122 5123isc_result_t dhcp_set_control_state (control_object_state_t oldstate, 5124 control_object_state_t newstate) 5125{ 5126 struct interface_info *ip; 5127 struct client_state *client; 5128 struct timeval tv; 5129 5130 if (newstate == server_shutdown) { 5131 /* Re-entry */ 5132 if (shutdown_signal == SIGUSR1) 5133 return ISC_R_SUCCESS; 5134 /* Log shutdown on signal. */ 5135 if ((shutdown_signal == SIGINT) || 5136 (shutdown_signal == SIGTERM)) { 5137 log_info("Received signal %d, initiating shutdown.", 5138 shutdown_signal); 5139 } 5140 /* Mark it was called. */ 5141 shutdown_signal = SIGUSR1; 5142 } 5143 5144 /* Do the right thing for each interface. */ 5145 for (ip = interfaces; ip; ip = ip -> next) { 5146 for (client = ip -> client; client; client = client -> next) { 5147 switch (newstate) { 5148 case server_startup: 5149 return ISC_R_SUCCESS; 5150 5151 case server_running: 5152 return ISC_R_SUCCESS; 5153 5154 case server_shutdown: 5155 if (client -> active && 5156 client -> active -> expiry > cur_time) { 5157#if defined (NSUPDATE) 5158 if (client->config->do_forward_update) { 5159 client_dns_remove(client, 5160 &client->active->address); 5161 } 5162#endif /* defined NSUPDATE */ 5163 5164 do_release (client); 5165 } 5166 break; 5167 5168 case server_hibernate: 5169 state_stop (client); 5170 break; 5171 5172 case server_awaken: 5173 state_reboot (client); 5174 break; 5175 } 5176 } 5177 } 5178 5179 if (newstate == server_shutdown) { 5180 tv.tv_sec = cur_tv.tv_sec; 5181 tv.tv_usec = cur_tv.tv_usec + 1; 5182 add_timeout(&tv, shutdown_exit, 0, 0, 0); 5183 } 5184 return ISC_R_SUCCESS; 5185} 5186 5187#if defined (NSUPDATE) 5188/* 5189 * Called after a timeout if the DNS update failed on the previous try. 5190 * Starts the retry process. If the retry times out it will schedule 5191 * this routine to run again after a 10x wait. 5192 */ 5193void 5194client_dns_update_timeout (void *cp) 5195{ 5196 dhcp_ddns_cb_t *ddns_cb = (dhcp_ddns_cb_t *)cp; 5197 struct client_state *client = (struct client_state *)ddns_cb->lease; 5198 isc_result_t status = ISC_R_FAILURE; 5199 5200 if ((client != NULL) && 5201 ((client->active != NULL) || 5202 (client->active_lease != NULL))) 5203 status = client_dns_update(client, ddns_cb); 5204 5205 /* 5206 * A status of timedout indicates that we started the update and 5207 * have released control of the control block. Any other status 5208 * indicates that we should clean up the control block. We either 5209 * got a success which indicates that we didn't really need to 5210 * send an update or some other error in which case we weren't able 5211 * to start the update process. In both cases we still own 5212 * the control block and should free it. 5213 */ 5214 if (status != ISC_R_TIMEDOUT) { 5215 dhclient_ddns_cb_free(ddns_cb, MDL); 5216 } 5217} 5218 5219/* 5220 * If the first query succeeds, the updater can conclude that it 5221 * has added a new name whose only RRs are the A and DHCID RR records. 5222 * The A RR update is now complete (and a client updater is finished, 5223 * while a server might proceed to perform a PTR RR update). 5224 * -- "Interaction between DHCP and DNS" 5225 * 5226 * If the second query succeeds, the updater can conclude that the current 5227 * client was the last client associated with the domain name, and that 5228 * the name now contains the updated A RR. The A RR update is now 5229 * complete (and a client updater is finished, while a server would 5230 * then proceed to perform a PTR RR update). 5231 * -- "Interaction between DHCP and DNS" 5232 * 5233 * If the second query fails with NXRRSET, the updater must conclude 5234 * that the client's desired name is in use by another host. At this 5235 * juncture, the updater can decide (based on some administrative 5236 * configuration outside of the scope of this document) whether to let 5237 * the existing owner of the name keep that name, and to (possibly) 5238 * perform some name disambiguation operation on behalf of the current 5239 * client, or to replace the RRs on the name with RRs that represent 5240 * the current client. If the configured policy allows replacement of 5241 * existing records, the updater submits a query that deletes the 5242 * existing A RR and the existing DHCID RR, adding A and DHCID RRs that 5243 * represent the IP address and client-identity of the new client. 5244 * -- "Interaction between DHCP and DNS" 5245 */ 5246 5247/* The first and second stages are pretty similar so we combine them */ 5248static void 5249client_dns_update_action(dhcp_ddns_cb_t *ddns_cb, 5250 isc_result_t eresult) 5251{ 5252 isc_result_t result; 5253 struct timeval tv; 5254 5255 switch(eresult) { 5256 case ISC_R_SUCCESS: 5257 default: 5258 /* Either we succeeded or broke in a bad way, clean up */ 5259 break; 5260 5261 case DNS_R_YXRRSET: 5262 /* 5263 * This is the only difference between the two stages, 5264 * check to see if it is the first stage, in which case 5265 * start the second stage 5266 */ 5267 if (ddns_cb->state == DDNS_STATE_ADD_FW_NXDOMAIN) { 5268 ddns_cb->state = DDNS_STATE_ADD_FW_YXDHCID; 5269 ddns_cb->cur_func = client_dns_update_action; 5270 5271 result = ddns_modify_fwd(ddns_cb, MDL); 5272 if (result == ISC_R_SUCCESS) { 5273 return; 5274 } 5275 } 5276 break; 5277 5278 case ISC_R_TIMEDOUT: 5279 /* 5280 * We got a timeout response from the DNS module. Schedule 5281 * another attempt for later. We forget the name, dhcid and 5282 * zone so if it gets changed we will get the new information. 5283 */ 5284 data_string_forget(&ddns_cb->fwd_name, MDL); 5285 data_string_forget(&ddns_cb->dhcid, MDL); 5286 if (ddns_cb->zone != NULL) { 5287 forget_zone((struct dns_zone **)&ddns_cb->zone); 5288 } 5289 5290 /* Reset to doing the first stage */ 5291 ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN; 5292 ddns_cb->cur_func = client_dns_update_action; 5293 5294 /* and update our timer */ 5295 if (ddns_cb->timeout < 3600) 5296 ddns_cb->timeout *= 10; 5297 tv.tv_sec = cur_tv.tv_sec + ddns_cb->timeout; 5298 tv.tv_usec = cur_tv.tv_usec; 5299 add_timeout(&tv, client_dns_update_timeout, 5300 ddns_cb, NULL, NULL); 5301 return; 5302 } 5303 5304 dhclient_ddns_cb_free(ddns_cb, MDL); 5305 return; 5306} 5307 5308/* See if we should do a DNS update, and if so, do it. */ 5309 5310isc_result_t 5311client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb) 5312{ 5313 struct data_string client_identifier; 5314 struct option_cache *oc; 5315 int ignorep; 5316 int result; 5317 int ddns_v4_type; 5318 isc_result_t rcode; 5319 5320 /* If we didn't send an FQDN option, we certainly aren't going to 5321 be doing an update. */ 5322 if (!client -> sent_options) 5323 return ISC_R_SUCCESS; 5324 5325 /* If we don't have a lease, we can't do an update. */ 5326 if ((client->active == NULL) && (client->active_lease == NULL)) 5327 return ISC_R_SUCCESS; 5328 5329 /* If we set the no client update flag, don't do the update. */ 5330 if ((oc = lookup_option (&fqdn_universe, client -> sent_options, 5331 FQDN_NO_CLIENT_UPDATE)) && 5332 evaluate_boolean_option_cache (&ignorep, (struct packet *)0, 5333 (struct lease *)0, client, 5334 client -> sent_options, 5335 (struct option_state *)0, 5336 &global_scope, oc, MDL)) 5337 return ISC_R_SUCCESS; 5338 5339 /* If we set the "server, please update" flag, or didn't set it 5340 to false, don't do the update. */ 5341 if (!(oc = lookup_option (&fqdn_universe, client -> sent_options, 5342 FQDN_SERVER_UPDATE)) || 5343 evaluate_boolean_option_cache (&ignorep, (struct packet *)0, 5344 (struct lease *)0, client, 5345 client -> sent_options, 5346 (struct option_state *)0, 5347 &global_scope, oc, MDL)) 5348 return ISC_R_SUCCESS; 5349 5350 /* If no FQDN option was supplied, don't do the update. */ 5351 if (!(oc = lookup_option (&fqdn_universe, client -> sent_options, 5352 FQDN_FQDN)) || 5353 !evaluate_option_cache (&ddns_cb->fwd_name, (struct packet *)0, 5354 (struct lease *)0, client, 5355 client -> sent_options, 5356 (struct option_state *)0, 5357 &global_scope, oc, MDL)) 5358 return ISC_R_SUCCESS; 5359 5360 /* 5361 * Construct the DHCID value for use in the DDNS update process 5362 * We have the newer standard version and the older interim version 5363 * chosen by the '-I' option. The interim version is left as is 5364 * for backwards compatibility. The standard version is based on 5365 * RFC 4701 section 3.3 5366 */ 5367 5368 result = 0; 5369 POST(result); 5370 memset(&client_identifier, 0, sizeof(client_identifier)); 5371 5372 if (std_dhcid == 1) { 5373 /* standard style */ 5374 ddns_cb->dhcid_class = dns_rdatatype_dhcid; 5375 ddns_v4_type = 1; 5376 } else { 5377 /* interim style */ 5378 ddns_cb->dhcid_class = dns_rdatatype_txt; 5379 /* for backwards compatibility */ 5380 ddns_v4_type = DHO_DHCP_CLIENT_IDENTIFIER; 5381 } 5382 if (client->active_lease != NULL) { 5383 /* V6 request, get the client identifier, then 5384 * construct the dhcid for either standard 5385 * or interim */ 5386 if (((oc = lookup_option(&dhcpv6_universe, 5387 client->sent_options, 5388 D6O_CLIENTID)) != NULL) && 5389 evaluate_option_cache(&client_identifier, NULL, 5390 NULL, client, 5391 client->sent_options, NULL, 5392 &global_scope, oc, MDL)) { 5393 result = get_dhcid(ddns_cb, 2, 5394 client_identifier.data, 5395 client_identifier.len); 5396 data_string_forget(&client_identifier, MDL); 5397 } else 5398 log_fatal("Impossible condition at %s:%d.", MDL); 5399 } else { 5400 /* 5401 * V4 request, use the client id if there is one or the 5402 * mac address if there isn't. If we have a client id 5403 * we check to see if it is an embedded DUID. 5404 */ 5405 if (((oc = lookup_option(&dhcp_universe, 5406 client->sent_options, 5407 DHO_DHCP_CLIENT_IDENTIFIER)) != NULL) && 5408 evaluate_option_cache(&client_identifier, NULL, 5409 NULL, client, 5410 client->sent_options, NULL, 5411 &global_scope, oc, MDL)) { 5412 if ((std_dhcid == 1) && (duid_v4 == 1) && 5413 (client_identifier.data[0] == 255)) { 5414 /* 5415 * This appears to be an embedded DUID, 5416 * extract it and treat it as such 5417 */ 5418 if (client_identifier.len <= 5) 5419 log_fatal("Impossible condition at %s:%d.", 5420 MDL); 5421 result = get_dhcid(ddns_cb, 2, 5422 client_identifier.data + 5, 5423 client_identifier.len - 5); 5424 } else { 5425 result = get_dhcid(ddns_cb, ddns_v4_type, 5426 client_identifier.data, 5427 client_identifier.len); 5428 } 5429 data_string_forget(&client_identifier, MDL); 5430 } else 5431 result = get_dhcid(ddns_cb, 0, 5432 client->interface->hw_address.hbuf, 5433 client->interface->hw_address.hlen); 5434 } 5435 5436 if (!result) { 5437 return ISC_R_SUCCESS; 5438 } 5439 5440 /* 5441 * Perform updates. 5442 */ 5443 if (ddns_cb->fwd_name.len && ddns_cb->dhcid.len) { 5444 rcode = ddns_modify_fwd(ddns_cb, MDL); 5445 } else 5446 rcode = ISC_R_FAILURE; 5447 5448 /* 5449 * A success from the modify routine means we are performing 5450 * async processing, for which we use the timedout error message. 5451 */ 5452 if (rcode == ISC_R_SUCCESS) { 5453 rcode = ISC_R_TIMEDOUT; 5454 } 5455 5456 return rcode; 5457} 5458 5459 5460/* 5461 * Schedule the first update. They will continue to retry occasionally 5462 * until they no longer time out (or fail). 5463 */ 5464void 5465dhclient_schedule_updates(struct client_state *client, 5466 struct iaddr *addr, 5467 int offset) 5468{ 5469 dhcp_ddns_cb_t *ddns_cb; 5470 struct timeval tv; 5471 5472 if (!client->config->do_forward_update) 5473 return; 5474 5475 /* cancel any outstanding ddns requests */ 5476 if (client->ddns_cb != NULL) { 5477 ddns_cancel(client->ddns_cb, MDL); 5478 client->ddns_cb = NULL; 5479 } 5480 5481 ddns_cb = ddns_cb_alloc(MDL); 5482 5483 if (ddns_cb != NULL) { 5484 ddns_cb->lease = (void *)client; 5485 ddns_cb->address = *addr; 5486 ddns_cb->timeout = 1; 5487 5488 /* 5489 * XXX: DNS TTL is a problem we need to solve properly. 5490 * Until that time, 300 is a placeholder default for 5491 * something that is less insane than a value scaled 5492 * by lease timeout. 5493 */ 5494 ddns_cb->ttl = 300; 5495 5496 ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN; 5497 ddns_cb->cur_func = client_dns_update_action; 5498 ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_INCLUDE_RRSET; 5499 5500 client->ddns_cb = ddns_cb; 5501 tv.tv_sec = cur_tv.tv_sec + offset; 5502 tv.tv_usec = cur_tv.tv_usec; 5503 add_timeout(&tv, client_dns_update_timeout, 5504 ddns_cb, NULL, NULL); 5505 } else { 5506 log_error("Unable to allocate dns update state for %s", 5507 piaddr(*addr)); 5508 } 5509} 5510#endif /* defined NSUPDATE */ 5511 5512void 5513dhcpv4_client_assignments(void) 5514{ 5515 struct servent *ent; 5516 5517 if (path_dhclient_pid == NULL) 5518 path_dhclient_pid = _PATH_DHCLIENT_PID; 5519 if (path_dhclient_db == NULL) 5520 path_dhclient_db = _PATH_DHCLIENT_DB; 5521 5522 /* Default to the DHCP/BOOTP port. */ 5523 if (!local_port) { 5524 /* If we're faking a relay agent, and we're not using loopback, 5525 use the server port, not the client port. */ 5526 if (mockup_relay && giaddr.s_addr != htonl(INADDR_LOOPBACK)) { 5527 local_port = htons(67); 5528 } else { 5529 ent = getservbyname("dhcpc", "udp"); 5530 if (ent == NULL) 5531 ent = getservbyname("bootpc", "udp"); 5532 if (ent == NULL) 5533 local_port = htons(68); 5534 else 5535 local_port = ent->s_port; 5536#ifndef __CYGWIN32__ 5537 endservent (); 5538#endif 5539 } 5540 } 5541 5542 /* If we're faking a relay agent, and we're not using loopback, 5543 we're using the server port, not the client port. */ 5544 if (mockup_relay && giaddr.s_addr != htonl(INADDR_LOOPBACK)) { 5545 remote_port = local_port; 5546 } else 5547 remote_port = htons(ntohs(local_port) - 1); /* XXX */ 5548} 5549 5550/* 5551 * The following routines are used to check that certain 5552 * strings are reasonable before we pass them to the scripts. 5553 * This avoids some problems with scripts treating the strings 5554 * as commands - see ticket 23722 5555 * The domain checking code should be done as part of assembling 5556 * the string but we are doing it here for now due to time 5557 * constraints. 5558 */ 5559 5560static int check_domain_name(const char *ptr, size_t len, int dots) 5561{ 5562 const char *p; 5563 5564 /* not empty or complete length not over 255 characters */ 5565 if ((len == 0) || (len > 256)) 5566 return(-1); 5567 5568 /* consists of [[:alnum:]-]+ labels separated by [.] */ 5569 /* a [_] is against RFC but seems to be "widely used"... */ 5570 for (p=ptr; (*p != 0) && (len-- > 0); p++) { 5571 if ((*p == '-') || (*p == '_')) { 5572 /* not allowed at begin or end of a label */ 5573 if (((p - ptr) == 0) || (len == 0) || (p[1] == '.')) 5574 return(-1); 5575 } else if (*p == '.') { 5576 /* each label has to be 1-63 characters; 5577 we allow [.] at the end ('foo.bar.') */ 5578 size_t d = p - ptr; 5579 if ((d <= 0) || (d >= 64)) 5580 return(-1); 5581 ptr = p + 1; /* jump to the next label */ 5582 if ((dots > 0) && (len > 0)) 5583 dots--; 5584 } else if (isalnum((unsigned char)*p) == 0) { 5585 /* also numbers at the begin are fine */ 5586 return(-1); 5587 } 5588 } 5589 return(dots ? -1 : 0); 5590} 5591 5592static int check_domain_name_list(const char *ptr, size_t len, int dots) 5593{ 5594 const char *p; 5595 int ret = -1; /* at least one needed */ 5596 5597 if ((ptr == NULL) || (len == 0)) 5598 return(-1); 5599 5600 for (p=ptr; (*p != 0) && (len > 0); p++, len--) { 5601 if (*p != ' ') 5602 continue; 5603 if (p > ptr) { 5604 if (check_domain_name(ptr, p - ptr, dots) != 0) 5605 return(-1); 5606 ret = 0; 5607 } 5608 ptr = p + 1; 5609 } 5610 if (p > ptr) 5611 return(check_domain_name(ptr, p - ptr, dots)); 5612 else 5613 return(ret); 5614} 5615 5616static int check_option_values(struct universe *universe, 5617 unsigned int opt, 5618 const char *ptr, 5619 size_t len) 5620{ 5621 if (ptr == NULL) 5622 return(-1); 5623 5624 /* just reject options we want to protect, will be escaped anyway */ 5625 if ((universe == NULL) || (universe == &dhcp_universe)) { 5626 switch(opt) { 5627 case DHO_DOMAIN_NAME: 5628#ifdef ACCEPT_LIST_IN_DOMAIN_NAME 5629 return check_domain_name_list(ptr, len, 0); 5630#else 5631 return check_domain_name(ptr, len, 0); 5632#endif 5633 case DHO_HOST_NAME: 5634 case DHO_NIS_DOMAIN: 5635 case DHO_NETBIOS_SCOPE: 5636 return check_domain_name(ptr, len, 0); 5637 break; 5638 case DHO_DOMAIN_SEARCH: 5639 return check_domain_name_list(ptr, len, 0); 5640 break; 5641 case DHO_ROOT_PATH: 5642 if (len == 0) 5643 return(-1); 5644 for (; (*ptr != 0) && (len-- > 0); ptr++) { 5645 if(!(isalnum((unsigned char)*ptr) || 5646 *ptr == '#' || *ptr == '%' || 5647 *ptr == '+' || *ptr == '-' || 5648 *ptr == '_' || *ptr == ':' || 5649 *ptr == '.' || *ptr == ',' || 5650 *ptr == '@' || *ptr == '~' || 5651 *ptr == '\\' || *ptr == '/' || 5652 *ptr == '[' || *ptr == ']' || 5653 *ptr == '=' || *ptr == ' ')) 5654 return(-1); 5655 } 5656 return(0); 5657 break; 5658 } 5659 } 5660 5661#ifdef DHCPv6 5662 if (universe == &dhcpv6_universe) { 5663 switch(opt) { 5664 case D6O_SIP_SERVERS_DNS: 5665 case D6O_DOMAIN_SEARCH: 5666 case D6O_NIS_DOMAIN_NAME: 5667 case D6O_NISP_DOMAIN_NAME: 5668 return check_domain_name_list(ptr, len, 0); 5669 break; 5670 } 5671 } 5672#endif 5673 5674 return(0); 5675} 5676 5677static void 5678add_reject(struct packet *packet) { 5679 struct iaddrmatchlist *list; 5680 5681 list = dmalloc(sizeof(struct iaddrmatchlist), MDL); 5682 if (!list) 5683 log_fatal ("no memory for reject list!"); 5684 5685 /* 5686 * client_addr is misleading - it is set to source address in common 5687 * code. 5688 */ 5689 list->match.addr = packet->client_addr; 5690 /* Set mask to indicate host address. */ 5691 list->match.mask.len = list->match.addr.len; 5692 memset(list->match.mask.iabuf, 0xff, sizeof(list->match.mask.iabuf)); 5693 5694 /* Append to reject list for the source interface. */ 5695 list->next = packet->interface->client->config->reject_list; 5696 packet->interface->client->config->reject_list = list; 5697 5698 /* 5699 * We should inform user that we won't be accepting this server 5700 * anymore. 5701 */ 5702 log_info("Server added to list of rejected servers."); 5703} 5704 5705#if defined(NSUPDATE) 5706/* Wrapper function around common ddns_cb_free function that ensures 5707 * we set the client_state pointer to the control block to NULL. */ 5708static void 5709dhclient_ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, char* file, int line) { 5710 if (ddns_cb) { 5711 struct client_state *client = (struct client_state *)ddns_cb->lease; 5712 if (client != NULL) { 5713 client->ddns_cb = NULL; 5714 } 5715 5716 ddns_cb_free(ddns_cb, file, line); 5717 } 5718} 5719#endif /* defined NSUPDATE */ 5720 5721#if defined(DHCPv6) && defined(DHCP4o6) 5722/* 5723 * \brief Omapi I/O handler 5724 * 5725 * The inter-process communication receive handler. 5726 * 5727 * On the DHCPv6 side, the message is either a POLL (which is answered 5728 * by a START or a STOP) or a DHCPv4-QUERY (which is forwarded to 5729 * DHCPv4 over DHCPv6 servers by forw_dhcpv4_query()). 5730 * 5731 * On the DHCPv4 side, the message is either a START, a STOP 5732 * (both for the DHCP4 over DHCPv6 state machine) or a DHCPv4-RESPONSE 5733 * (which is processed by recv_dhcpv4_response()). 5734 * 5735 * \param h the OMAPI object 5736 * \return a result for I/O success or error (used by the I/O subsystem) 5737 */ 5738isc_result_t dhcpv4o6_handler(omapi_object_t *h) { 5739 char buf[65536]; 5740 char start_msg[5] = { 'S', 'T', 'A', 'R', 'T' }; 5741 char stop_msg[4] = { 'S', 'T', 'O', 'P' }; 5742 char poll_msg[4] = { 'P', 'O', 'L', 'L' }; 5743 struct data_string raw; 5744 int cc; 5745 5746 if (h->type != dhcp4o6_type) 5747 return DHCP_R_INVALIDARG; 5748 5749 cc = recv(dhcp4o6_fd, buf, sizeof(buf), 0); 5750 if (cc <= 0) 5751 return ISC_R_UNEXPECTED; 5752 5753 if (local_family == AF_INET6) { 5754 if ((cc == 4) && 5755 (memcmp(buf, poll_msg, sizeof(poll_msg)) == 0)) { 5756 log_info("RCV: POLL"); 5757 if (dhcp4o6_state < 0) 5758 cc = send(dhcp4o6_fd, stop_msg, 5759 sizeof(stop_msg), 0); 5760 else 5761 cc = send(dhcp4o6_fd, start_msg, 5762 sizeof(start_msg), 0); 5763 if (cc < 0) { 5764 log_error("dhcpv4o6_handler: send(): %m"); 5765 return ISC_R_IOERROR; 5766 } 5767 } else { 5768 if (cc < DHCP_FIXED_NON_UDP + 8) 5769 return ISC_R_UNEXPECTED; 5770 memset(&raw, 0, sizeof(raw)); 5771 if (!buffer_allocate(&raw.buffer, cc, MDL)) { 5772 log_error("dhcpv4o6_handler: " 5773 "no memory buffer."); 5774 return ISC_R_NOMEMORY; 5775 } 5776 raw.data = raw.buffer->data; 5777 raw.len = cc; 5778 memcpy(raw.buffer->data, buf, cc); 5779 5780 forw_dhcpv4_query(&raw); 5781 5782 data_string_forget(&raw, MDL); 5783 } 5784 } else { 5785 if ((cc == 4) && 5786 (memcmp(buf, stop_msg, sizeof(stop_msg)) == 0)) { 5787 log_info("RCV: STOP"); 5788 if (dhcp4o6_state > 0) { 5789 dhcp4o6_state = 0; 5790 dhcp4o6_poll(NULL); 5791 } 5792 } else if ((cc == 5) && 5793 (memcmp(buf, start_msg, sizeof(start_msg)) == 0)) { 5794 log_info("RCV: START"); 5795 if (dhcp4o6_state == 0) 5796 cancel_timeout(dhcp4o6_poll, NULL); 5797 dhcp4o6_state = 1; 5798 dhcp4o6_resume(); 5799 } else { 5800 if (cc < DHCP_FIXED_NON_UDP + 16) 5801 return ISC_R_UNEXPECTED; 5802 memset(&raw, 0, sizeof(raw)); 5803 if (!buffer_allocate(&raw.buffer, cc, MDL)) { 5804 log_error("dhcpv4o6_handler: " 5805 "no memory buffer."); 5806 return ISC_R_NOMEMORY; 5807 } 5808 raw.data = raw.buffer->data; 5809 raw.len = cc; 5810 memcpy(raw.buffer->data, buf, cc); 5811 5812 recv_dhcpv4_response(&raw); 5813 5814 data_string_forget(&raw, MDL); 5815 } 5816 } 5817 5818 return ISC_R_SUCCESS; 5819} 5820 5821/* 5822 * \brief Poll the DHCPv6 client 5823 * (DHCPv4 client function) 5824 * 5825 * A POLL message is sent to the DHCPv6 client periodically to check 5826 * if the DHCPv6 is ready (i.e., has a valid DHCPv4-over-DHCPv6 server 5827 * address option). 5828 */ 5829static void dhcp4o6_poll(void *dummy) { 5830 char msg[4] = { 'P', 'O', 'L', 'L' }; 5831 struct timeval tv; 5832 int cc; 5833 5834 IGNORE_UNUSED(dummy); 5835 5836 if (dhcp4o6_state < 0) 5837 dhcp4o6_state = 0; 5838 5839 log_info("POLL"); 5840 5841 cc = send(dhcp4o6_fd, msg, sizeof(msg), 0); 5842 if (cc < 0) 5843 log_error("dhcp4o6_poll: send(): %m"); 5844 5845 tv.tv_sec = cur_time + 60; 5846 tv.tv_usec = random() % 1000000; 5847 5848 add_timeout(&tv, dhcp4o6_poll, NULL, 0, 0); 5849} 5850 5851/* 5852 * \brief Resume pending operations 5853 * (DHCPv4 client function) 5854 * 5855 * A START message was received from the DHCPv6 client so pending 5856 * operations (RELEASE or REBOOT) must be resumed. 5857 */ 5858static void dhcp4o6_resume() { 5859 struct interface_info *ip; 5860 struct client_state *client; 5861 5862 for (ip = interfaces; ip != NULL; ip = ip->next) { 5863 for (client = ip->client; client != NULL; 5864 client = client->next) { 5865 if (client->pending == P_RELEASE) 5866 do_release(client); 5867 else if (client->pending == P_REBOOT) 5868 state_reboot(client); 5869 } 5870 } 5871} 5872 5873/* 5874 * \brief Send a START to the DHCPv4 client 5875 * (DHCPv6 client function) 5876 * 5877 * First check if there is a valid DHCPv4-over-DHCPv6 server address option, 5878 * and when found go UP and on a transition from another state send 5879 * a START message to the DHCPv4 client. 5880 */ 5881void dhcp4o6_start() { 5882 struct interface_info *ip; 5883 struct client_state *client; 5884 struct dhc6_lease *lease; 5885 struct option_cache *oc; 5886 struct data_string addrs; 5887 char msg[5] = { 'S', 'T', 'A', 'R', 'T' }; 5888 int cc; 5889 5890 memset(&addrs, 0, sizeof(addrs)); 5891 for (ip = interfaces; ip != NULL; ip = ip->next) { 5892 for (client = ip->client; client != NULL; 5893 client = client->next) { 5894 if ((client->state != S_BOUND) && 5895 (client->state != S_RENEWING) && 5896 (client->state != S_REBINDING)) 5897 continue; 5898 lease = client->active_lease; 5899 if ((lease == NULL) || lease->released) 5900 continue; 5901 oc = lookup_option(&dhcpv6_universe, 5902 lease->options, 5903 D6O_DHCP4_O_DHCP6_SERVER); 5904 if ((oc == NULL) || 5905 !evaluate_option_cache(&addrs, NULL, NULL, NULL, 5906 lease->options, NULL, 5907 &global_scope, oc, MDL)) 5908 continue; 5909 if ((addrs.len % 16) != 0) { 5910 data_string_forget(&addrs, MDL); 5911 continue; 5912 } 5913 data_string_forget(&addrs, MDL); 5914 goto found; 5915 } 5916 } 5917 log_info("dhcp4o6_start: failed"); 5918 dhcp4o6_stop(); 5919 return; 5920 5921found: 5922 if (dhcp4o6_state == 1) 5923 return; 5924 log_info("dhcp4o6_start: go to UP"); 5925 dhcp4o6_state = 1; 5926 5927 cc = send(dhcp4o6_fd, msg, sizeof(msg), 0); 5928 if (cc < 0) 5929 log_info("dhcp4o6_start: send(): %m"); 5930} 5931 5932/* 5933 * Send a STOP to the DHCPv4 client 5934 * (DHCPv6 client function) 5935 * 5936 * Go DOWN and on a transition from another state send a STOP message 5937 * to the DHCPv4 client. 5938 */ 5939static void dhcp4o6_stop() { 5940 char msg[4] = { 'S', 'T', 'O', 'P' }; 5941 int cc; 5942 5943 if (dhcp4o6_state == -1) 5944 return; 5945 5946 log_info("dhcp4o6_stop: go to DOWN"); 5947 dhcp4o6_state = -1; 5948 5949 cc = send(dhcp4o6_fd, msg, sizeof(msg), 0); 5950 if (cc < 0) 5951 log_error("dhcp4o6_stop: send(): %m"); 5952} 5953#endif /* DHCPv6 && DHCP4o6 */ 5954