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