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