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