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