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