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