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