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