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