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