]> git.ipfire.org Git - thirdparty/dhcp.git/blob - client/dhclient.c
1a7ac85e8a91c8f807436808dd12b2a972c62625
[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 client->state = S_INIT;
1306 state_init(cpp);
1307 }
1308
1309 /*
1310 * start_v6only is called when a requested v6-only-preferred option was
1311 * returned by the server. */
1312
1313 void start_v6only(client, v6only_wait)
1314 struct client_state *client;
1315 uint32_t v6only_wait;
1316 {
1317 struct timeval tv;
1318
1319 /* Enter V6ONLY state. */
1320
1321 client->state = S_V6ONLY;
1322
1323 /* Run the client script. */
1324 script_init(client, "V6ONLY", NULL);
1325 if (client->active) {
1326 script_write_params(client, "old_", client->active);
1327 destroy_client_lease(client->active);
1328 client->active = NULL;
1329 }
1330 script_write_requested(client);
1331 client_envadd(client, "", "v6-only-preferred", "%lu",
1332 (long unsigned)v6only_wait);
1333 script_go(client);
1334
1335 /* Trigger finish_v6only after V6ONLY_WAIT seconds. */
1336 tv.tv_sec = cur_tv.tv_sec + v6only_wait;
1337 tv.tv_usec = cur_tv.tv_usec;
1338
1339 add_timeout(&tv, finish_v6only, client, 0, 0);
1340 }
1341
1342 /*
1343 * state_selecting is called when one or more DHCPOFFER packets have been
1344 * received and a configurable period of time has passed.
1345 */
1346
1347 void state_selecting (cpp)
1348 void *cpp;
1349 {
1350 struct client_state *client = cpp;
1351 struct client_lease *lp, *next, *picked;
1352
1353
1354 ASSERT_STATE(state, S_SELECTING);
1355
1356 /*
1357 * Cancel state_selecting and send_discover timeouts, since either
1358 * one could have got us here.
1359 */
1360 cancel_timeout (state_selecting, client);
1361 cancel_timeout (send_discover, client);
1362
1363 /*
1364 * We have received one or more DHCPOFFER packets. Currently,
1365 * the only criterion by which we judge leases is whether or
1366 * not we get a response when we arp for them.
1367 */
1368 picked = NULL;
1369 for (lp = client -> offered_leases; lp; lp = next) {
1370 next = lp -> next;
1371
1372 /*
1373 * Check to see if we got an ARPREPLY for the address
1374 * in this particular lease.
1375 */
1376 if (!picked) {
1377 picked = lp;
1378 picked -> next = NULL;
1379 } else {
1380 destroy_client_lease (lp);
1381 }
1382 }
1383 client -> offered_leases = NULL;
1384
1385 /*
1386 * If we just tossed all the leases we were offered, go back
1387 * to square one.
1388 */
1389 if (!picked) {
1390 client -> state = S_INIT;
1391 state_init (client);
1392 return;
1393 }
1394
1395 /* If it was a BOOTREPLY, we can just take the address right now. */
1396 if (picked -> is_bootp) {
1397 client -> new = picked;
1398
1399 /* Make up some lease expiry times
1400 XXX these should be configurable. */
1401 client -> new -> expiry = cur_time + 12000;
1402 client -> new -> renewal += cur_time + 8000;
1403 client -> new -> rebind += cur_time + 10000;
1404
1405 client -> state = S_REQUESTING;
1406
1407 /* Bind to the address we received. */
1408 bind_lease (client);
1409 return;
1410 }
1411
1412 /* Go to the REQUESTING state. */
1413 client -> destination = iaddr_broadcast;
1414 client -> state = S_REQUESTING;
1415 client -> first_sending = cur_time;
1416 client -> interval = client -> config -> initial_interval;
1417
1418 /* Make a DHCPREQUEST packet from the lease we picked. */
1419 make_request (client, picked);
1420 client -> xid = client -> packet.xid;
1421
1422 /* Toss the lease we picked - we'll get it back in a DHCPACK. */
1423 destroy_client_lease (picked);
1424
1425 /* Add an immediate timeout to send the first DHCPREQUEST packet. */
1426 send_request (client);
1427 }
1428
1429 /* state_requesting is called when we receive a DHCPACK message after
1430 having sent out one or more DHCPREQUEST packets. */
1431
1432 void dhcpack (packet)
1433 struct packet *packet;
1434 {
1435 struct interface_info *ip = packet -> interface;
1436 struct client_state *client;
1437 uint32_t v6only_wait;
1438 struct client_lease *lease;
1439 struct option_cache *oc;
1440 struct data_string ds;
1441
1442 /* If we're not receptive to an offer right now, or if the offer
1443 has an unrecognizable transaction id, then just drop it. */
1444 for (client = ip -> client; client; client = client -> next) {
1445 if (client -> xid == packet -> raw -> xid)
1446 break;
1447 }
1448 if (!client ||
1449 (packet -> interface -> hw_address.hlen - 1 !=
1450 packet -> raw -> hlen) ||
1451 (memcmp (&packet -> interface -> hw_address.hbuf [1],
1452 packet -> raw -> chaddr, packet -> raw -> hlen))) {
1453 #if defined (DEBUG)
1454 log_debug ("DHCPACK in wrong transaction.");
1455 #endif
1456 return;
1457 }
1458
1459 if (client -> state != S_REBOOTING &&
1460 client -> state != S_REQUESTING &&
1461 client -> state != S_RENEWING &&
1462 client -> state != S_REBINDING) {
1463 #if defined (DEBUG)
1464 log_debug ("DHCPACK in wrong state.");
1465 #endif
1466 return;
1467 }
1468
1469 log_info ("DHCPACK of %s from %s",
1470 inet_ntoa(packet->raw->yiaddr),
1471 piaddr (packet->client_addr));
1472
1473 /* Check v6only first. */
1474 v6only_wait = check_v6only(packet, client);
1475 if (v6only_wait > 0) {
1476 log_info("v6 only preferred for %lu.",
1477 (long unsigned)v6only_wait);
1478 start_v6only(client, v6only_wait);
1479 return;
1480 }
1481
1482 lease = packet_to_lease (packet, client);
1483 if (!lease) {
1484 log_info ("packet_to_lease failed.");
1485 return;
1486 }
1487
1488 client -> new = lease;
1489
1490 /* Stop resending DHCPREQUEST. */
1491 cancel_timeout (send_request, client);
1492
1493 /* Figure out the lease time. */
1494 oc = lookup_option (&dhcp_universe, client -> new -> options,
1495 DHO_DHCP_LEASE_TIME);
1496 memset (&ds, 0, sizeof ds);
1497 if (oc &&
1498 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
1499 packet -> options, client -> new -> options,
1500 &global_scope, oc, MDL)) {
1501 if (ds.len > 3)
1502 client -> new -> expiry = getULong (ds.data);
1503 else
1504 client -> new -> expiry = 0;
1505 data_string_forget (&ds, MDL);
1506 } else
1507 client -> new -> expiry = 0;
1508
1509 if (client->new->expiry == 0) {
1510 struct timeval tv;
1511
1512 log_error ("no expiry time on offered lease.");
1513
1514 /* Quench this (broken) server. Return to INIT to reselect. */
1515 add_reject(packet);
1516
1517 /* 1/2 second delay to restart at INIT. */
1518 tv.tv_sec = cur_tv.tv_sec;
1519 tv.tv_usec = cur_tv.tv_usec + 500000;
1520
1521 if (tv.tv_usec >= 1000000) {
1522 tv.tv_sec++;
1523 tv.tv_usec -= 1000000;
1524 }
1525
1526 add_timeout(&tv, state_init, client, 0, 0);
1527 return;
1528 }
1529
1530 /*
1531 * A number that looks negative here is really just very large,
1532 * because the lease expiry offset is unsigned.
1533 */
1534 if (client->new->expiry < 0)
1535 client->new->expiry = TIME_MAX;
1536
1537 /* Take the server-provided renewal time if there is one. */
1538 oc = lookup_option (&dhcp_universe, client -> new -> options,
1539 DHO_DHCP_RENEWAL_TIME);
1540 if (oc &&
1541 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
1542 packet -> options, client -> new -> options,
1543 &global_scope, oc, MDL)) {
1544 if (ds.len > 3)
1545 client -> new -> renewal = getULong (ds.data);
1546 else
1547 client -> new -> renewal = 0;
1548 data_string_forget (&ds, MDL);
1549 } else
1550 client -> new -> renewal = 0;
1551
1552 /* If it wasn't specified by the server, calculate it. */
1553 if (!client -> new -> renewal)
1554 client -> new -> renewal = client -> new -> expiry / 2 + 1;
1555
1556 if (client -> new -> renewal <= 0)
1557 client -> new -> renewal = TIME_MAX;
1558
1559 /* Now introduce some randomness to the renewal time: */
1560 if (client->new->renewal <= ((TIME_MAX / 3) - 3))
1561 client->new->renewal = (((client->new->renewal * 3) + 3) / 4) +
1562 (((random() % client->new->renewal) + 3) / 4);
1563
1564 /* Same deal with the rebind time. */
1565 oc = lookup_option (&dhcp_universe, client -> new -> options,
1566 DHO_DHCP_REBINDING_TIME);
1567 if (oc &&
1568 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
1569 packet -> options, client -> new -> options,
1570 &global_scope, oc, MDL)) {
1571 if (ds.len > 3)
1572 client -> new -> rebind = getULong (ds.data);
1573 else
1574 client -> new -> rebind = 0;
1575 data_string_forget (&ds, MDL);
1576 } else
1577 client -> new -> rebind = 0;
1578
1579 if (client -> new -> rebind <= 0) {
1580 if (client -> new -> expiry <= TIME_MAX / 7)
1581 client -> new -> rebind =
1582 client -> new -> expiry * 7 / 8;
1583 else
1584 client -> new -> rebind =
1585 client -> new -> expiry / 8 * 7;
1586 }
1587
1588 /* Make sure our randomness didn't run the renewal time past the
1589 rebind time. */
1590 if (client -> new -> renewal > client -> new -> rebind) {
1591 if (client -> new -> rebind <= TIME_MAX / 3)
1592 client -> new -> renewal =
1593 client -> new -> rebind * 3 / 4;
1594 else
1595 client -> new -> renewal =
1596 client -> new -> rebind / 4 * 3;
1597 }
1598
1599 client -> new -> expiry += cur_time;
1600 /* Lease lengths can never be negative. */
1601 if (client -> new -> expiry < cur_time)
1602 client -> new -> expiry = TIME_MAX;
1603 client -> new -> renewal += cur_time;
1604 if (client -> new -> renewal < cur_time)
1605 client -> new -> renewal = TIME_MAX;
1606 client -> new -> rebind += cur_time;
1607 if (client -> new -> rebind < cur_time)
1608 client -> new -> rebind = TIME_MAX;
1609
1610 bind_lease (client);
1611 }
1612
1613 void bind_lease (client)
1614 struct client_state *client;
1615 {
1616 struct timeval tv;
1617
1618 /* Remember the medium. */
1619 client->new->medium = client->medium;
1620
1621 /* Run the client script with the new parameters. */
1622 script_init(client, (client->state == S_REQUESTING ? "BOUND" :
1623 (client->state == S_RENEWING ? "RENEW" :
1624 (client->state == S_REBOOTING ? "REBOOT" :
1625 "REBIND"))),
1626 client->new->medium);
1627 if (client->active && client->state != S_REBOOTING)
1628 script_write_params(client, "old_", client->active);
1629 script_write_params(client, "new_", client->new);
1630 script_write_requested(client);
1631 if (client->alias)
1632 script_write_params(client, "alias_", client->alias);
1633
1634 /* If the BOUND/RENEW code detects another machine using the
1635 offered address, it exits nonzero. We need to send a
1636 DHCPDECLINE and toss the lease. */
1637 if (script_go(client)) {
1638 make_decline(client, client->new);
1639 send_decline(client);
1640 destroy_client_lease(client->new);
1641 client->new = NULL;
1642 if (onetry) {
1643 if (!quiet) {
1644 log_info("Unable to obtain a lease on first "
1645 "try (declined). Exiting.");
1646 }
1647
1648 #if defined (CALL_SCRIPT_ON_ONETRY_FAIL)
1649 /* Let's call a script and we're done */
1650 script_init(client, "FAIL", (struct string_list *)0);
1651 script_go(client);
1652 #endif
1653 finish(2);
1654 } else {
1655 struct timeval tv;
1656 tv.tv_sec = cur_tv.tv_sec + decline_wait_time;
1657 tv.tv_usec = cur_tv.tv_usec;
1658 add_timeout(&tv, state_init, client, 0, 0);
1659 return;
1660 }
1661 }
1662
1663 /* Write out the new lease if it has been long enough. */
1664 if (!client->last_write ||
1665 (cur_time - client->last_write) >= MIN_LEASE_WRITE)
1666 write_client_lease(client, client->new, 0, 1);
1667
1668 /* Replace the old active lease with the new one. */
1669 if (client->active) {
1670 if (client->active->is_static) {
1671 // We need to preserve the fallback lease in case
1672 // we lose DHCP service again.
1673 add_to_tail(&client->leases, client->active);
1674 } else {
1675 destroy_client_lease(client->active);
1676 }
1677 }
1678
1679 client->active = client->new;
1680 client->new = NULL;
1681
1682 /* Set up a timeout to start the renewal process. */
1683 tv.tv_sec = client->active->renewal;
1684 tv.tv_usec = ((client->active->renewal - cur_tv.tv_sec) > 1) ?
1685 random() % 1000000 : cur_tv.tv_usec;
1686 add_timeout(&tv, state_bound, client, 0, 0);
1687
1688 log_info("bound to %s -- renewal in %ld seconds.",
1689 piaddr(client->active->address),
1690 (long)(client->active->renewal - cur_time));
1691 client->state = S_BOUND;
1692 reinitialize_interfaces();
1693 detach();
1694 #if defined (NSUPDATE)
1695 if (client->config->do_forward_update)
1696 dhclient_schedule_updates(client, &client->active->address, 1);
1697 #endif /* defined NSUPDATE */
1698
1699 }
1700
1701 /* state_bound is called when we've successfully bound to a particular
1702 lease, but the renewal time on that lease has expired. We are
1703 expected to unicast a DHCPREQUEST to the server that gave us our
1704 original lease. */
1705
1706 void state_bound (cpp)
1707 void *cpp;
1708 {
1709 struct client_state *client = cpp;
1710 struct option_cache *oc;
1711 struct data_string ds;
1712
1713 ASSERT_STATE(state, S_BOUND);
1714
1715 /* T1 has expired. */
1716 make_request (client, client -> active);
1717 client -> xid = client -> packet.xid;
1718
1719 memset (&ds, 0, sizeof ds);
1720 oc = lookup_option (&dhcp_universe, client -> active -> options,
1721 DHO_DHCP_SERVER_IDENTIFIER);
1722 if (oc &&
1723 evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0,
1724 client, (struct option_state *)0,
1725 client -> active -> options,
1726 &global_scope, oc, MDL)) {
1727 if (ds.len > 3) {
1728 memcpy (client -> destination.iabuf, ds.data, 4);
1729 client -> destination.len = 4;
1730 } else
1731 client -> destination = iaddr_broadcast;
1732
1733 data_string_forget (&ds, MDL);
1734 } else
1735 client -> destination = iaddr_broadcast;
1736
1737 client -> first_sending = cur_time;
1738 client -> interval = client -> config -> initial_interval;
1739 client -> state = S_RENEWING;
1740
1741 /* Send the first packet immediately. */
1742 send_request (client);
1743 }
1744
1745 /* state_stop is called when we've been told to shut down. We unconfigure
1746 the interfaces, and then stop operating until told otherwise. */
1747
1748 void state_stop (cpp)
1749 void *cpp;
1750 {
1751 struct client_state *client = cpp;
1752
1753 client->pending = P_NONE;
1754
1755 /* Cancel all timeouts. */
1756 cancel_timeout(state_selecting, client);
1757 cancel_timeout(send_discover, client);
1758 cancel_timeout(send_request, client);
1759 cancel_timeout(state_bound, client);
1760 cancel_timeout(finish_v6only, client);
1761
1762 /* If we have an address, unconfigure it. */
1763 if (client->active) {
1764 script_init(client, "STOP", client->active->medium);
1765 script_write_params(client, "old_", client->active);
1766 script_write_requested(client);
1767 if (client->alias)
1768 script_write_params(client, "alias_", client->alias);
1769 script_go(client);
1770 }
1771 }
1772
1773 int commit_leases ()
1774 {
1775 return 0;
1776 }
1777
1778 int write_lease (lease)
1779 struct lease *lease;
1780 {
1781 return 0;
1782 }
1783
1784 int write_host (host)
1785 struct host_decl *host;
1786 {
1787 return 0;
1788 }
1789
1790 void db_startup (testp)
1791 int testp;
1792 {
1793 }
1794
1795 void bootp (packet)
1796 struct packet *packet;
1797 {
1798 struct iaddrmatchlist *ap;
1799 char addrbuf[4*16];
1800 char maskbuf[4*16];
1801
1802 if (packet -> raw -> op != BOOTREPLY)
1803 return;
1804
1805 /* If there's a reject list, make sure this packet's sender isn't
1806 on it. */
1807 for (ap = packet -> interface -> client -> config -> reject_list;
1808 ap; ap = ap -> next) {
1809 if (addr_match(&packet->client_addr, &ap->match)) {
1810
1811 /* piaddr() returns its result in a static
1812 buffer sized 4*16 (see common/inet.c). */
1813
1814 strcpy(addrbuf, piaddr(ap->match.addr));
1815 strcpy(maskbuf, piaddr(ap->match.mask));
1816
1817 log_info("BOOTREPLY from %s rejected by rule %s "
1818 "mask %s.", piaddr(packet->client_addr),
1819 addrbuf, maskbuf);
1820 return;
1821 }
1822 }
1823
1824 dhcpoffer (packet);
1825
1826 }
1827
1828 void dhcp (packet)
1829 struct packet *packet;
1830 {
1831 struct iaddrmatchlist *ap;
1832 void (*handler) (struct packet *);
1833 const char *type;
1834 char addrbuf[4*16];
1835 char maskbuf[4*16];
1836
1837 switch (packet -> packet_type) {
1838 case DHCPOFFER:
1839 handler = dhcpoffer;
1840 type = "DHCPOFFER";
1841 break;
1842
1843 case DHCPNAK:
1844 handler = dhcpnak;
1845 type = "DHCPNACK";
1846 break;
1847
1848 case DHCPACK:
1849 handler = dhcpack;
1850 type = "DHCPACK";
1851 break;
1852
1853 default:
1854 return;
1855 }
1856
1857 /* If there's a reject list, make sure this packet's sender isn't
1858 on it. */
1859 for (ap = packet -> interface -> client -> config -> reject_list;
1860 ap; ap = ap -> next) {
1861 if (addr_match(&packet->client_addr, &ap->match)) {
1862
1863 /* piaddr() returns its result in a static
1864 buffer sized 4*16 (see common/inet.c). */
1865
1866 strcpy(addrbuf, piaddr(ap->match.addr));
1867 strcpy(maskbuf, piaddr(ap->match.mask));
1868
1869 log_info("%s from %s rejected by rule %s mask %s.",
1870 type, piaddr(packet->client_addr),
1871 addrbuf, maskbuf);
1872 return;
1873 }
1874 }
1875 (*handler) (packet);
1876 }
1877
1878 #ifdef DHCPv6
1879 void
1880 dhcpv6(struct packet *packet) {
1881 struct iaddrmatchlist *ap;
1882 struct client_state *client;
1883 char addrbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")];
1884
1885 /* Silently drop bogus messages. */
1886 if (packet->dhcpv6_msg_type >= dhcpv6_type_name_max)
1887 return;
1888
1889 /* Discard, with log, packets from quenched sources. */
1890 for (ap = packet->interface->client->config->reject_list ;
1891 ap ; ap = ap->next) {
1892 if (addr_match(&packet->client_addr, &ap->match)) {
1893 strcpy(addrbuf, piaddr(packet->client_addr));
1894 log_info("%s from %s rejected by rule %s",
1895 dhcpv6_type_names[packet->dhcpv6_msg_type],
1896 addrbuf,
1897 piaddrmask(&ap->match.addr, &ap->match.mask));
1898 return;
1899 }
1900 }
1901
1902 /* Screen out nonsensical messages. */
1903 switch(packet->dhcpv6_msg_type) {
1904 #ifdef DHCP4o6
1905 case DHCPV6_DHCPV4_RESPONSE:
1906 if (dhcpv4_over_dhcpv6) {
1907 log_info("RCV: %s message on %s from %s.",
1908 dhcpv6_type_names[packet->dhcpv6_msg_type],
1909 packet->interface->name,
1910 piaddr(packet->client_addr));
1911 forw_dhcpv4_response(packet);
1912 }
1913 return;
1914 #endif
1915 case DHCPV6_ADVERTISE:
1916 case DHCPV6_RECONFIGURE:
1917 if (stateless)
1918 return;
1919 /* Falls through */
1920 case DHCPV6_REPLY:
1921 log_info("RCV: %s message on %s from %s.",
1922 dhcpv6_type_names[packet->dhcpv6_msg_type],
1923 packet->interface->name, piaddr(packet->client_addr));
1924 break;
1925
1926 default:
1927 return;
1928 }
1929
1930 /* Find a client state that matches the incoming XID. */
1931 for (client = packet->interface->client ; client ;
1932 client = client->next) {
1933 if (memcmp(&client->dhcpv6_transaction_id,
1934 packet->dhcpv6_transaction_id, 3) == 0) {
1935 client->v6_handler(packet, client);
1936 return;
1937 }
1938 }
1939
1940 /* XXX: temporary log for debugging */
1941 log_info("Packet received, but nothing done with it.");
1942 }
1943
1944 #ifdef DHCP4o6
1945 /*
1946 * \brief Forward a DHCPv4-response to the DHCPv4 client.
1947 * (DHCPv6 client function)
1948 *
1949 * The DHCPv6 client receives a DHCPv4-response which is forwarded
1950 * to the DHCPv4 client.
1951 * Format: address:16 + DHCPv4 message content
1952 * (we have no state to keep the address so it is transported in
1953 * DHCPv6 <-> DHCPv6 inter-process messages)
1954 *
1955 * \param packet the DHCPv4-response packet
1956 */
1957 static void forw_dhcpv4_response(struct packet *packet)
1958 {
1959 struct option_cache *oc;
1960 struct data_string enc_opt_data;
1961 struct data_string ds;
1962 int cc;
1963
1964 /*
1965 * Discard if relay is not ready.
1966 */
1967 if (dhcp4o6_state == -1) {
1968 log_info("forw_dhcpv4_response: not ready.");
1969 return;
1970 }
1971
1972 if (packet->client_addr.len != 16) {
1973 log_error("forw_dhcpv4_response: bad address");
1974 return;
1975 }
1976
1977 /*
1978 * Get our encapsulated DHCPv4 message.
1979 */
1980 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_DHCPV4_MSG);
1981 if (oc == NULL) {
1982 log_info("DHCPv4-response from %s missing "
1983 "DHCPv4 Message option.",
1984 piaddr(packet->client_addr));
1985 return;
1986 }
1987
1988 memset(&enc_opt_data, 0, sizeof(enc_opt_data));
1989 if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL,
1990 NULL, NULL, &global_scope, oc, MDL)) {
1991 log_error("forw_dhcpv4_response: error evaluating "
1992 "DHCPv4 message.");
1993 data_string_forget(&enc_opt_data, MDL);
1994 return;
1995 }
1996
1997 if (enc_opt_data.len < DHCP_FIXED_NON_UDP) {
1998 log_error("forw_dhcpv4_response: "
1999 "no memory for encapsulated packet.");
2000 data_string_forget(&enc_opt_data, MDL);
2001 return;
2002 }
2003
2004 /*
2005 * Append address.
2006 */
2007 memset(&ds, 0, sizeof(ds));
2008 if (!buffer_allocate(&ds.buffer, enc_opt_data.len + 16, MDL)) {
2009 log_error("forw_dhcpv4_response: no memory buffer.");
2010 data_string_forget(&enc_opt_data, MDL);
2011 return;
2012 }
2013 ds.data = ds.buffer->data;
2014 ds.len = enc_opt_data.len + 16;
2015 memcpy(ds.buffer->data, enc_opt_data.data, enc_opt_data.len);
2016 memcpy(ds.buffer->data + enc_opt_data.len,
2017 packet->client_addr.iabuf, 16);
2018 data_string_forget(&enc_opt_data, MDL);
2019
2020 /*
2021 * Forward them.
2022 */
2023 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
2024 if (cc < 0)
2025 log_error("forw_dhcpv4_response: send(): %m");
2026
2027 data_string_forget(&ds, MDL);
2028 }
2029
2030 /*
2031 * \brief Receive a DHCPv4-response from the DHCPv6 client.
2032 * (DHCPv4 client function)
2033 *
2034 * The DHCPv4 client receives a DHCPv4-response forwarded
2035 * by the DHCPv6 client (using \ref forw_dhcpv4_response())
2036 *
2037 * \param raw the DHCPv4-response raw packet
2038 */
2039 static void recv_dhcpv4_response(struct data_string *raw)
2040 {
2041 struct packet *packet;
2042 struct iaddr from;
2043
2044 if (interfaces == NULL) {
2045 log_error("recv_dhcpv4_response: no interfaces.");
2046 return;
2047 }
2048
2049 from.len = 16;
2050 memcpy(from.iabuf, raw->data + (raw->len - 16), 16);
2051
2052 /*
2053 * Build a packet structure.
2054 */
2055 packet = NULL;
2056 if (!packet_allocate(&packet, MDL)) {
2057 log_error("recv_dhcpv4_response: no memory for packet.");
2058 return;
2059 }
2060
2061 packet->raw = (struct dhcp_packet *) raw->data;
2062 packet->packet_length = raw->len - 16;
2063 packet->client_port = remote_port;
2064 packet->client_addr = from;
2065 interface_reference(&packet->interface, interfaces, MDL);
2066
2067 /* Allocate packet->options now so it is non-null for all packets */
2068 if (!option_state_allocate (&packet->options, MDL)) {
2069 log_error("recv_dhcpv4_response: no memory for options.");
2070 packet_dereference (&packet, MDL);
2071 return;
2072 }
2073
2074 /* If there's an option buffer, try to parse it. */
2075 if (packet->packet_length >= DHCP_FIXED_NON_UDP + 4) {
2076 struct option_cache *op;
2077 if (!parse_options(packet)) {
2078 if (packet->options)
2079 option_state_dereference
2080 (&packet->options, MDL);
2081 packet_dereference (&packet, MDL);
2082 return;
2083 }
2084
2085 if (packet->options_valid &&
2086 (op = lookup_option(&dhcp_universe,
2087 packet->options,
2088 DHO_DHCP_MESSAGE_TYPE))) {
2089 struct data_string dp;
2090 memset(&dp, 0, sizeof dp);
2091 evaluate_option_cache(&dp, packet, NULL, NULL,
2092 packet->options, NULL,
2093 NULL, op, MDL);
2094 if (dp.len > 0)
2095 packet->packet_type = dp.data[0];
2096 else
2097 packet->packet_type = 0;
2098 data_string_forget(&dp, MDL);
2099 }
2100 }
2101
2102 if (validate_packet(packet) != 0) {
2103 if (packet->packet_type)
2104 dhcp(packet);
2105 else
2106 bootp(packet);
2107 }
2108
2109 /* If the caller kept the packet, they'll have upped the refcnt. */
2110 packet_dereference(&packet, MDL);
2111 }
2112 #endif /* DHCP4o6 */
2113 #endif /* DHCPv6 */
2114
2115 void dhcpoffer (packet)
2116 struct packet *packet;
2117 {
2118 struct interface_info *ip = packet -> interface;
2119 struct client_state *client;
2120 uint32_t v6only_wait;
2121 struct client_lease *lease, *lp;
2122 struct option **req;
2123 int i;
2124 int stop_selecting;
2125 const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
2126 char obuf [1024];
2127 struct timeval tv;
2128
2129 #ifdef DEBUG_PACKET
2130 dump_packet (packet);
2131 #endif
2132
2133 /* Find a client state that matches the xid... */
2134 for (client = ip -> client; client; client = client -> next)
2135 if (client -> xid == packet -> raw -> xid)
2136 break;
2137
2138 /* If we're not receptive to an offer right now, or if the offer
2139 has an unrecognizable transaction id, then just drop it. */
2140 if (!client ||
2141 client -> state != S_SELECTING ||
2142 (packet -> interface -> hw_address.hlen - 1 !=
2143 packet -> raw -> hlen) ||
2144 (memcmp (&packet -> interface -> hw_address.hbuf [1],
2145 packet -> raw -> chaddr, packet -> raw -> hlen))) {
2146 #if defined (DEBUG)
2147 log_debug ("%s in wrong transaction.", name);
2148 #endif
2149 return;
2150 }
2151
2152 sprintf (obuf, "%s of %s from %s", name,
2153 inet_ntoa(packet->raw->yiaddr),
2154 piaddr(packet->client_addr));
2155
2156 /* Check v6only first. */
2157 v6only_wait = check_v6only(packet, client);
2158 if (v6only_wait > 0) {
2159 log_info("%s: v6 only preferred for %lu.", obuf,
2160 (long unsigned)v6only_wait);
2161 start_v6only(client, v6only_wait);
2162 return;
2163 }
2164
2165 /* If this lease doesn't supply the minimum required DHCPv4 parameters,
2166 * ignore it.
2167 */
2168 req = client->config->required_options;
2169 if (req != NULL) {
2170 for (i = 0 ; req[i] != NULL ; i++) {
2171 if ((req[i]->universe == &dhcp_universe) &&
2172 !lookup_option(&dhcp_universe, packet->options,
2173 req[i]->code)) {
2174 struct option *option = NULL;
2175 unsigned code = req[i]->code;
2176
2177 option_code_hash_lookup(&option,
2178 dhcp_universe.code_hash,
2179 &code, 0, MDL);
2180
2181 if (option)
2182 log_info("%s: no %s option.", obuf,
2183 option->name);
2184 else
2185 log_info("%s: no unknown-%u option.",
2186 obuf, code);
2187
2188 option_dereference(&option, MDL);
2189
2190 return;
2191 }
2192 }
2193 }
2194
2195 /* If we've already seen this lease, don't record it again. */
2196 for (lease = client -> offered_leases; lease; lease = lease -> next) {
2197 if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
2198 !memcmp (lease -> address.iabuf,
2199 &packet -> raw -> yiaddr, lease -> address.len)) {
2200 log_debug ("%s: already seen.", obuf);
2201 return;
2202 }
2203 }
2204
2205 lease = packet_to_lease (packet, client);
2206 if (!lease) {
2207 log_info ("%s: packet_to_lease failed.", obuf);
2208 return;
2209 }
2210
2211 /* log it now, so it emits before the request goes out */
2212 log_info("%s", obuf);
2213
2214 /* If this lease was acquired through a BOOTREPLY, record that
2215 fact. */
2216 if (!packet -> options_valid || !packet -> packet_type)
2217 lease -> is_bootp = 1;
2218
2219 /* Record the medium under which this lease was offered. */
2220 lease -> medium = client -> medium;
2221
2222 /* Figure out when we're supposed to stop selecting. */
2223 stop_selecting = (client -> first_sending +
2224 client -> config -> select_interval);
2225
2226 /* If this is the lease we asked for, put it at the head of the
2227 list, and don't mess with the arp request timeout. */
2228 if (lease -> address.len == client -> requested_address.len &&
2229 !memcmp (lease -> address.iabuf,
2230 client -> requested_address.iabuf,
2231 client -> requested_address.len)) {
2232 lease -> next = client -> offered_leases;
2233 client -> offered_leases = lease;
2234 } else {
2235 /* Put the lease at the end of the list. */
2236 lease -> next = (struct client_lease *)0;
2237 if (!client -> offered_leases)
2238 client -> offered_leases = lease;
2239 else {
2240 for (lp = client -> offered_leases; lp -> next;
2241 lp = lp -> next)
2242 ;
2243 lp -> next = lease;
2244 }
2245 }
2246
2247 /* If the selecting interval has expired, go immediately to
2248 state_selecting(). Otherwise, time out into
2249 state_selecting at the select interval. */
2250 if (stop_selecting <= cur_tv.tv_sec)
2251 state_selecting (client);
2252 else {
2253 tv.tv_sec = stop_selecting;
2254 tv.tv_usec = cur_tv.tv_usec;
2255 add_timeout(&tv, state_selecting, client, 0, 0);
2256 cancel_timeout(send_discover, client);
2257 }
2258 }
2259
2260 /* Allocate a client_lease structure and initialize it from the parameters
2261 in the specified packet. */
2262
2263 struct client_lease *packet_to_lease (packet, client)
2264 struct packet *packet;
2265 struct client_state *client;
2266 {
2267 struct client_lease *lease;
2268 unsigned i;
2269 struct option_cache *oc;
2270 struct option *option = NULL;
2271 struct data_string data;
2272
2273 lease = (struct client_lease *)new_client_lease (MDL);
2274
2275 if (!lease) {
2276 log_error("packet_to_lease: no memory to record lease.\n");
2277 return NULL;
2278 }
2279
2280 memset(lease, 0, sizeof(*lease));
2281
2282 /* Copy the lease options. */
2283 option_state_reference(&lease->options, packet->options, MDL);
2284
2285 lease->address.len = sizeof(packet->raw->yiaddr);
2286 memcpy(lease->address.iabuf, &packet->raw->yiaddr,
2287 lease->address.len);
2288
2289 lease->next_srv_addr.len = sizeof(packet->raw->siaddr);
2290 memcpy(lease->next_srv_addr.iabuf, &packet->raw->siaddr,
2291 lease->next_srv_addr.len);
2292
2293 memset(&data, 0, sizeof(data));
2294
2295 if (client -> config -> vendor_space_name) {
2296 i = DHO_VENDOR_ENCAPSULATED_OPTIONS;
2297
2298 /* See if there was a vendor encapsulation option. */
2299 oc = lookup_option (&dhcp_universe, lease -> options, i);
2300 if (oc &&
2301 client -> config -> vendor_space_name &&
2302 evaluate_option_cache (&data, packet,
2303 (struct lease *)0, client,
2304 packet -> options, lease -> options,
2305 &global_scope, oc, MDL)) {
2306 if (data.len) {
2307 if (!option_code_hash_lookup(&option,
2308 dhcp_universe.code_hash,
2309 &i, 0, MDL))
2310 log_fatal("Unable to find VENDOR "
2311 "option (%s:%d).", MDL);
2312 parse_encapsulated_suboptions
2313 (packet -> options, option,
2314 data.data, data.len, &dhcp_universe,
2315 client -> config -> vendor_space_name
2316 );
2317
2318 option_dereference(&option, MDL);
2319 }
2320 data_string_forget (&data, MDL);
2321 }
2322 } else
2323 i = 0;
2324
2325 /* Figure out the overload flag. */
2326 oc = lookup_option (&dhcp_universe, lease -> options,
2327 DHO_DHCP_OPTION_OVERLOAD);
2328 if (oc &&
2329 evaluate_option_cache (&data, packet, (struct lease *)0, client,
2330 packet -> options, lease -> options,
2331 &global_scope, oc, MDL)) {
2332 if (data.len > 0)
2333 i = data.data [0];
2334 else
2335 i = 0;
2336 data_string_forget (&data, MDL);
2337 } else
2338 i = 0;
2339
2340 /* If the server name was filled out, copy it. */
2341 if (!(i & 2) && packet -> raw -> sname [0]) {
2342 unsigned len;
2343 /* Don't count on the NUL terminator. */
2344 for (len = 0; len < DHCP_SNAME_LEN; len++)
2345 if (!packet -> raw -> sname [len])
2346 break;
2347 lease -> server_name = dmalloc (len + 1, MDL);
2348 if (!lease -> server_name) {
2349 log_error ("dhcpoffer: no memory for server name.\n");
2350 destroy_client_lease (lease);
2351 return (struct client_lease *)0;
2352 } else {
2353 memcpy (lease -> server_name,
2354 packet -> raw -> sname, len);
2355 lease -> server_name [len] = 0;
2356 }
2357 }
2358
2359 /* Ditto for the filename. */
2360 if (!(i & 1) && packet -> raw -> file [0]) {
2361 unsigned len;
2362 /* Don't count on the NUL terminator. */
2363 for (len = 0; len < DHCP_FILE_LEN; len++)
2364 if (!packet -> raw -> file [len])
2365 break;
2366 lease -> filename = dmalloc (len + 1, MDL);
2367 if (!lease -> filename) {
2368 log_error ("dhcpoffer: no memory for filename.\n");
2369 destroy_client_lease (lease);
2370 return (struct client_lease *)0;
2371 } else {
2372 memcpy (lease -> filename,
2373 packet -> raw -> file, len);
2374 lease -> filename [len] = 0;
2375 }
2376 }
2377
2378 execute_statements_in_scope(NULL, (struct packet *)packet, NULL,
2379 client, lease->options, lease->options,
2380 &global_scope, client->config->on_receipt,
2381 NULL, NULL);
2382
2383 return lease;
2384 }
2385
2386 void dhcpnak (packet)
2387 struct packet *packet;
2388 {
2389 struct interface_info *ip = packet -> interface;
2390 struct client_state *client;
2391
2392 /* Find a client state that matches the xid... */
2393 for (client = ip -> client; client; client = client -> next)
2394 if (client -> xid == packet -> raw -> xid)
2395 break;
2396
2397 /* If we're not receptive to an offer right now, or if the offer
2398 has an unrecognizable transaction id, then just drop it. */
2399 if (!client ||
2400 (packet -> interface -> hw_address.hlen - 1 !=
2401 packet -> raw -> hlen) ||
2402 (memcmp (&packet -> interface -> hw_address.hbuf [1],
2403 packet -> raw -> chaddr, packet -> raw -> hlen))) {
2404 #if defined (DEBUG)
2405 log_debug ("DHCPNAK in wrong transaction.");
2406 #endif
2407 return;
2408 }
2409
2410 if (client -> state != S_REBOOTING &&
2411 client -> state != S_REQUESTING &&
2412 client -> state != S_RENEWING &&
2413 client -> state != S_REBINDING) {
2414 #if defined (DEBUG)
2415 log_debug ("DHCPNAK in wrong state.");
2416 #endif
2417 return;
2418 }
2419
2420 log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
2421
2422 if (!client -> active) {
2423 #if defined (DEBUG)
2424 log_info ("DHCPNAK with no active lease.\n");
2425 #endif
2426 return;
2427 }
2428
2429 /* If we get a DHCPNAK, we use the EXPIRE dhclient-script state
2430 * to indicate that we want all old bindings to be removed. (It
2431 * is possible that we may get a NAK while in the RENEW state,
2432 * so we might have bindings active at that time)
2433 */
2434 script_init(client, "EXPIRE", NULL);
2435 script_write_params(client, "old_", client->active);
2436 script_write_requested(client);
2437 if (client->alias)
2438 script_write_params(client, "alias_", client->alias);
2439 script_go(client);
2440
2441 destroy_client_lease (client -> active);
2442 client -> active = (struct client_lease *)0;
2443
2444 /* Stop sending DHCPREQUEST packets... */
2445 cancel_timeout (send_request, client);
2446
2447 /* On some scripts, 'EXPIRE' causes the interface to be ifconfig'd
2448 * down (this expunges any routes and arp cache). This makes the
2449 * interface unusable by state_init(), which we call next. So, we
2450 * need to 'PREINIT' the interface to bring it back up.
2451 */
2452 script_init(client, "PREINIT", NULL);
2453 if (client->alias)
2454 script_write_params(client, "alias_", client->alias);
2455 script_go(client);
2456
2457 client -> state = S_INIT;
2458 state_init (client);
2459 }
2460
2461 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
2462 one after the right interval has expired. If we don't get an offer by
2463 the time we reach the panic interval, call the panic function. */
2464
2465 void send_discover (cpp)
2466 void *cpp;
2467 {
2468 struct client_state *client = cpp;
2469
2470 int result;
2471 int interval;
2472 int increase = 1;
2473 struct timeval tv;
2474
2475 /* Figure out how long it's been since we started transmitting. */
2476 interval = cur_time - client -> first_sending;
2477
2478 /* If we're past the panic timeout, call the script and tell it
2479 we haven't found anything for this interface yet. */
2480 if (interval > client -> config -> timeout) {
2481 state_panic (client);
2482 return;
2483 }
2484
2485 /* If we're selecting media, try the whole list before doing
2486 the exponential backoff, but if we've already received an
2487 offer, stop looping, because we obviously have it right. */
2488 if (!client -> offered_leases &&
2489 client -> config -> media) {
2490 int fail = 0;
2491 again:
2492 if (client -> medium) {
2493 client -> medium = client -> medium -> next;
2494 increase = 0;
2495 }
2496 if (!client -> medium) {
2497 if (fail)
2498 log_fatal ("No valid media types for %s!",
2499 client -> interface -> name);
2500 client -> medium =
2501 client -> config -> media;
2502 increase = 1;
2503 }
2504
2505 log_info ("Trying medium \"%s\" %d",
2506 client -> medium -> string, increase);
2507 script_init(client, "MEDIUM", client -> medium);
2508 if (script_go(client)) {
2509 fail = 1;
2510 goto again;
2511 }
2512 }
2513
2514 /* If we're supposed to increase the interval, do so. If it's
2515 currently zero (i.e., we haven't sent any packets yet), set
2516 it to initial_interval; otherwise, add to it a random number
2517 between zero and two times itself. On average, this means
2518 that it will double with every transmission. */
2519 if (increase) {
2520 if (!client->interval)
2521 client->interval = client->config->initial_interval;
2522 else
2523 client->interval += random() % (2 * client->interval);
2524
2525 /* Don't backoff past cutoff. */
2526 if (client->interval > client->config->backoff_cutoff)
2527 client->interval = (client->config->backoff_cutoff / 2)
2528 + (random() % client->config->backoff_cutoff);
2529 } else if (!client->interval)
2530 client->interval = client->config->initial_interval;
2531
2532 /* If the backoff would take us to the panic timeout, just use that
2533 as the interval. */
2534 if (cur_time + client -> interval >
2535 client -> first_sending + client -> config -> timeout)
2536 client -> interval =
2537 (client -> first_sending +
2538 client -> config -> timeout) - cur_time + 1;
2539
2540 /* Record the number of seconds since we started sending. */
2541 if (interval < 65536)
2542 client -> packet.secs = htons (interval);
2543 else
2544 client -> packet.secs = htons (65535);
2545 client -> secs = client -> packet.secs;
2546
2547 #if defined(DHCPv6) && defined(DHCP4o6)
2548 if (dhcpv4_over_dhcpv6) {
2549 log_info ("DHCPDISCOVER interval %ld",
2550 (long)(client -> interval));
2551 } else
2552 #endif
2553 log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
2554 client -> name ? client -> name : client -> interface -> name,
2555 inet_ntoa (sockaddr_broadcast.sin_addr),
2556 ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
2557
2558 /* Send out a packet. */
2559 #if defined(DHCPv6) && defined(DHCP4o6)
2560 if (dhcpv4_over_dhcpv6) {
2561 result = send_dhcpv4_query(client, 1);
2562 } else
2563 #endif
2564 result = send_packet(client->interface, NULL, &client->packet,
2565 client->packet_length, inaddr_any,
2566 &sockaddr_broadcast, NULL);
2567 if (result < 0) {
2568 #if defined(DHCPv6) && defined(DHCP4o6)
2569 if (dhcpv4_over_dhcpv6) {
2570 log_error("%s:%d: Failed to send %d byte long packet.",
2571 MDL, client->packet_length);
2572 } else
2573 #endif
2574 log_error("%s:%d: Failed to send %d byte long packet over %s "
2575 "interface.", MDL, client->packet_length,
2576 client->interface->name);
2577 }
2578
2579 /*
2580 * If we used 0 microseconds here, and there were other clients on the
2581 * same network with a synchronized local clock (ntp), and a similar
2582 * zero-microsecond-scheduler behavior, then we could be participating
2583 * in a sub-second DOS ttck.
2584 */
2585 tv.tv_sec = cur_tv.tv_sec + client->interval;
2586 tv.tv_usec = client->interval > 1 ? random() % 1000000 : cur_tv.tv_usec;
2587 add_timeout(&tv, send_discover, client, 0, 0);
2588 }
2589
2590
2591 /*
2592 * \brief Remove leases from a list of leases which duplicate a given lease
2593 *
2594 * Searches through a linked-list of leases, remove the first one matches the
2595 * given lease's address and value of is_static. The latter test is done
2596 * so we only remove leases that are from the same source (i.e server/lease file
2597 * vs config file). This ensures we do not discard "fallback" config file leases
2598 * that happen to match non-config file leases.
2599 *
2600 * \param lease_list list of leases to clean
2601 * \param lease lease for which duplicates should be removed
2602 */
2603 void discard_duplicate (struct client_lease** lease_list, struct client_lease* lease) {
2604 struct client_lease *cur, *prev, *next;
2605
2606 if (!lease_list || !lease) {
2607 return;
2608 }
2609
2610 prev = (struct client_lease *)0;
2611 for (cur = *lease_list; cur; cur = next) {
2612 next = cur->next;
2613 if ((cur->is_static == lease->is_static) &&
2614 (cur->address.len == lease->address.len &&
2615 !memcmp (cur->address.iabuf, lease->address.iabuf,
2616 lease->address.len))) {
2617 if (prev)
2618 prev->next = next;
2619 else
2620 *lease_list = next;
2621
2622 destroy_client_lease (cur);
2623 break;
2624 } else {
2625 prev = cur;
2626 }
2627 }
2628 }
2629
2630 /*
2631 * \brief Add a given lease to the end of list of leases
2632 *
2633 * Searches through a linked-list of leases, removing any that match the
2634 * given lease's address and value of is_static. The latter test is done
2635 * so we only remove leases that are from the same source (i.e server/lease file
2636 * vs config file). This ensures we do not discard "fallback" config file leases
2637 * that happen to match non-config file leases.
2638 *
2639 * \param lease_list list of leases to clean
2640 * \param lease lease for which duplicates should be removed
2641 */
2642 void add_to_tail(struct client_lease** lease_list,
2643 struct client_lease* lease)
2644 {
2645 if (!lease_list || !lease) {
2646 return;
2647 }
2648
2649 /* If there is already a lease for this address and
2650 * is_static value, toss discard it. This ensures
2651 * we only keep one dynamic and/or one static lease
2652 * for a given address. */
2653 discard_duplicate(lease_list, lease);
2654
2655 /* Find the tail */
2656 struct client_lease* tail;
2657 for (tail = *lease_list; tail && tail->next; tail = tail->next){};
2658
2659 /* Ensure the tail points nowhere. */
2660 lease->next = NULL;
2661
2662 /* Add to the tail. */
2663 if (!tail) {
2664 *lease_list = lease;
2665 } else {
2666 tail->next = lease;
2667 }
2668 }
2669
2670 #if 0
2671 void dbg_print_lease(char *text, struct client_lease* lease) {
2672 if (!lease) {
2673 log_debug("%s, lease is null", text);
2674 } else {
2675 log_debug ("%s: %p addr:%s expires:%ld :is_static? %d",
2676 text, lease, piaddr (lease->address),
2677 (lease->expiry - cur_time),
2678 lease->is_static);
2679 }
2680 }
2681 #endif
2682
2683 /* state_panic gets called if we haven't received any offers in a preset
2684 amount of time. When this happens, we try to use existing leases that
2685 haven't yet expired, and failing that, we call the client script and
2686 hope it can do something. */
2687
2688 void state_panic (cpp)
2689 void *cpp;
2690 {
2691 struct client_state *client = cpp;
2692 struct client_lease *loop;
2693 struct client_lease *lp;
2694 struct timeval tv;
2695
2696 loop = lp = client -> active;
2697
2698 log_info ("No DHCPOFFERS received.");
2699
2700 /* We may not have an active lease, but we may have some
2701 predefined leases that we can try. */
2702 if (!client -> active && client -> leases)
2703 goto activate_next;
2704
2705 /* Run through the list of leases and see if one can be used. */
2706 while (client -> active) {
2707 if (client -> active -> expiry > cur_time) {
2708 log_info ("Trying %s lease %s",
2709 (client -> active -> is_static
2710 ? "fallback" : "recorded"),
2711 piaddr (client -> active -> address));
2712 /* Run the client script with the existing
2713 parameters. */
2714 script_init(client, "TIMEOUT",
2715 client -> active -> medium);
2716 script_write_params(client, "new_", client -> active);
2717 script_write_requested(client);
2718 if (client -> alias)
2719 script_write_params(client, "alias_",
2720 client -> alias);
2721
2722 /* If the old lease is still good and doesn't
2723 yet need renewal, go into BOUND state and
2724 timeout at the renewal time. */
2725 if (!script_go(client)) {
2726 if (cur_time < client -> active -> renewal) {
2727 client -> state = S_BOUND;
2728 log_info ("bound: renewal in %ld %s.",
2729 (long)(client -> active -> renewal -
2730 cur_time), "seconds");
2731 tv.tv_sec = client->active->renewal;
2732 tv.tv_usec = ((client->active->renewal -
2733 cur_time) > 1) ?
2734 random() % 1000000 :
2735 cur_tv.tv_usec;
2736 add_timeout(&tv, state_bound, client, 0, 0);
2737 } else {
2738 client -> state = S_BOUND;
2739 log_info ("bound: immediate renewal.");
2740 state_bound (client);
2741 }
2742 reinitialize_interfaces ();
2743 detach ();
2744 return;
2745 }
2746 }
2747
2748 /* If there are no other leases, give up. */
2749 if (!client -> leases) {
2750 client -> leases = client -> active;
2751 client -> active = (struct client_lease *)0;
2752 break;
2753 }
2754
2755 activate_next:
2756 /* Otherwise, put the active lease at the end of the
2757 lease list, and try another lease.. */
2758 add_to_tail(&client->leases, client->active);
2759
2760 client -> active = client -> leases;
2761 client -> leases = client -> leases -> next;
2762
2763 /* If we already tried this lease, we've exhausted the
2764 set of leases, so we might as well give up for
2765 now. */
2766 if (client -> active == loop)
2767 break;
2768 else if (!loop)
2769 loop = client -> active;
2770 }
2771
2772 /* No leases were available, or what was available didn't work, so
2773 tell the shell script that we failed to allocate an address,
2774 and try again later. */
2775 if (onetry) {
2776 if (!quiet) {
2777 log_info ("Unable to obtain a lease on first try.%s",
2778 " Exiting.");
2779 }
2780
2781 #if defined (CALL_SCRIPT_ON_ONETRY_FAIL)
2782 /* Let's call a script and we're done */
2783 script_init(client, "FAIL", (struct string_list *)0);
2784 script_go(client);
2785 #endif
2786 finish(2);
2787 }
2788
2789 log_info ("No working leases in persistent database - sleeping.");
2790 script_init(client, "FAIL", (struct string_list *)0);
2791 if (client -> alias)
2792 script_write_params(client, "alias_", client -> alias);
2793 script_go(client);
2794 client -> state = S_INIT;
2795 tv.tv_sec = cur_tv.tv_sec + ((client->config->retry_interval + 1) / 2 +
2796 (random() % client->config->retry_interval));
2797 tv.tv_usec = ((tv.tv_sec - cur_tv.tv_sec) > 1) ?
2798 random() % 1000000 : cur_tv.tv_usec;
2799 add_timeout(&tv, state_init, client, 0, 0);
2800 detach ();
2801 }
2802
2803 void send_request (cpp)
2804 void *cpp;
2805 {
2806 struct client_state *client = cpp;
2807
2808 int result;
2809 int interval;
2810 struct sockaddr_in destination;
2811 struct in_addr from;
2812 struct timeval tv;
2813 char rip_buf[128];
2814 const char* rip_str = "";
2815
2816 /* Figure out how long it's been since we started transmitting. */
2817 interval = cur_time - client -> first_sending;
2818
2819 /* If we're in the INIT-REBOOT or REQUESTING state and we're
2820 past the reboot timeout, go to INIT and see if we can
2821 DISCOVER an address... */
2822 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
2823 means either that we're on a network with no DHCP server,
2824 or that our server is down. In the latter case, assuming
2825 that there is a backup DHCP server, DHCPDISCOVER will get
2826 us a new address, but we could also have successfully
2827 reused our old address. In the former case, we're hosed
2828 anyway. This is not a win-prone situation. */
2829 if ((client -> state == S_REBOOTING ||
2830 client -> state == S_REQUESTING) &&
2831 interval > client -> config -> reboot_timeout) {
2832 cancel:
2833 client -> state = S_INIT;
2834 cancel_timeout (send_request, client);
2835 state_init (client);
2836 return;
2837 }
2838
2839 /* If we're in the reboot state, make sure the media is set up
2840 correctly. */
2841 if (client -> state == S_REBOOTING &&
2842 !client -> medium &&
2843 client -> active -> medium ) {
2844 script_init(client, "MEDIUM", client -> active -> medium);
2845
2846 /* If the medium we chose won't fly, go to INIT state. */
2847 if (script_go(client))
2848 goto cancel;
2849
2850 /* Record the medium. */
2851 client -> medium = client -> active -> medium;
2852 }
2853
2854 /* If the lease has expired, relinquish the address and go back
2855 to the INIT state. */
2856 if (client -> state != S_REQUESTING &&
2857 cur_time > client -> active -> expiry) {
2858 /* Run the client script with the new parameters. */
2859 script_init(client, "EXPIRE", (struct string_list *)0);
2860 script_write_params(client, "old_", client -> active);
2861 script_write_requested(client);
2862 if (client -> alias)
2863 script_write_params(client, "alias_",
2864 client -> alias);
2865 script_go(client);
2866
2867 /* Now do a preinit on the interface so that we can
2868 discover a new address. */
2869 script_init(client, "PREINIT", (struct string_list *)0);
2870 if (client -> alias)
2871 script_write_params(client, "alias_",
2872 client -> alias);
2873 script_go(client);
2874
2875 client -> state = S_INIT;
2876 state_init (client);
2877 return;
2878 }
2879
2880 /* Do the exponential backoff... */
2881 if (!client -> interval)
2882 client -> interval = client -> config -> initial_interval;
2883 else {
2884 client -> interval += ((random () >> 2) %
2885 (2 * client -> interval));
2886 }
2887
2888 /* Don't backoff past cutoff. */
2889 if (client -> interval >
2890 client -> config -> backoff_cutoff)
2891 client -> interval =
2892 ((client -> config -> backoff_cutoff / 2)
2893 + ((random () >> 2) %
2894 client -> config -> backoff_cutoff));
2895
2896 /* If the backoff would take us to the expiry time, just set the
2897 timeout to the expiry time. */
2898 if (client -> state != S_REQUESTING &&
2899 cur_time + client -> interval > client -> active -> expiry)
2900 client -> interval =
2901 client -> active -> expiry - cur_time + 1;
2902
2903 /* If the lease T2 time has elapsed, or if we're not yet bound,
2904 broadcast the DHCPREQUEST rather than unicasting. */
2905 if (client -> state == S_REQUESTING ||
2906 client -> state == S_REBOOTING ||
2907 cur_time > client -> active -> rebind)
2908 destination.sin_addr = sockaddr_broadcast.sin_addr;
2909 else
2910 memcpy (&destination.sin_addr.s_addr,
2911 client -> destination.iabuf,
2912 sizeof destination.sin_addr.s_addr);
2913 destination.sin_port = remote_port;
2914 destination.sin_family = AF_INET;
2915 #ifdef HAVE_SA_LEN
2916 destination.sin_len = sizeof destination;
2917 #endif
2918
2919 if (client -> state == S_RENEWING ||
2920 client -> state == S_REBINDING)
2921 memcpy (&from, client -> active -> address.iabuf,
2922 sizeof from);
2923 else
2924 from.s_addr = INADDR_ANY;
2925
2926 /* Record the number of seconds since we started sending. */
2927 if (client -> state == S_REQUESTING)
2928 client -> packet.secs = client -> secs;
2929 else {
2930 if (interval < 65536)
2931 client -> packet.secs = htons (interval);
2932 else
2933 client -> packet.secs = htons (65535);
2934 }
2935
2936 #if defined(DHCPv6) && defined(DHCP4o6)
2937 if (dhcpv4_over_dhcpv6) {
2938 log_info ("DHCPREQUEST");
2939 } else
2940 #endif
2941 memset(rip_buf, 0x0, sizeof(rip_buf));
2942 if (client->state == S_BOUND || client->state == S_RENEWING ||
2943 client->state == S_REBINDING) {
2944 rip_str = inet_ntoa(client->packet.ciaddr);
2945 } else {
2946 rip_str = piaddr(client->requested_address);
2947 }
2948
2949 strncpy(rip_buf, rip_str, sizeof(rip_buf)-1);
2950 log_info ("DHCPREQUEST for %s on %s to %s port %d", rip_buf,
2951 client->name ? client->name : client->interface->name,
2952 inet_ntoa(destination.sin_addr),
2953 ntohs (destination.sin_port));
2954
2955 #if defined(DHCPv6) && defined(DHCP4o6)
2956 if (dhcpv4_over_dhcpv6) {
2957 int broadcast = 0;
2958 if (destination.sin_addr.s_addr == INADDR_BROADCAST)
2959 broadcast = 1;
2960 result = send_dhcpv4_query(client, broadcast);
2961 if (result < 0) {
2962 log_error("%s:%d: Failed to send %d byte long packet.",
2963 MDL, client->packet_length);
2964 }
2965 } else
2966 #endif
2967 if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
2968 fallback_interface) {
2969 result = send_packet(fallback_interface, NULL, &client->packet,
2970 client->packet_length, from, &destination,
2971 NULL);
2972 if (result < 0) {
2973 log_error("%s:%d: Failed to send %d byte long packet "
2974 "over %s interface.", MDL,
2975 client->packet_length,
2976 fallback_interface->name);
2977 }
2978 }
2979 else {
2980 /* Send out a packet. */
2981 result = send_packet(client->interface, NULL, &client->packet,
2982 client->packet_length, from, &destination,
2983 NULL);
2984 if (result < 0) {
2985 log_error("%s:%d: Failed to send %d byte long packet"
2986 " over %s interface.", MDL,
2987 client->packet_length,
2988 client->interface->name);
2989 }
2990 }
2991
2992 tv.tv_sec = cur_tv.tv_sec + client->interval;
2993 tv.tv_usec = ((tv.tv_sec - cur_tv.tv_sec) > 1) ?
2994 random() % 1000000 : cur_tv.tv_usec;
2995 add_timeout(&tv, send_request, client, 0, 0);
2996 }
2997
2998 void send_decline (cpp)
2999 void *cpp;
3000 {
3001 struct client_state *client = cpp;
3002
3003 int result;
3004
3005 #if defined(DHCPv6) && defined(DHCP4o6)
3006 if (dhcpv4_over_dhcpv6) {
3007 log_info ("DHCPDECLINE");
3008 } else
3009 #endif
3010 log_info ("DHCPDECLINE of %s on %s to %s port %d",
3011 piaddr(client->requested_address),
3012 (client->name ? client->name : client->interface->name),
3013 inet_ntoa(sockaddr_broadcast.sin_addr),
3014 ntohs(sockaddr_broadcast.sin_port));
3015
3016 /* Send out a packet. */
3017 #if defined(DHCPv6) && defined(DHCP4o6)
3018 if (dhcpv4_over_dhcpv6) {
3019 result = send_dhcpv4_query(client, 1);
3020 } else
3021 #endif
3022 result = send_packet(client->interface, NULL, &client->packet,
3023 client->packet_length, inaddr_any,
3024 &sockaddr_broadcast, NULL);
3025 if (result < 0) {
3026 #if defined(DHCPv6) && defined(DHCP4o6)
3027 if (dhcpv4_over_dhcpv6) {
3028 log_error("%s:%d: Failed to send %d byte long packet.",
3029 MDL, client->packet_length);
3030 } else
3031 #endif
3032 log_error("%s:%d: Failed to send %d byte long packet over %s"
3033 " interface.", MDL, client->packet_length,
3034 client->interface->name);
3035 }
3036 }
3037
3038 void send_release (cpp)
3039 void *cpp;
3040 {
3041 struct client_state *client = cpp;
3042
3043 int result;
3044 struct sockaddr_in destination;
3045 struct in_addr from;
3046
3047 memcpy (&from, client -> active -> address.iabuf,
3048 sizeof from);
3049 memcpy (&destination.sin_addr.s_addr,
3050 client -> destination.iabuf,
3051 sizeof destination.sin_addr.s_addr);
3052 destination.sin_port = remote_port;
3053 destination.sin_family = AF_INET;
3054 #ifdef HAVE_SA_LEN
3055 destination.sin_len = sizeof destination;
3056 #endif
3057
3058 /* Set the lease to end now, so that we don't accidentally
3059 reuse it if we restart before the old expiry time. */
3060 client -> active -> expiry =
3061 client -> active -> renewal =
3062 client -> active -> rebind = cur_time;
3063 if (!write_client_lease (client, client -> active, 1, 1)) {
3064 log_error ("Can't release lease: lease write failed.");
3065 return;
3066 }
3067
3068 #if defined(DHCPv6) && defined(DHCP4o6)
3069 if (dhcpv4_over_dhcpv6) {
3070 log_info ("DHCPRELEASE");
3071 } else
3072 #endif
3073 log_info ("DHCPRELEASE of %s on %s to %s port %d",
3074 piaddr(client->active->address),
3075 client->name ? client->name : client->interface->name,
3076 inet_ntoa (destination.sin_addr),
3077 ntohs (destination.sin_port));
3078
3079 #if defined(DHCPv6) && defined(DHCP4o6)
3080 if (dhcpv4_over_dhcpv6) {
3081 int broadcast = 0;
3082 if (destination.sin_addr.s_addr == INADDR_BROADCAST)
3083 broadcast = 1;
3084 result = send_dhcpv4_query(client, broadcast);
3085 if (result < 0) {
3086 log_error("%s:%d: Failed to send %d byte long packet.",
3087 MDL, client->packet_length);
3088 }
3089 } else
3090 #endif
3091 if (fallback_interface) {
3092 result = send_packet(fallback_interface, NULL, &client->packet,
3093 client->packet_length, from, &destination,
3094 NULL);
3095 if (result < 0) {
3096 log_error("%s:%d: Failed to send %d byte long packet"
3097 " over %s interface.", MDL,
3098 client->packet_length,
3099 fallback_interface->name);
3100 }
3101 } else {
3102 /* Send out a packet. */
3103 result = send_packet(client->interface, NULL, &client->packet,
3104 client->packet_length, from, &destination,
3105 NULL);
3106 if (result < 0) {
3107 log_error ("%s:%d: Failed to send %d byte long packet"
3108 " over %s interface.", MDL,
3109 client->packet_length,
3110 client->interface->name);
3111 }
3112
3113 }
3114 }
3115
3116 #if defined(DHCPv6) && defined(DHCP4o6)
3117 /*
3118 * \brief Send a DHCPv4-query to the DHCPv6 client
3119 * (DHCPv4 client function)
3120 *
3121 * The DHCPv4 client sends a DHCPv4-query to the DHCPv6 client over
3122 * the inter-process communication socket.
3123 *
3124 * \param client the DHCPv4 client state
3125 * \param broadcast the broadcast flag
3126 * \return the sent byte count (-1 on error)
3127 */
3128 static int send_dhcpv4_query(struct client_state *client, int broadcast) {
3129 struct data_string ds;
3130 struct dhcpv4_over_dhcpv6_packet *query;
3131 int ofs, len, cc;
3132
3133 if (dhcp4o6_state <= 0) {
3134 log_info("send_dhcpv4_query: not ready.");
3135 return -1;
3136 }
3137
3138 /*
3139 * Compute buffer length and allocate it.
3140 */
3141 len = ofs = (int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options));
3142 len += dhcpv6_universe.tag_size + dhcpv6_universe.length_size;
3143 len += client->packet_length;
3144 memset(&ds, 0, sizeof(ds));
3145 if (!buffer_allocate(&ds.buffer, len, MDL)) {
3146 log_error("Unable to allocate memory for DHCPv4-query.");
3147 return -1;
3148 }
3149 ds.data = ds.buffer->data;
3150 ds.len = len;
3151
3152 /*
3153 * Fill header.
3154 */
3155 query = (struct dhcpv4_over_dhcpv6_packet *)ds.data;
3156 query->msg_type = DHCPV6_DHCPV4_QUERY;
3157 query->flags[0] = query->flags[1] = query->flags[2] = 0;
3158 if (!broadcast)
3159 query->flags[0] |= DHCP4O6_QUERY_UNICAST;
3160
3161 /*
3162 * Append DHCPv4 message.
3163 */
3164 dhcpv6_universe.store_tag(ds.buffer->data + ofs, D6O_DHCPV4_MSG);
3165 ofs += dhcpv6_universe.tag_size;
3166 dhcpv6_universe.store_length(ds.buffer->data + ofs,
3167 client->packet_length);
3168 ofs += dhcpv6_universe.length_size;
3169 memcpy(ds.buffer->data + ofs, &client->packet, client->packet_length);
3170
3171 /*
3172 * Send DHCPv6 message.
3173 */
3174 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
3175 if (cc < 0)
3176 log_error("send_dhcpv4_query: send(): %m");
3177
3178 data_string_forget(&ds, MDL);
3179
3180 return cc;
3181 }
3182
3183 /*
3184 * \brief Forward a DHCPv4-query to all DHCPv4 over DHCPv6 server addresses.
3185 * (DHCPv6 client function)
3186 *
3187 * \param raw the DHCPv6 DHCPv4-query message raw content
3188 */
3189 static void forw_dhcpv4_query(struct data_string *raw) {
3190 struct interface_info *ip;
3191 struct client_state *client;
3192 struct dhc6_lease *lease;
3193 struct option_cache *oc;
3194 struct data_string addrs;
3195 struct sockaddr_in6 sin6;
3196 int i, send_ret, attempt, success;
3197
3198 attempt = success = 0;
3199 memset(&sin6, 0, sizeof(sin6));
3200 sin6.sin6_family = AF_INET6;
3201 sin6.sin6_port = remote_port;
3202 #ifdef HAVE_SA_LEN
3203 sin6.sin6_len = sizeof(sin6);
3204 #endif
3205 memset(&addrs, 0, sizeof(addrs));
3206 for (ip = interfaces; ip != NULL; ip = ip->next) {
3207 for (client = ip->client; client != NULL;
3208 client = client->next) {
3209 if ((client->state != S_BOUND) &&
3210 (client->state != S_RENEWING) &&
3211 (client->state != S_REBINDING))
3212 continue;
3213 lease = client->active_lease;
3214 if ((lease == NULL) || lease->released)
3215 continue;
3216 oc = lookup_option(&dhcpv6_universe,
3217 lease->options,
3218 D6O_DHCP4_O_DHCP6_SERVER);
3219 if ((oc == NULL) ||
3220 !evaluate_option_cache(&addrs, NULL, NULL, NULL,
3221 lease->options, NULL,
3222 &global_scope, oc, MDL) ||
3223 ((addrs.len % sizeof(sin6.sin6_addr)) != 0)) {
3224 data_string_forget(&addrs, MDL);
3225 continue;
3226 }
3227 if (addrs.len == 0) {
3228 /* note there is nothing to forget */
3229 inet_pton(AF_INET6,
3230 All_DHCP_Relay_Agents_and_Servers,
3231 &sin6.sin6_addr);
3232 attempt++;
3233 send_ret = send_packet6(ip, raw->data,
3234 raw->len, &sin6);
3235 if (send_ret == raw->len)
3236 success++;
3237 continue;
3238 }
3239 for (i = 0; i < addrs.len;
3240 i += sizeof(sin6.sin6_addr)) {
3241 memcpy(&sin6.sin6_addr, addrs.data + i,
3242 sizeof(sin6.sin6_addr));
3243 attempt++;
3244 send_ret = send_packet6(ip, raw->data,
3245 raw->len, &sin6);
3246 if (send_ret == raw->len)
3247 success++;
3248 }
3249 data_string_forget(&addrs, MDL);
3250 }
3251 }
3252
3253 log_info("forw_dhcpv4_query: sent(%d): %d/%d",
3254 raw->len, success, attempt);
3255
3256 if (attempt == 0)
3257 dhcp4o6_stop();
3258 }
3259 #endif
3260
3261 void
3262 make_client_options(struct client_state *client, struct client_lease *lease,
3263 u_int8_t *type, struct option_cache *sid,
3264 struct iaddr *rip, struct option **prl,
3265 struct option_state **op)
3266 {
3267 unsigned i;
3268 struct option_cache *oc;
3269 struct option *option = NULL;
3270 struct buffer *bp = NULL;
3271
3272 /* If there are any leftover options, get rid of them. */
3273 if (*op)
3274 option_state_dereference(op, MDL);
3275
3276 /* Allocate space for options. */
3277 option_state_allocate(op, MDL);
3278
3279 /* Send the server identifier if provided. */
3280 if (sid)
3281 save_option(&dhcp_universe, *op, sid);
3282
3283 oc = NULL;
3284
3285 /* Send the requested address if provided. */
3286 if (rip) {
3287 client->requested_address = *rip;
3288 i = DHO_DHCP_REQUESTED_ADDRESS;
3289 if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash,
3290 &i, 0, MDL) &&
3291 make_const_option_cache(&oc, NULL, rip->iabuf, rip->len,
3292 option, MDL)))
3293 log_error ("can't make requested address cache.");
3294 else {
3295 save_option(&dhcp_universe, *op, oc);
3296 option_cache_dereference(&oc, MDL);
3297 }
3298 option_dereference(&option, MDL);
3299 } else {
3300 client->requested_address.len = 0;
3301 }
3302
3303 i = DHO_DHCP_MESSAGE_TYPE;
3304 if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash, &i, 0,
3305 MDL) &&
3306 make_const_option_cache(&oc, NULL, type, 1, option, MDL)))
3307 log_error("can't make message type.");
3308 else {
3309 save_option(&dhcp_universe, *op, oc);
3310 option_cache_dereference(&oc, MDL);
3311 }
3312 option_dereference(&option, MDL);
3313
3314 if (prl) {
3315 int len;
3316
3317 /* Probe the length of the list. */
3318 len = 0;
3319 for (i = 0 ; prl[i] != NULL ; i++)
3320 if (prl[i]->universe == &dhcp_universe)
3321 len++;
3322
3323 if (!buffer_allocate(&bp, len, MDL))
3324 log_error("can't make parameter list buffer.");
3325 else {
3326 unsigned code = DHO_DHCP_PARAMETER_REQUEST_LIST;
3327
3328 len = 0;
3329 for (i = 0 ; prl[i] != NULL ; i++)
3330 if (prl[i]->universe == &dhcp_universe)
3331 bp->data[len++] = prl[i]->code;
3332
3333 if (!(option_code_hash_lookup(&option,
3334 dhcp_universe.code_hash,
3335 &code, 0, MDL) &&
3336 make_const_option_cache(&oc, &bp, NULL, len,
3337 option, MDL))) {
3338 if (bp != NULL)
3339 buffer_dereference(&bp, MDL);
3340 log_error ("can't make option cache");
3341 } else {
3342 save_option(&dhcp_universe, *op, oc);
3343 option_cache_dereference(&oc, MDL);
3344 }
3345 option_dereference(&option, MDL);
3346 }
3347 }
3348
3349 /*
3350 * If requested (duid_v4 == 1) add an RFC4361 compliant client-identifier
3351 * This can be overridden by including a client id in the configuration
3352 * file.
3353 */
3354 if (duid_v4 == 1) {
3355 struct data_string client_identifier;
3356 int hw_idx, hw_len;
3357
3358 memset(&client_identifier, 0, sizeof(client_identifier));
3359 client_identifier.len = 1 + 4 + default_duid.len;
3360 if (!buffer_allocate(&client_identifier.buffer,
3361 client_identifier.len, MDL))
3362 log_fatal("no memory for default DUID!");
3363 client_identifier.data = client_identifier.buffer->data;
3364
3365 i = DHO_DHCP_CLIENT_IDENTIFIER;
3366
3367 /* Client-identifier type : 1 byte */
3368 *client_identifier.buffer->data = 255;
3369
3370 /* IAID : 4 bytes
3371 * we use the low 4 bytes from the interface address
3372 */
3373 if (client->interface->hw_address.hlen > 4) {
3374 hw_idx = client->interface->hw_address.hlen - 4;
3375 hw_len = 4;
3376 } else {
3377 hw_idx = 0;
3378 hw_len = client->interface->hw_address.hlen;
3379 }
3380 memcpy(&client_identifier.buffer->data + 5 - hw_len,
3381 client->interface->hw_address.hbuf + hw_idx,
3382 hw_len);
3383
3384 /* Add the default duid */
3385 memcpy(&client_identifier.buffer->data+(1+4),
3386 default_duid.data, default_duid.len);
3387
3388 /* And save the option */
3389 if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash,
3390 &i, 0, MDL) &&
3391 make_const_option_cache(&oc, NULL,
3392 (u_int8_t *)client_identifier.data,
3393 client_identifier.len,
3394 option, MDL)))
3395 log_error ("can't make requested client id cache..");
3396 else {
3397 save_option (&dhcp_universe, *op, oc);
3398 option_cache_dereference (&oc, MDL);
3399 }
3400 option_dereference(&option, MDL);
3401 }
3402
3403 /* Run statements that need to be run on transmission. */
3404 if (client->config->on_transmission)
3405 execute_statements_in_scope(NULL, NULL, NULL, client,
3406 (lease ? lease->options : NULL),
3407 *op, &global_scope,
3408 client->config->on_transmission,
3409 NULL, NULL);
3410 }
3411
3412 void make_discover (client, lease)
3413 struct client_state *client;
3414 struct client_lease *lease;
3415 {
3416 unsigned char discover = DHCPDISCOVER;
3417 struct option_state *options = (struct option_state *)0;
3418
3419 memset (&client -> packet, 0, sizeof (client -> packet));
3420
3421 make_client_options (client,
3422 lease, &discover, (struct option_cache *)0,
3423 lease ? &lease -> address : (struct iaddr *)0,
3424 client -> config -> requested_options,
3425 &options);
3426
3427 /* Set up the option buffer... */
3428 client -> packet_length =
3429 cons_options ((struct packet *)0, &client -> packet,
3430 (struct lease *)0, client,
3431 /* maximum packet size */1500,
3432 (struct option_state *)0,
3433 options,
3434 /* scope */ &global_scope,
3435 /* overload */ 0,
3436 /* terminate */0,
3437 /* bootpp */0,
3438 (struct data_string *)0,
3439 client -> config -> vendor_space_name);
3440
3441 option_state_dereference (&options, MDL);
3442 if (client -> packet_length < BOOTP_MIN_LEN)
3443 client -> packet_length = BOOTP_MIN_LEN;
3444
3445 client -> packet.op = BOOTREQUEST;
3446 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
3447 /* Assumes hw_address is known, otherwise a random value may result */
3448 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
3449 client -> packet.hops = 0;
3450 client -> packet.xid = random ();
3451 client -> packet.secs = 0; /* filled in by send_discover. */
3452
3453 if (can_receive_unicast_unconfigured (client -> interface))
3454 client -> packet.flags = 0;
3455 else
3456 client -> packet.flags = htons (BOOTP_BROADCAST);
3457
3458 memset (&(client -> packet.ciaddr),
3459 0, sizeof client -> packet.ciaddr);
3460 memset (&(client -> packet.yiaddr),
3461 0, sizeof client -> packet.yiaddr);
3462 memset (&(client -> packet.siaddr),
3463 0, sizeof client -> packet.siaddr);
3464 client -> packet.giaddr = giaddr;
3465 if (client -> interface -> hw_address.hlen > 0)
3466 memcpy (client -> packet.chaddr,
3467 &client -> interface -> hw_address.hbuf [1],
3468 (unsigned)(client -> interface -> hw_address.hlen - 1));
3469
3470 #ifdef DEBUG_PACKET
3471 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
3472 #endif
3473 }
3474
3475
3476 void make_request (client, lease)
3477 struct client_state *client;
3478 struct client_lease *lease;
3479 {
3480 unsigned char request = DHCPREQUEST;
3481 struct option_cache *oc;
3482
3483 memset (&client -> packet, 0, sizeof (client -> packet));
3484
3485 if (client -> state == S_REQUESTING)
3486 oc = lookup_option (&dhcp_universe, lease -> options,
3487 DHO_DHCP_SERVER_IDENTIFIER);
3488 else
3489 oc = (struct option_cache *)0;
3490
3491 if (client -> sent_options)
3492 option_state_dereference (&client -> sent_options, MDL);
3493
3494 make_client_options (client, lease, &request, oc,
3495 ((client -> state == S_REQUESTING ||
3496 client -> state == S_REBOOTING)
3497 ? &lease -> address
3498 : (struct iaddr *)0),
3499 client -> config -> requested_options,
3500 &client -> sent_options);
3501
3502 /* Set up the option buffer... */
3503 client -> packet_length =
3504 cons_options ((struct packet *)0, &client -> packet,
3505 (struct lease *)0, client,
3506 /* maximum packet size */1500,
3507 (struct option_state *)0,
3508 client -> sent_options,
3509 /* scope */ &global_scope,
3510 /* overload */ 0,
3511 /* terminate */0,
3512 /* bootpp */0,
3513 (struct data_string *)0,
3514 client -> config -> vendor_space_name);
3515
3516 if (client -> packet_length < BOOTP_MIN_LEN)
3517 client -> packet_length = BOOTP_MIN_LEN;
3518
3519 client -> packet.op = BOOTREQUEST;
3520 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
3521 /* Assumes hw_address is known, otherwise a random value may result */
3522 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
3523 client -> packet.hops = 0;
3524 client -> packet.xid = client -> xid;
3525 client -> packet.secs = 0; /* Filled in by send_request. */
3526
3527 /* If we own the address we're requesting, put it in ciaddr;
3528 otherwise set ciaddr to zero. */
3529 if (client -> state == S_BOUND ||
3530 client -> state == S_RENEWING ||
3531 client -> state == S_REBINDING) {
3532 memcpy (&client -> packet.ciaddr,
3533 lease -> address.iabuf, lease -> address.len);
3534 client -> packet.flags = 0;
3535 } else {
3536 memset (&client -> packet.ciaddr, 0,
3537 sizeof client -> packet.ciaddr);
3538 if (can_receive_unicast_unconfigured (client -> interface))
3539 client -> packet.flags = 0;
3540 else
3541 client -> packet.flags = htons (BOOTP_BROADCAST);
3542 }
3543
3544 memset (&client -> packet.yiaddr, 0,
3545 sizeof client -> packet.yiaddr);
3546 memset (&client -> packet.siaddr, 0,
3547 sizeof client -> packet.siaddr);
3548 if (client -> state != S_BOUND &&
3549 client -> state != S_RENEWING)
3550 client -> packet.giaddr = giaddr;
3551 else
3552 memset (&client -> packet.giaddr, 0,
3553 sizeof client -> packet.giaddr);
3554 if (client -> interface -> hw_address.hlen > 0)
3555 memcpy (client -> packet.chaddr,
3556 &client -> interface -> hw_address.hbuf [1],
3557 (unsigned)(client -> interface -> hw_address.hlen - 1));
3558
3559 #ifdef DEBUG_PACKET
3560 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
3561 #endif
3562 }
3563
3564 void make_decline (client, lease)
3565 struct client_state *client;
3566 struct client_lease *lease;
3567 {
3568 unsigned char decline = DHCPDECLINE;
3569 struct option_cache *oc;
3570
3571 struct option_state *options = (struct option_state *)0;
3572
3573 /* Create the options cache. */
3574 oc = lookup_option (&dhcp_universe, lease -> options,
3575 DHO_DHCP_SERVER_IDENTIFIER);
3576 make_client_options(client, lease, &decline, oc, &lease->address,
3577 NULL, &options);
3578
3579 /* Consume the options cache into the option buffer. */
3580 memset (&client -> packet, 0, sizeof (client -> packet));
3581 client -> packet_length =
3582 cons_options ((struct packet *)0, &client -> packet,
3583 (struct lease *)0, client, 0,
3584 (struct option_state *)0, options,
3585 &global_scope, 0, 0, 0, (struct data_string *)0,
3586 client -> config -> vendor_space_name);
3587
3588 /* Destroy the options cache. */
3589 option_state_dereference (&options, MDL);
3590
3591 if (client -> packet_length < BOOTP_MIN_LEN)
3592 client -> packet_length = BOOTP_MIN_LEN;
3593
3594 client -> packet.op = BOOTREQUEST;
3595 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
3596 /* Assumes hw_address is known, otherwise a random value may result */
3597 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
3598 client -> packet.hops = 0;
3599 client -> packet.xid = client -> xid;
3600 client -> packet.secs = 0; /* Filled in by send_request. */
3601 if (can_receive_unicast_unconfigured (client -> interface))
3602 client -> packet.flags = 0;
3603 else
3604 client -> packet.flags = htons (BOOTP_BROADCAST);
3605
3606 /* ciaddr must always be zero. */
3607 memset (&client -> packet.ciaddr, 0,
3608 sizeof client -> packet.ciaddr);
3609 memset (&client -> packet.yiaddr, 0,
3610 sizeof client -> packet.yiaddr);
3611 memset (&client -> packet.siaddr, 0,
3612 sizeof client -> packet.siaddr);
3613 client -> packet.giaddr = giaddr;
3614 memcpy (client -> packet.chaddr,
3615 &client -> interface -> hw_address.hbuf [1],
3616 client -> interface -> hw_address.hlen);
3617
3618 #ifdef DEBUG_PACKET
3619 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
3620 #endif
3621 }
3622
3623 void make_release (client, lease)
3624 struct client_state *client;
3625 struct client_lease *lease;
3626 {
3627 unsigned char request = DHCPRELEASE;
3628 struct option_cache *oc;
3629
3630 struct option_state *options = (struct option_state *)0;
3631
3632 memset (&client -> packet, 0, sizeof (client -> packet));
3633
3634 oc = lookup_option (&dhcp_universe, lease -> options,
3635 DHO_DHCP_SERVER_IDENTIFIER);
3636 make_client_options(client, lease, &request, oc, NULL, NULL, &options);
3637
3638 /* Set up the option buffer... */
3639 client -> packet_length =
3640 cons_options ((struct packet *)0, &client -> packet,
3641 (struct lease *)0, client,
3642 /* maximum packet size */1500,
3643 (struct option_state *)0,
3644 options,
3645 /* scope */ &global_scope,
3646 /* overload */ 0,
3647 /* terminate */0,
3648 /* bootpp */0,
3649 (struct data_string *)0,
3650 client -> config -> vendor_space_name);
3651
3652 if (client -> packet_length < BOOTP_MIN_LEN)
3653 client -> packet_length = BOOTP_MIN_LEN;
3654 option_state_dereference (&options, MDL);
3655
3656 client -> packet.op = BOOTREQUEST;
3657 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
3658 /* Assumes hw_address is known, otherwise a random value may result */
3659 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
3660 client -> packet.hops = 0;
3661 client -> packet.xid = random ();
3662 client -> packet.secs = 0;
3663 client -> packet.flags = 0;
3664 memcpy (&client -> packet.ciaddr,
3665 lease -> address.iabuf, lease -> address.len);
3666 memset (&client -> packet.yiaddr, 0,
3667 sizeof client -> packet.yiaddr);
3668 memset (&client -> packet.siaddr, 0,
3669 sizeof client -> packet.siaddr);
3670 client -> packet.giaddr = giaddr;
3671 memcpy (client -> packet.chaddr,
3672 &client -> interface -> hw_address.hbuf [1],
3673 client -> interface -> hw_address.hlen);
3674
3675 #ifdef DEBUG_PACKET
3676 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
3677 #endif
3678 }
3679
3680 void destroy_client_lease (lease)
3681 struct client_lease *lease;
3682 {
3683 if (lease -> server_name)
3684 dfree (lease -> server_name, MDL);
3685 if (lease -> filename)
3686 dfree (lease -> filename, MDL);
3687 option_state_dereference (&lease -> options, MDL);
3688 free_client_lease (lease, MDL);
3689 }
3690
3691 FILE *leaseFile = NULL;
3692 int leases_written = 0;
3693
3694 void rewrite_client_leases ()
3695 {
3696 struct interface_info *ip;
3697 struct client_state *client;
3698 struct client_lease *lp;
3699
3700 if (leaseFile != NULL)
3701 fclose (leaseFile);
3702 leaseFile = fopen (path_dhclient_db, "w");
3703 if (leaseFile == NULL) {
3704 log_error ("can't create %s: %m", path_dhclient_db);
3705 return;
3706 }
3707
3708 /* If there is a default duid, write it out. */
3709 if (default_duid.len != 0)
3710 write_duid(&default_duid);
3711
3712 /* Write out all the leases attached to configured interfaces that
3713 we know about. */
3714 for (ip = interfaces; ip; ip = ip -> next) {
3715 for (client = ip -> client; client; client = client -> next) {
3716 for (lp = client -> leases; lp; lp = lp -> next) {
3717 write_client_lease (client, lp, 1, 0);
3718 }
3719 if (client -> active)
3720 write_client_lease (client,
3721 client -> active, 1, 0);
3722
3723 if (client->active_lease != NULL)
3724 write_client6_lease(client,
3725 client->active_lease,
3726 1, 0);
3727
3728 /* Reset last_write after rewrites. */
3729 client->last_write = 0;
3730 }
3731 }
3732
3733 /* Write out any leases that are attached to interfaces that aren't
3734 currently configured. */
3735 for (ip = dummy_interfaces; ip; ip = ip -> next) {
3736 for (client = ip -> client; client; client = client -> next) {
3737 for (lp = client -> leases; lp; lp = lp -> next) {
3738 write_client_lease (client, lp, 1, 0);
3739 }
3740 if (client -> active)
3741 write_client_lease (client,
3742 client -> active, 1, 0);
3743
3744 if (client->active_lease != NULL)
3745 write_client6_lease(client,
3746 client->active_lease,
3747 1, 0);
3748
3749 /* Reset last_write after rewrites. */
3750 client->last_write = 0;
3751 }
3752 }
3753 fflush (leaseFile);
3754 }
3755
3756 void write_lease_option (struct option_cache *oc,
3757 struct packet *packet, struct lease *lease,
3758 struct client_state *client_state,
3759 struct option_state *in_options,
3760 struct option_state *cfg_options,
3761 struct binding_scope **scope,
3762 struct universe *u, void *stuff)
3763 {
3764 const char *name, *dot;
3765 struct data_string ds;
3766 char *preamble = stuff;
3767
3768 memset (&ds, 0, sizeof ds);
3769
3770 if (u != &dhcp_universe) {
3771 name = u -> name;
3772 dot = ".";
3773 } else {
3774 name = "";
3775 dot = "";
3776 }
3777 if (evaluate_option_cache (&ds, packet, lease, client_state,
3778 in_options, cfg_options, scope, oc, MDL)) {
3779 /* The option name */
3780 fprintf(leaseFile, "%soption %s%s%s", preamble,
3781 name, dot, oc->option->name);
3782
3783 /* The option value if there is one */
3784 if ((oc->option->format == NULL) ||
3785 (oc->option->format[0] != 'Z')) {
3786 fprintf(leaseFile, " %s",
3787 pretty_print_option(oc->option, ds.data,
3788 ds.len, 1, 1));
3789 }
3790
3791 /* The closing semi-colon and newline */
3792 fprintf(leaseFile, ";\n");
3793
3794 data_string_forget (&ds, MDL);
3795 }
3796 }
3797
3798 /* Write an option cache to the lease store. */
3799 static void
3800 write_options(struct client_state *client, struct option_state *options,
3801 const char *preamble)
3802 {
3803 int i;
3804
3805 for (i = 0; i < options->universe_count; i++) {
3806 option_space_foreach(NULL, NULL, client, NULL, options,
3807 &global_scope, universes[i],
3808 (char *)preamble, write_lease_option);
3809 }
3810 }
3811
3812 /*
3813 * The "best" default DUID, since we cannot predict any information
3814 * about the system (such as whether or not the hardware addresses are
3815 * integrated into the motherboard or similar), is the "LLT", link local
3816 * plus time, DUID. For real stateless "LL" is better.
3817 *
3818 * Once generated, this duid is stored into the state database, and
3819 * retained across restarts.
3820 *
3821 * For the time being, there is probably a different state database for
3822 * every daemon, so this winds up being a per-interface identifier...which
3823 * is not how it is intended. Upcoming rearchitecting the client should
3824 * address this "one daemon model."
3825 */
3826 void
3827 form_duid(struct data_string *duid, const char *file, int line)
3828 {
3829 struct interface_info *ip;
3830 int len;
3831 char *str;
3832
3833 /* For now, just use the first interface on the list. */
3834 ip = interfaces;
3835
3836 if (ip == NULL)
3837 log_fatal("Impossible condition at %s:%d.", MDL);
3838
3839 if ((ip->hw_address.hlen == 0) ||
3840 (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
3841 log_fatal("Impossible hardware address length at %s:%d.", MDL);
3842
3843 if (duid_type == 0)
3844 duid_type = stateless ? DUID_LL : DUID_LLT;
3845
3846 /*
3847 * 2 bytes for the 'duid type' field.
3848 * 2 bytes for the 'htype' field.
3849 * (DUID_LLT) 4 bytes for the 'current time'.
3850 * enough bytes for the hardware address (note that hw_address has
3851 * the 'htype' on byte zero).
3852 */
3853 len = 4 + (ip->hw_address.hlen - 1);
3854 if (duid_type == DUID_LLT)
3855 len += 4;
3856 if (!buffer_allocate(&duid->buffer, len, MDL))
3857 log_fatal("no memory for default DUID!");
3858 duid->data = duid->buffer->data;
3859 duid->len = len;
3860
3861 /* Basic Link Local Address type of DUID. */
3862 if (duid_type == DUID_LLT) {
3863 putUShort(duid->buffer->data, DUID_LLT);
3864 putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]);
3865 putULong(duid->buffer->data + 4, cur_time - DUID_TIME_EPOCH);
3866 memcpy(duid->buffer->data + 8, ip->hw_address.hbuf + 1,
3867 ip->hw_address.hlen - 1);
3868 } else {
3869 putUShort(duid->buffer->data, DUID_LL);
3870 putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]);
3871 memcpy(duid->buffer->data + 4, ip->hw_address.hbuf + 1,
3872 ip->hw_address.hlen - 1);
3873 }
3874
3875 /* Now format the output based on lease-id-format */
3876 str = format_lease_id(duid->data, duid->len,
3877 top_level_config.lease_id_format, MDL);
3878 if (str == NULL) {
3879 log_info("form_duid: Couldn't allocate memory to log duid!");
3880 } else {
3881 log_info("Created duid %s.", str);
3882 dfree(str, MDL);
3883 }
3884 }
3885
3886 /* Write the default DUID to the lease store. */
3887 static isc_result_t
3888 write_duid(struct data_string *duid)
3889 {
3890 char *str;
3891 int stat;
3892
3893 if ((duid == NULL) || (duid->len <= 2))
3894 return DHCP_R_INVALIDARG;
3895
3896 if (leaseFile == NULL) { /* XXX? */
3897 leaseFile = fopen(path_dhclient_db, "w");
3898 if (leaseFile == NULL) {
3899 log_error("can't create %s: %m", path_dhclient_db);
3900 return ISC_R_IOERROR;
3901 }
3902 }
3903
3904 /* Generate a formatted duid string per lease-id-format */
3905 str = format_lease_id(duid->data, duid->len,
3906 top_level_config.lease_id_format, MDL);
3907 if (str == NULL)
3908 return ISC_R_NOMEMORY;
3909
3910 stat = fprintf(leaseFile, "default-duid %s;\n", str);
3911 dfree(str, MDL);
3912 if (stat <= 0)
3913 return ISC_R_IOERROR;
3914
3915 if (fflush(leaseFile) != 0)
3916 return ISC_R_IOERROR;
3917
3918 return ISC_R_SUCCESS;
3919 }
3920
3921 /* Write a DHCPv6 lease to the store. */
3922 isc_result_t
3923 write_client6_lease(struct client_state *client, struct dhc6_lease *lease,
3924 int rewrite, int sync)
3925 {
3926 struct dhc6_ia *ia;
3927 struct dhc6_addr *addr;
3928 int stat;
3929 const char *ianame;
3930
3931 /* This should include the current lease. */
3932 if (!rewrite && (leases_written++ > 20)) {
3933 rewrite_client_leases();
3934 leases_written = 0;
3935 return ISC_R_SUCCESS;
3936 }
3937
3938 if (client == NULL || lease == NULL)
3939 return DHCP_R_INVALIDARG;
3940
3941 if (leaseFile == NULL) { /* XXX? */
3942 leaseFile = fopen(path_dhclient_db, "w");
3943 if (leaseFile == NULL) {
3944 log_error("can't create %s: %m", path_dhclient_db);
3945 return ISC_R_IOERROR;
3946 }
3947 }
3948
3949 stat = fprintf(leaseFile, "lease6 {\n");
3950 if (stat <= 0)
3951 return ISC_R_IOERROR;
3952
3953 stat = fprintf(leaseFile, " interface \"%s\";\n",
3954 client->interface->name);
3955 if (stat <= 0)
3956 return ISC_R_IOERROR;
3957
3958 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
3959 switch (ia->ia_type) {
3960 case D6O_IA_NA:
3961 default:
3962 ianame = "ia-na";
3963 break;
3964 case D6O_IA_TA:
3965 ianame = "ia-ta";
3966 break;
3967 case D6O_IA_PD:
3968 ianame = "ia-pd";
3969 break;
3970 }
3971
3972 /* For some reason IAID was never octal or hex, but string or
3973 * hex. Go figure. So for compatibilty's sake we will either
3974 * do hex or "legacy" i.e string rather than octal. What a
3975 * cluster. */
3976 switch(top_level_config.lease_id_format) {
3977 case TOKEN_HEX: {
3978 char* iaid_str = format_lease_id(
3979 (const unsigned char *) &ia->iaid, 4,
3980 top_level_config.lease_id_format, MDL);
3981
3982 if (!iaid_str) {
3983 log_error("Can't format iaid");
3984 return ISC_R_IOERROR;
3985 }
3986
3987 stat = fprintf(leaseFile, " %s %s {\n",
3988 ianame, iaid_str);
3989 dfree(iaid_str, MDL);
3990 break;
3991 }
3992
3993 case TOKEN_OCTAL:
3994 default:
3995 stat = fprintf(leaseFile, " %s %s {\n", ianame,
3996 print_hex_1(4, ia->iaid, 12));
3997 break;
3998 }
3999
4000 if (stat <= 0)
4001 return ISC_R_IOERROR;
4002
4003 if (ia->ia_type != D6O_IA_TA)
4004 stat = fprintf(leaseFile, " starts %d;\n"
4005 " renew %u;\n"
4006 " rebind %u;\n",
4007 (int)ia->starts, ia->renew, ia->rebind);
4008 else
4009 stat = fprintf(leaseFile, " starts %d;\n",
4010 (int)ia->starts);
4011 if (stat <= 0)
4012 return ISC_R_IOERROR;
4013
4014 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
4015 if (ia->ia_type != D6O_IA_PD)
4016 stat = fprintf(leaseFile,
4017 " iaaddr %s {\n",
4018 piaddr(addr->address));
4019 else
4020 stat = fprintf(leaseFile,
4021 " iaprefix %s/%d {\n",
4022 piaddr(addr->address),
4023 (int)addr->plen);
4024 if (stat <= 0)
4025 return ISC_R_IOERROR;
4026
4027 stat = fprintf(leaseFile, " starts %d;\n"
4028 " preferred-life %u;\n"
4029 " max-life %u;\n",
4030 (int)addr->starts, addr->preferred_life,
4031 addr->max_life);
4032 if (stat <= 0)
4033 return ISC_R_IOERROR;
4034
4035 if (addr->options != NULL)
4036 write_options(client, addr->options, " ");
4037
4038 stat = fprintf(leaseFile, " }\n");
4039 if (stat <= 0)
4040 return ISC_R_IOERROR;
4041 }
4042
4043 if (ia->options != NULL)
4044 write_options(client, ia->options, " ");
4045
4046 stat = fprintf(leaseFile, " }\n");
4047 if (stat <= 0)
4048 return ISC_R_IOERROR;
4049 }
4050
4051 if (lease->released) {
4052 stat = fprintf(leaseFile, " released;\n");
4053 if (stat <= 0)
4054 return ISC_R_IOERROR;
4055 }
4056
4057 if (lease->options != NULL)
4058 write_options(client, lease->options, " ");
4059
4060 stat = fprintf(leaseFile, "}\n");
4061 if (stat <= 0)
4062 return ISC_R_IOERROR;
4063
4064 if (fflush(leaseFile) != 0)
4065 return ISC_R_IOERROR;
4066
4067 if (sync) {
4068 if (fsync(fileno(leaseFile)) < 0) {
4069 log_error("write_client_lease: fsync(): %m");
4070 return ISC_R_IOERROR;
4071 }
4072 }
4073
4074 return ISC_R_SUCCESS;
4075 }
4076
4077 int write_client_lease (client, lease, rewrite, makesure)
4078 struct client_state *client;
4079 struct client_lease *lease;
4080 int rewrite;
4081 int makesure;
4082 {
4083 struct data_string ds;
4084 int errors = 0;
4085 char *s;
4086 const char *tval;
4087
4088 if (!rewrite) {
4089 if (leases_written++ > 20) {
4090 rewrite_client_leases ();
4091 leases_written = 0;
4092 }
4093 }
4094
4095 /* If the lease came from the config file, we don't need to stash
4096 a copy in the lease database. */
4097 if (lease -> is_static)
4098 return 1;
4099
4100 if (leaseFile == NULL) { /* XXX */
4101 leaseFile = fopen (path_dhclient_db, "w");
4102 if (leaseFile == NULL) {
4103 log_error ("can't create %s: %m", path_dhclient_db);
4104 return 0;
4105 }
4106 }
4107
4108 errno = 0;
4109 fprintf (leaseFile, "lease {\n");
4110 if (lease -> is_bootp) {
4111 fprintf (leaseFile, " bootp;\n");
4112 if (errno) {
4113 ++errors;
4114 errno = 0;
4115 }
4116 }
4117 fprintf (leaseFile, " interface \"%s\";\n",
4118 client -> interface -> name);
4119 if (errno) {
4120 ++errors;
4121 errno = 0;
4122 }
4123 if (client -> name) {
4124 fprintf (leaseFile, " name \"%s\";\n", client -> name);
4125 if (errno) {
4126 ++errors;
4127 errno = 0;
4128 }
4129 }
4130 fprintf (leaseFile, " fixed-address %s;\n",
4131 piaddr (lease -> address));
4132 if (errno) {
4133 ++errors;
4134 errno = 0;
4135 }
4136 if (lease -> filename) {
4137 s = quotify_string (lease -> filename, MDL);
4138 if (s) {
4139 fprintf (leaseFile, " filename \"%s\";\n", s);
4140 if (errno) {
4141 ++errors;
4142 errno = 0;
4143 }
4144 dfree (s, MDL);
4145 } else
4146 errors++;
4147
4148 }
4149 if (lease->server_name != NULL) {
4150 s = quotify_string(lease->server_name, MDL);
4151 if (s != NULL) {
4152 fprintf(leaseFile, " server-name \"%s\";\n", s);
4153 if (errno) {
4154 ++errors;
4155 errno = 0;
4156 }
4157 dfree(s, MDL);
4158 } else
4159 ++errors;
4160 }
4161 if (lease -> medium) {
4162 s = quotify_string (lease -> medium -> string, MDL);
4163 if (s) {
4164 fprintf (leaseFile, " medium \"%s\";\n", s);
4165 if (errno) {
4166 ++errors;
4167 errno = 0;
4168 }
4169 dfree (s, MDL);
4170 } else
4171 errors++;
4172 }
4173 if (errno != 0) {
4174 errors++;
4175 errno = 0;
4176 }
4177
4178 memset (&ds, 0, sizeof ds);
4179
4180 write_options(client, lease->options, " ");
4181
4182 tval = print_time(lease->renewal);
4183 if (tval == NULL ||
4184 fprintf(leaseFile, " renew %s\n", tval) < 0)
4185 errors++;
4186
4187 tval = print_time(lease->rebind);
4188 if (tval == NULL ||
4189 fprintf(leaseFile, " rebind %s\n", tval) < 0)
4190 errors++;
4191
4192 tval = print_time(lease->expiry);
4193 if (tval == NULL ||
4194 fprintf(leaseFile, " expire %s\n", tval) < 0)
4195 errors++;
4196
4197 if (fprintf(leaseFile, "}\n") < 0)
4198 errors++;
4199
4200 if (fflush(leaseFile) != 0)
4201 errors++;
4202
4203 client->last_write = cur_time;
4204
4205 if (!errors && makesure) {
4206 if (fsync (fileno (leaseFile)) < 0) {
4207 log_info ("write_client_lease: %m");
4208 return 0;
4209 }
4210 }
4211
4212 return errors ? 0 : 1;
4213 }
4214
4215 /* Variables holding name of script and file pointer for writing to
4216 script. Needless to say, this is not reentrant - only one script
4217 can be invoked at a time. */
4218 char scriptName [256];
4219 FILE *scriptFile;
4220
4221 /**
4222 * @brief Initializes basic variables for a script
4223 *
4224 * This function is called as an initial preparation for calling a script.
4225 * It sets up a number of common env. variables that will be passed to
4226 * the script. For actual script calling, see @ref script_go .
4227 *
4228 * @param client variables will be stored here (if null, the whole function
4229 * is no-op)
4230 * @param reason specified the reason for calling a script (must be non-null)
4231 * @param medium if specified, defines medium type (may be null)
4232 */
4233 void script_init(struct client_state *client, const char *reason,
4234 struct string_list *medium)
4235 {
4236 struct string_list *sl, *next;
4237
4238 if (client) {
4239 for (sl = client -> env; sl; sl = next) {
4240 next = sl -> next;
4241 dfree (sl, MDL);
4242 }
4243 client -> env = (struct string_list *)0;
4244 client -> envc = 0;
4245
4246 if (client -> interface) {
4247 client_envadd (client, "", "interface", "%s",
4248 client -> interface -> name);
4249 }
4250 if (client -> name)
4251 client_envadd (client,
4252 "", "client", "%s", client -> name);
4253 if (medium)
4254 client_envadd (client,
4255 "", "medium", "%s", medium -> string);
4256
4257 client_envadd (client, "", "reason", "%s", reason);
4258 client_envadd (client, "", "pid", "%ld", (long int)getpid ());
4259 #if defined(DHCPv6)
4260 client_envadd (client, "", "dad_wait_time", "%ld",
4261 (long int)dad_wait_time);
4262 #endif
4263 }
4264 }
4265
4266 void client_option_envadd (struct option_cache *oc,
4267 struct packet *packet, struct lease *lease,
4268 struct client_state *client_state,
4269 struct option_state *in_options,
4270 struct option_state *cfg_options,
4271 struct binding_scope **scope,
4272 struct universe *u, void *stuff)
4273 {
4274 struct envadd_state *es = stuff;
4275 struct data_string data;
4276 memset (&data, 0, sizeof data);
4277
4278 if (evaluate_option_cache (&data, packet, lease, client_state,
4279 in_options, cfg_options, scope, oc, MDL)) {
4280 if (data.len) {
4281 char name [256];
4282 if (dhcp_option_ev_name (name, sizeof name,
4283 oc->option)) {
4284 const char *value;
4285 size_t length;
4286 value = pretty_print_option(oc->option,
4287 data.data,
4288 data.len, 0, 0);
4289 length = strlen(value);
4290
4291 if (check_option_values(oc->option->universe,
4292 oc->option->code,
4293 value, length) == 0) {
4294 client_envadd(es->client, es->prefix,
4295 name, "%s", value);
4296 } else {
4297 log_error("suspect value in %s "
4298 "option - discarded",
4299 name);
4300 }
4301 }
4302 }
4303
4304 data_string_forget (&data, MDL);
4305 }
4306 }
4307
4308 /**
4309 * @brief Adds parameters to environment variables for a script
4310 *
4311 * This function add details of specified lease to a list of env. variables
4312 * to be passed to a script. The lease details will be prepended with
4313 * specified prefix (e.g. "old_") and added to the list stored in client.
4314 * Following variables may be set:
4315 * - ip_address
4316 * - next_server
4317 * - network_number
4318 * - broadcast_address
4319 * - filename
4320 * - server_name
4321 * - expiry
4322 *
4323 * @param client env. variables will be stored here
4324 * @param prefix textual prefix to be added to each variable (e.g. "old_")
4325 * @param lease lease details will be extracted from here
4326 */
4327 void script_write_params(struct client_state *client, const char *prefix,
4328 struct client_lease *lease)
4329 {
4330 int i;
4331 struct data_string data;
4332 struct option_cache *oc;
4333 struct envadd_state es;
4334
4335 es.client = client;
4336 es.prefix = prefix;
4337
4338 client_envadd (client,
4339 prefix, "ip_address", "%s", piaddr (lease -> address));
4340
4341 /* If we've set the next server address in the lease structure
4342 put it into an environment variable for the script */
4343 if (lease->next_srv_addr.len != 0) {
4344 client_envadd(client, prefix, "next_server", "%s",
4345 piaddr(lease->next_srv_addr));
4346 }
4347
4348 /* For the benefit of Linux (and operating systems which may
4349 have similar needs), compute the network address based on
4350 the supplied ip address and netmask, if provided. Also
4351 compute the broadcast address (the host address all ones
4352 broadcast address, not the host address all zeroes
4353 broadcast address). */
4354
4355 memset (&data, 0, sizeof data);
4356 oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK);
4357 if (oc && evaluate_option_cache (&data, (struct packet *)0,
4358 (struct lease *)0, client,
4359 (struct option_state *)0,
4360 lease -> options,
4361 &global_scope, oc, MDL)) {
4362 if (data.len > 3) {
4363 struct iaddr netmask, subnet, broadcast;
4364
4365 /*
4366 * No matter the length of the subnet-mask option,
4367 * use only the first four octets. Note that
4368 * subnet-mask options longer than 4 octets are not
4369 * in conformance with RFC 2132, but servers with this
4370 * flaw do exist.
4371 */
4372 memcpy(netmask.iabuf, data.data, 4);
4373 netmask.len = 4;
4374 data_string_forget (&data, MDL);
4375
4376 subnet = subnet_number (lease -> address, netmask);
4377 if (subnet.len) {
4378 client_envadd (client, prefix, "network_number",
4379 "%s", piaddr (subnet));
4380
4381 oc = lookup_option (&dhcp_universe,
4382 lease -> options,
4383 DHO_BROADCAST_ADDRESS);
4384 if (!oc ||
4385 !(evaluate_option_cache
4386 (&data, (struct packet *)0,
4387 (struct lease *)0, client,
4388 (struct option_state *)0,
4389 lease -> options,
4390 &global_scope, oc, MDL))) {
4391 broadcast = broadcast_addr (subnet, netmask);
4392 if (broadcast.len) {
4393 client_envadd (client,
4394 prefix, "broadcast_address",
4395 "%s", piaddr (broadcast));
4396 }
4397 }
4398 }
4399 }
4400 data_string_forget (&data, MDL);
4401 }
4402
4403 if (lease->filename) {
4404 if (check_option_values(NULL, DHO_ROOT_PATH,
4405 lease->filename,
4406 strlen(lease->filename)) == 0) {
4407 client_envadd(client, prefix, "filename",
4408 "%s", lease->filename);
4409 } else {
4410 log_error("suspect value in %s "
4411 "option - discarded",
4412 lease->filename);
4413 }
4414 }
4415
4416 if (lease->server_name) {
4417 if (check_option_values(NULL, DHO_HOST_NAME,
4418 lease->server_name,
4419 strlen(lease->server_name)) == 0 ) {
4420 client_envadd (client, prefix, "server_name",
4421 "%s", lease->server_name);
4422 } else {
4423 log_error("suspect value in %s "
4424 "option - discarded",
4425 lease->server_name);
4426 }
4427 }
4428
4429 for (i = 0; i < lease -> options -> universe_count; i++) {
4430 option_space_foreach ((struct packet *)0, (struct lease *)0,
4431 client, (struct option_state *)0,
4432 lease -> options, &global_scope,
4433 universes [i],
4434 &es, client_option_envadd);
4435 }
4436
4437 client_envadd (client, prefix, "expiry", "%lu",
4438 (unsigned long)(lease -> expiry));
4439 }
4440
4441 /**
4442 * @brief Write out the environent variable the client requested.
4443 * Write out the environment variables for the objects that the
4444 * client requested. If the object was requested the variable will be:
4445 * requested_<option_name>=1
4446 * If it wasn't requested there won't be a variable.
4447 *
4448 * @param client client structure
4449 */
4450 void script_write_requested(struct client_state *client)
4451 {
4452 int i;
4453 struct option **req;
4454 char name[256];
4455 req = client->config->requested_options;
4456
4457 if (req == NULL)
4458 return;
4459
4460 for (i = 0 ; req[i] != NULL ; i++) {
4461 if ((req[i]->universe == &dhcp_universe) &&
4462 dhcp_option_ev_name(name, sizeof(name), req[i])) {
4463 client_envadd(client, "requested_", name, "%d", 1);
4464 }
4465 }
4466 }
4467
4468 /**
4469 * @brief Calls external script.
4470 *
4471 * External script is specified either using -sf command line or
4472 * script parameter in the configuration file.
4473 *
4474 * @param client specifies client information (environment variables,
4475 * and other parameters will be extracted and passed to the script.
4476 * @return If positive, it contains exit code of the process running script.
4477 * If negative, returns the signal number that cause the script process
4478 * to terminate.
4479 */
4480 int script_go(struct client_state *client)
4481 {
4482 char *scriptName;
4483 char *argv [2];
4484 char **envp;
4485 char reason [] = "REASON=NBI";
4486 static char client_path [] = CLIENT_PATH;
4487 int i;
4488 struct string_list *sp, *next;
4489 int pid, wpid, wstatus;
4490
4491 if (client)
4492 scriptName = client -> config -> script_name;
4493 else
4494 scriptName = top_level_config.script_name;
4495
4496 envp = dmalloc (((client ? client -> envc : 2) +
4497 client_env_count + 2) * sizeof (char *), MDL);
4498 if (!envp) {
4499 log_error ("No memory for client script environment.");
4500 return 0;
4501 }
4502 i = 0;
4503 /* Copy out the environment specified on the command line,
4504 if any. */
4505 for (sp = client_env; sp; sp = sp -> next) {
4506 envp [i++] = sp -> string;
4507 }
4508 /* Copy out the environment specified by dhclient. */
4509 if (client) {
4510 for (sp = client -> env; sp; sp = sp -> next) {
4511 envp [i++] = sp -> string;
4512 }
4513 } else {
4514 envp [i++] = reason;
4515 }
4516 /* Set $PATH. */
4517 envp [i++] = client_path;
4518 envp [i] = (char *)0;
4519
4520 argv [0] = scriptName;
4521 argv [1] = (char *)0;
4522
4523 pid = fork ();
4524 if (pid < 0) {
4525 log_error ("fork: %m");
4526 wstatus = 0;
4527 } else if (pid) {
4528 do {
4529 wpid = wait (&wstatus);
4530 } while (wpid != pid && wpid > 0);
4531 if (wpid < 0) {
4532 log_error ("wait: %m");
4533 wstatus = 0;
4534 }
4535 } else {
4536 /* We don't want to pass an open file descriptor for
4537 * dhclient.leases when executing dhclient-script.
4538 */
4539 if (leaseFile != NULL)
4540 fclose(leaseFile);
4541 execve (scriptName, argv, envp);
4542 log_error ("execve (%s, ...): %m", scriptName);
4543 exit (0);
4544 }
4545
4546 if (client) {
4547 for (sp = client -> env; sp; sp = next) {
4548 next = sp -> next;
4549 dfree (sp, MDL);
4550 }
4551 client -> env = (struct string_list *)0;
4552 client -> envc = 0;
4553 }
4554 dfree (envp, MDL);
4555 gettimeofday(&cur_tv, NULL);
4556 return (WIFEXITED (wstatus) ?
4557 WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
4558 }
4559
4560 void client_envadd (struct client_state *client,
4561 const char *prefix, const char *name, const char *fmt, ...)
4562 {
4563 char spbuf [1024];
4564 char *s;
4565 unsigned len;
4566 struct string_list *val;
4567 va_list list;
4568
4569 va_start (list, fmt);
4570 len = vsnprintf (spbuf, sizeof spbuf, fmt, list);
4571 va_end (list);
4572
4573 val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ +
4574 len + sizeof *val, MDL);
4575 if (!val) {
4576 log_error ("client_envadd: cannot allocate space for variable");
4577 return;
4578 }
4579
4580 s = val -> string;
4581 strcpy (s, prefix);
4582 strcat (s, name);
4583 s += strlen (s);
4584 *s++ = '=';
4585 if (len >= sizeof spbuf) {
4586 va_start (list, fmt);
4587 vsnprintf (s, len + 1, fmt, list);
4588 va_end (list);
4589 } else {
4590 strcpy (s, spbuf);
4591 }
4592
4593 val -> next = client -> env;
4594 client -> env = val;
4595 client -> envc++;
4596 }
4597
4598 int dhcp_option_ev_name (buf, buflen, option)
4599 char *buf;
4600 size_t buflen;
4601 struct option *option;
4602 {
4603 int i, j;
4604 const char *s;
4605
4606 j = 0;
4607 if (option -> universe != &dhcp_universe) {
4608 s = option -> universe -> name;
4609 i = 0;
4610 } else {
4611 s = option -> name;
4612 i = 1;
4613 }
4614
4615 do {
4616 while (*s) {
4617 if (j + 1 == buflen)
4618 return 0;
4619 if (*s == '-')
4620 buf [j++] = '_';
4621 else
4622 buf [j++] = *s;
4623 ++s;
4624 }
4625 if (!i) {
4626 s = option -> name;
4627 if (j + 1 == buflen)
4628 return 0;
4629 buf [j++] = '_';
4630 }
4631 ++i;
4632 } while (i != 2);
4633
4634 buf [j] = 0;
4635 return 1;
4636 }
4637
4638 void finish (char ret)
4639 {
4640 if (no_daemon || dfd[0] == -1 || dfd[1] == -1)
4641 exit((int)ret);
4642 if (write(dfd[1], &ret, 1) != 1)
4643 log_fatal("write to parent: %m");
4644 (void) close(dfd[1]);
4645 dfd[0] = dfd[1] = -1;
4646 exit((int)ret);
4647 }
4648
4649 void detach ()
4650 {
4651 char buf = 0;
4652
4653 /* Don't become a daemon if the user requested otherwise. */
4654 if (no_daemon) {
4655 write_client_pid_file ();
4656 return;
4657 }
4658
4659 /* Only do it once. */
4660 if (dfd[0] == -1 || dfd[1] == -1)
4661 return;
4662
4663 /* Signal parent we started successfully. */
4664 if (write(dfd[1], &buf, 1) != 1)
4665 log_fatal("write to parent: %m");
4666 (void) close(dfd[1]);
4667 dfd[0] = dfd[1] = -1;
4668
4669 /* Stop logging to stderr... */
4670 log_perror = 0;
4671
4672 /* Become session leader and get pid... */
4673 (void) setsid ();
4674
4675 /* Close standard I/O descriptors. */
4676 (void) close(0);
4677 (void) close(1);
4678 (void) close(2);
4679
4680 /* Reopen them on /dev/null. */
4681 (void) open("/dev/null", O_RDWR);
4682 (void) open("/dev/null", O_RDWR);
4683 (void) open("/dev/null", O_RDWR);
4684
4685 write_client_pid_file ();
4686
4687 IGNORE_RET (chdir("/"));
4688
4689 }
4690
4691 void write_client_pid_file ()
4692 {
4693 FILE *pf;
4694 int pfdesc;
4695
4696 /* nothing to do if the user doesn't want a pid file */
4697 if (no_pid_file == ISC_TRUE) {
4698 return;
4699 }
4700
4701 pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
4702
4703 if (pfdesc < 0) {
4704 log_error ("Can't create %s: %m", path_dhclient_pid);
4705 return;
4706 }
4707
4708 pf = fdopen (pfdesc, "w");
4709 if (!pf) {
4710 close(pfdesc);
4711 log_error ("Can't fdopen %s: %m", path_dhclient_pid);
4712 } else {
4713 fprintf (pf, "%ld\n", (long)getpid ());
4714 fclose (pf);
4715 }
4716 }
4717
4718 void client_location_changed ()
4719 {
4720 struct interface_info *ip;
4721 struct client_state *client;
4722
4723 for (ip = interfaces; ip; ip = ip -> next) {
4724 for (client = ip -> client; client; client = client -> next) {
4725 switch (client -> state) {
4726 case S_SELECTING:
4727 cancel_timeout (send_discover, client);
4728 break;
4729
4730 case S_BOUND:
4731 cancel_timeout (state_bound, client);
4732 break;
4733
4734 case S_REBOOTING:
4735 case S_REQUESTING:
4736 case S_RENEWING:
4737 cancel_timeout (send_request, client);
4738 break;
4739
4740 case S_INIT:
4741 case S_REBINDING:
4742 case S_STOPPED:
4743 case S_DECLINING:
4744 case S_V6ONLY:
4745 break;
4746 }
4747 client -> state = S_INIT;
4748 state_reboot (client);
4749 }
4750 }
4751 }
4752
4753 void do_release(client)
4754 struct client_state *client;
4755 {
4756 struct data_string ds;
4757 struct option_cache *oc;
4758
4759 #if defined(DHCPv6) && defined(DHCP4o6)
4760 if (dhcpv4_over_dhcpv6 && (dhcp4o6_state <= 0)) {
4761 if (dhcp4o6_state < 0)
4762 dhcp4o6_poll(NULL);
4763 client->pending = P_RELEASE;
4764 return;
4765 }
4766 #endif
4767
4768 /* Pick a random xid. */
4769 client -> xid = random ();
4770
4771 /* is there even a lease to release? */
4772 if (client -> active) {
4773 /* Make a DHCPRELEASE packet, and set appropriate per-interface
4774 flags. */
4775 make_release (client, client -> active);
4776
4777 memset (&ds, 0, sizeof ds);
4778 oc = lookup_option (&dhcp_universe,
4779 client -> active -> options,
4780 DHO_DHCP_SERVER_IDENTIFIER);
4781 if (oc &&
4782 evaluate_option_cache (&ds, (struct packet *)0,
4783 (struct lease *)0, client,
4784 (struct option_state *)0,
4785 client -> active -> options,
4786 &global_scope, oc, MDL)) {
4787 if (ds.len > 3) {
4788 memcpy (client -> destination.iabuf,
4789 ds.data, 4);
4790 client -> destination.len = 4;
4791 } else
4792 client -> destination = iaddr_broadcast;
4793
4794 data_string_forget (&ds, MDL);
4795 } else
4796 client -> destination = iaddr_broadcast;
4797 client -> first_sending = cur_time;
4798 client -> interval = client -> config -> initial_interval;
4799
4800 /* Zap the medium list... */
4801 client -> medium = (struct string_list *)0;
4802
4803 /* Send out the first and only DHCPRELEASE packet. */
4804 send_release (client);
4805
4806 /* Do the client script RELEASE operation. */
4807 script_init (client,
4808 "RELEASE", (struct string_list *)0);
4809 if (client -> alias)
4810 script_write_params(client, "alias_",
4811 client -> alias);
4812 script_write_params(client, "old_", client -> active);
4813 script_write_requested(client);
4814 script_go(client);
4815 }
4816
4817 /* Cancel any timeouts. */
4818 cancel_timeout (state_bound, client);
4819 cancel_timeout (send_discover, client);
4820 cancel_timeout (state_init, client);
4821 cancel_timeout (send_request, client);
4822 cancel_timeout (state_reboot, client);
4823 cancel_timeout (finish_v6only, client);
4824 client -> state = S_STOPPED;
4825
4826 #if defined(DHCPv6) && defined(DHCP4o6)
4827 if (dhcpv4_over_dhcpv6)
4828 finish(0);
4829 #endif
4830 }
4831
4832 int dhclient_interface_shutdown_hook (struct interface_info *interface)
4833 {
4834 do_release (interface -> client);
4835
4836 return 1;
4837 }
4838
4839 int dhclient_interface_discovery_hook (struct interface_info *tmp)
4840 {
4841 struct interface_info *last, *ip;
4842 /* See if we can find the client from dummy_interfaces */
4843 last = 0;
4844 for (ip = dummy_interfaces; ip; ip = ip -> next) {
4845 if (!strcmp (ip -> name, tmp -> name)) {
4846 /* Remove from dummy_interfaces */
4847 if (last) {
4848 ip = (struct interface_info *)0;
4849 interface_reference (&ip, last -> next, MDL);
4850 interface_dereference (&last -> next, MDL);
4851 if (ip -> next) {
4852 interface_reference (&last -> next,
4853 ip -> next, MDL);
4854 interface_dereference (&ip -> next,
4855 MDL);
4856 }
4857 } else {
4858 ip = (struct interface_info *)0;
4859 interface_reference (&ip,
4860 dummy_interfaces, MDL);
4861 interface_dereference (&dummy_interfaces, MDL);
4862 if (ip -> next) {
4863 interface_reference (&dummy_interfaces,
4864 ip -> next, MDL);
4865 interface_dereference (&ip -> next,
4866 MDL);
4867 }
4868 }
4869 /* Copy "client" to tmp */
4870 if (ip -> client) {
4871 tmp -> client = ip -> client;
4872 tmp -> client -> interface = tmp;
4873 }
4874 interface_dereference (&ip, MDL);
4875 break;
4876 }
4877 last = ip;
4878 }
4879 return 1;
4880 }
4881
4882 isc_result_t dhclient_interface_startup_hook (struct interface_info *interface)
4883 {
4884 struct interface_info *ip;
4885 struct client_state *client;
4886
4887 /* This code needs some rethinking. It doesn't test against
4888 a signal name, and it just kind of bulls into doing something
4889 that may or may not be appropriate. */
4890
4891 if (interfaces) {
4892 interface_reference (&interface -> next, interfaces, MDL);
4893 interface_dereference (&interfaces, MDL);
4894 }
4895 interface_reference (&interfaces, interface, MDL);
4896
4897 discover_interfaces (DISCOVER_UNCONFIGURED);
4898
4899 for (ip = interfaces; ip; ip = ip -> next) {
4900 /* If interfaces were specified, don't configure
4901 interfaces that weren't specified! */
4902 if (ip -> flags & INTERFACE_RUNNING ||
4903 (ip -> flags & (INTERFACE_REQUESTED |
4904 INTERFACE_AUTOMATIC)) !=
4905 INTERFACE_REQUESTED)
4906 continue;
4907 script_init (ip -> client,
4908 "PREINIT", (struct string_list *)0);
4909 if (ip -> client -> alias)
4910 script_write_params(ip -> client, "alias_",
4911 ip -> client -> alias);
4912 script_go(ip -> client);
4913 }
4914
4915 discover_interfaces (interfaces_requested != 0
4916 ? DISCOVER_REQUESTED
4917 : DISCOVER_RUNNING);
4918
4919 for (ip = interfaces; ip; ip = ip -> next) {
4920 if (ip -> flags & INTERFACE_RUNNING)
4921 continue;
4922 ip -> flags |= INTERFACE_RUNNING;
4923 for (client = ip->client ; client ; client = client->next) {
4924 client->state = S_INIT;
4925 state_reboot(client);
4926 }
4927 }
4928 return ISC_R_SUCCESS;
4929 }
4930
4931 /* The client should never receive a relay agent information option,
4932 so if it does, log it and discard it. */
4933
4934 int parse_agent_information_option (packet, len, data)
4935 struct packet *packet;
4936 int len;
4937 u_int8_t *data;
4938 {
4939 return 1;
4940 }
4941
4942 /* The client never sends relay agent information options. */
4943
4944 unsigned cons_agent_information_options (cfg_options, outpacket,
4945 agentix, length)
4946 struct option_state *cfg_options;
4947 struct dhcp_packet *outpacket;
4948 unsigned agentix;
4949 unsigned length;
4950 {
4951 return length;
4952 }
4953
4954 static void shutdown_exit (void *foo)
4955 {
4956 /* get rid of the pid if we can */
4957 if (no_pid_file == ISC_FALSE)
4958 (void) unlink(path_dhclient_pid);
4959 finish(0);
4960 }
4961
4962 #if defined (NSUPDATE)
4963 /*
4964 * If the first query fails, the updater MUST NOT delete the DNS name. It
4965 * may be that the host whose lease on the server has expired has moved
4966 * to another network and obtained a lease from a different server,
4967 * which has caused the client's A RR to be replaced. It may also be
4968 * that some other client has been configured with a name that matches
4969 * the name of the DHCP client, and the policy was that the last client
4970 * to specify the name would get the name. In this case, the DHCID RR
4971 * will no longer match the updater's notion of the client-identity of
4972 * the host pointed to by the DNS name.
4973 * -- "Interaction between DHCP and DNS"
4974 */
4975
4976 /* The first and second stages are pretty similar so we combine them */
4977 void
4978 client_dns_remove_action(dhcp_ddns_cb_t *ddns_cb,
4979 isc_result_t eresult)
4980 {
4981
4982 isc_result_t result;
4983
4984 if ((eresult == ISC_R_SUCCESS) &&
4985 (ddns_cb->state == DDNS_STATE_REM_FW_YXDHCID)) {
4986 /* Do the second stage of the FWD removal */
4987 ddns_cb->state = DDNS_STATE_REM_FW_NXRR;
4988
4989 result = ddns_modify_fwd(ddns_cb, MDL);
4990 if (result == ISC_R_SUCCESS) {
4991 return;
4992 }
4993 }
4994
4995 /* If we are done or have an error clean up */
4996 dhclient_ddns_cb_free(ddns_cb, MDL);
4997 return;
4998 }
4999
5000 void
5001 client_dns_remove(struct client_state *client,
5002 struct iaddr *addr)
5003 {
5004 dhcp_ddns_cb_t *ddns_cb;
5005 isc_result_t result;
5006
5007 /* if we have an old ddns request for this client, cancel it */
5008 if (client->ddns_cb != NULL) {
5009 ddns_cancel(client->ddns_cb, MDL);
5010 client->ddns_cb = NULL;
5011 }
5012
5013 ddns_cb = ddns_cb_alloc(MDL);
5014 if (ddns_cb != NULL) {
5015 ddns_cb->address = *addr;
5016 ddns_cb->timeout = 0;
5017
5018 ddns_cb->state = DDNS_STATE_REM_FW_YXDHCID;
5019 ddns_cb->flags = DDNS_UPDATE_ADDR;
5020 ddns_cb->cur_func = client_dns_remove_action;
5021
5022 result = client_dns_update(client, ddns_cb);
5023
5024 if (result != ISC_R_TIMEDOUT) {
5025 dhclient_ddns_cb_free(ddns_cb, MDL);
5026 }
5027 }
5028 }
5029 #endif /* defined NSUPDATE */
5030
5031
5032 isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
5033 control_object_state_t newstate)
5034 {
5035 struct interface_info *ip;
5036 struct client_state *client;
5037 struct timeval tv;
5038
5039 if (newstate == server_shutdown) {
5040 /* Re-entry */
5041 if (shutdown_signal == SIGUSR1)
5042 return ISC_R_SUCCESS;
5043 /* Log shutdown on signal. */
5044 if ((shutdown_signal == SIGINT) ||
5045 (shutdown_signal == SIGTERM)) {
5046 log_info("Received signal %d, initiating shutdown.",
5047 shutdown_signal);
5048 }
5049 /* Mark it was called. */
5050 shutdown_signal = SIGUSR1;
5051 }
5052
5053 /* Do the right thing for each interface. */
5054 for (ip = interfaces; ip; ip = ip -> next) {
5055 for (client = ip -> client; client; client = client -> next) {
5056 switch (newstate) {
5057 case server_startup:
5058 return ISC_R_SUCCESS;
5059
5060 case server_running:
5061 return ISC_R_SUCCESS;
5062
5063 case server_shutdown:
5064 if (client -> active &&
5065 client -> active -> expiry > cur_time) {
5066 #if defined (NSUPDATE)
5067 if (client->config->do_forward_update) {
5068 client_dns_remove(client,
5069 &client->active->address);
5070 }
5071 #endif /* defined NSUPDATE */
5072
5073 do_release (client);
5074 }
5075 break;
5076
5077 case server_hibernate:
5078 state_stop (client);
5079 break;
5080
5081 case server_awaken:
5082 state_reboot (client);
5083 break;
5084 }
5085 }
5086 }
5087
5088 if (newstate == server_shutdown) {
5089 tv.tv_sec = cur_tv.tv_sec;
5090 tv.tv_usec = cur_tv.tv_usec + 1;
5091 add_timeout(&tv, shutdown_exit, 0, 0, 0);
5092 }
5093 return ISC_R_SUCCESS;
5094 }
5095
5096 #if defined (NSUPDATE)
5097 /*
5098 * Called after a timeout if the DNS update failed on the previous try.
5099 * Starts the retry process. If the retry times out it will schedule
5100 * this routine to run again after a 10x wait.
5101 */
5102 void
5103 client_dns_update_timeout (void *cp)
5104 {
5105 dhcp_ddns_cb_t *ddns_cb = (dhcp_ddns_cb_t *)cp;
5106 struct client_state *client = (struct client_state *)ddns_cb->lease;
5107 isc_result_t status = ISC_R_FAILURE;
5108
5109 if ((client != NULL) &&
5110 ((client->active != NULL) ||
5111 (client->active_lease != NULL)))
5112 status = client_dns_update(client, ddns_cb);
5113
5114 /*
5115 * A status of timedout indicates that we started the update and
5116 * have released control of the control block. Any other status
5117 * indicates that we should clean up the control block. We either
5118 * got a success which indicates that we didn't really need to
5119 * send an update or some other error in which case we weren't able
5120 * to start the update process. In both cases we still own
5121 * the control block and should free it.
5122 */
5123 if (status != ISC_R_TIMEDOUT) {
5124 dhclient_ddns_cb_free(ddns_cb, MDL);
5125 }
5126 }
5127
5128 /*
5129 * If the first query succeeds, the updater can conclude that it
5130 * has added a new name whose only RRs are the A and DHCID RR records.
5131 * The A RR update is now complete (and a client updater is finished,
5132 * while a server might proceed to perform a PTR RR update).
5133 * -- "Interaction between DHCP and DNS"
5134 *
5135 * If the second query succeeds, the updater can conclude that the current
5136 * client was the last client associated with the domain name, and that
5137 * the name now contains the updated A RR. The A RR update is now
5138 * complete (and a client updater is finished, while a server would
5139 * then proceed to perform a PTR RR update).
5140 * -- "Interaction between DHCP and DNS"
5141 *
5142 * If the second query fails with NXRRSET, the updater must conclude
5143 * that the client's desired name is in use by another host. At this
5144 * juncture, the updater can decide (based on some administrative
5145 * configuration outside of the scope of this document) whether to let
5146 * the existing owner of the name keep that name, and to (possibly)
5147 * perform some name disambiguation operation on behalf of the current
5148 * client, or to replace the RRs on the name with RRs that represent
5149 * the current client. If the configured policy allows replacement of
5150 * existing records, the updater submits a query that deletes the
5151 * existing A RR and the existing DHCID RR, adding A and DHCID RRs that
5152 * represent the IP address and client-identity of the new client.
5153 * -- "Interaction between DHCP and DNS"
5154 */
5155
5156 /* The first and second stages are pretty similar so we combine them */
5157 void
5158 client_dns_update_action(dhcp_ddns_cb_t *ddns_cb,
5159 isc_result_t eresult)
5160 {
5161 isc_result_t result;
5162 struct timeval tv;
5163
5164 switch(eresult) {
5165 case ISC_R_SUCCESS:
5166 default:
5167 /* Either we succeeded or broke in a bad way, clean up */
5168 break;
5169
5170 case DNS_R_YXRRSET:
5171 /*
5172 * This is the only difference between the two stages,
5173 * check to see if it is the first stage, in which case
5174 * start the second stage
5175 */
5176 if (ddns_cb->state == DDNS_STATE_ADD_FW_NXDOMAIN) {
5177 ddns_cb->state = DDNS_STATE_ADD_FW_YXDHCID;
5178 ddns_cb->cur_func = client_dns_update_action;
5179
5180 result = ddns_modify_fwd(ddns_cb, MDL);
5181 if (result == ISC_R_SUCCESS) {
5182 return;
5183 }
5184 }
5185 break;
5186
5187 case ISC_R_TIMEDOUT:
5188 /*
5189 * We got a timeout response from the DNS module. Schedule
5190 * another attempt for later. We forget the name, dhcid and
5191 * zone so if it gets changed we will get the new information.
5192 */
5193 data_string_forget(&ddns_cb->fwd_name, MDL);
5194 data_string_forget(&ddns_cb->dhcid, MDL);
5195 if (ddns_cb->zone != NULL) {
5196 forget_zone((struct dns_zone **)&ddns_cb->zone);
5197 }
5198
5199 /* Reset to doing the first stage */
5200 ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN;
5201 ddns_cb->cur_func = client_dns_update_action;
5202
5203 /* and update our timer */
5204 if (ddns_cb->timeout < 3600)
5205 ddns_cb->timeout *= 10;
5206 tv.tv_sec = cur_tv.tv_sec + ddns_cb->timeout;
5207 tv.tv_usec = cur_tv.tv_usec;
5208 add_timeout(&tv, client_dns_update_timeout,
5209 ddns_cb, NULL, NULL);
5210 return;
5211 }
5212
5213 dhclient_ddns_cb_free(ddns_cb, MDL);
5214 return;
5215 }
5216
5217 /* See if we should do a DNS update, and if so, do it. */
5218
5219 isc_result_t
5220 client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb)
5221 {
5222 struct data_string client_identifier;
5223 struct option_cache *oc;
5224 int ignorep;
5225 int result;
5226 int ddns_v4_type;
5227 isc_result_t rcode;
5228
5229 /* If we didn't send an FQDN option, we certainly aren't going to
5230 be doing an update. */
5231 if (!client -> sent_options)
5232 return ISC_R_SUCCESS;
5233
5234 /* If we don't have a lease, we can't do an update. */
5235 if ((client->active == NULL) && (client->active_lease == NULL))
5236 return ISC_R_SUCCESS;
5237
5238 /* If we set the no client update flag, don't do the update. */
5239 if ((oc = lookup_option (&fqdn_universe, client -> sent_options,
5240 FQDN_NO_CLIENT_UPDATE)) &&
5241 evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
5242 (struct lease *)0, client,
5243 client -> sent_options,
5244 (struct option_state *)0,
5245 &global_scope, oc, MDL))
5246 return ISC_R_SUCCESS;
5247
5248 /* If we set the "server, please update" flag, or didn't set it
5249 to false, don't do the update. */
5250 if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
5251 FQDN_SERVER_UPDATE)) ||
5252 evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
5253 (struct lease *)0, client,
5254 client -> sent_options,
5255 (struct option_state *)0,
5256 &global_scope, oc, MDL))
5257 return ISC_R_SUCCESS;
5258
5259 /* If no FQDN option was supplied, don't do the update. */
5260 if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
5261 FQDN_FQDN)) ||
5262 !evaluate_option_cache (&ddns_cb->fwd_name, (struct packet *)0,
5263 (struct lease *)0, client,
5264 client -> sent_options,
5265 (struct option_state *)0,
5266 &global_scope, oc, MDL))
5267 return ISC_R_SUCCESS;
5268
5269 /*
5270 * Construct the DHCID value for use in the DDNS update process
5271 * We have the newer standard version and the older interim version
5272 * chosen by the '-I' option. The interim version is left as is
5273 * for backwards compatibility. The standard version is based on
5274 * RFC 4701 section 3.3
5275 */
5276
5277 result = 0;
5278 POST(result);
5279 memset(&client_identifier, 0, sizeof(client_identifier));
5280
5281 if (std_dhcid == 1) {
5282 /* standard style */
5283 ddns_cb->dhcid_class = dns_rdatatype_dhcid;
5284 ddns_v4_type = 1;
5285 } else {
5286 /* interim style */
5287 ddns_cb->dhcid_class = dns_rdatatype_txt;
5288 /* for backwards compatibility */
5289 ddns_v4_type = DHO_DHCP_CLIENT_IDENTIFIER;
5290 }
5291 if (client->active_lease != NULL) {
5292 /* V6 request, get the client identifier, then
5293 * construct the dhcid for either standard
5294 * or interim */
5295 if (((oc = lookup_option(&dhcpv6_universe,
5296 client->sent_options,
5297 D6O_CLIENTID)) != NULL) &&
5298 evaluate_option_cache(&client_identifier, NULL,
5299 NULL, client,
5300 client->sent_options, NULL,
5301 &global_scope, oc, MDL)) {
5302 result = get_dhcid(ddns_cb, 2,
5303 client_identifier.data,
5304 client_identifier.len);
5305 data_string_forget(&client_identifier, MDL);
5306 } else
5307 log_fatal("Impossible condition at %s:%d.", MDL);
5308 } else {
5309 /*
5310 * V4 request, use the client id if there is one or the
5311 * mac address if there isn't. If we have a client id
5312 * we check to see if it is an embedded DUID.
5313 */
5314 if (((oc = lookup_option(&dhcp_universe,
5315 client->sent_options,
5316 DHO_DHCP_CLIENT_IDENTIFIER)) != NULL) &&
5317 evaluate_option_cache(&client_identifier, NULL,
5318 NULL, client,
5319 client->sent_options, NULL,
5320 &global_scope, oc, MDL)) {
5321 if ((std_dhcid == 1) && (duid_v4 == 1) &&
5322 (client_identifier.data[0] == 255)) {
5323 /*
5324 * This appears to be an embedded DUID,
5325 * extract it and treat it as such
5326 */
5327 if (client_identifier.len <= 5)
5328 log_fatal("Impossible condition at %s:%d.",
5329 MDL);
5330 result = get_dhcid(ddns_cb, 2,
5331 client_identifier.data + 5,
5332 client_identifier.len - 5);
5333 } else {
5334 result = get_dhcid(ddns_cb, ddns_v4_type,
5335 client_identifier.data,
5336 client_identifier.len);
5337 }
5338 data_string_forget(&client_identifier, MDL);
5339 } else
5340 result = get_dhcid(ddns_cb, 0,
5341 client->interface->hw_address.hbuf,
5342 client->interface->hw_address.hlen);
5343 }
5344
5345 if (!result) {
5346 return ISC_R_SUCCESS;
5347 }
5348
5349 /*
5350 * Perform updates.
5351 */
5352 if (ddns_cb->fwd_name.len && ddns_cb->dhcid.len) {
5353 rcode = ddns_modify_fwd(ddns_cb, MDL);
5354 } else
5355 rcode = ISC_R_FAILURE;
5356
5357 /*
5358 * A success from the modify routine means we are performing
5359 * async processing, for which we use the timedout error message.
5360 */
5361 if (rcode == ISC_R_SUCCESS) {
5362 rcode = ISC_R_TIMEDOUT;
5363 }
5364
5365 return rcode;
5366 }
5367
5368
5369 /*
5370 * Schedule the first update. They will continue to retry occasionally
5371 * until they no longer time out (or fail).
5372 */
5373 void
5374 dhclient_schedule_updates(struct client_state *client,
5375 struct iaddr *addr,
5376 int offset)
5377 {
5378 dhcp_ddns_cb_t *ddns_cb;
5379 struct timeval tv;
5380
5381 if (!client->config->do_forward_update)
5382 return;
5383
5384 /* cancel any outstanding ddns requests */
5385 if (client->ddns_cb != NULL) {
5386 ddns_cancel(client->ddns_cb, MDL);
5387 client->ddns_cb = NULL;
5388 }
5389
5390 ddns_cb = ddns_cb_alloc(MDL);
5391
5392 if (ddns_cb != NULL) {
5393 ddns_cb->lease = (void *)client;
5394 ddns_cb->address = *addr;
5395 ddns_cb->timeout = 1;
5396
5397 /*
5398 * XXX: DNS TTL is a problem we need to solve properly.
5399 * Until that time, 300 is a placeholder default for
5400 * something that is less insane than a value scaled
5401 * by lease timeout.
5402 */
5403 ddns_cb->ttl = 300;
5404
5405 ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN;
5406 ddns_cb->cur_func = client_dns_update_action;
5407 ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_INCLUDE_RRSET;
5408
5409 client->ddns_cb = ddns_cb;
5410 tv.tv_sec = cur_tv.tv_sec + offset;
5411 tv.tv_usec = cur_tv.tv_usec;
5412 add_timeout(&tv, client_dns_update_timeout,
5413 ddns_cb, NULL, NULL);
5414 } else {
5415 log_error("Unable to allocate dns update state for %s",
5416 piaddr(*addr));
5417 }
5418 }
5419 #endif /* defined NSUPDATE */
5420
5421 void
5422 dhcpv4_client_assignments(void)
5423 {
5424 struct servent *ent;
5425
5426 if (path_dhclient_pid == NULL)
5427 path_dhclient_pid = _PATH_DHCLIENT_PID;
5428 if (path_dhclient_db == NULL)
5429 path_dhclient_db = _PATH_DHCLIENT_DB;
5430
5431 /* Default to the DHCP/BOOTP port. */
5432 if (!local_port) {
5433 /* If we're faking a relay agent, and we're not using loopback,
5434 use the server port, not the client port. */
5435 if (mockup_relay && giaddr.s_addr != htonl(INADDR_LOOPBACK)) {
5436 local_port = htons(67);
5437 } else {
5438 ent = getservbyname("dhcpc", "udp");
5439 if (ent == NULL)
5440 ent = getservbyname("bootpc", "udp");
5441 if (ent == NULL)
5442 local_port = htons(68);
5443 else
5444 local_port = ent->s_port;
5445 #ifndef __CYGWIN32__
5446 endservent ();
5447 #endif
5448 }
5449 }
5450
5451 /* If we're faking a relay agent, and we're not using loopback,
5452 we're using the server port, not the client port. */
5453 if (mockup_relay && giaddr.s_addr != htonl(INADDR_LOOPBACK)) {
5454 remote_port = local_port;
5455 } else
5456 remote_port = htons(ntohs(local_port) - 1); /* XXX */
5457 }
5458
5459 /*
5460 * The following routines are used to check that certain
5461 * strings are reasonable before we pass them to the scripts.
5462 * This avoids some problems with scripts treating the strings
5463 * as commands - see ticket 23722
5464 * The domain checking code should be done as part of assembling
5465 * the string but we are doing it here for now due to time
5466 * constraints.
5467 */
5468
5469 static int check_domain_name(const char *ptr, size_t len, int dots)
5470 {
5471 const char *p;
5472
5473 /* not empty or complete length not over 255 characters */
5474 if ((len == 0) || (len > 256))
5475 return(-1);
5476
5477 /* consists of [[:alnum:]-]+ labels separated by [.] */
5478 /* a [_] is against RFC but seems to be "widely used"... */
5479 for (p=ptr; (*p != 0) && (len-- > 0); p++) {
5480 if ((*p == '-') || (*p == '_')) {
5481 /* not allowed at begin or end of a label */
5482 if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
5483 return(-1);
5484 } else if (*p == '.') {
5485 /* each label has to be 1-63 characters;
5486 we allow [.] at the end ('foo.bar.') */
5487 size_t d = p - ptr;
5488 if ((d <= 0) || (d >= 64))
5489 return(-1);
5490 ptr = p + 1; /* jump to the next label */
5491 if ((dots > 0) && (len > 0))
5492 dots--;
5493 } else if (isalnum((unsigned char)*p) == 0) {
5494 /* also numbers at the begin are fine */
5495 return(-1);
5496 }
5497 }
5498 return(dots ? -1 : 0);
5499 }
5500
5501 static int check_domain_name_list(const char *ptr, size_t len, int dots)
5502 {
5503 const char *p;
5504 int ret = -1; /* at least one needed */
5505
5506 if ((ptr == NULL) || (len == 0))
5507 return(-1);
5508
5509 for (p=ptr; (*p != 0) && (len > 0); p++, len--) {
5510 if (*p != ' ')
5511 continue;
5512 if (p > ptr) {
5513 if (check_domain_name(ptr, p - ptr, dots) != 0)
5514 return(-1);
5515 ret = 0;
5516 }
5517 ptr = p + 1;
5518 }
5519 if (p > ptr)
5520 return(check_domain_name(ptr, p - ptr, dots));
5521 else
5522 return(ret);
5523 }
5524
5525 static int check_option_values(struct universe *universe,
5526 unsigned int opt,
5527 const char *ptr,
5528 size_t len)
5529 {
5530 if (ptr == NULL)
5531 return(-1);
5532
5533 /* just reject options we want to protect, will be escaped anyway */
5534 if ((universe == NULL) || (universe == &dhcp_universe)) {
5535 switch(opt) {
5536 case DHO_DOMAIN_NAME:
5537 #ifdef ACCEPT_LIST_IN_DOMAIN_NAME
5538 return check_domain_name_list(ptr, len, 0);
5539 #else
5540 return check_domain_name(ptr, len, 0);
5541 #endif
5542 case DHO_HOST_NAME:
5543 case DHO_NIS_DOMAIN:
5544 case DHO_NETBIOS_SCOPE:
5545 return check_domain_name(ptr, len, 0);
5546 break;
5547 case DHO_DOMAIN_SEARCH:
5548 return check_domain_name_list(ptr, len, 0);
5549 break;
5550 case DHO_ROOT_PATH:
5551 if (len == 0)
5552 return(-1);
5553 for (; (*ptr != 0) && (len-- > 0); ptr++) {
5554 if(!(isalnum((unsigned char)*ptr) ||
5555 *ptr == '#' || *ptr == '%' ||
5556 *ptr == '+' || *ptr == '-' ||
5557 *ptr == '_' || *ptr == ':' ||
5558 *ptr == '.' || *ptr == ',' ||
5559 *ptr == '@' || *ptr == '~' ||
5560 *ptr == '\\' || *ptr == '/' ||
5561 *ptr == '[' || *ptr == ']' ||
5562 *ptr == '=' || *ptr == ' '))
5563 return(-1);
5564 }
5565 return(0);
5566 break;
5567 }
5568 }
5569
5570 #ifdef DHCPv6
5571 if (universe == &dhcpv6_universe) {
5572 switch(opt) {
5573 case D6O_SIP_SERVERS_DNS:
5574 case D6O_DOMAIN_SEARCH:
5575 case D6O_NIS_DOMAIN_NAME:
5576 case D6O_NISP_DOMAIN_NAME:
5577 return check_domain_name_list(ptr, len, 0);
5578 break;
5579 }
5580 }
5581 #endif
5582
5583 return(0);
5584 }
5585
5586 static void
5587 add_reject(struct packet *packet) {
5588 struct iaddrmatchlist *list;
5589
5590 list = dmalloc(sizeof(struct iaddrmatchlist), MDL);
5591 if (!list)
5592 log_fatal ("no memory for reject list!");
5593
5594 /*
5595 * client_addr is misleading - it is set to source address in common
5596 * code.
5597 */
5598 list->match.addr = packet->client_addr;
5599 /* Set mask to indicate host address. */
5600 list->match.mask.len = list->match.addr.len;
5601 memset(list->match.mask.iabuf, 0xff, sizeof(list->match.mask.iabuf));
5602
5603 /* Append to reject list for the source interface. */
5604 list->next = packet->interface->client->config->reject_list;
5605 packet->interface->client->config->reject_list = list;
5606
5607 /*
5608 * We should inform user that we won't be accepting this server
5609 * anymore.
5610 */
5611 log_info("Server added to list of rejected servers.");
5612 }
5613
5614 #if defined(NSUPDATE)
5615 /* Wrapper function around common ddns_cb_free function that ensures
5616 * we set the client_state pointer to the control block to NULL. */
5617 static void
5618 dhclient_ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, char* file, int line) {
5619 if (ddns_cb) {
5620 struct client_state *client = (struct client_state *)ddns_cb->lease;
5621 if (client != NULL) {
5622 client->ddns_cb = NULL;
5623 }
5624
5625 ddns_cb_free(ddns_cb, file, line);
5626 }
5627 }
5628 #endif /* defined NSUPDATE */
5629
5630 #if defined(DHCPv6) && defined(DHCP4o6)
5631 /*
5632 * \brief Omapi I/O handler
5633 *
5634 * The inter-process communication receive handler.
5635 *
5636 * On the DHCPv6 side, the message is either a POLL (which is answered
5637 * by a START or a STOP) or a DHCPv4-QUERY (which is forwarded to
5638 * DHCPv4 over DHCPv6 servers by forw_dhcpv4_query()).
5639 *
5640 * On the DHCPv4 side, the message is either a START, a STOP
5641 * (both for the DHCP4 over DHCPv6 state machine) or a DHCPv4-RESPONSE
5642 * (which is processed by recv_dhcpv4_response()).
5643 *
5644 * \param h the OMAPI object
5645 * \return a result for I/O success or error (used by the I/O subsystem)
5646 */
5647 isc_result_t dhcpv4o6_handler(omapi_object_t *h) {
5648 char buf[65536];
5649 char start_msg[5] = { 'S', 'T', 'A', 'R', 'T' };
5650 char stop_msg[4] = { 'S', 'T', 'O', 'P' };
5651 char poll_msg[4] = { 'P', 'O', 'L', 'L' };
5652 struct data_string raw;
5653 int cc;
5654
5655 if (h->type != dhcp4o6_type)
5656 return DHCP_R_INVALIDARG;
5657
5658 cc = recv(dhcp4o6_fd, buf, sizeof(buf), 0);
5659 if (cc <= 0)
5660 return ISC_R_UNEXPECTED;
5661
5662 if (local_family == AF_INET6) {
5663 if ((cc == 4) &&
5664 (memcmp(buf, poll_msg, sizeof(poll_msg)) == 0)) {
5665 log_info("RCV: POLL");
5666 if (dhcp4o6_state < 0)
5667 cc = send(dhcp4o6_fd, stop_msg,
5668 sizeof(stop_msg), 0);
5669 else
5670 cc = send(dhcp4o6_fd, start_msg,
5671 sizeof(start_msg), 0);
5672 if (cc < 0) {
5673 log_error("dhcpv4o6_handler: send(): %m");
5674 return ISC_R_IOERROR;
5675 }
5676 } else {
5677 if (cc < DHCP_FIXED_NON_UDP + 8)
5678 return ISC_R_UNEXPECTED;
5679 memset(&raw, 0, sizeof(raw));
5680 if (!buffer_allocate(&raw.buffer, cc, MDL)) {
5681 log_error("dhcpv4o6_handler: "
5682 "no memory buffer.");
5683 return ISC_R_NOMEMORY;
5684 }
5685 raw.data = raw.buffer->data;
5686 raw.len = cc;
5687 memcpy(raw.buffer->data, buf, cc);
5688
5689 forw_dhcpv4_query(&raw);
5690
5691 data_string_forget(&raw, MDL);
5692 }
5693 } else {
5694 if ((cc == 4) &&
5695 (memcmp(buf, stop_msg, sizeof(stop_msg)) == 0)) {
5696 log_info("RCV: STOP");
5697 if (dhcp4o6_state > 0) {
5698 dhcp4o6_state = 0;
5699 dhcp4o6_poll(NULL);
5700 }
5701 } else if ((cc == 5) &&
5702 (memcmp(buf, start_msg, sizeof(start_msg)) == 0)) {
5703 log_info("RCV: START");
5704 if (dhcp4o6_state == 0)
5705 cancel_timeout(dhcp4o6_poll, NULL);
5706 dhcp4o6_state = 1;
5707 dhcp4o6_resume();
5708 } else {
5709 if (cc < DHCP_FIXED_NON_UDP + 16)
5710 return ISC_R_UNEXPECTED;
5711 memset(&raw, 0, sizeof(raw));
5712 if (!buffer_allocate(&raw.buffer, cc, MDL)) {
5713 log_error("dhcpv4o6_handler: "
5714 "no memory buffer.");
5715 return ISC_R_NOMEMORY;
5716 }
5717 raw.data = raw.buffer->data;
5718 raw.len = cc;
5719 memcpy(raw.buffer->data, buf, cc);
5720
5721 recv_dhcpv4_response(&raw);
5722
5723 data_string_forget(&raw, MDL);
5724 }
5725 }
5726
5727 return ISC_R_SUCCESS;
5728 }
5729
5730 /*
5731 * \brief Poll the DHCPv6 client
5732 * (DHCPv4 client function)
5733 *
5734 * A POLL message is sent to the DHCPv6 client periodically to check
5735 * if the DHCPv6 is ready (i.e., has a valid DHCPv4-over-DHCPv6 server
5736 * address option).
5737 */
5738 static void dhcp4o6_poll(void *dummy) {
5739 char msg[4] = { 'P', 'O', 'L', 'L' };
5740 struct timeval tv;
5741 int cc;
5742
5743 IGNORE_UNUSED(dummy);
5744
5745 if (dhcp4o6_state < 0)
5746 dhcp4o6_state = 0;
5747
5748 log_info("POLL");
5749
5750 cc = send(dhcp4o6_fd, msg, sizeof(msg), 0);
5751 if (cc < 0)
5752 log_error("dhcp4o6_poll: send(): %m");
5753
5754 tv.tv_sec = cur_time + 60;
5755 tv.tv_usec = random() % 1000000;
5756
5757 add_timeout(&tv, dhcp4o6_poll, NULL, 0, 0);
5758 }
5759
5760 /*
5761 * \brief Resume pending operations
5762 * (DHCPv4 client function)
5763 *
5764 * A START message was received from the DHCPv6 client so pending
5765 * operations (RELEASE or REBOOT) must be resumed.
5766 */
5767 static void dhcp4o6_resume() {
5768 struct interface_info *ip;
5769 struct client_state *client;
5770
5771 for (ip = interfaces; ip != NULL; ip = ip->next) {
5772 for (client = ip->client; client != NULL;
5773 client = client->next) {
5774 if (client->pending == P_RELEASE)
5775 do_release(client);
5776 else if (client->pending == P_REBOOT)
5777 state_reboot(client);
5778 }
5779 }
5780 }
5781
5782 /*
5783 * \brief Send a START to the DHCPv4 client
5784 * (DHCPv6 client function)
5785 *
5786 * First check if there is a valid DHCPv4-over-DHCPv6 server address option,
5787 * and when found go UP and on a transition from another state send
5788 * a START message to the DHCPv4 client.
5789 */
5790 void dhcp4o6_start() {
5791 struct interface_info *ip;
5792 struct client_state *client;
5793 struct dhc6_lease *lease;
5794 struct option_cache *oc;
5795 struct data_string addrs;
5796 char msg[5] = { 'S', 'T', 'A', 'R', 'T' };
5797 int cc;
5798
5799 memset(&addrs, 0, sizeof(addrs));
5800 for (ip = interfaces; ip != NULL; ip = ip->next) {
5801 for (client = ip->client; client != NULL;
5802 client = client->next) {
5803 if ((client->state != S_BOUND) &&
5804 (client->state != S_RENEWING) &&
5805 (client->state != S_REBINDING))
5806 continue;
5807 lease = client->active_lease;
5808 if ((lease == NULL) || lease->released)
5809 continue;
5810 oc = lookup_option(&dhcpv6_universe,
5811 lease->options,
5812 D6O_DHCP4_O_DHCP6_SERVER);
5813 if ((oc == NULL) ||
5814 !evaluate_option_cache(&addrs, NULL, NULL, NULL,
5815 lease->options, NULL,
5816 &global_scope, oc, MDL))
5817 continue;
5818 if ((addrs.len % 16) != 0) {
5819 data_string_forget(&addrs, MDL);
5820 continue;
5821 }
5822 data_string_forget(&addrs, MDL);
5823 goto found;
5824 }
5825 }
5826 log_info("dhcp4o6_start: failed");
5827 dhcp4o6_stop();
5828 return;
5829
5830 found:
5831 if (dhcp4o6_state == 1)
5832 return;
5833 log_info("dhcp4o6_start: go to UP");
5834 dhcp4o6_state = 1;
5835
5836 cc = send(dhcp4o6_fd, msg, sizeof(msg), 0);
5837 if (cc < 0)
5838 log_info("dhcp4o6_start: send(): %m");
5839 }
5840
5841 /*
5842 * Send a STOP to the DHCPv4 client
5843 * (DHCPv6 client function)
5844 *
5845 * Go DOWN and on a transition from another state send a STOP message
5846 * to the DHCPv4 client.
5847 */
5848 static void dhcp4o6_stop() {
5849 char msg[4] = { 'S', 'T', 'O', 'P' };
5850 int cc;
5851
5852 if (dhcp4o6_state == -1)
5853 return;
5854
5855 log_info("dhcp4o6_stop: go to DOWN");
5856 dhcp4o6_state = -1;
5857
5858 cc = send(dhcp4o6_fd, msg, sizeof(msg), 0);
5859 if (cc < 0)
5860 log_error("dhcp4o6_stop: send(): %m");
5861 }
5862 #endif /* DHCPv6 && DHCP4o6 */