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