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