6 * Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
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.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
25 * https://www.isc.org/
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.
41 #include <dns/result.h>
43 TIME default_lease_time
= 43200; /* 12 hours... */
44 TIME max_lease_time
= 86400; /* 24 hours... */
46 const char *path_dhclient_conf
= _PATH_DHCLIENT_CONF
;
47 const char *path_dhclient_db
= NULL
;
48 const char *path_dhclient_pid
= NULL
;
49 static char path_dhclient_script_array
[] = _PATH_DHCLIENT_SCRIPT
;
50 char *path_dhclient_script
= path_dhclient_script_array
;
51 const char *path_dhclient_duid
= NULL
;
53 /* False (default) => we write and use a pid file */
54 isc_boolean_t no_pid_file
= ISC_FALSE
;
56 int dhcp_max_agent_option_packet_length
= 0;
58 int interfaces_requested
= 0;
60 struct iaddr iaddr_broadcast
= { 4, { 255, 255, 255, 255 } };
61 struct iaddr iaddr_any
= { 4, { 0, 0, 0, 0 } };
62 struct in_addr inaddr_any
;
63 struct sockaddr_in sockaddr_broadcast
;
64 struct in_addr giaddr
;
65 struct data_string default_duid
;
70 /* ASSERT_STATE() does nothing now; it used to be
71 assert (state_is == state_shouldbe). */
72 #define ASSERT_STATE(state_is, state_shouldbe) {}
75 static const char copyright
[] = "Copyright 2004-2015 Internet Systems Consortium.";
76 static const char arr
[] = "All rights reserved.";
77 static const char message
[] = "Internet Systems Consortium DHCP Client";
78 static const char url
[] = "For info, please visit https://www.isc.org/software/dhcp/";
79 #endif /* UNIT_TEST */
81 u_int16_t local_port
= 0;
82 u_int16_t remote_port
= 0;
83 #if defined(DHCPv6) && defined(DHCP4o6)
84 int dhcp4o6_state
= -1; /* -1 = stopped, 0 = polling, 1 = started */
87 struct string_list
*client_env
= NULL
;
88 int client_env_count
= 0;
93 int wanted_ia_na
= -1; /* the absolute value is the real one. */
96 int require_all_ias
= 0; /* If the user requires all of the IAs to
97 be available before accepting a lease
98 0 = no, 1 = requries */
99 char *mockup_relay
= NULL
;
101 char *progname
= NULL
;
103 void run_stateless(int exit_mode
, u_int16_t port
);
105 static isc_result_t
write_duid(struct data_string
*duid
);
106 static void add_reject(struct packet
*packet
);
108 static int check_domain_name(const char *ptr
, size_t len
, int dots
);
109 static int check_domain_name_list(const char *ptr
, size_t len
, int dots
);
110 static int check_option_values(struct universe
*universe
, unsigned int opt
,
111 const char *ptr
, size_t len
);
113 static void dhclient_ddns_cb_free(dhcp_ddns_cb_t
*ddns_cb
,
114 char* file
, int line
);
118 * \brief Print the generic usage message
120 * If the user has provided an incorrect command line print out
121 * the description of the command line. The arguments provide
122 * a way for the caller to request more specific information about
123 * the error be printed as well. Mostly this will be that some
124 * comamnd doesn't include its argument.
126 * \param sfmt - The basic string and format for the specific error
127 * \param sarg - Generally the offending argument from the comamnd line.
132 #if defined(DHCPv6) && defined(DHCP4o6)
133 static void dhcp4o6_poll(void *dummy
);
134 static void dhcp4o6_resume(void);
135 static void recv_dhcpv4_response(struct data_string
*raw
);
136 static int send_dhcpv4_query(struct client_state
*client
, int broadcast
);
138 static void dhcp4o6_stop(void);
139 static void forw_dhcpv4_response(struct packet
*packet
);
140 static void forw_dhcpv4_query(struct data_string
*raw
);
144 /* These are only used when we call usage() from the main routine
145 * which isn't compiled when building for unit tests
147 static const char use_noarg
[] = "No argument for command: %s";
149 static const char use_v6command
[] = "Command not used for DHCPv4: %s";
153 usage(const char *sfmt
, const char *sarg
)
155 log_info("%s %s", message
, PACKAGE_VERSION
);
160 /* If desired print out the specific error message */
161 #ifdef PRINT_SPECIFIC_CL_ERRORS
163 log_error(sfmt
, sarg
);
166 log_fatal("Usage: %s "
169 "[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>]\n"
170 " [-p <port>] [-D LL|LLT] \n"
172 "[-4|-6] [-SNTPRI1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n"
175 "[-I1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n"
177 " [-s server-addr] [-cf config-file]\n"
178 " [-df duid-file] [-lf lease-file]\n"
179 " [-pf pid-file] [--no-pid] [-e VAR=val]\n"
180 " [-sf script-file] [interface]*",
181 isc_file_basename(progname
));
185 main(int argc
, char **argv
) {
188 struct interface_info
*ip
;
189 struct client_state
*client
;
194 int release_mode
= 0;
196 omapi_object_t
*listener
;
199 int no_dhclient_conf
= 0;
200 int no_dhclient_db
= 0;
201 int no_dhclient_pid
= 0;
202 int no_dhclient_script
= 0;
204 int local_family_set
= 0;
206 u_int16_t dhcp4o6_port
= 0;
212 progname
= "dhclient";
217 /* Initialize client globals. */
218 memset(&default_duid
, 0, sizeof(default_duid
));
220 /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
221 2 (stderr) are open. To do this, we assume that when we
222 open a file the lowest available file descriptor is used. */
223 fd
= open("/dev/null", O_RDWR
);
225 fd
= open("/dev/null", O_RDWR
);
227 fd
= open("/dev/null", O_RDWR
);
229 log_perror
= 0; /* No sense logging to /dev/null. */
233 openlog(isc_file_basename(progname
), DHCP_LOG_OPTIONS
, LOG_DAEMON
);
235 #if !(defined(DEBUG) || defined(__CYGWIN32__))
236 setlogmask(LOG_UPTO(LOG_INFO
));
239 /* Set up the isc and dns library managers */
240 status
= dhcp_context_create(DHCP_CONTEXT_PRE_DB
| DHCP_CONTEXT_POST_DB
,
242 if (status
!= ISC_R_SUCCESS
)
243 log_fatal("Can't initialize context: %s",
244 isc_result_totext(status
));
246 /* Set up the OMAPI. */
247 status
= omapi_init();
248 if (status
!= ISC_R_SUCCESS
)
249 log_fatal("Can't initialize OMAPI: %s",
250 isc_result_totext(status
));
252 /* Set up the OMAPI wrappers for various server database internal
254 dhcp_common_objects_setup();
256 dhcp_interface_discovery_hook
= dhclient_interface_discovery_hook
;
257 dhcp_interface_shutdown_hook
= dhclient_interface_shutdown_hook
;
258 dhcp_interface_startup_hook
= dhclient_interface_startup_hook
;
260 for (i
= 1; i
< argc
; i
++) {
261 if (!strcmp(argv
[i
], "-r")) {
265 } else if (!strcmp(argv
[i
], "-4")) {
266 if (local_family_set
&& local_family
!= AF_INET
)
267 log_fatal("Client can only do v4 or v6, not "
269 local_family_set
= 1;
270 local_family
= AF_INET
;
271 } else if (!strcmp(argv
[i
], "-6")) {
272 if (local_family_set
&& local_family
!= AF_INET6
)
273 log_fatal("Client can only do v4 or v6, not "
275 local_family_set
= 1;
276 local_family
= AF_INET6
;
278 } else if (!strcmp(argv
[i
], "-4o6")) {
280 usage(use_noarg
, argv
[i
-1]);
281 dhcp4o6_port
= validate_port_pair(argv
[i
]);
283 log_debug("DHCPv4 over DHCPv6 over ::1 port %d and %d",
285 ntohs(dhcp4o6_port
) + 1);
286 dhcpv4_over_dhcpv6
= 1;
289 } else if (!strcmp(argv
[i
], "-x")) { /* eXit, no release */
293 } else if (!strcmp(argv
[i
], "-p")) {
295 usage(use_noarg
, argv
[i
-1]);
296 local_port
= validate_port(argv
[i
]);
297 log_debug("binding to user-specified port %d",
299 } else if (!strcmp(argv
[i
], "-d")) {
302 } else if (!strcmp(argv
[i
], "-pf")) {
304 usage(use_noarg
, argv
[i
-1]);
305 path_dhclient_pid
= argv
[i
];
307 } else if (!strcmp(argv
[i
], "--no-pid")) {
308 no_pid_file
= ISC_TRUE
;
309 } else if (!strcmp(argv
[i
], "-cf")) {
311 usage(use_noarg
, argv
[i
-1]);
312 path_dhclient_conf
= argv
[i
];
313 no_dhclient_conf
= 1;
314 } else if (!strcmp(argv
[i
], "-df")) {
316 usage(use_noarg
, argv
[i
-1]);
317 path_dhclient_duid
= argv
[i
];
318 } else if (!strcmp(argv
[i
], "-lf")) {
320 usage(use_noarg
, argv
[i
-1]);
321 path_dhclient_db
= argv
[i
];
323 } else if (!strcmp(argv
[i
], "-sf")) {
325 usage(use_noarg
, argv
[i
-1]);
326 path_dhclient_script
= argv
[i
];
327 no_dhclient_script
= 1;
328 } else if (!strcmp(argv
[i
], "-1")) {
330 } else if (!strcmp(argv
[i
], "-q")) {
332 } else if (!strcmp(argv
[i
], "-s")) {
334 usage(use_noarg
, argv
[i
-1]);
336 } else if (!strcmp(argv
[i
], "-g")) {
338 usage(use_noarg
, argv
[i
-1]);
339 mockup_relay
= argv
[i
];
340 } else if (!strcmp(argv
[i
], "-nw")) {
342 } else if (!strcmp(argv
[i
], "-n")) {
343 /* do not start up any interfaces */
344 interfaces_requested
= -1;
345 } else if (!strcmp(argv
[i
], "-w")) {
346 /* do not exit if there are no broadcast interfaces. */
348 } else if (!strcmp(argv
[i
], "-e")) {
349 struct string_list
*tmp
;
351 usage(use_noarg
, argv
[i
-1]);
352 tmp
= dmalloc(strlen(argv
[i
]) + sizeof *tmp
, MDL
);
354 log_fatal("No memory for %s", argv
[i
]);
355 strcpy(tmp
->string
, argv
[i
]);
356 tmp
->next
= client_env
;
360 } else if (!strcmp(argv
[i
], "-S")) {
361 if (local_family_set
&& (local_family
== AF_INET
)) {
362 usage(use_v6command
, argv
[i
]);
364 local_family_set
= 1;
365 local_family
= AF_INET6
;
368 } else if (!strcmp(argv
[i
], "-N")) {
369 if (local_family_set
&& (local_family
== AF_INET
)) {
370 usage(use_v6command
, argv
[i
]);
372 local_family_set
= 1;
373 local_family
= AF_INET6
;
374 if (wanted_ia_na
< 0) {
378 } else if (!strcmp(argv
[i
], "-T")) {
379 if (local_family_set
&& (local_family
== AF_INET
)) {
380 usage(use_v6command
, argv
[i
]);
382 local_family_set
= 1;
383 local_family
= AF_INET6
;
384 if (wanted_ia_na
< 0) {
388 } else if (!strcmp(argv
[i
], "-P")) {
389 if (local_family_set
&& (local_family
== AF_INET
)) {
390 usage(use_v6command
, argv
[i
]);
392 local_family_set
= 1;
393 local_family
= AF_INET6
;
394 if (wanted_ia_na
< 0) {
398 } else if (!strcmp(argv
[i
], "-R")) {
399 if (local_family_set
&& (local_family
== AF_INET
)) {
400 usage(use_v6command
, argv
[i
]);
402 local_family_set
= 1;
403 local_family
= AF_INET6
;
406 } else if (!strcmp(argv
[i
], "-D")) {
409 usage(use_noarg
, argv
[i
-1]);
410 if (!strcasecmp(argv
[i
], "LL")) {
412 } else if (!strcasecmp(argv
[i
], "LLT")) {
413 duid_type
= DUID_LLT
;
415 usage("Unknown argument to -D: %s", argv
[i
]);
417 } else if (!strcmp(argv
[i
], "-i")) {
418 /* enable DUID support for DHCPv4 clients */
420 } else if (!strcmp(argv
[i
], "-I")) {
421 /* enable standard DHCID support for DDNS updates */
423 } else if (!strcmp(argv
[i
], "-v")) {
425 } else if (!strcmp(argv
[i
], "--version")) {
426 const char vstring
[] = "isc-dhclient-";
427 IGNORE_RET(write(STDERR_FILENO
, vstring
,
429 IGNORE_RET(write(STDERR_FILENO
,
431 strlen(PACKAGE_VERSION
)));
432 IGNORE_RET(write(STDERR_FILENO
, "\n", 1));
434 } else if (argv
[i
][0] == '-') {
435 usage("Unknown command: %s", argv
[i
]);
436 } else if (interfaces_requested
< 0) {
437 usage("No interfaces comamnd -n and "
438 " requested interface %s", argv
[i
]);
440 struct interface_info
*tmp
= NULL
;
442 status
= interface_allocate(&tmp
, MDL
);
443 if (status
!= ISC_R_SUCCESS
)
444 log_fatal("Can't record interface %s:%s",
445 argv
[i
], isc_result_totext(status
));
446 if (strlen(argv
[i
]) >= sizeof(tmp
->name
))
447 log_fatal("%s: interface name too long (is %ld)",
448 argv
[i
], (long)strlen(argv
[i
]));
449 strcpy(tmp
->name
, argv
[i
]);
451 interface_reference(&tmp
->next
,
453 interface_dereference(&interfaces
, MDL
);
455 interface_reference(&interfaces
, tmp
, MDL
);
456 tmp
->flags
= INTERFACE_REQUESTED
;
457 interfaces_requested
++;
461 if (wanted_ia_na
< 0) {
465 /* Support only one (requested) interface for Prefix Delegation. */
466 if (wanted_ia_pd
&& (interfaces_requested
!= 1)) {
467 usage("PD %s only supports one requested interface", "-P");
470 #if defined(DHCPv6) && defined(DHCP4o6)
471 if ((local_family
== AF_INET6
) && dhcpv4_over_dhcpv6
&&
472 (exit_mode
|| release_mode
))
473 log_error("Can't relay DHCPv4-over-DHCPv6 "
474 "without a persistent DHCPv6 client");
475 if ((local_family
== AF_INET
) && dhcpv4_over_dhcpv6
&&
476 (interfaces_requested
!= 1))
477 log_fatal("DHCPv4-over-DHCPv6 requires an explicit "
478 "interface on which to be applied");
481 if (!no_dhclient_conf
&& (s
= getenv("PATH_DHCLIENT_CONF"))) {
482 path_dhclient_conf
= s
;
484 if (!no_dhclient_db
&& (s
= getenv("PATH_DHCLIENT_DB"))) {
485 path_dhclient_db
= s
;
487 if (!no_dhclient_pid
&& (s
= getenv("PATH_DHCLIENT_PID"))) {
488 path_dhclient_pid
= s
;
490 if (!no_dhclient_script
&& (s
= getenv("PATH_DHCLIENT_SCRIPT"))) {
491 path_dhclient_script
= s
;
494 /* Set up the initial dhcp option universe. */
495 initialize_common_option_spaces();
497 /* Assign v4 or v6 specific running parameters. */
498 if (local_family
== AF_INET
)
499 dhcpv4_client_assignments();
501 else if (local_family
== AF_INET6
)
502 dhcpv6_client_assignments();
505 log_fatal("Impossible condition at %s:%d.", MDL
);
508 * convert relative path names to absolute, for files that need
509 * to be reopened after chdir() has been called
511 if (path_dhclient_db
[0] != '/') {
512 const char *old_path
= path_dhclient_db
;
513 path_dhclient_db
= realpath(path_dhclient_db
, NULL
);
514 if (path_dhclient_db
== NULL
)
515 log_fatal("Failed to get realpath for %s: %s", old_path
, strerror(errno
));
518 if (path_dhclient_script
[0] != '/') {
519 const char *old_path
= path_dhclient_script
;
520 path_dhclient_script
= realpath(path_dhclient_script
, NULL
);
521 if (path_dhclient_script
== NULL
)
522 log_fatal("Failed to get realpath for %s: %s", old_path
, strerror(errno
));
526 * See if we should kill off any currently running client
527 * we don't try to kill it off if the user told us not
528 * to write a pid file - we assume they are controlling
529 * the process in some other fashion.
531 if ((release_mode
|| exit_mode
) && (no_pid_file
== ISC_FALSE
)) {
537 if ((pidfd
= fopen(path_dhclient_pid
, "r")) != NULL
) {
538 e
= fscanf(pidfd
, "%ld\n", &temp
);
539 oldpid
= (pid_t
)temp
;
541 if (e
!= 0 && e
!= EOF
&& oldpid
) {
542 if (kill(oldpid
, SIGTERM
) == 0) {
543 log_info("Killed old client process");
544 (void) unlink(path_dhclient_pid
);
546 * wait for the old process to
548 * Note kill() with sig=0 could
549 * detect termination but only
550 * the parent can be signaled...
553 } else if (errno
== ESRCH
) {
554 log_info("Removed stale PID file");
555 (void) unlink(path_dhclient_pid
);
563 log_info("%s %s", message
, PACKAGE_VERSION
);
570 quiet_interface_discovery
= 1;
573 /* If we're given a relay agent address to insert, for testing
574 purposes, figure out what it is. */
576 if (!inet_aton(mockup_relay
, &giaddr
)) {
578 he
= gethostbyname(mockup_relay
);
580 memcpy(&giaddr
, he
->h_addr_list
[0],
583 log_fatal("%s: no such host", mockup_relay
);
588 /* Get the current time... */
589 gettimeofday(&cur_tv
, NULL
);
591 sockaddr_broadcast
.sin_family
= AF_INET
;
592 sockaddr_broadcast
.sin_port
= remote_port
;
594 if (!inet_aton(server
, &sockaddr_broadcast
.sin_addr
)) {
596 he
= gethostbyname(server
);
598 memcpy(&sockaddr_broadcast
.sin_addr
,
600 sizeof sockaddr_broadcast
.sin_addr
);
602 sockaddr_broadcast
.sin_addr
.s_addr
=
606 sockaddr_broadcast
.sin_addr
.s_addr
= INADDR_BROADCAST
;
609 inaddr_any
.s_addr
= INADDR_ANY
;
611 /* Stateless special case. */
613 if (release_mode
|| (wanted_ia_na
> 0) ||
614 wanted_ia_ta
|| wanted_ia_pd
||
615 (interfaces_requested
!= 1)) {
616 usage("Stateless commnad: %s incompatibile with "
617 "other commands", "-S");
619 #if defined(DHCPv6) && defined(DHCP4o6)
620 run_stateless(exit_mode
, dhcp4o6_port
);
622 run_stateless(exit_mode
, 0);
627 /* Discover all the network interfaces. */
628 discover_interfaces(DISCOVER_UNCONFIGURED
);
630 /* Parse the dhclient.conf file. */
633 /* Parse the lease database. */
634 read_client_leases();
636 /* If desired parse the secondary lease database for a DUID */
637 if ((default_duid
.len
== 0) && (path_dhclient_duid
!= NULL
)) {
641 /* Rewrite the lease database... */
642 rewrite_client_leases();
645 /* config_counter(&snd_counter, &rcv_counter); */
648 * If no broadcast interfaces were discovered, call the script
653 * Call dhclient-script with the NBI flag,
654 * in case somebody cares.
656 script_init(NULL
, "NBI", NULL
);
660 * If we haven't been asked to persist, waiting for new
661 * interfaces, then just exit.
664 /* Nothing more to do. */
665 log_info("No broadcast interfaces found - exiting.");
668 } else if (!release_mode
&& !exit_mode
) {
669 /* Call the script with the list of interfaces. */
670 for (ip
= interfaces
; ip
; ip
= ip
->next
) {
672 * If interfaces were specified, don't configure
673 * interfaces that weren't specified!
675 if ((interfaces_requested
> 0) &&
676 ((ip
->flags
& (INTERFACE_REQUESTED
|
677 INTERFACE_AUTOMATIC
)) !=
678 INTERFACE_REQUESTED
))
681 if (local_family
== AF_INET6
) {
682 script_init(ip
->client
, "PREINIT6", NULL
);
684 script_init(ip
->client
, "PREINIT", NULL
);
685 if (ip
->client
->alias
!= NULL
)
686 script_write_params(ip
->client
,
690 script_go(ip
->client
);
694 /* At this point, all the interfaces that the script thinks
695 are relevant should be running, so now we once again call
696 discover_interfaces(), and this time ask it to actually set
697 up the interfaces. */
698 discover_interfaces(interfaces_requested
!= 0
702 /* Make up a seed for the random number generator from current
703 time plus the sum of the last four bytes of each
704 interface's hardware address interpreted as an integer.
705 Not much entropy, but we're booting, so we're not likely to
706 find anything better. */
708 for (ip
= interfaces
; ip
; ip
= ip
->next
) {
711 &ip
->hw_address
.hbuf
[ip
->hw_address
.hlen
-
712 sizeof seed
], sizeof seed
);
715 srandom(seed
+ cur_time
+ (unsigned)getpid());
719 * Establish a default DUID. We always do so for v6 and
720 * do so if desired for v4 via the -D or -i options
722 if ((local_family
== AF_INET6
) ||
723 ((local_family
== AF_INET
) && (duid_v4
== 1))) {
724 if (default_duid
.len
== 0) {
725 if (default_duid
.buffer
!= NULL
)
726 data_string_forget(&default_duid
, MDL
);
728 form_duid(&default_duid
, MDL
);
729 write_duid(&default_duid
);
733 #if defined(DHCPv6) && defined(DHCP4o6)
734 if (dhcpv4_over_dhcpv6
&& !exit_mode
)
735 dhcp4o6_setup(dhcp4o6_port
);
738 /* Start a configuration state machine for each interface. */
740 if (local_family
== AF_INET6
) {
741 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
742 for (client
= ip
->client
; client
!= NULL
;
743 client
= client
->next
) {
745 start_release6(client
);
747 } else if (exit_mode
) {
748 unconfigure6(client
, "STOP6");
752 /* If we have a previous binding, Confirm
753 * that we can (or can't) still use it.
755 if ((client
->active_lease
!= NULL
) &&
756 !client
->active_lease
->released
)
757 start_confirm6(client
);
765 for (ip
= interfaces
; ip
; ip
= ip
->next
) {
766 ip
->flags
|= INTERFACE_RUNNING
;
767 for (client
= ip
->client
; client
;
768 client
= client
->next
) {
774 client
->state
= S_INIT
;
776 if (top_level_config
.initial_delay
>0)
779 if (top_level_config
.
785 tv
.tv_usec
= random()
789 * distribution than just
792 add_timeout(&tv
, state_reboot
,
795 state_reboot(client
);
808 if ((local_family
== AF_INET6
) || dhcpv4_over_dhcpv6
) {
816 /* Start up a listener for the object management API protocol. */
817 if (top_level_config
.omapi_port
!= -1) {
819 result
= omapi_generic_new(&listener
, MDL
);
820 if (result
!= ISC_R_SUCCESS
)
821 log_fatal("Can't allocate new generic object: %s\n",
822 isc_result_totext(result
));
823 result
= omapi_protocol_listen(listener
,
825 top_level_config
.omapi_port
,
827 if (result
!= ISC_R_SUCCESS
)
828 log_fatal("Can't start OMAPI protocol: %s",
829 isc_result_totext (result
));
832 /* Set up the bootp packet handler... */
833 bootp_packet_handler
= do_packet
;
835 dhcpv6_packet_handler
= do_packet6
;
838 #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
839 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
840 dmalloc_cutoff_generation
= dmalloc_generation
;
841 dmalloc_longterm
= dmalloc_outstanding
;
842 dmalloc_outstanding
= 0;
845 #if defined(ENABLE_GENTLE_SHUTDOWN)
846 /* no signal handlers until we deal with the side effects */
847 /* install signal handlers */
848 signal(SIGINT
, dhcp_signal_handler
); /* control-c */
849 signal(SIGTERM
, dhcp_signal_handler
); /* kill */
852 /* If we're not supposed to wait before getting the address,
857 /* If we're not going to daemonize, write the pid file
859 if (no_daemon
|| nowait
)
860 write_client_pid_file();
862 /* Start dispatching packets and timeouts... */
865 /* In fact dispatch() never returns. */
870 * \brief Run the DHCPv6 stateless client (dhclient -6 -S)
872 * \param exist_mode set to 1 when dhclient was called with -x
873 * \param port DHCPv4-over-DHCPv6 client inter-process communication
874 * UDP port pair (port,port+1 with port in network byte order)
877 void run_stateless(int exit_mode
, u_int16_t port
)
880 struct client_state
*client
;
881 omapi_object_t
*listener
;
888 /* Discover the network interface. */
889 discover_interfaces(DISCOVER_REQUESTED
);
892 usage("No interfaces available for stateless command: %s", "-S");
894 /* Parse the dhclient.conf file. */
896 if (dhcpv4_over_dhcpv6
) {
897 /* Mark we want to request IRT too! */
898 dhcpv4_over_dhcpv6
++;
903 /* Parse the lease database. */
904 read_client_leases();
906 /* If desired parse the secondary lease database for a DUID */
907 if ((default_duid
.len
== 0) && (path_dhclient_duid
!= NULL
)) {
911 /* Establish a default DUID. */
912 if (default_duid
.len
== 0) {
913 if (default_duid
.buffer
!= NULL
)
914 data_string_forget(&default_duid
, MDL
);
916 form_duid(&default_duid
, MDL
);
920 if (dhcpv4_over_dhcpv6
&& !exit_mode
)
924 /* Start a configuration state machine. */
925 for (client
= interfaces
->client
;
927 client
= client
->next
) {
929 unconfigure6(client
, "STOP6");
932 start_info_request6(client
);
937 /* Start up a listener for the object management API protocol. */
938 if (top_level_config
.omapi_port
!= -1) {
940 result
= omapi_generic_new(&listener
, MDL
);
941 if (result
!= ISC_R_SUCCESS
)
942 log_fatal("Can't allocate new generic object: %s\n",
943 isc_result_totext(result
));
944 result
= omapi_protocol_listen(listener
,
946 top_level_config
.omapi_port
,
948 if (result
!= ISC_R_SUCCESS
)
949 log_fatal("Can't start OMAPI protocol: %s",
950 isc_result_totext(result
));
953 /* Set up the packet handler... */
954 dhcpv6_packet_handler
= do_packet6
;
956 #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
957 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
958 dmalloc_cutoff_generation
= dmalloc_generation
;
959 dmalloc_longterm
= dmalloc_outstanding
;
960 dmalloc_outstanding
= 0;
963 /* If we're not supposed to wait before getting the address,
968 /* If we're not going to daemonize, write the pid file
970 if (no_daemon
|| nowait
)
971 write_client_pid_file();
973 /* Start dispatching packets and timeouts... */
979 #endif /* !UNIT_TEST */
981 isc_result_t
find_class (struct class **c
,
982 const char *s
, const char *file
, int line
)
987 int check_collection (packet
, lease
, collection
)
988 struct packet
*packet
;
990 struct collection
*collection
;
995 void classify (packet
, class)
996 struct packet
*packet
;
1001 void unbill_class (lease
)
1002 struct lease
*lease
;
1006 int find_subnet (struct subnet
**sp
,
1007 struct iaddr addr
, const char *file
, int line
)
1012 /* Individual States:
1014 * Each routine is called from the dhclient_state_machine() in one of
1016 * -> entering INIT state
1017 * -> recvpacket_flag == 0: timeout in this state
1018 * -> otherwise: received a packet in this state
1020 * Return conditions as handled by dhclient_state_machine():
1021 * Returns 1, sendpacket_flag = 1: send packet, reset timer.
1022 * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
1023 * Returns 0: finish the nap which was interrupted for no good reason.
1025 * Several per-interface variables are used to keep track of the process:
1026 * active_lease: the lease that is being used on the interface
1027 * (null pointer if not configured yet).
1028 * offered_leases: leases corresponding to DHCPOFFER messages that have
1029 * been sent to us by DHCP servers.
1030 * acked_leases: leases corresponding to DHCPACK messages that have been
1031 * sent to us by DHCP servers.
1032 * sendpacket: DHCP packet we're trying to send.
1033 * destination: IP address to send sendpacket to
1034 * In addition, there are several relevant per-lease variables.
1035 * T1_expiry, T2_expiry, lease_expiry: lease milestones
1036 * In the active lease, these control the process of renewing the lease;
1037 * In leases on the acked_leases list, this simply determines when we
1038 * can no longer legitimately use the lease.
1041 void state_reboot (cpp
)
1044 struct client_state
*client
= cpp
;
1046 #if defined(DHCPv6) && defined(DHCP4o6)
1047 if (dhcpv4_over_dhcpv6
&& (dhcp4o6_state
<= 0)) {
1048 if (dhcp4o6_state
< 0)
1050 client
->pending
= P_REBOOT
;
1055 client
->pending
= P_NONE
;
1057 /* If we don't remember an active lease, go straight to INIT. */
1058 if (!client
-> active
||
1059 client
-> active
-> is_bootp
||
1060 client
-> active
-> expiry
<= cur_time
) {
1061 state_init (client
);
1065 /* We are in the rebooting state. */
1066 client
-> state
= S_REBOOTING
;
1069 * make_request doesn't initialize xid because it normally comes
1070 * from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
1071 * so pick an xid now.
1073 client
-> xid
= random ();
1076 * Make a DHCPREQUEST packet, and set
1077 * appropriate per-interface flags.
1079 make_request (client
, client
-> active
);
1080 client
-> destination
= iaddr_broadcast
;
1081 client
-> first_sending
= cur_time
;
1082 client
-> interval
= client
-> config
-> initial_interval
;
1084 /* Zap the medium list... */
1085 client
-> medium
= NULL
;
1087 /* Send out the first DHCPREQUEST packet. */
1088 send_request (client
);
1091 /* Called when a lease has completely expired and we've been unable to
1094 void state_init (cpp
)
1097 struct client_state
*client
= cpp
;
1099 ASSERT_STATE(state
, S_INIT
);
1101 /* Make a DHCPDISCOVER packet, and set appropriate per-interface
1103 make_discover (client
, client
-> active
);
1104 client
-> xid
= client
-> packet
.xid
;
1105 client
-> destination
= iaddr_broadcast
;
1106 client
-> state
= S_SELECTING
;
1107 client
-> first_sending
= cur_time
;
1108 client
-> interval
= client
-> config
-> initial_interval
;
1110 /* Add an immediate timeout to cause the first DHCPDISCOVER packet
1112 send_discover (client
);
1116 * state_selecting is called when one or more DHCPOFFER packets have been
1117 * received and a configurable period of time has passed.
1120 void state_selecting (cpp
)
1123 struct client_state
*client
= cpp
;
1124 struct client_lease
*lp
, *next
, *picked
;
1127 ASSERT_STATE(state
, S_SELECTING
);
1130 * Cancel state_selecting and send_discover timeouts, since either
1131 * one could have got us here.
1133 cancel_timeout (state_selecting
, client
);
1134 cancel_timeout (send_discover
, client
);
1137 * We have received one or more DHCPOFFER packets. Currently,
1138 * the only criterion by which we judge leases is whether or
1139 * not we get a response when we arp for them.
1142 for (lp
= client
-> offered_leases
; lp
; lp
= next
) {
1146 * Check to see if we got an ARPREPLY for the address
1147 * in this particular lease.
1151 picked
-> next
= NULL
;
1153 destroy_client_lease (lp
);
1156 client
-> offered_leases
= NULL
;
1159 * If we just tossed all the leases we were offered, go back
1163 client
-> state
= S_INIT
;
1164 state_init (client
);
1168 /* If it was a BOOTREPLY, we can just take the address right now. */
1169 if (picked
-> is_bootp
) {
1170 client
-> new = picked
;
1172 /* Make up some lease expiry times
1173 XXX these should be configurable. */
1174 client
-> new -> expiry
= cur_time
+ 12000;
1175 client
-> new -> renewal
+= cur_time
+ 8000;
1176 client
-> new -> rebind
+= cur_time
+ 10000;
1178 client
-> state
= S_REQUESTING
;
1180 /* Bind to the address we received. */
1181 bind_lease (client
);
1185 /* Go to the REQUESTING state. */
1186 client
-> destination
= iaddr_broadcast
;
1187 client
-> state
= S_REQUESTING
;
1188 client
-> first_sending
= cur_time
;
1189 client
-> interval
= client
-> config
-> initial_interval
;
1191 /* Make a DHCPREQUEST packet from the lease we picked. */
1192 make_request (client
, picked
);
1193 client
-> xid
= client
-> packet
.xid
;
1195 /* Toss the lease we picked - we'll get it back in a DHCPACK. */
1196 destroy_client_lease (picked
);
1198 /* Add an immediate timeout to send the first DHCPREQUEST packet. */
1199 send_request (client
);
1202 /* state_requesting is called when we receive a DHCPACK message after
1203 having sent out one or more DHCPREQUEST packets. */
1205 void dhcpack (packet
)
1206 struct packet
*packet
;
1208 struct interface_info
*ip
= packet
-> interface
;
1209 struct client_state
*client
;
1210 struct client_lease
*lease
;
1211 struct option_cache
*oc
;
1212 struct data_string ds
;
1214 /* If we're not receptive to an offer right now, or if the offer
1215 has an unrecognizable transaction id, then just drop it. */
1216 for (client
= ip
-> client
; client
; client
= client
-> next
) {
1217 if (client
-> xid
== packet
-> raw
-> xid
)
1221 (packet
-> interface
-> hw_address
.hlen
- 1 !=
1222 packet
-> raw
-> hlen
) ||
1223 (memcmp (&packet
-> interface
-> hw_address
.hbuf
[1],
1224 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
))) {
1226 log_debug ("DHCPACK in wrong transaction.");
1231 if (client
-> state
!= S_REBOOTING
&&
1232 client
-> state
!= S_REQUESTING
&&
1233 client
-> state
!= S_RENEWING
&&
1234 client
-> state
!= S_REBINDING
) {
1236 log_debug ("DHCPACK in wrong state.");
1241 log_info ("DHCPACK from %s", piaddr (packet
-> client_addr
));
1243 lease
= packet_to_lease (packet
, client
);
1245 log_info ("packet_to_lease failed.");
1249 client
-> new = lease
;
1251 /* Stop resending DHCPREQUEST. */
1252 cancel_timeout (send_request
, client
);
1254 /* Figure out the lease time. */
1255 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
,
1256 DHO_DHCP_LEASE_TIME
);
1257 memset (&ds
, 0, sizeof ds
);
1259 evaluate_option_cache (&ds
, packet
, (struct lease
*)0, client
,
1260 packet
-> options
, client
-> new -> options
,
1261 &global_scope
, oc
, MDL
)) {
1263 client
-> new -> expiry
= getULong (ds
.data
);
1265 client
-> new -> expiry
= 0;
1266 data_string_forget (&ds
, MDL
);
1268 client
-> new -> expiry
= 0;
1270 if (client
->new->expiry
== 0) {
1273 log_error ("no expiry time on offered lease.");
1275 /* Quench this (broken) server. Return to INIT to reselect. */
1278 /* 1/2 second delay to restart at INIT. */
1279 tv
.tv_sec
= cur_tv
.tv_sec
;
1280 tv
.tv_usec
= cur_tv
.tv_usec
+ 500000;
1282 if (tv
.tv_usec
>= 1000000) {
1284 tv
.tv_usec
-= 1000000;
1287 add_timeout(&tv
, state_init
, client
, 0, 0);
1292 * A number that looks negative here is really just very large,
1293 * because the lease expiry offset is unsigned.
1295 if (client
->new->expiry
< 0)
1296 client
->new->expiry
= TIME_MAX
;
1298 /* Take the server-provided renewal time if there is one. */
1299 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
,
1300 DHO_DHCP_RENEWAL_TIME
);
1302 evaluate_option_cache (&ds
, packet
, (struct lease
*)0, client
,
1303 packet
-> options
, client
-> new -> options
,
1304 &global_scope
, oc
, MDL
)) {
1306 client
-> new -> renewal
= getULong (ds
.data
);
1308 client
-> new -> renewal
= 0;
1309 data_string_forget (&ds
, MDL
);
1311 client
-> new -> renewal
= 0;
1313 /* If it wasn't specified by the server, calculate it. */
1314 if (!client
-> new -> renewal
)
1315 client
-> new -> renewal
= client
-> new -> expiry
/ 2 + 1;
1317 if (client
-> new -> renewal
<= 0)
1318 client
-> new -> renewal
= TIME_MAX
;
1320 /* Now introduce some randomness to the renewal time: */
1321 if (client
->new->renewal
<= ((TIME_MAX
/ 3) - 3))
1322 client
->new->renewal
= (((client
->new->renewal
* 3) + 3) / 4) +
1323 (((random() % client
->new->renewal
) + 3) / 4);
1325 /* Same deal with the rebind time. */
1326 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
,
1327 DHO_DHCP_REBINDING_TIME
);
1329 evaluate_option_cache (&ds
, packet
, (struct lease
*)0, client
,
1330 packet
-> options
, client
-> new -> options
,
1331 &global_scope
, oc
, MDL
)) {
1333 client
-> new -> rebind
= getULong (ds
.data
);
1335 client
-> new -> rebind
= 0;
1336 data_string_forget (&ds
, MDL
);
1338 client
-> new -> rebind
= 0;
1340 if (client
-> new -> rebind
<= 0) {
1341 if (client
-> new -> expiry
<= TIME_MAX
/ 7)
1342 client
-> new -> rebind
=
1343 client
-> new -> expiry
* 7 / 8;
1345 client
-> new -> rebind
=
1346 client
-> new -> expiry
/ 8 * 7;
1349 /* Make sure our randomness didn't run the renewal time past the
1351 if (client
-> new -> renewal
> client
-> new -> rebind
) {
1352 if (client
-> new -> rebind
<= TIME_MAX
/ 3)
1353 client
-> new -> renewal
=
1354 client
-> new -> rebind
* 3 / 4;
1356 client
-> new -> renewal
=
1357 client
-> new -> rebind
/ 4 * 3;
1360 client
-> new -> expiry
+= cur_time
;
1361 /* Lease lengths can never be negative. */
1362 if (client
-> new -> expiry
< cur_time
)
1363 client
-> new -> expiry
= TIME_MAX
;
1364 client
-> new -> renewal
+= cur_time
;
1365 if (client
-> new -> renewal
< cur_time
)
1366 client
-> new -> renewal
= TIME_MAX
;
1367 client
-> new -> rebind
+= cur_time
;
1368 if (client
-> new -> rebind
< cur_time
)
1369 client
-> new -> rebind
= TIME_MAX
;
1371 bind_lease (client
);
1374 void bind_lease (client
)
1375 struct client_state
*client
;
1379 /* Remember the medium. */
1380 client
->new->medium
= client
->medium
;
1382 /* Run the client script with the new parameters. */
1383 script_init(client
, (client
->state
== S_REQUESTING
? "BOUND" :
1384 (client
->state
== S_RENEWING
? "RENEW" :
1385 (client
->state
== S_REBOOTING
? "REBOOT" :
1387 client
->new->medium
);
1388 if (client
->active
&& client
->state
!= S_REBOOTING
)
1389 script_write_params(client
, "old_", client
->active
);
1390 script_write_params (client
, "new_", client
->new);
1391 script_write_requested(client
);
1393 script_write_params(client
, "alias_", client
->alias
);
1395 /* If the BOUND/RENEW code detects another machine using the
1396 offered address, it exits nonzero. We need to send a
1397 DHCPDECLINE and toss the lease. */
1398 if (script_go(client
)) {
1399 make_decline(client
, client
->new);
1400 send_decline(client
);
1401 destroy_client_lease(client
->new);
1405 log_info("Unable to obtain a lease on first "
1406 "try (declined). Exiting.");
1414 /* Write out the new lease if it has been long enough. */
1415 if (!client
->last_write
||
1416 (cur_time
- client
->last_write
) >= MIN_LEASE_WRITE
)
1417 write_client_lease(client
, client
->new, 0, 1);
1419 /* Replace the old active lease with the new one. */
1421 destroy_client_lease(client
->active
);
1422 client
->active
= client
->new;
1425 /* Set up a timeout to start the renewal process. */
1426 tv
.tv_sec
= client
->active
->renewal
;
1427 tv
.tv_usec
= ((client
->active
->renewal
- cur_tv
.tv_sec
) > 1) ?
1428 random() % 1000000 : cur_tv
.tv_usec
;
1429 add_timeout(&tv
, state_bound
, client
, 0, 0);
1431 log_info("bound to %s -- renewal in %ld seconds.",
1432 piaddr(client
->active
->address
),
1433 (long)(client
->active
->renewal
- cur_time
));
1434 client
->state
= S_BOUND
;
1435 reinitialize_interfaces();
1437 #if defined (NSUPDATE)
1438 if (client
->config
->do_forward_update
)
1439 dhclient_schedule_updates(client
, &client
->active
->address
, 1);
1443 /* state_bound is called when we've successfully bound to a particular
1444 lease, but the renewal time on that lease has expired. We are
1445 expected to unicast a DHCPREQUEST to the server that gave us our
1448 void state_bound (cpp
)
1451 struct client_state
*client
= cpp
;
1452 struct option_cache
*oc
;
1453 struct data_string ds
;
1455 ASSERT_STATE(state
, S_BOUND
);
1457 /* T1 has expired. */
1458 make_request (client
, client
-> active
);
1459 client
-> xid
= client
-> packet
.xid
;
1461 memset (&ds
, 0, sizeof ds
);
1462 oc
= lookup_option (&dhcp_universe
, client
-> active
-> options
,
1463 DHO_DHCP_SERVER_IDENTIFIER
);
1465 evaluate_option_cache (&ds
, (struct packet
*)0, (struct lease
*)0,
1466 client
, (struct option_state
*)0,
1467 client
-> active
-> options
,
1468 &global_scope
, oc
, MDL
)) {
1470 memcpy (client
-> destination
.iabuf
, ds
.data
, 4);
1471 client
-> destination
.len
= 4;
1473 client
-> destination
= iaddr_broadcast
;
1475 data_string_forget (&ds
, MDL
);
1477 client
-> destination
= iaddr_broadcast
;
1479 client
-> first_sending
= cur_time
;
1480 client
-> interval
= client
-> config
-> initial_interval
;
1481 client
-> state
= S_RENEWING
;
1483 /* Send the first packet immediately. */
1484 send_request (client
);
1487 /* state_stop is called when we've been told to shut down. We unconfigure
1488 the interfaces, and then stop operating until told otherwise. */
1490 void state_stop (cpp
)
1493 struct client_state
*client
= cpp
;
1495 client
->pending
= P_NONE
;
1497 /* Cancel all timeouts. */
1498 cancel_timeout(state_selecting
, client
);
1499 cancel_timeout(send_discover
, client
);
1500 cancel_timeout(send_request
, client
);
1501 cancel_timeout(state_bound
, client
);
1503 /* If we have an address, unconfigure it. */
1504 if (client
->active
) {
1505 script_init(client
, "STOP", client
->active
->medium
);
1506 script_write_params(client
, "old_", client
->active
);
1507 script_write_requested(client
);
1509 script_write_params(client
, "alias_", client
->alias
);
1514 int commit_leases ()
1519 int write_lease (lease
)
1520 struct lease
*lease
;
1525 int write_host (host
)
1526 struct host_decl
*host
;
1531 void db_startup (testp
)
1537 struct packet
*packet
;
1539 struct iaddrmatchlist
*ap
;
1543 if (packet
-> raw
-> op
!= BOOTREPLY
)
1546 /* If there's a reject list, make sure this packet's sender isn't
1548 for (ap
= packet
-> interface
-> client
-> config
-> reject_list
;
1549 ap
; ap
= ap
-> next
) {
1550 if (addr_match(&packet
->client_addr
, &ap
->match
)) {
1552 /* piaddr() returns its result in a static
1553 buffer sized 4*16 (see common/inet.c). */
1555 strcpy(addrbuf
, piaddr(ap
->match
.addr
));
1556 strcpy(maskbuf
, piaddr(ap
->match
.mask
));
1558 log_info("BOOTREPLY from %s rejected by rule %s "
1559 "mask %s.", piaddr(packet
->client_addr
),
1570 struct packet
*packet
;
1572 struct iaddrmatchlist
*ap
;
1573 void (*handler
) (struct packet
*);
1578 switch (packet
-> packet_type
) {
1580 handler
= dhcpoffer
;
1598 /* If there's a reject list, make sure this packet's sender isn't
1600 for (ap
= packet
-> interface
-> client
-> config
-> reject_list
;
1601 ap
; ap
= ap
-> next
) {
1602 if (addr_match(&packet
->client_addr
, &ap
->match
)) {
1604 /* piaddr() returns its result in a static
1605 buffer sized 4*16 (see common/inet.c). */
1607 strcpy(addrbuf
, piaddr(ap
->match
.addr
));
1608 strcpy(maskbuf
, piaddr(ap
->match
.mask
));
1610 log_info("%s from %s rejected by rule %s mask %s.",
1611 type
, piaddr(packet
->client_addr
),
1616 (*handler
) (packet
);
1621 dhcpv6(struct packet
*packet
) {
1622 struct iaddrmatchlist
*ap
;
1623 struct client_state
*client
;
1624 char addrbuf
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")];
1626 /* Silently drop bogus messages. */
1627 if (packet
->dhcpv6_msg_type
>= dhcpv6_type_name_max
)
1630 /* Discard, with log, packets from quenched sources. */
1631 for (ap
= packet
->interface
->client
->config
->reject_list
;
1632 ap
; ap
= ap
->next
) {
1633 if (addr_match(&packet
->client_addr
, &ap
->match
)) {
1634 strcpy(addrbuf
, piaddr(packet
->client_addr
));
1635 log_info("%s from %s rejected by rule %s",
1636 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
1638 piaddrmask(&ap
->match
.addr
, &ap
->match
.mask
));
1643 /* Screen out nonsensical messages. */
1644 switch(packet
->dhcpv6_msg_type
) {
1646 case DHCPV6_DHCPV4_RESPONSE
:
1647 if (dhcpv4_over_dhcpv6
) {
1648 log_info("RCV: %s message on %s from %s.",
1649 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
1650 packet
->interface
->name
,
1651 piaddr(packet
->client_addr
));
1652 forw_dhcpv4_response(packet
);
1656 case DHCPV6_ADVERTISE
:
1657 case DHCPV6_RECONFIGURE
:
1662 log_info("RCV: %s message on %s from %s.",
1663 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
1664 packet
->interface
->name
, piaddr(packet
->client_addr
));
1671 /* Find a client state that matches the incoming XID. */
1672 for (client
= packet
->interface
->client
; client
;
1673 client
= client
->next
) {
1674 if (memcmp(&client
->dhcpv6_transaction_id
,
1675 packet
->dhcpv6_transaction_id
, 3) == 0) {
1676 client
->v6_handler(packet
, client
);
1681 /* XXX: temporary log for debugging */
1682 log_info("Packet received, but nothing done with it.");
1687 * \brief Forward a DHCPv4-response to the DHCPv4 client.
1688 * (DHCPv6 client function)
1690 * The DHCPv6 client receives a DHCPv4-response which is forwarded
1691 * to the DHCPv4 client.
1692 * Format: address:16 + DHCPv4 message content
1693 * (we have no state to keep the address so it is transported in
1694 * DHCPv6 <-> DHCPv6 inter-process messages)
1696 * \param packet the DHCPv4-response packet
1698 static void forw_dhcpv4_response(struct packet
*packet
)
1700 struct option_cache
*oc
;
1701 struct data_string enc_opt_data
;
1702 struct data_string ds
;
1706 * Discard if relay is not ready.
1708 if (dhcp4o6_state
== -1) {
1709 log_info("forw_dhcpv4_response: not ready.");
1713 if (packet
->client_addr
.len
!= 16) {
1714 log_error("forw_dhcpv4_response: bad address");
1719 * Get our encapsulated DHCPv4 message.
1721 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_DHCPV4_MSG
);
1723 log_info("DHCPv4-response from %s missing "
1724 "DHCPv4 Message option.",
1725 piaddr(packet
->client_addr
));
1729 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
1730 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
1731 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
1732 log_error("forw_dhcpv4_response: error evaluating "
1734 data_string_forget(&enc_opt_data
, MDL
);
1738 if (enc_opt_data
.len
< DHCP_FIXED_NON_UDP
) {
1739 log_error("forw_dhcpv4_response: "
1740 "no memory for encapsulated packet.");
1741 data_string_forget(&enc_opt_data
, MDL
);
1748 memset(&ds
, 0, sizeof(ds
));
1749 if (!buffer_allocate(&ds
.buffer
, enc_opt_data
.len
+ 16, MDL
)) {
1750 log_error("forw_dhcpv4_response: no memory buffer.");
1751 data_string_forget(&enc_opt_data
, MDL
);
1754 ds
.data
= ds
.buffer
->data
;
1755 ds
.len
= enc_opt_data
.len
+ 16;
1756 memcpy(ds
.buffer
->data
, enc_opt_data
.data
, enc_opt_data
.len
);
1757 memcpy(ds
.buffer
->data
+ enc_opt_data
.len
,
1758 packet
->client_addr
.iabuf
, 16);
1759 data_string_forget(&enc_opt_data
, MDL
);
1764 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
1766 log_error("forw_dhcpv4_response: send(): %m");
1768 data_string_forget(&ds
, MDL
);
1772 * \brief Receive a DHCPv4-response from the DHCPv6 client.
1773 * (DHCPv4 client function)
1775 * The DHCPv4 client receives a DHCPv4-response forwarded
1776 * by the DHCPv6 client (using \ref forw_dhcpv4_response())
1778 * \param raw the DHCPv4-response raw packet
1780 static void recv_dhcpv4_response(struct data_string
*raw
)
1782 struct packet
*packet
;
1785 if (interfaces
== NULL
) {
1786 log_error("recv_dhcpv4_response: no interfaces.");
1791 memcpy(from
.iabuf
, raw
->data
+ (raw
->len
- 16), 16);
1794 * Build a packet structure.
1797 if (!packet_allocate(&packet
, MDL
)) {
1798 log_error("recv_dhcpv4_response: no memory for packet.");
1802 packet
->raw
= (struct dhcp_packet
*) raw
->data
;
1803 packet
->packet_length
= raw
->len
- 16;
1804 packet
->client_port
= remote_port
;
1805 packet
->client_addr
= from
;
1806 interface_reference(&packet
->interface
, interfaces
, MDL
);
1808 /* Allocate packet->options now so it is non-null for all packets */
1809 if (!option_state_allocate (&packet
->options
, MDL
)) {
1810 log_error("recv_dhcpv4_response: no memory for options.");
1811 packet_dereference (&packet
, MDL
);
1815 /* If there's an option buffer, try to parse it. */
1816 if (packet
->packet_length
>= DHCP_FIXED_NON_UDP
+ 4) {
1817 struct option_cache
*op
;
1818 if (!parse_options(packet
)) {
1819 if (packet
->options
)
1820 option_state_dereference
1821 (&packet
->options
, MDL
);
1822 packet_dereference (&packet
, MDL
);
1826 if (packet
->options_valid
&&
1827 (op
= lookup_option(&dhcp_universe
,
1829 DHO_DHCP_MESSAGE_TYPE
))) {
1830 struct data_string dp
;
1831 memset(&dp
, 0, sizeof dp
);
1832 evaluate_option_cache(&dp
, packet
, NULL
, NULL
,
1833 packet
->options
, NULL
,
1836 packet
->packet_type
= dp
.data
[0];
1838 packet
->packet_type
= 0;
1839 data_string_forget(&dp
, MDL
);
1843 if (validate_packet(packet
) != 0) {
1844 if (packet
->packet_type
)
1850 /* If the caller kept the packet, they'll have upped the refcnt. */
1851 packet_dereference(&packet
, MDL
);
1853 #endif /* DHCP4o6 */
1856 void dhcpoffer (packet
)
1857 struct packet
*packet
;
1859 struct interface_info
*ip
= packet
-> interface
;
1860 struct client_state
*client
;
1861 struct client_lease
*lease
, *lp
;
1862 struct option
**req
;
1865 const char *name
= packet
-> packet_type
? "DHCPOFFER" : "BOOTREPLY";
1870 dump_packet (packet
);
1873 /* Find a client state that matches the xid... */
1874 for (client
= ip
-> client
; client
; client
= client
-> next
)
1875 if (client
-> xid
== packet
-> raw
-> xid
)
1878 /* If we're not receptive to an offer right now, or if the offer
1879 has an unrecognizable transaction id, then just drop it. */
1881 client
-> state
!= S_SELECTING
||
1882 (packet
-> interface
-> hw_address
.hlen
- 1 !=
1883 packet
-> raw
-> hlen
) ||
1884 (memcmp (&packet
-> interface
-> hw_address
.hbuf
[1],
1885 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
))) {
1887 log_debug ("%s in wrong transaction.", name
);
1892 sprintf (obuf
, "%s from %s", name
, piaddr (packet
-> client_addr
));
1895 /* If this lease doesn't supply the minimum required DHCPv4 parameters,
1898 req
= client
->config
->required_options
;
1900 for (i
= 0 ; req
[i
] != NULL
; i
++) {
1901 if ((req
[i
]->universe
== &dhcp_universe
) &&
1902 !lookup_option(&dhcp_universe
, packet
->options
,
1904 struct option
*option
= NULL
;
1905 unsigned code
= req
[i
]->code
;
1907 option_code_hash_lookup(&option
,
1908 dhcp_universe
.code_hash
,
1912 log_info("%s: no %s option.", obuf
,
1915 log_info("%s: no unknown-%u option.",
1918 option_dereference(&option
, MDL
);
1925 /* If we've already seen this lease, don't record it again. */
1926 for (lease
= client
-> offered_leases
; lease
; lease
= lease
-> next
) {
1927 if (lease
-> address
.len
== sizeof packet
-> raw
-> yiaddr
&&
1928 !memcmp (lease
-> address
.iabuf
,
1929 &packet
-> raw
-> yiaddr
, lease
-> address
.len
)) {
1930 log_debug ("%s: already seen.", obuf
);
1935 lease
= packet_to_lease (packet
, client
);
1937 log_info ("%s: packet_to_lease failed.", obuf
);
1941 /* If this lease was acquired through a BOOTREPLY, record that
1943 if (!packet
-> options_valid
|| !packet
-> packet_type
)
1944 lease
-> is_bootp
= 1;
1946 /* Record the medium under which this lease was offered. */
1947 lease
-> medium
= client
-> medium
;
1949 /* Figure out when we're supposed to stop selecting. */
1950 stop_selecting
= (client
-> first_sending
+
1951 client
-> config
-> select_interval
);
1953 /* If this is the lease we asked for, put it at the head of the
1954 list, and don't mess with the arp request timeout. */
1955 if (lease
-> address
.len
== client
-> requested_address
.len
&&
1956 !memcmp (lease
-> address
.iabuf
,
1957 client
-> requested_address
.iabuf
,
1958 client
-> requested_address
.len
)) {
1959 lease
-> next
= client
-> offered_leases
;
1960 client
-> offered_leases
= lease
;
1962 /* Put the lease at the end of the list. */
1963 lease
-> next
= (struct client_lease
*)0;
1964 if (!client
-> offered_leases
)
1965 client
-> offered_leases
= lease
;
1967 for (lp
= client
-> offered_leases
; lp
-> next
;
1974 /* If the selecting interval has expired, go immediately to
1975 state_selecting(). Otherwise, time out into
1976 state_selecting at the select interval. */
1977 if (stop_selecting
<= cur_tv
.tv_sec
)
1978 state_selecting (client
);
1980 tv
.tv_sec
= stop_selecting
;
1981 tv
.tv_usec
= cur_tv
.tv_usec
;
1982 add_timeout(&tv
, state_selecting
, client
, 0, 0);
1983 cancel_timeout(send_discover
, client
);
1985 log_info("%s", obuf
);
1988 /* Allocate a client_lease structure and initialize it from the parameters
1989 in the specified packet. */
1991 struct client_lease
*packet_to_lease (packet
, client
)
1992 struct packet
*packet
;
1993 struct client_state
*client
;
1995 struct client_lease
*lease
;
1997 struct option_cache
*oc
;
1998 struct option
*option
= NULL
;
1999 struct data_string data
;
2001 lease
= (struct client_lease
*)new_client_lease (MDL
);
2004 log_error("packet_to_lease: no memory to record lease.\n");
2008 memset(lease
, 0, sizeof(*lease
));
2010 /* Copy the lease options. */
2011 option_state_reference(&lease
->options
, packet
->options
, MDL
);
2013 lease
->address
.len
= sizeof(packet
->raw
->yiaddr
);
2014 memcpy(lease
->address
.iabuf
, &packet
->raw
->yiaddr
,
2015 lease
->address
.len
);
2017 lease
->next_srv_addr
.len
= sizeof(packet
->raw
->siaddr
);
2018 memcpy(lease
->next_srv_addr
.iabuf
, &packet
->raw
->siaddr
,
2019 lease
->next_srv_addr
.len
);
2021 memset(&data
, 0, sizeof(data
));
2023 if (client
-> config
-> vendor_space_name
) {
2024 i
= DHO_VENDOR_ENCAPSULATED_OPTIONS
;
2026 /* See if there was a vendor encapsulation option. */
2027 oc
= lookup_option (&dhcp_universe
, lease
-> options
, i
);
2029 client
-> config
-> vendor_space_name
&&
2030 evaluate_option_cache (&data
, packet
,
2031 (struct lease
*)0, client
,
2032 packet
-> options
, lease
-> options
,
2033 &global_scope
, oc
, MDL
)) {
2035 if (!option_code_hash_lookup(&option
,
2036 dhcp_universe
.code_hash
,
2038 log_fatal("Unable to find VENDOR "
2039 "option (%s:%d).", MDL
);
2040 parse_encapsulated_suboptions
2041 (packet
-> options
, option
,
2042 data
.data
, data
.len
, &dhcp_universe
,
2043 client
-> config
-> vendor_space_name
2046 option_dereference(&option
, MDL
);
2048 data_string_forget (&data
, MDL
);
2053 /* Figure out the overload flag. */
2054 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
2055 DHO_DHCP_OPTION_OVERLOAD
);
2057 evaluate_option_cache (&data
, packet
, (struct lease
*)0, client
,
2058 packet
-> options
, lease
-> options
,
2059 &global_scope
, oc
, MDL
)) {
2064 data_string_forget (&data
, MDL
);
2068 /* If the server name was filled out, copy it. */
2069 if (!(i
& 2) && packet
-> raw
-> sname
[0]) {
2071 /* Don't count on the NUL terminator. */
2072 for (len
= 0; len
< DHCP_SNAME_LEN
; len
++)
2073 if (!packet
-> raw
-> sname
[len
])
2075 lease
-> server_name
= dmalloc (len
+ 1, MDL
);
2076 if (!lease
-> server_name
) {
2077 log_error ("dhcpoffer: no memory for server name.\n");
2078 destroy_client_lease (lease
);
2079 return (struct client_lease
*)0;
2081 memcpy (lease
-> server_name
,
2082 packet
-> raw
-> sname
, len
);
2083 lease
-> server_name
[len
] = 0;
2087 /* Ditto for the filename. */
2088 if (!(i
& 1) && packet
-> raw
-> file
[0]) {
2090 /* Don't count on the NUL terminator. */
2091 for (len
= 0; len
< DHCP_FILE_LEN
; len
++)
2092 if (!packet
-> raw
-> file
[len
])
2094 lease
-> filename
= dmalloc (len
+ 1, MDL
);
2095 if (!lease
-> filename
) {
2096 log_error ("dhcpoffer: no memory for filename.\n");
2097 destroy_client_lease (lease
);
2098 return (struct client_lease
*)0;
2100 memcpy (lease
-> filename
,
2101 packet
-> raw
-> file
, len
);
2102 lease
-> filename
[len
] = 0;
2106 execute_statements_in_scope(NULL
, (struct packet
*)packet
, NULL
,
2107 client
, lease
->options
, lease
->options
,
2108 &global_scope
, client
->config
->on_receipt
,
2114 void dhcpnak (packet
)
2115 struct packet
*packet
;
2117 struct interface_info
*ip
= packet
-> interface
;
2118 struct client_state
*client
;
2120 /* Find a client state that matches the xid... */
2121 for (client
= ip
-> client
; client
; client
= client
-> next
)
2122 if (client
-> xid
== packet
-> raw
-> xid
)
2125 /* If we're not receptive to an offer right now, or if the offer
2126 has an unrecognizable transaction id, then just drop it. */
2128 (packet
-> interface
-> hw_address
.hlen
- 1 !=
2129 packet
-> raw
-> hlen
) ||
2130 (memcmp (&packet
-> interface
-> hw_address
.hbuf
[1],
2131 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
))) {
2133 log_debug ("DHCPNAK in wrong transaction.");
2138 if (client
-> state
!= S_REBOOTING
&&
2139 client
-> state
!= S_REQUESTING
&&
2140 client
-> state
!= S_RENEWING
&&
2141 client
-> state
!= S_REBINDING
) {
2143 log_debug ("DHCPNAK in wrong state.");
2148 log_info ("DHCPNAK from %s", piaddr (packet
-> client_addr
));
2150 if (!client
-> active
) {
2152 log_info ("DHCPNAK with no active lease.\n");
2157 /* If we get a DHCPNAK, we use the EXPIRE dhclient-script state
2158 * to indicate that we want all old bindings to be removed. (It
2159 * is possible that we may get a NAK while in the RENEW state,
2160 * so we might have bindings active at that time)
2162 script_init(client
, "EXPIRE", NULL
);
2163 script_write_params(client
, "old_", client
->active
);
2164 script_write_requested(client
);
2166 script_write_params(client
, "alias_", client
->alias
);
2169 destroy_client_lease (client
-> active
);
2170 client
-> active
= (struct client_lease
*)0;
2172 /* Stop sending DHCPREQUEST packets... */
2173 cancel_timeout (send_request
, client
);
2175 /* On some scripts, 'EXPIRE' causes the interface to be ifconfig'd
2176 * down (this expunges any routes and arp cache). This makes the
2177 * interface unusable by state_init(), which we call next. So, we
2178 * need to 'PREINIT' the interface to bring it back up.
2180 script_init(client
, "PREINIT", NULL
);
2182 script_write_params(client
, "alias_", client
->alias
);
2185 client
-> state
= S_INIT
;
2186 state_init (client
);
2189 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
2190 one after the right interval has expired. If we don't get an offer by
2191 the time we reach the panic interval, call the panic function. */
2193 void send_discover (cpp
)
2196 struct client_state
*client
= cpp
;
2203 /* Figure out how long it's been since we started transmitting. */
2204 interval
= cur_time
- client
-> first_sending
;
2206 /* If we're past the panic timeout, call the script and tell it
2207 we haven't found anything for this interface yet. */
2208 if (interval
> client
-> config
-> timeout
) {
2209 state_panic (client
);
2213 /* If we're selecting media, try the whole list before doing
2214 the exponential backoff, but if we've already received an
2215 offer, stop looping, because we obviously have it right. */
2216 if (!client
-> offered_leases
&&
2217 client
-> config
-> media
) {
2220 if (client
-> medium
) {
2221 client
-> medium
= client
-> medium
-> next
;
2224 if (!client
-> medium
) {
2226 log_fatal ("No valid media types for %s!",
2227 client
-> interface
-> name
);
2229 client
-> config
-> media
;
2233 log_info ("Trying medium \"%s\" %d",
2234 client
-> medium
-> string
, increase
);
2235 script_init (client
, "MEDIUM", client
-> medium
);
2236 if (script_go (client
)) {
2242 /* If we're supposed to increase the interval, do so. If it's
2243 currently zero (i.e., we haven't sent any packets yet), set
2244 it to initial_interval; otherwise, add to it a random number
2245 between zero and two times itself. On average, this means
2246 that it will double with every transmission. */
2248 if (!client
->interval
)
2249 client
->interval
= client
->config
->initial_interval
;
2251 client
->interval
+= random() % (2 * client
->interval
);
2253 /* Don't backoff past cutoff. */
2254 if (client
->interval
> client
->config
->backoff_cutoff
)
2255 client
->interval
= (client
->config
->backoff_cutoff
/ 2)
2256 + (random() % client
->config
->backoff_cutoff
);
2257 } else if (!client
->interval
)
2258 client
->interval
= client
->config
->initial_interval
;
2260 /* If the backoff would take us to the panic timeout, just use that
2262 if (cur_time
+ client
-> interval
>
2263 client
-> first_sending
+ client
-> config
-> timeout
)
2264 client
-> interval
=
2265 (client
-> first_sending
+
2266 client
-> config
-> timeout
) - cur_time
+ 1;
2268 /* Record the number of seconds since we started sending. */
2269 if (interval
< 65536)
2270 client
-> packet
.secs
= htons (interval
);
2272 client
-> packet
.secs
= htons (65535);
2273 client
-> secs
= client
-> packet
.secs
;
2275 #if defined(DHCPv6) && defined(DHCP4o6)
2276 if (dhcpv4_over_dhcpv6
) {
2277 log_info ("DHCPDISCOVER interval %ld",
2278 (long)(client
-> interval
));
2281 log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
2282 client
-> name
? client
-> name
: client
-> interface
-> name
,
2283 inet_ntoa (sockaddr_broadcast
.sin_addr
),
2284 ntohs (sockaddr_broadcast
.sin_port
), (long)(client
-> interval
));
2286 /* Send out a packet. */
2287 #if defined(DHCPv6) && defined(DHCP4o6)
2288 if (dhcpv4_over_dhcpv6
) {
2289 result
= send_dhcpv4_query(client
, 1);
2292 result
= send_packet(client
->interface
, NULL
, &client
->packet
,
2293 client
->packet_length
, inaddr_any
,
2294 &sockaddr_broadcast
, NULL
);
2296 #if defined(DHCPv6) && defined(DHCP4o6)
2297 if (dhcpv4_over_dhcpv6
) {
2298 log_error("%s:%d: Failed to send %d byte long packet.",
2299 MDL
, client
->packet_length
);
2302 log_error("%s:%d: Failed to send %d byte long packet over %s "
2303 "interface.", MDL
, client
->packet_length
,
2304 client
->interface
->name
);
2308 * If we used 0 microseconds here, and there were other clients on the
2309 * same network with a synchronized local clock (ntp), and a similar
2310 * zero-microsecond-scheduler behavior, then we could be participating
2311 * in a sub-second DOS ttck.
2313 tv
.tv_sec
= cur_tv
.tv_sec
+ client
->interval
;
2314 tv
.tv_usec
= client
->interval
> 1 ? random() % 1000000 : cur_tv
.tv_usec
;
2315 add_timeout(&tv
, send_discover
, client
, 0, 0);
2318 /* state_panic gets called if we haven't received any offers in a preset
2319 amount of time. When this happens, we try to use existing leases that
2320 haven't yet expired, and failing that, we call the client script and
2321 hope it can do something. */
2323 void state_panic (cpp
)
2326 struct client_state
*client
= cpp
;
2327 struct client_lease
*loop
;
2328 struct client_lease
*lp
;
2331 loop
= lp
= client
-> active
;
2333 log_info ("No DHCPOFFERS received.");
2335 /* We may not have an active lease, but we may have some
2336 predefined leases that we can try. */
2337 if (!client
-> active
&& client
-> leases
)
2340 /* Run through the list of leases and see if one can be used. */
2341 while (client
-> active
) {
2342 if (client
-> active
-> expiry
> cur_time
) {
2343 log_info ("Trying recorded lease %s",
2344 piaddr (client
-> active
-> address
));
2345 /* Run the client script with the existing
2347 script_init (client
, "TIMEOUT",
2348 client
-> active
-> medium
);
2349 script_write_params (client
, "new_", client
-> active
);
2350 script_write_requested(client
);
2351 if (client
-> alias
)
2352 script_write_params (client
, "alias_",
2355 /* If the old lease is still good and doesn't
2356 yet need renewal, go into BOUND state and
2357 timeout at the renewal time. */
2358 if (!script_go (client
)) {
2359 if (cur_time
< client
-> active
-> renewal
) {
2360 client
-> state
= S_BOUND
;
2361 log_info ("bound: renewal in %ld %s.",
2362 (long)(client
-> active
-> renewal
-
2363 cur_time
), "seconds");
2364 tv
.tv_sec
= client
->active
->renewal
;
2365 tv
.tv_usec
= ((client
->active
->renewal
-
2367 random() % 1000000 :
2369 add_timeout(&tv
, state_bound
, client
, 0, 0);
2371 client
-> state
= S_BOUND
;
2372 log_info ("bound: immediate renewal.");
2373 state_bound (client
);
2375 reinitialize_interfaces ();
2381 /* If there are no other leases, give up. */
2382 if (!client
-> leases
) {
2383 client
-> leases
= client
-> active
;
2384 client
-> active
= (struct client_lease
*)0;
2389 /* Otherwise, put the active lease at the end of the
2390 lease list, and try another lease.. */
2391 for (lp
= client
-> leases
; lp
-> next
; lp
= lp
-> next
)
2393 lp
-> next
= client
-> active
;
2395 lp
-> next
-> next
= (struct client_lease
*)0;
2397 client
-> active
= client
-> leases
;
2398 client
-> leases
= client
-> leases
-> next
;
2400 /* If we already tried this lease, we've exhausted the
2401 set of leases, so we might as well give up for
2403 if (client
-> active
== loop
)
2406 loop
= client
-> active
;
2409 /* No leases were available, or what was available didn't work, so
2410 tell the shell script that we failed to allocate an address,
2411 and try again later. */
2414 log_info ("Unable to obtain a lease on first try.%s",
2419 log_info ("No working leases in persistent database - sleeping.");
2420 script_init (client
, "FAIL", (struct string_list
*)0);
2421 if (client
-> alias
)
2422 script_write_params (client
, "alias_", client
-> alias
);
2424 client
-> state
= S_INIT
;
2425 tv
.tv_sec
= cur_tv
.tv_sec
+ ((client
->config
->retry_interval
+ 1) / 2 +
2426 (random() % client
->config
->retry_interval
));
2427 tv
.tv_usec
= ((tv
.tv_sec
- cur_tv
.tv_sec
) > 1) ?
2428 random() % 1000000 : cur_tv
.tv_usec
;
2429 add_timeout(&tv
, state_init
, client
, 0, 0);
2433 void send_request (cpp
)
2436 struct client_state
*client
= cpp
;
2440 struct sockaddr_in destination
;
2441 struct in_addr from
;
2444 /* Figure out how long it's been since we started transmitting. */
2445 interval
= cur_time
- client
-> first_sending
;
2447 /* If we're in the INIT-REBOOT or REQUESTING state and we're
2448 past the reboot timeout, go to INIT and see if we can
2449 DISCOVER an address... */
2450 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
2451 means either that we're on a network with no DHCP server,
2452 or that our server is down. In the latter case, assuming
2453 that there is a backup DHCP server, DHCPDISCOVER will get
2454 us a new address, but we could also have successfully
2455 reused our old address. In the former case, we're hosed
2456 anyway. This is not a win-prone situation. */
2457 if ((client
-> state
== S_REBOOTING
||
2458 client
-> state
== S_REQUESTING
) &&
2459 interval
> client
-> config
-> reboot_timeout
) {
2461 client
-> state
= S_INIT
;
2462 cancel_timeout (send_request
, client
);
2463 state_init (client
);
2467 /* If we're in the reboot state, make sure the media is set up
2469 if (client
-> state
== S_REBOOTING
&&
2470 !client
-> medium
&&
2471 client
-> active
-> medium
) {
2472 script_init (client
, "MEDIUM", client
-> active
-> medium
);
2474 /* If the medium we chose won't fly, go to INIT state. */
2475 if (script_go (client
))
2478 /* Record the medium. */
2479 client
-> medium
= client
-> active
-> medium
;
2482 /* If the lease has expired, relinquish the address and go back
2483 to the INIT state. */
2484 if (client
-> state
!= S_REQUESTING
&&
2485 cur_time
> client
-> active
-> expiry
) {
2486 /* Run the client script with the new parameters. */
2487 script_init (client
, "EXPIRE", (struct string_list
*)0);
2488 script_write_params (client
, "old_", client
-> active
);
2489 script_write_requested(client
);
2490 if (client
-> alias
)
2491 script_write_params (client
, "alias_",
2495 /* Now do a preinit on the interface so that we can
2496 discover a new address. */
2497 script_init (client
, "PREINIT", (struct string_list
*)0);
2498 if (client
-> alias
)
2499 script_write_params (client
, "alias_",
2503 client
-> state
= S_INIT
;
2504 state_init (client
);
2508 /* Do the exponential backoff... */
2509 if (!client
-> interval
)
2510 client
-> interval
= client
-> config
-> initial_interval
;
2512 client
-> interval
+= ((random () >> 2) %
2513 (2 * client
-> interval
));
2516 /* Don't backoff past cutoff. */
2517 if (client
-> interval
>
2518 client
-> config
-> backoff_cutoff
)
2519 client
-> interval
=
2520 ((client
-> config
-> backoff_cutoff
/ 2)
2521 + ((random () >> 2) %
2522 client
-> config
-> backoff_cutoff
));
2524 /* If the backoff would take us to the expiry time, just set the
2525 timeout to the expiry time. */
2526 if (client
-> state
!= S_REQUESTING
&&
2527 cur_time
+ client
-> interval
> client
-> active
-> expiry
)
2528 client
-> interval
=
2529 client
-> active
-> expiry
- cur_time
+ 1;
2531 /* If the lease T2 time has elapsed, or if we're not yet bound,
2532 broadcast the DHCPREQUEST rather than unicasting. */
2533 if (client
-> state
== S_REQUESTING
||
2534 client
-> state
== S_REBOOTING
||
2535 cur_time
> client
-> active
-> rebind
)
2536 destination
.sin_addr
= sockaddr_broadcast
.sin_addr
;
2538 memcpy (&destination
.sin_addr
.s_addr
,
2539 client
-> destination
.iabuf
,
2540 sizeof destination
.sin_addr
.s_addr
);
2541 destination
.sin_port
= remote_port
;
2542 destination
.sin_family
= AF_INET
;
2544 destination
.sin_len
= sizeof destination
;
2547 if (client
-> state
== S_RENEWING
||
2548 client
-> state
== S_REBINDING
)
2549 memcpy (&from
, client
-> active
-> address
.iabuf
,
2552 from
.s_addr
= INADDR_ANY
;
2554 /* Record the number of seconds since we started sending. */
2555 if (client
-> state
== S_REQUESTING
)
2556 client
-> packet
.secs
= client
-> secs
;
2558 if (interval
< 65536)
2559 client
-> packet
.secs
= htons (interval
);
2561 client
-> packet
.secs
= htons (65535);
2564 #if defined(DHCPv6) && defined(DHCP4o6)
2565 if (dhcpv4_over_dhcpv6
) {
2566 log_info ("DHCPREQUEST");
2569 log_info ("DHCPREQUEST on %s to %s port %d",
2570 client
-> name
? client
-> name
: client
-> interface
-> name
,
2571 inet_ntoa (destination
.sin_addr
),
2572 ntohs (destination
.sin_port
));
2574 #if defined(DHCPv6) && defined(DHCP4o6)
2575 if (dhcpv4_over_dhcpv6
) {
2577 if (destination
.sin_addr
.s_addr
== INADDR_BROADCAST
)
2579 result
= send_dhcpv4_query(client
, broadcast
);
2581 log_error("%s:%d: Failed to send %d byte long packet.",
2582 MDL
, client
->packet_length
);
2586 if (destination
.sin_addr
.s_addr
!= INADDR_BROADCAST
&&
2587 fallback_interface
) {
2588 result
= send_packet(fallback_interface
, NULL
, &client
->packet
,
2589 client
->packet_length
, from
, &destination
,
2592 log_error("%s:%d: Failed to send %d byte long packet "
2593 "over %s interface.", MDL
,
2594 client
->packet_length
,
2595 fallback_interface
->name
);
2599 /* Send out a packet. */
2600 result
= send_packet(client
->interface
, NULL
, &client
->packet
,
2601 client
->packet_length
, from
, &destination
,
2604 log_error("%s:%d: Failed to send %d byte long packet"
2605 " over %s interface.", MDL
,
2606 client
->packet_length
,
2607 client
->interface
->name
);
2611 tv
.tv_sec
= cur_tv
.tv_sec
+ client
->interval
;
2612 tv
.tv_usec
= ((tv
.tv_sec
- cur_tv
.tv_sec
) > 1) ?
2613 random() % 1000000 : cur_tv
.tv_usec
;
2614 add_timeout(&tv
, send_request
, client
, 0, 0);
2617 void send_decline (cpp
)
2620 struct client_state
*client
= cpp
;
2624 #if defined(DHCPv6) && defined(DHCP4o6)
2625 if (dhcpv4_over_dhcpv6
) {
2626 log_info ("DHCPDECLINE");
2629 log_info ("DHCPDECLINE on %s to %s port %d",
2630 client
->name
? client
->name
: client
->interface
->name
,
2631 inet_ntoa(sockaddr_broadcast
.sin_addr
),
2632 ntohs(sockaddr_broadcast
.sin_port
));
2634 /* Send out a packet. */
2635 #if defined(DHCPv6) && defined(DHCP4o6)
2636 if (dhcpv4_over_dhcpv6
) {
2637 result
= send_dhcpv4_query(client
, 1);
2640 result
= send_packet(client
->interface
, NULL
, &client
->packet
,
2641 client
->packet_length
, inaddr_any
,
2642 &sockaddr_broadcast
, NULL
);
2644 #if defined(DHCPv6) && defined(DHCP4o6)
2645 if (dhcpv4_over_dhcpv6
) {
2646 log_error("%s:%d: Failed to send %d byte long packet.",
2647 MDL
, client
->packet_length
);
2650 log_error("%s:%d: Failed to send %d byte long packet over %s"
2651 " interface.", MDL
, client
->packet_length
,
2652 client
->interface
->name
);
2656 void send_release (cpp
)
2659 struct client_state
*client
= cpp
;
2662 struct sockaddr_in destination
;
2663 struct in_addr from
;
2665 memcpy (&from
, client
-> active
-> address
.iabuf
,
2667 memcpy (&destination
.sin_addr
.s_addr
,
2668 client
-> destination
.iabuf
,
2669 sizeof destination
.sin_addr
.s_addr
);
2670 destination
.sin_port
= remote_port
;
2671 destination
.sin_family
= AF_INET
;
2673 destination
.sin_len
= sizeof destination
;
2676 /* Set the lease to end now, so that we don't accidentally
2677 reuse it if we restart before the old expiry time. */
2678 client
-> active
-> expiry
=
2679 client
-> active
-> renewal
=
2680 client
-> active
-> rebind
= cur_time
;
2681 if (!write_client_lease (client
, client
-> active
, 1, 1)) {
2682 log_error ("Can't release lease: lease write failed.");
2686 #if defined(DHCPv6) && defined(DHCP4o6)
2687 if (dhcpv4_over_dhcpv6
) {
2688 log_info ("DHCPRELEASE");
2691 log_info ("DHCPRELEASE on %s to %s port %d",
2692 client
-> name
? client
-> name
: client
-> interface
-> name
,
2693 inet_ntoa (destination
.sin_addr
),
2694 ntohs (destination
.sin_port
));
2696 #if defined(DHCPv6) && defined(DHCP4o6)
2697 if (dhcpv4_over_dhcpv6
) {
2699 if (destination
.sin_addr
.s_addr
== INADDR_BROADCAST
)
2701 result
= send_dhcpv4_query(client
, broadcast
);
2703 log_error("%s:%d: Failed to send %d byte long packet.",
2704 MDL
, client
->packet_length
);
2708 if (fallback_interface
) {
2709 result
= send_packet(fallback_interface
, NULL
, &client
->packet
,
2710 client
->packet_length
, from
, &destination
,
2713 log_error("%s:%d: Failed to send %d byte long packet"
2714 " over %s interface.", MDL
,
2715 client
->packet_length
,
2716 fallback_interface
->name
);
2719 /* Send out a packet. */
2720 result
= send_packet(client
->interface
, NULL
, &client
->packet
,
2721 client
->packet_length
, from
, &destination
,
2724 log_error ("%s:%d: Failed to send %d byte long packet"
2725 " over %s interface.", MDL
,
2726 client
->packet_length
,
2727 client
->interface
->name
);
2733 #if defined(DHCPv6) && defined(DHCP4o6)
2735 * \brief Send a DHCPv4-query to the DHCPv6 client
2736 * (DHCPv4 client function)
2738 * The DHCPv4 client sends a DHCPv4-query to the DHCPv6 client over
2739 * the inter-process communication socket.
2741 * \param client the DHCPv4 client state
2742 * \param broadcast the broadcast flag
2743 * \return the sent byte count (-1 on error)
2745 static int send_dhcpv4_query(struct client_state
*client
, int broadcast
) {
2746 struct data_string ds
;
2747 struct dhcpv4_over_dhcpv6_packet
*query
;
2750 if (dhcp4o6_state
<= 0) {
2751 log_info("send_dhcpv4_query: not ready.");
2756 * Compute buffer length and allocate it.
2758 len
= ofs
= (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
2759 len
+= dhcpv6_universe
.tag_size
+ dhcpv6_universe
.length_size
;
2760 len
+= client
->packet_length
;
2761 memset(&ds
, 0, sizeof(ds
));
2762 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
2763 log_error("Unable to allocate memory for DHCPv4-query.");
2766 ds
.data
= ds
.buffer
->data
;
2772 query
= (struct dhcpv4_over_dhcpv6_packet
*)ds
.data
;
2773 query
->msg_type
= DHCPV6_DHCPV4_QUERY
;
2774 query
->flags
[0] = query
->flags
[1] = query
->flags
[2] = 0;
2776 query
->flags
[0] |= DHCP4O6_QUERY_UNICAST
;
2779 * Append DHCPv4 message.
2781 dhcpv6_universe
.store_tag(ds
.buffer
->data
+ ofs
, D6O_DHCPV4_MSG
);
2782 ofs
+= dhcpv6_universe
.tag_size
;
2783 dhcpv6_universe
.store_length(ds
.buffer
->data
+ ofs
,
2784 client
->packet_length
);
2785 ofs
+= dhcpv6_universe
.length_size
;
2786 memcpy(ds
.buffer
->data
+ ofs
, &client
->packet
, client
->packet_length
);
2789 * Send DHCPv6 message.
2791 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
2793 log_error("send_dhcpv4_query: send(): %m");
2795 data_string_forget(&ds
, MDL
);
2801 * \brief Forward a DHCPv4-query to all DHCPv4 over DHCPv6 server addresses.
2802 * (DHCPv6 client function)
2804 * \param raw the DHCPv6 DHCPv4-query message raw content
2806 static void forw_dhcpv4_query(struct data_string
*raw
) {
2807 struct interface_info
*ip
;
2808 struct client_state
*client
;
2809 struct dhc6_lease
*lease
;
2810 struct option_cache
*oc
;
2811 struct data_string addrs
;
2812 struct sockaddr_in6 sin6
;
2813 int i
, send_ret
, attempt
, success
;
2815 attempt
= success
= 0;
2816 memset(&sin6
, 0, sizeof(sin6
));
2817 sin6
.sin6_family
= AF_INET6
;
2818 sin6
.sin6_port
= remote_port
;
2820 sin6
.sin6_len
= sizeof(sin6
);
2822 memset(&addrs
, 0, sizeof(addrs
));
2823 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
2824 for (client
= ip
->client
; client
!= NULL
;
2825 client
= client
->next
) {
2826 if ((client
->state
!= S_BOUND
) &&
2827 (client
->state
!= S_RENEWING
) &&
2828 (client
->state
!= S_REBINDING
))
2830 lease
= client
->active_lease
;
2831 if ((lease
== NULL
) || lease
->released
)
2833 oc
= lookup_option(&dhcpv6_universe
,
2835 D6O_DHCP4_O_DHCP6_SERVER
);
2837 !evaluate_option_cache(&addrs
, NULL
, NULL
, NULL
,
2838 lease
->options
, NULL
,
2839 &global_scope
, oc
, MDL
) ||
2840 ((addrs
.len
% sizeof(sin6
.sin6_addr
)) != 0)) {
2841 data_string_forget(&addrs
, MDL
);
2844 if (addrs
.len
== 0) {
2845 /* note there is nothing to forget */
2847 All_DHCP_Relay_Agents_and_Servers
,
2850 send_ret
= send_packet6(ip
, raw
->data
,
2852 if (send_ret
== raw
->len
)
2856 for (i
= 0; i
< addrs
.len
;
2857 i
+= sizeof(sin6
.sin6_addr
)) {
2858 memcpy(&sin6
.sin6_addr
, addrs
.data
+ i
,
2859 sizeof(sin6
.sin6_addr
));
2861 send_ret
= send_packet6(ip
, raw
->data
,
2863 if (send_ret
== raw
->len
)
2866 data_string_forget(&addrs
, MDL
);
2870 log_info("forw_dhcpv4_query: sent(%d): %d/%d",
2871 raw
->len
, success
, attempt
);
2879 make_client_options(struct client_state
*client
, struct client_lease
*lease
,
2880 u_int8_t
*type
, struct option_cache
*sid
,
2881 struct iaddr
*rip
, struct option
**prl
,
2882 struct option_state
**op
)
2885 struct option_cache
*oc
;
2886 struct option
*option
= NULL
;
2887 struct buffer
*bp
= NULL
;
2889 /* If there are any leftover options, get rid of them. */
2891 option_state_dereference(op
, MDL
);
2893 /* Allocate space for options. */
2894 option_state_allocate(op
, MDL
);
2896 /* Send the server identifier if provided. */
2898 save_option(&dhcp_universe
, *op
, sid
);
2902 /* Send the requested address if provided. */
2904 client
->requested_address
= *rip
;
2905 i
= DHO_DHCP_REQUESTED_ADDRESS
;
2906 if (!(option_code_hash_lookup(&option
, dhcp_universe
.code_hash
,
2908 make_const_option_cache(&oc
, NULL
, rip
->iabuf
, rip
->len
,
2910 log_error ("can't make requested address cache.");
2912 save_option(&dhcp_universe
, *op
, oc
);
2913 option_cache_dereference(&oc
, MDL
);
2915 option_dereference(&option
, MDL
);
2917 client
->requested_address
.len
= 0;
2920 i
= DHO_DHCP_MESSAGE_TYPE
;
2921 if (!(option_code_hash_lookup(&option
, dhcp_universe
.code_hash
, &i
, 0,
2923 make_const_option_cache(&oc
, NULL
, type
, 1, option
, MDL
)))
2924 log_error("can't make message type.");
2926 save_option(&dhcp_universe
, *op
, oc
);
2927 option_cache_dereference(&oc
, MDL
);
2929 option_dereference(&option
, MDL
);
2934 /* Probe the length of the list. */
2936 for (i
= 0 ; prl
[i
] != NULL
; i
++)
2937 if (prl
[i
]->universe
== &dhcp_universe
)
2940 if (!buffer_allocate(&bp
, len
, MDL
))
2941 log_error("can't make parameter list buffer.");
2943 unsigned code
= DHO_DHCP_PARAMETER_REQUEST_LIST
;
2946 for (i
= 0 ; prl
[i
] != NULL
; i
++)
2947 if (prl
[i
]->universe
== &dhcp_universe
)
2948 bp
->data
[len
++] = prl
[i
]->code
;
2950 if (!(option_code_hash_lookup(&option
,
2951 dhcp_universe
.code_hash
,
2953 make_const_option_cache(&oc
, &bp
, NULL
, len
,
2956 buffer_dereference(&bp
, MDL
);
2957 log_error ("can't make option cache");
2959 save_option(&dhcp_universe
, *op
, oc
);
2960 option_cache_dereference(&oc
, MDL
);
2962 option_dereference(&option
, MDL
);
2967 * If requested (duid_v4 == 1) add an RFC4361 compliant client-identifier
2968 * This can be overridden by including a client id in the configuration
2972 struct data_string client_identifier
;
2975 memset(&client_identifier
, 0, sizeof(client_identifier
));
2976 client_identifier
.len
= 1 + 4 + default_duid
.len
;
2977 if (!buffer_allocate(&client_identifier
.buffer
,
2978 client_identifier
.len
, MDL
))
2979 log_fatal("no memory for default DUID!");
2980 client_identifier
.data
= client_identifier
.buffer
->data
;
2982 i
= DHO_DHCP_CLIENT_IDENTIFIER
;
2984 /* Client-identifier type : 1 byte */
2985 *client_identifier
.buffer
->data
= 255;
2988 * we use the low 4 bytes from the interface address
2990 if (client
->interface
->hw_address
.hlen
> 4) {
2991 hw_idx
= client
->interface
->hw_address
.hlen
- 4;
2995 hw_len
= client
->interface
->hw_address
.hlen
;
2997 memcpy(&client_identifier
.buffer
->data
+ 5 - hw_len
,
2998 client
->interface
->hw_address
.hbuf
+ hw_idx
,
3001 /* Add the default duid */
3002 memcpy(&client_identifier
.buffer
->data
+(1+4),
3003 default_duid
.data
, default_duid
.len
);
3005 /* And save the option */
3006 if (!(option_code_hash_lookup(&option
, dhcp_universe
.code_hash
,
3008 make_const_option_cache(&oc
, NULL
,
3009 (u_int8_t
*)client_identifier
.data
,
3010 client_identifier
.len
,
3012 log_error ("can't make requested client id cache..");
3014 save_option (&dhcp_universe
, *op
, oc
);
3015 option_cache_dereference (&oc
, MDL
);
3017 option_dereference(&option
, MDL
);
3020 /* Run statements that need to be run on transmission. */
3021 if (client
->config
->on_transmission
)
3022 execute_statements_in_scope(NULL
, NULL
, NULL
, client
,
3023 (lease
? lease
->options
: NULL
),
3025 client
->config
->on_transmission
,
3029 void make_discover (client
, lease
)
3030 struct client_state
*client
;
3031 struct client_lease
*lease
;
3033 unsigned char discover
= DHCPDISCOVER
;
3034 struct option_state
*options
= (struct option_state
*)0;
3036 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
3038 make_client_options (client
,
3039 lease
, &discover
, (struct option_cache
*)0,
3040 lease
? &lease
-> address
: (struct iaddr
*)0,
3041 client
-> config
-> requested_options
,
3044 /* Set up the option buffer... */
3045 client
-> packet_length
=
3046 cons_options ((struct packet
*)0, &client
-> packet
,
3047 (struct lease
*)0, client
,
3048 /* maximum packet size */1500,
3049 (struct option_state
*)0,
3051 /* scope */ &global_scope
,
3055 (struct data_string
*)0,
3056 client
-> config
-> vendor_space_name
);
3058 option_state_dereference (&options
, MDL
);
3059 if (client
-> packet_length
< BOOTP_MIN_LEN
)
3060 client
-> packet_length
= BOOTP_MIN_LEN
;
3062 client
-> packet
.op
= BOOTREQUEST
;
3063 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
3064 /* Assumes hw_address is known, otherwise a random value may result */
3065 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
3066 client
-> packet
.hops
= 0;
3067 client
-> packet
.xid
= random ();
3068 client
-> packet
.secs
= 0; /* filled in by send_discover. */
3070 if (can_receive_unicast_unconfigured (client
-> interface
))
3071 client
-> packet
.flags
= 0;
3073 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
3075 memset (&(client
-> packet
.ciaddr
),
3076 0, sizeof client
-> packet
.ciaddr
);
3077 memset (&(client
-> packet
.yiaddr
),
3078 0, sizeof client
-> packet
.yiaddr
);
3079 memset (&(client
-> packet
.siaddr
),
3080 0, sizeof client
-> packet
.siaddr
);
3081 client
-> packet
.giaddr
= giaddr
;
3082 if (client
-> interface
-> hw_address
.hlen
> 0)
3083 memcpy (client
-> packet
.chaddr
,
3084 &client
-> interface
-> hw_address
.hbuf
[1],
3085 (unsigned)(client
-> interface
-> hw_address
.hlen
- 1));
3088 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
3093 void make_request (client
, lease
)
3094 struct client_state
*client
;
3095 struct client_lease
*lease
;
3097 unsigned char request
= DHCPREQUEST
;
3098 struct option_cache
*oc
;
3100 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
3102 if (client
-> state
== S_REQUESTING
)
3103 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
3104 DHO_DHCP_SERVER_IDENTIFIER
);
3106 oc
= (struct option_cache
*)0;
3108 if (client
-> sent_options
)
3109 option_state_dereference (&client
-> sent_options
, MDL
);
3111 make_client_options (client
, lease
, &request
, oc
,
3112 ((client
-> state
== S_REQUESTING
||
3113 client
-> state
== S_REBOOTING
)
3115 : (struct iaddr
*)0),
3116 client
-> config
-> requested_options
,
3117 &client
-> sent_options
);
3119 /* Set up the option buffer... */
3120 client
-> packet_length
=
3121 cons_options ((struct packet
*)0, &client
-> packet
,
3122 (struct lease
*)0, client
,
3123 /* maximum packet size */1500,
3124 (struct option_state
*)0,
3125 client
-> sent_options
,
3126 /* scope */ &global_scope
,
3130 (struct data_string
*)0,
3131 client
-> config
-> vendor_space_name
);
3133 if (client
-> packet_length
< BOOTP_MIN_LEN
)
3134 client
-> packet_length
= BOOTP_MIN_LEN
;
3136 client
-> packet
.op
= BOOTREQUEST
;
3137 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
3138 /* Assumes hw_address is known, otherwise a random value may result */
3139 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
3140 client
-> packet
.hops
= 0;
3141 client
-> packet
.xid
= client
-> xid
;
3142 client
-> packet
.secs
= 0; /* Filled in by send_request. */
3144 /* If we own the address we're requesting, put it in ciaddr;
3145 otherwise set ciaddr to zero. */
3146 if (client
-> state
== S_BOUND
||
3147 client
-> state
== S_RENEWING
||
3148 client
-> state
== S_REBINDING
) {
3149 memcpy (&client
-> packet
.ciaddr
,
3150 lease
-> address
.iabuf
, lease
-> address
.len
);
3151 client
-> packet
.flags
= 0;
3153 memset (&client
-> packet
.ciaddr
, 0,
3154 sizeof client
-> packet
.ciaddr
);
3155 if (can_receive_unicast_unconfigured (client
-> interface
))
3156 client
-> packet
.flags
= 0;
3158 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
3161 memset (&client
-> packet
.yiaddr
, 0,
3162 sizeof client
-> packet
.yiaddr
);
3163 memset (&client
-> packet
.siaddr
, 0,
3164 sizeof client
-> packet
.siaddr
);
3165 if (client
-> state
!= S_BOUND
&&
3166 client
-> state
!= S_RENEWING
)
3167 client
-> packet
.giaddr
= giaddr
;
3169 memset (&client
-> packet
.giaddr
, 0,
3170 sizeof client
-> packet
.giaddr
);
3171 if (client
-> interface
-> hw_address
.hlen
> 0)
3172 memcpy (client
-> packet
.chaddr
,
3173 &client
-> interface
-> hw_address
.hbuf
[1],
3174 (unsigned)(client
-> interface
-> hw_address
.hlen
- 1));
3177 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
3181 void make_decline (client
, lease
)
3182 struct client_state
*client
;
3183 struct client_lease
*lease
;
3185 unsigned char decline
= DHCPDECLINE
;
3186 struct option_cache
*oc
;
3188 struct option_state
*options
= (struct option_state
*)0;
3190 /* Create the options cache. */
3191 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
3192 DHO_DHCP_SERVER_IDENTIFIER
);
3193 make_client_options(client
, lease
, &decline
, oc
, &lease
->address
,
3196 /* Consume the options cache into the option buffer. */
3197 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
3198 client
-> packet_length
=
3199 cons_options ((struct packet
*)0, &client
-> packet
,
3200 (struct lease
*)0, client
, 0,
3201 (struct option_state
*)0, options
,
3202 &global_scope
, 0, 0, 0, (struct data_string
*)0,
3203 client
-> config
-> vendor_space_name
);
3205 /* Destroy the options cache. */
3206 option_state_dereference (&options
, MDL
);
3208 if (client
-> packet_length
< BOOTP_MIN_LEN
)
3209 client
-> packet_length
= BOOTP_MIN_LEN
;
3211 client
-> packet
.op
= BOOTREQUEST
;
3212 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
3213 /* Assumes hw_address is known, otherwise a random value may result */
3214 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
3215 client
-> packet
.hops
= 0;
3216 client
-> packet
.xid
= client
-> xid
;
3217 client
-> packet
.secs
= 0; /* Filled in by send_request. */
3218 if (can_receive_unicast_unconfigured (client
-> interface
))
3219 client
-> packet
.flags
= 0;
3221 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
3223 /* ciaddr must always be zero. */
3224 memset (&client
-> packet
.ciaddr
, 0,
3225 sizeof client
-> packet
.ciaddr
);
3226 memset (&client
-> packet
.yiaddr
, 0,
3227 sizeof client
-> packet
.yiaddr
);
3228 memset (&client
-> packet
.siaddr
, 0,
3229 sizeof client
-> packet
.siaddr
);
3230 client
-> packet
.giaddr
= giaddr
;
3231 memcpy (client
-> packet
.chaddr
,
3232 &client
-> interface
-> hw_address
.hbuf
[1],
3233 client
-> interface
-> hw_address
.hlen
);
3236 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
3240 void make_release (client
, lease
)
3241 struct client_state
*client
;
3242 struct client_lease
*lease
;
3244 unsigned char request
= DHCPRELEASE
;
3245 struct option_cache
*oc
;
3247 struct option_state
*options
= (struct option_state
*)0;
3249 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
3251 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
3252 DHO_DHCP_SERVER_IDENTIFIER
);
3253 make_client_options(client
, lease
, &request
, oc
, NULL
, NULL
, &options
);
3255 /* Set up the option buffer... */
3256 client
-> packet_length
=
3257 cons_options ((struct packet
*)0, &client
-> packet
,
3258 (struct lease
*)0, client
,
3259 /* maximum packet size */1500,
3260 (struct option_state
*)0,
3262 /* scope */ &global_scope
,
3266 (struct data_string
*)0,
3267 client
-> config
-> vendor_space_name
);
3269 if (client
-> packet_length
< BOOTP_MIN_LEN
)
3270 client
-> packet_length
= BOOTP_MIN_LEN
;
3271 option_state_dereference (&options
, MDL
);
3273 client
-> packet
.op
= BOOTREQUEST
;
3274 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
3275 /* Assumes hw_address is known, otherwise a random value may result */
3276 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
3277 client
-> packet
.hops
= 0;
3278 client
-> packet
.xid
= random ();
3279 client
-> packet
.secs
= 0;
3280 client
-> packet
.flags
= 0;
3281 memcpy (&client
-> packet
.ciaddr
,
3282 lease
-> address
.iabuf
, lease
-> address
.len
);
3283 memset (&client
-> packet
.yiaddr
, 0,
3284 sizeof client
-> packet
.yiaddr
);
3285 memset (&client
-> packet
.siaddr
, 0,
3286 sizeof client
-> packet
.siaddr
);
3287 client
-> packet
.giaddr
= giaddr
;
3288 memcpy (client
-> packet
.chaddr
,
3289 &client
-> interface
-> hw_address
.hbuf
[1],
3290 client
-> interface
-> hw_address
.hlen
);
3293 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
3297 void destroy_client_lease (lease
)
3298 struct client_lease
*lease
;
3300 if (lease
-> server_name
)
3301 dfree (lease
-> server_name
, MDL
);
3302 if (lease
-> filename
)
3303 dfree (lease
-> filename
, MDL
);
3304 option_state_dereference (&lease
-> options
, MDL
);
3305 free_client_lease (lease
, MDL
);
3308 FILE *leaseFile
= NULL
;
3309 int leases_written
= 0;
3311 void rewrite_client_leases ()
3313 struct interface_info
*ip
;
3314 struct client_state
*client
;
3315 struct client_lease
*lp
;
3317 if (leaseFile
!= NULL
)
3319 leaseFile
= fopen (path_dhclient_db
, "w");
3320 if (leaseFile
== NULL
) {
3321 log_error ("can't create %s: %m", path_dhclient_db
);
3325 /* If there is a default duid, write it out. */
3326 if (default_duid
.len
!= 0)
3327 write_duid(&default_duid
);
3329 /* Write out all the leases attached to configured interfaces that
3331 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
3332 for (client
= ip
-> client
; client
; client
= client
-> next
) {
3333 for (lp
= client
-> leases
; lp
; lp
= lp
-> next
) {
3334 write_client_lease (client
, lp
, 1, 0);
3336 if (client
-> active
)
3337 write_client_lease (client
,
3338 client
-> active
, 1, 0);
3340 if (client
->active_lease
!= NULL
)
3341 write_client6_lease(client
,
3342 client
->active_lease
,
3345 /* Reset last_write after rewrites. */
3346 client
->last_write
= 0;
3350 /* Write out any leases that are attached to interfaces that aren't
3351 currently configured. */
3352 for (ip
= dummy_interfaces
; ip
; ip
= ip
-> next
) {
3353 for (client
= ip
-> client
; client
; client
= client
-> next
) {
3354 for (lp
= client
-> leases
; lp
; lp
= lp
-> next
) {
3355 write_client_lease (client
, lp
, 1, 0);
3357 if (client
-> active
)
3358 write_client_lease (client
,
3359 client
-> active
, 1, 0);
3361 if (client
->active_lease
!= NULL
)
3362 write_client6_lease(client
,
3363 client
->active_lease
,
3366 /* Reset last_write after rewrites. */
3367 client
->last_write
= 0;
3373 void write_lease_option (struct option_cache
*oc
,
3374 struct packet
*packet
, struct lease
*lease
,
3375 struct client_state
*client_state
,
3376 struct option_state
*in_options
,
3377 struct option_state
*cfg_options
,
3378 struct binding_scope
**scope
,
3379 struct universe
*u
, void *stuff
)
3381 const char *name
, *dot
;
3382 struct data_string ds
;
3383 char *preamble
= stuff
;
3385 memset (&ds
, 0, sizeof ds
);
3387 if (u
!= &dhcp_universe
) {
3394 if (evaluate_option_cache (&ds
, packet
, lease
, client_state
,
3395 in_options
, cfg_options
, scope
, oc
, MDL
)) {
3396 /* The option name */
3397 fprintf(leaseFile
, "%soption %s%s%s", preamble
,
3398 name
, dot
, oc
->option
->name
);
3400 /* The option value if there is one */
3401 if ((oc
->option
->format
== NULL
) ||
3402 (oc
->option
->format
[0] != 'Z')) {
3403 fprintf(leaseFile
, " %s",
3404 pretty_print_option(oc
->option
, ds
.data
,
3408 /* The closing semi-colon and newline */
3409 fprintf(leaseFile
, ";\n");
3411 data_string_forget (&ds
, MDL
);
3415 /* Write an option cache to the lease store. */
3417 write_options(struct client_state
*client
, struct option_state
*options
,
3418 const char *preamble
)
3422 for (i
= 0; i
< options
->universe_count
; i
++) {
3423 option_space_foreach(NULL
, NULL
, client
, NULL
, options
,
3424 &global_scope
, universes
[i
],
3425 (char *)preamble
, write_lease_option
);
3430 * The "best" default DUID, since we cannot predict any information
3431 * about the system (such as whether or not the hardware addresses are
3432 * integrated into the motherboard or similar), is the "LLT", link local
3433 * plus time, DUID. For real stateless "LL" is better.
3435 * Once generated, this duid is stored into the state database, and
3436 * retained across restarts.
3438 * For the time being, there is probably a different state database for
3439 * every daemon, so this winds up being a per-interface identifier...which
3440 * is not how it is intended. Upcoming rearchitecting the client should
3441 * address this "one daemon model."
3444 form_duid(struct data_string
*duid
, const char *file
, int line
)
3446 struct interface_info
*ip
;
3450 /* For now, just use the first interface on the list. */
3454 log_fatal("Impossible condition at %s:%d.", MDL
);
3456 if ((ip
->hw_address
.hlen
== 0) ||
3457 (ip
->hw_address
.hlen
> sizeof(ip
->hw_address
.hbuf
)))
3458 log_fatal("Impossible hardware address length at %s:%d.", MDL
);
3461 duid_type
= stateless
? DUID_LL
: DUID_LLT
;
3464 * 2 bytes for the 'duid type' field.
3465 * 2 bytes for the 'htype' field.
3466 * (DUID_LLT) 4 bytes for the 'current time'.
3467 * enough bytes for the hardware address (note that hw_address has
3468 * the 'htype' on byte zero).
3470 len
= 4 + (ip
->hw_address
.hlen
- 1);
3471 if (duid_type
== DUID_LLT
)
3473 if (!buffer_allocate(&duid
->buffer
, len
, MDL
))
3474 log_fatal("no memory for default DUID!");
3475 duid
->data
= duid
->buffer
->data
;
3478 /* Basic Link Local Address type of DUID. */
3479 if (duid_type
== DUID_LLT
) {
3480 putUShort(duid
->buffer
->data
, DUID_LLT
);
3481 putUShort(duid
->buffer
->data
+ 2, ip
->hw_address
.hbuf
[0]);
3482 putULong(duid
->buffer
->data
+ 4, cur_time
- DUID_TIME_EPOCH
);
3483 memcpy(duid
->buffer
->data
+ 8, ip
->hw_address
.hbuf
+ 1,
3484 ip
->hw_address
.hlen
- 1);
3486 putUShort(duid
->buffer
->data
, DUID_LL
);
3487 putUShort(duid
->buffer
->data
+ 2, ip
->hw_address
.hbuf
[0]);
3488 memcpy(duid
->buffer
->data
+ 4, ip
->hw_address
.hbuf
+ 1,
3489 ip
->hw_address
.hlen
- 1);
3492 str
= quotify_buf(duid
->data
, duid
->len
, MDL
);
3494 log_info("Created duid.");
3496 log_info("Created duid %s.", str
);
3501 /* Write the default DUID to the lease store. */
3503 write_duid(struct data_string
*duid
)
3508 if ((duid
== NULL
) || (duid
->len
<= 2))
3509 return DHCP_R_INVALIDARG
;
3511 if (leaseFile
== NULL
) { /* XXX? */
3512 leaseFile
= fopen(path_dhclient_db
, "w");
3513 if (leaseFile
== NULL
) {
3514 log_error("can't create %s: %m", path_dhclient_db
);
3515 return ISC_R_IOERROR
;
3519 /* It would make more sense to write this as a hex string,
3520 * but our function to do that (print_hex_n) uses a fixed
3521 * length buffer...and we can't guarantee a duid would be
3522 * less than the fixed length.
3524 str
= quotify_buf(duid
->data
, duid
->len
, MDL
);
3526 return ISC_R_NOMEMORY
;
3528 stat
= fprintf(leaseFile
, "default-duid \"%s\";\n", str
);
3531 return ISC_R_IOERROR
;
3533 if (fflush(leaseFile
) != 0)
3534 return ISC_R_IOERROR
;
3536 return ISC_R_SUCCESS
;
3539 /* Write a DHCPv6 lease to the store. */
3541 write_client6_lease(struct client_state
*client
, struct dhc6_lease
*lease
,
3542 int rewrite
, int sync
)
3545 struct dhc6_addr
*addr
;
3549 /* This should include the current lease. */
3550 if (!rewrite
&& (leases_written
++ > 20)) {
3551 rewrite_client_leases();
3553 return ISC_R_SUCCESS
;
3556 if (client
== NULL
|| lease
== NULL
)
3557 return DHCP_R_INVALIDARG
;
3559 if (leaseFile
== NULL
) { /* XXX? */
3560 leaseFile
= fopen(path_dhclient_db
, "w");
3561 if (leaseFile
== NULL
) {
3562 log_error("can't create %s: %m", path_dhclient_db
);
3563 return ISC_R_IOERROR
;
3567 stat
= fprintf(leaseFile
, "lease6 {\n");
3569 return ISC_R_IOERROR
;
3571 stat
= fprintf(leaseFile
, " interface \"%s\";\n",
3572 client
->interface
->name
);
3574 return ISC_R_IOERROR
;
3576 for (ia
= lease
->bindings
; ia
!= NULL
; ia
= ia
->next
) {
3577 switch (ia
->ia_type
) {
3589 stat
= fprintf(leaseFile
, " %s %s {\n",
3590 ianame
, print_hex_1(4, ia
->iaid
, 12));
3592 return ISC_R_IOERROR
;
3594 if (ia
->ia_type
!= D6O_IA_TA
)
3595 stat
= fprintf(leaseFile
, " starts %d;\n"
3598 (int)ia
->starts
, ia
->renew
, ia
->rebind
);
3600 stat
= fprintf(leaseFile
, " starts %d;\n",
3603 return ISC_R_IOERROR
;
3605 for (addr
= ia
->addrs
; addr
!= NULL
; addr
= addr
->next
) {
3606 if (ia
->ia_type
!= D6O_IA_PD
)
3607 stat
= fprintf(leaseFile
,
3609 piaddr(addr
->address
));
3611 stat
= fprintf(leaseFile
,
3612 " iaprefix %s/%d {\n",
3613 piaddr(addr
->address
),
3616 return ISC_R_IOERROR
;
3618 stat
= fprintf(leaseFile
, " starts %d;\n"
3619 " preferred-life %u;\n"
3621 (int)addr
->starts
, addr
->preferred_life
,
3624 return ISC_R_IOERROR
;
3626 if (addr
->options
!= NULL
)
3627 write_options(client
, addr
->options
, " ");
3629 stat
= fprintf(leaseFile
, " }\n");
3631 return ISC_R_IOERROR
;
3634 if (ia
->options
!= NULL
)
3635 write_options(client
, ia
->options
, " ");
3637 stat
= fprintf(leaseFile
, " }\n");
3639 return ISC_R_IOERROR
;
3642 if (lease
->released
) {
3643 stat
= fprintf(leaseFile
, " released;\n");
3645 return ISC_R_IOERROR
;
3648 if (lease
->options
!= NULL
)
3649 write_options(client
, lease
->options
, " ");
3651 stat
= fprintf(leaseFile
, "}\n");
3653 return ISC_R_IOERROR
;
3655 if (fflush(leaseFile
) != 0)
3656 return ISC_R_IOERROR
;
3659 if (fsync(fileno(leaseFile
)) < 0) {
3660 log_error("write_client_lease: fsync(): %m");
3661 return ISC_R_IOERROR
;
3665 return ISC_R_SUCCESS
;
3668 int write_client_lease (client
, lease
, rewrite
, makesure
)
3669 struct client_state
*client
;
3670 struct client_lease
*lease
;
3674 struct data_string ds
;
3680 if (leases_written
++ > 20) {
3681 rewrite_client_leases ();
3686 /* If the lease came from the config file, we don't need to stash
3687 a copy in the lease database. */
3688 if (lease
-> is_static
)
3691 if (leaseFile
== NULL
) { /* XXX */
3692 leaseFile
= fopen (path_dhclient_db
, "w");
3693 if (leaseFile
== NULL
) {
3694 log_error ("can't create %s: %m", path_dhclient_db
);
3700 fprintf (leaseFile
, "lease {\n");
3701 if (lease
-> is_bootp
) {
3702 fprintf (leaseFile
, " bootp;\n");
3708 fprintf (leaseFile
, " interface \"%s\";\n",
3709 client
-> interface
-> name
);
3714 if (client
-> name
) {
3715 fprintf (leaseFile
, " name \"%s\";\n", client
-> name
);
3721 fprintf (leaseFile
, " fixed-address %s;\n",
3722 piaddr (lease
-> address
));
3727 if (lease
-> filename
) {
3728 s
= quotify_string (lease
-> filename
, MDL
);
3730 fprintf (leaseFile
, " filename \"%s\";\n", s
);
3740 if (lease
->server_name
!= NULL
) {
3741 s
= quotify_string(lease
->server_name
, MDL
);
3743 fprintf(leaseFile
, " server-name \"%s\";\n", s
);
3752 if (lease
-> medium
) {
3753 s
= quotify_string (lease
-> medium
-> string
, MDL
);
3755 fprintf (leaseFile
, " medium \"%s\";\n", s
);
3769 memset (&ds
, 0, sizeof ds
);
3771 write_options(client
, lease
->options
, " ");
3773 tval
= print_time(lease
->renewal
);
3775 fprintf(leaseFile
, " renew %s\n", tval
) < 0)
3778 tval
= print_time(lease
->rebind
);
3780 fprintf(leaseFile
, " rebind %s\n", tval
) < 0)
3783 tval
= print_time(lease
->expiry
);
3785 fprintf(leaseFile
, " expire %s\n", tval
) < 0)
3788 if (fprintf(leaseFile
, "}\n") < 0)
3791 if (fflush(leaseFile
) != 0)
3794 client
->last_write
= cur_time
;
3796 if (!errors
&& makesure
) {
3797 if (fsync (fileno (leaseFile
)) < 0) {
3798 log_info ("write_client_lease: %m");
3803 return errors
? 0 : 1;
3806 /* Variables holding name of script and file pointer for writing to
3807 script. Needless to say, this is not reentrant - only one script
3808 can be invoked at a time. */
3809 char scriptName
[256];
3812 void script_init (client
, reason
, medium
)
3813 struct client_state
*client
;
3815 struct string_list
*medium
;
3817 struct string_list
*sl
, *next
;
3820 for (sl
= client
-> env
; sl
; sl
= next
) {
3824 client
-> env
= (struct string_list
*)0;
3827 if (client
-> interface
) {
3828 client_envadd (client
, "", "interface", "%s",
3829 client
-> interface
-> name
);
3832 client_envadd (client
,
3833 "", "client", "%s", client
-> name
);
3835 client_envadd (client
,
3836 "", "medium", "%s", medium
-> string
);
3838 client_envadd (client
, "", "reason", "%s", reason
);
3839 client_envadd (client
, "", "pid", "%ld", (long int)getpid ());
3843 void client_option_envadd (struct option_cache
*oc
,
3844 struct packet
*packet
, struct lease
*lease
,
3845 struct client_state
*client_state
,
3846 struct option_state
*in_options
,
3847 struct option_state
*cfg_options
,
3848 struct binding_scope
**scope
,
3849 struct universe
*u
, void *stuff
)
3851 struct envadd_state
*es
= stuff
;
3852 struct data_string data
;
3853 memset (&data
, 0, sizeof data
);
3855 if (evaluate_option_cache (&data
, packet
, lease
, client_state
,
3856 in_options
, cfg_options
, scope
, oc
, MDL
)) {
3859 if (dhcp_option_ev_name (name
, sizeof name
,
3863 value
= pretty_print_option(oc
->option
,
3866 length
= strlen(value
);
3868 if (check_option_values(oc
->option
->universe
,
3870 value
, length
) == 0) {
3871 client_envadd(es
->client
, es
->prefix
,
3874 log_error("suspect value in %s "
3875 "option - discarded",
3878 data_string_forget (&data
, MDL
);
3884 void script_write_params (client
, prefix
, lease
)
3885 struct client_state
*client
;
3887 struct client_lease
*lease
;
3890 struct data_string data
;
3891 struct option_cache
*oc
;
3892 struct envadd_state es
;
3897 client_envadd (client
,
3898 prefix
, "ip_address", "%s", piaddr (lease
-> address
));
3900 /* If we've set the next server address in the lease structure
3901 put it into an environment variable for the script */
3902 if (lease
->next_srv_addr
.len
!= 0) {
3903 client_envadd(client
, prefix
, "next_server", "%s",
3904 piaddr(lease
->next_srv_addr
));
3907 /* For the benefit of Linux (and operating systems which may
3908 have similar needs), compute the network address based on
3909 the supplied ip address and netmask, if provided. Also
3910 compute the broadcast address (the host address all ones
3911 broadcast address, not the host address all zeroes
3912 broadcast address). */
3914 memset (&data
, 0, sizeof data
);
3915 oc
= lookup_option (&dhcp_universe
, lease
-> options
, DHO_SUBNET_MASK
);
3916 if (oc
&& evaluate_option_cache (&data
, (struct packet
*)0,
3917 (struct lease
*)0, client
,
3918 (struct option_state
*)0,
3920 &global_scope
, oc
, MDL
)) {
3922 struct iaddr netmask
, subnet
, broadcast
;
3925 * No matter the length of the subnet-mask option,
3926 * use only the first four octets. Note that
3927 * subnet-mask options longer than 4 octets are not
3928 * in conformance with RFC 2132, but servers with this
3931 memcpy(netmask
.iabuf
, data
.data
, 4);
3933 data_string_forget (&data
, MDL
);
3935 subnet
= subnet_number (lease
-> address
, netmask
);
3937 client_envadd (client
, prefix
, "network_number",
3938 "%s", piaddr (subnet
));
3940 oc
= lookup_option (&dhcp_universe
,
3942 DHO_BROADCAST_ADDRESS
);
3944 !(evaluate_option_cache
3945 (&data
, (struct packet
*)0,
3946 (struct lease
*)0, client
,
3947 (struct option_state
*)0,
3949 &global_scope
, oc
, MDL
))) {
3950 broadcast
= broadcast_addr (subnet
, netmask
);
3951 if (broadcast
.len
) {
3952 client_envadd (client
,
3953 prefix
, "broadcast_address",
3954 "%s", piaddr (broadcast
));
3959 data_string_forget (&data
, MDL
);
3962 if (lease
->filename
) {
3963 if (check_option_values(NULL
, DHO_ROOT_PATH
,
3965 strlen(lease
->filename
)) == 0) {
3966 client_envadd(client
, prefix
, "filename",
3967 "%s", lease
->filename
);
3969 log_error("suspect value in %s "
3970 "option - discarded",
3975 if (lease
->server_name
) {
3976 if (check_option_values(NULL
, DHO_HOST_NAME
,
3978 strlen(lease
->server_name
)) == 0 ) {
3979 client_envadd (client
, prefix
, "server_name",
3980 "%s", lease
->server_name
);
3982 log_error("suspect value in %s "
3983 "option - discarded",
3984 lease
->server_name
);
3988 for (i
= 0; i
< lease
-> options
-> universe_count
; i
++) {
3989 option_space_foreach ((struct packet
*)0, (struct lease
*)0,
3990 client
, (struct option_state
*)0,
3991 lease
-> options
, &global_scope
,
3993 &es
, client_option_envadd
);
3995 client_envadd (client
, prefix
, "expiry", "%d", (int)(lease
-> expiry
));
3999 * Write out the environment variables for the objects that the
4000 * client requested. If the object was requested the variable will be:
4001 * requested_<option_name>=1
4002 * If it wasn't requested there won't be a variable.
4004 void script_write_requested(client
)
4005 struct client_state
*client
;
4008 struct option
**req
;
4010 req
= client
->config
->requested_options
;
4015 for (i
= 0 ; req
[i
] != NULL
; i
++) {
4016 if ((req
[i
]->universe
== &dhcp_universe
) &&
4017 dhcp_option_ev_name(name
, sizeof(name
), req
[i
])) {
4018 client_envadd(client
, "requested_", name
, "%d", 1);
4023 int script_go (client
)
4024 struct client_state
*client
;
4029 char reason
[] = "REASON=NBI";
4030 static char client_path
[] = CLIENT_PATH
;
4032 struct string_list
*sp
, *next
;
4033 int pid
, wpid
, wstatus
;
4036 scriptName
= client
-> config
-> script_name
;
4038 scriptName
= top_level_config
.script_name
;
4040 envp
= dmalloc (((client
? client
-> envc
: 2) +
4041 client_env_count
+ 2) * sizeof (char *), MDL
);
4043 log_error ("No memory for client script environment.");
4047 /* Copy out the environment specified on the command line,
4049 for (sp
= client_env
; sp
; sp
= sp
-> next
) {
4050 envp
[i
++] = sp
-> string
;
4052 /* Copy out the environment specified by dhclient. */
4054 for (sp
= client
-> env
; sp
; sp
= sp
-> next
) {
4055 envp
[i
++] = sp
-> string
;
4058 envp
[i
++] = reason
;
4061 envp
[i
++] = client_path
;
4062 envp
[i
] = (char *)0;
4064 argv
[0] = scriptName
;
4065 argv
[1] = (char *)0;
4069 log_error ("fork: %m");
4073 wpid
= wait (&wstatus
);
4074 } while (wpid
!= pid
&& wpid
> 0);
4076 log_error ("wait: %m");
4080 /* We don't want to pass an open file descriptor for
4081 * dhclient.leases when executing dhclient-script.
4083 if (leaseFile
!= NULL
)
4085 execve (scriptName
, argv
, envp
);
4086 log_error ("execve (%s, ...): %m", scriptName
);
4091 for (sp
= client
-> env
; sp
; sp
= next
) {
4095 client
-> env
= (struct string_list
*)0;
4099 gettimeofday(&cur_tv
, NULL
);
4100 return (WIFEXITED (wstatus
) ?
4101 WEXITSTATUS (wstatus
) : -WTERMSIG (wstatus
));
4104 void client_envadd (struct client_state
*client
,
4105 const char *prefix
, const char *name
, const char *fmt
, ...)
4110 struct string_list
*val
;
4113 va_start (list
, fmt
);
4114 len
= vsnprintf (spbuf
, sizeof spbuf
, fmt
, list
);
4117 val
= dmalloc (strlen (prefix
) + strlen (name
) + 1 /* = */ +
4118 len
+ sizeof *val
, MDL
);
4126 if (len
>= sizeof spbuf
) {
4127 va_start (list
, fmt
);
4128 vsnprintf (s
, len
+ 1, fmt
, list
);
4132 val
-> next
= client
-> env
;
4133 client
-> env
= val
;
4137 int dhcp_option_ev_name (buf
, buflen
, option
)
4140 struct option
*option
;
4146 if (option
-> universe
!= &dhcp_universe
) {
4147 s
= option
-> universe
-> name
;
4156 if (j
+ 1 == buflen
)
4166 if (j
+ 1 == buflen
)
4179 static int state
= 0;
4182 /* Don't become a daemon if the user requested otherwise. */
4184 write_client_pid_file ();
4188 /* Only do it once. */
4193 /* Stop logging to stderr... */
4196 /* Become a daemon... */
4197 if ((pid
= fork ()) < 0)
4198 log_fatal ("Can't fork daemon: %m");
4201 /* Become session leader and get pid... */
4204 /* Close standard I/O descriptors. */
4209 /* Reopen them on /dev/null. */
4210 (void) open("/dev/null", O_RDWR
);
4211 (void) open("/dev/null", O_RDWR
);
4212 (void) open("/dev/null", O_RDWR
);
4214 write_client_pid_file ();
4216 IGNORE_RET (chdir("/"));
4219 void write_client_pid_file ()
4224 /* nothing to do if the user doesn't want a pid file */
4225 if (no_pid_file
== ISC_TRUE
) {
4229 pfdesc
= open (path_dhclient_pid
, O_CREAT
| O_TRUNC
| O_WRONLY
, 0644);
4232 log_error ("Can't create %s: %m", path_dhclient_pid
);
4236 pf
= fdopen (pfdesc
, "w");
4239 log_error ("Can't fdopen %s: %m", path_dhclient_pid
);
4241 fprintf (pf
, "%ld\n", (long)getpid ());
4246 void client_location_changed ()
4248 struct interface_info
*ip
;
4249 struct client_state
*client
;
4251 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
4252 for (client
= ip
-> client
; client
; client
= client
-> next
) {
4253 switch (client
-> state
) {
4255 cancel_timeout (send_discover
, client
);
4259 cancel_timeout (state_bound
, client
);
4265 cancel_timeout (send_request
, client
);
4273 client
-> state
= S_INIT
;
4274 state_reboot (client
);
4279 void do_release(client
)
4280 struct client_state
*client
;
4282 struct data_string ds
;
4283 struct option_cache
*oc
;
4285 #if defined(DHCPv6) && defined(DHCP4o6)
4286 if (dhcpv4_over_dhcpv6
&& (dhcp4o6_state
<= 0)) {
4287 if (dhcp4o6_state
< 0)
4289 client
->pending
= P_RELEASE
;
4294 /* Pick a random xid. */
4295 client
-> xid
= random ();
4297 /* is there even a lease to release? */
4298 if (client
-> active
) {
4299 /* Make a DHCPRELEASE packet, and set appropriate per-interface
4301 make_release (client
, client
-> active
);
4303 memset (&ds
, 0, sizeof ds
);
4304 oc
= lookup_option (&dhcp_universe
,
4305 client
-> active
-> options
,
4306 DHO_DHCP_SERVER_IDENTIFIER
);
4308 evaluate_option_cache (&ds
, (struct packet
*)0,
4309 (struct lease
*)0, client
,
4310 (struct option_state
*)0,
4311 client
-> active
-> options
,
4312 &global_scope
, oc
, MDL
)) {
4314 memcpy (client
-> destination
.iabuf
,
4316 client
-> destination
.len
= 4;
4318 client
-> destination
= iaddr_broadcast
;
4320 data_string_forget (&ds
, MDL
);
4322 client
-> destination
= iaddr_broadcast
;
4323 client
-> first_sending
= cur_time
;
4324 client
-> interval
= client
-> config
-> initial_interval
;
4326 /* Zap the medium list... */
4327 client
-> medium
= (struct string_list
*)0;
4329 /* Send out the first and only DHCPRELEASE packet. */
4330 send_release (client
);
4332 /* Do the client script RELEASE operation. */
4333 script_init (client
,
4334 "RELEASE", (struct string_list
*)0);
4335 if (client
-> alias
)
4336 script_write_params (client
, "alias_",
4338 script_write_params (client
, "old_", client
-> active
);
4339 script_write_requested(client
);
4343 /* Cancel any timeouts. */
4344 cancel_timeout (state_bound
, client
);
4345 cancel_timeout (send_discover
, client
);
4346 cancel_timeout (state_init
, client
);
4347 cancel_timeout (send_request
, client
);
4348 cancel_timeout (state_reboot
, client
);
4349 client
-> state
= S_STOPPED
;
4351 #if defined(DHCPv6) && defined(DHCP4o6)
4352 if (dhcpv4_over_dhcpv6
)
4357 int dhclient_interface_shutdown_hook (struct interface_info
*interface
)
4359 do_release (interface
-> client
);
4364 int dhclient_interface_discovery_hook (struct interface_info
*tmp
)
4366 struct interface_info
*last
, *ip
;
4367 /* See if we can find the client from dummy_interfaces */
4369 for (ip
= dummy_interfaces
; ip
; ip
= ip
-> next
) {
4370 if (!strcmp (ip
-> name
, tmp
-> name
)) {
4371 /* Remove from dummy_interfaces */
4373 ip
= (struct interface_info
*)0;
4374 interface_reference (&ip
, last
-> next
, MDL
);
4375 interface_dereference (&last
-> next
, MDL
);
4377 interface_reference (&last
-> next
,
4379 interface_dereference (&ip
-> next
,
4383 ip
= (struct interface_info
*)0;
4384 interface_reference (&ip
,
4385 dummy_interfaces
, MDL
);
4386 interface_dereference (&dummy_interfaces
, MDL
);
4388 interface_reference (&dummy_interfaces
,
4390 interface_dereference (&ip
-> next
,
4394 /* Copy "client" to tmp */
4396 tmp
-> client
= ip
-> client
;
4397 tmp
-> client
-> interface
= tmp
;
4399 interface_dereference (&ip
, MDL
);
4407 isc_result_t
dhclient_interface_startup_hook (struct interface_info
*interface
)
4409 struct interface_info
*ip
;
4410 struct client_state
*client
;
4412 /* This code needs some rethinking. It doesn't test against
4413 a signal name, and it just kind of bulls into doing something
4414 that may or may not be appropriate. */
4417 interface_reference (&interface
-> next
, interfaces
, MDL
);
4418 interface_dereference (&interfaces
, MDL
);
4420 interface_reference (&interfaces
, interface
, MDL
);
4422 discover_interfaces (DISCOVER_UNCONFIGURED
);
4424 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
4425 /* If interfaces were specified, don't configure
4426 interfaces that weren't specified! */
4427 if (ip
-> flags
& INTERFACE_RUNNING
||
4428 (ip
-> flags
& (INTERFACE_REQUESTED
|
4429 INTERFACE_AUTOMATIC
)) !=
4430 INTERFACE_REQUESTED
)
4432 script_init (ip
-> client
,
4433 "PREINIT", (struct string_list
*)0);
4434 if (ip
-> client
-> alias
)
4435 script_write_params (ip
-> client
, "alias_",
4436 ip
-> client
-> alias
);
4437 script_go (ip
-> client
);
4440 discover_interfaces (interfaces_requested
!= 0
4441 ? DISCOVER_REQUESTED
4442 : DISCOVER_RUNNING
);
4444 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
4445 if (ip
-> flags
& INTERFACE_RUNNING
)
4447 ip
-> flags
|= INTERFACE_RUNNING
;
4448 for (client
= ip
->client
; client
; client
= client
->next
) {
4449 client
->state
= S_INIT
;
4450 state_reboot(client
);
4453 return ISC_R_SUCCESS
;
4456 /* The client should never receive a relay agent information option,
4457 so if it does, log it and discard it. */
4459 int parse_agent_information_option (packet
, len
, data
)
4460 struct packet
*packet
;
4467 /* The client never sends relay agent information options. */
4469 unsigned cons_agent_information_options (cfg_options
, outpacket
,
4471 struct option_state
*cfg_options
;
4472 struct dhcp_packet
*outpacket
;
4479 static void shutdown_exit (void *foo
)
4481 /* get rid of the pid if we can */
4482 if (no_pid_file
== ISC_FALSE
)
4483 (void) unlink(path_dhclient_pid
);
4487 #if defined (NSUPDATE)
4489 * If the first query fails, the updater MUST NOT delete the DNS name. It
4490 * may be that the host whose lease on the server has expired has moved
4491 * to another network and obtained a lease from a different server,
4492 * which has caused the client's A RR to be replaced. It may also be
4493 * that some other client has been configured with a name that matches
4494 * the name of the DHCP client, and the policy was that the last client
4495 * to specify the name would get the name. In this case, the DHCID RR
4496 * will no longer match the updater's notion of the client-identity of
4497 * the host pointed to by the DNS name.
4498 * -- "Interaction between DHCP and DNS"
4501 /* The first and second stages are pretty similar so we combine them */
4503 client_dns_remove_action(dhcp_ddns_cb_t
*ddns_cb
,
4504 isc_result_t eresult
)
4507 isc_result_t result
;
4509 if ((eresult
== ISC_R_SUCCESS
) &&
4510 (ddns_cb
->state
== DDNS_STATE_REM_FW_YXDHCID
)) {
4511 /* Do the second stage of the FWD removal */
4512 ddns_cb
->state
= DDNS_STATE_REM_FW_NXRR
;
4514 result
= ddns_modify_fwd(ddns_cb
, MDL
);
4515 if (result
== ISC_R_SUCCESS
) {
4520 /* If we are done or have an error clean up */
4521 dhclient_ddns_cb_free(ddns_cb
, MDL
);
4526 client_dns_remove(struct client_state
*client
,
4529 dhcp_ddns_cb_t
*ddns_cb
;
4530 isc_result_t result
;
4532 /* if we have an old ddns request for this client, cancel it */
4533 if (client
->ddns_cb
!= NULL
) {
4534 ddns_cancel(client
->ddns_cb
, MDL
);
4535 client
->ddns_cb
= NULL
;
4538 ddns_cb
= ddns_cb_alloc(MDL
);
4539 if (ddns_cb
!= NULL
) {
4540 ddns_cb
->address
= *addr
;
4541 ddns_cb
->timeout
= 0;
4543 ddns_cb
->state
= DDNS_STATE_REM_FW_YXDHCID
;
4544 ddns_cb
->flags
= DDNS_UPDATE_ADDR
;
4545 ddns_cb
->cur_func
= client_dns_remove_action
;
4547 result
= client_dns_update(client
, ddns_cb
);
4549 if (result
!= ISC_R_TIMEDOUT
) {
4550 dhclient_ddns_cb_free(ddns_cb
, MDL
);
4556 isc_result_t
dhcp_set_control_state (control_object_state_t oldstate
,
4557 control_object_state_t newstate
)
4559 struct interface_info
*ip
;
4560 struct client_state
*client
;
4563 if (newstate
== server_shutdown
) {
4565 if (shutdown_signal
== SIGUSR1
)
4566 return ISC_R_SUCCESS
;
4567 /* Log shutdown on signal. */
4568 if ((shutdown_signal
== SIGINT
) ||
4569 (shutdown_signal
== SIGTERM
)) {
4570 log_info("Received signal %d, initiating shutdown.",
4573 /* Mark it was called. */
4574 shutdown_signal
= SIGUSR1
;
4577 /* Do the right thing for each interface. */
4578 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
4579 for (client
= ip
-> client
; client
; client
= client
-> next
) {
4581 case server_startup
:
4582 return ISC_R_SUCCESS
;
4584 case server_running
:
4585 return ISC_R_SUCCESS
;
4587 case server_shutdown
:
4588 if (client
-> active
&&
4589 client
-> active
-> expiry
> cur_time
) {
4590 #if defined (NSUPDATE)
4591 if (client
->config
->do_forward_update
) {
4592 client_dns_remove(client
,
4593 &client
->active
->address
);
4596 do_release (client
);
4600 case server_hibernate
:
4601 state_stop (client
);
4605 state_reboot (client
);
4611 if (newstate
== server_shutdown
) {
4612 tv
.tv_sec
= cur_tv
.tv_sec
;
4613 tv
.tv_usec
= cur_tv
.tv_usec
+ 1;
4614 add_timeout(&tv
, shutdown_exit
, 0, 0, 0);
4616 return ISC_R_SUCCESS
;
4619 #if defined (NSUPDATE)
4621 * Called after a timeout if the DNS update failed on the previous try.
4622 * Starts the retry process. If the retry times out it will schedule
4623 * this routine to run again after a 10x wait.
4626 client_dns_update_timeout (void *cp
)
4628 dhcp_ddns_cb_t
*ddns_cb
= (dhcp_ddns_cb_t
*)cp
;
4629 struct client_state
*client
= (struct client_state
*)ddns_cb
->lease
;
4630 isc_result_t status
= ISC_R_FAILURE
;
4632 if ((client
!= NULL
) &&
4633 ((client
->active
!= NULL
) ||
4634 (client
->active_lease
!= NULL
)))
4635 status
= client_dns_update(client
, ddns_cb
);
4638 * A status of timedout indicates that we started the update and
4639 * have released control of the control block. Any other status
4640 * indicates that we should clean up the control block. We either
4641 * got a success which indicates that we didn't really need to
4642 * send an update or some other error in which case we weren't able
4643 * to start the update process. In both cases we still own
4644 * the control block and should free it.
4646 if (status
!= ISC_R_TIMEDOUT
) {
4647 dhclient_ddns_cb_free(ddns_cb
, MDL
);
4652 * If the first query succeeds, the updater can conclude that it
4653 * has added a new name whose only RRs are the A and DHCID RR records.
4654 * The A RR update is now complete (and a client updater is finished,
4655 * while a server might proceed to perform a PTR RR update).
4656 * -- "Interaction between DHCP and DNS"
4658 * If the second query succeeds, the updater can conclude that the current
4659 * client was the last client associated with the domain name, and that
4660 * the name now contains the updated A RR. The A RR update is now
4661 * complete (and a client updater is finished, while a server would
4662 * then proceed to perform a PTR RR update).
4663 * -- "Interaction between DHCP and DNS"
4665 * If the second query fails with NXRRSET, the updater must conclude
4666 * that the client's desired name is in use by another host. At this
4667 * juncture, the updater can decide (based on some administrative
4668 * configuration outside of the scope of this document) whether to let
4669 * the existing owner of the name keep that name, and to (possibly)
4670 * perform some name disambiguation operation on behalf of the current
4671 * client, or to replace the RRs on the name with RRs that represent
4672 * the current client. If the configured policy allows replacement of
4673 * existing records, the updater submits a query that deletes the
4674 * existing A RR and the existing DHCID RR, adding A and DHCID RRs that
4675 * represent the IP address and client-identity of the new client.
4676 * -- "Interaction between DHCP and DNS"
4679 /* The first and second stages are pretty similar so we combine them */
4681 client_dns_update_action(dhcp_ddns_cb_t
*ddns_cb
,
4682 isc_result_t eresult
)
4684 isc_result_t result
;
4690 /* Either we succeeded or broke in a bad way, clean up */
4695 * This is the only difference between the two stages,
4696 * check to see if it is the first stage, in which case
4697 * start the second stage
4699 if (ddns_cb
->state
== DDNS_STATE_ADD_FW_NXDOMAIN
) {
4700 ddns_cb
->state
= DDNS_STATE_ADD_FW_YXDHCID
;
4701 ddns_cb
->cur_func
= client_dns_update_action
;
4703 result
= ddns_modify_fwd(ddns_cb
, MDL
);
4704 if (result
== ISC_R_SUCCESS
) {
4710 case ISC_R_TIMEDOUT
:
4712 * We got a timeout response from the DNS module. Schedule
4713 * another attempt for later. We forget the name, dhcid and
4714 * zone so if it gets changed we will get the new information.
4716 data_string_forget(&ddns_cb
->fwd_name
, MDL
);
4717 data_string_forget(&ddns_cb
->dhcid
, MDL
);
4718 if (ddns_cb
->zone
!= NULL
) {
4719 forget_zone((struct dns_zone
**)&ddns_cb
->zone
);
4722 /* Reset to doing the first stage */
4723 ddns_cb
->state
= DDNS_STATE_ADD_FW_NXDOMAIN
;
4724 ddns_cb
->cur_func
= client_dns_update_action
;
4726 /* and update our timer */
4727 if (ddns_cb
->timeout
< 3600)
4728 ddns_cb
->timeout
*= 10;
4729 tv
.tv_sec
= cur_tv
.tv_sec
+ ddns_cb
->timeout
;
4730 tv
.tv_usec
= cur_tv
.tv_usec
;
4731 add_timeout(&tv
, client_dns_update_timeout
,
4732 ddns_cb
, NULL
, NULL
);
4736 dhclient_ddns_cb_free(ddns_cb
, MDL
);
4740 /* See if we should do a DNS update, and if so, do it. */
4743 client_dns_update(struct client_state
*client
, dhcp_ddns_cb_t
*ddns_cb
)
4745 struct data_string client_identifier
;
4746 struct option_cache
*oc
;
4752 /* If we didn't send an FQDN option, we certainly aren't going to
4753 be doing an update. */
4754 if (!client
-> sent_options
)
4755 return ISC_R_SUCCESS
;
4757 /* If we don't have a lease, we can't do an update. */
4758 if ((client
->active
== NULL
) && (client
->active_lease
== NULL
))
4759 return ISC_R_SUCCESS
;
4761 /* If we set the no client update flag, don't do the update. */
4762 if ((oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
4763 FQDN_NO_CLIENT_UPDATE
)) &&
4764 evaluate_boolean_option_cache (&ignorep
, (struct packet
*)0,
4765 (struct lease
*)0, client
,
4766 client
-> sent_options
,
4767 (struct option_state
*)0,
4768 &global_scope
, oc
, MDL
))
4769 return ISC_R_SUCCESS
;
4771 /* If we set the "server, please update" flag, or didn't set it
4772 to false, don't do the update. */
4773 if (!(oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
4774 FQDN_SERVER_UPDATE
)) ||
4775 evaluate_boolean_option_cache (&ignorep
, (struct packet
*)0,
4776 (struct lease
*)0, client
,
4777 client
-> sent_options
,
4778 (struct option_state
*)0,
4779 &global_scope
, oc
, MDL
))
4780 return ISC_R_SUCCESS
;
4782 /* If no FQDN option was supplied, don't do the update. */
4783 if (!(oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
4785 !evaluate_option_cache (&ddns_cb
->fwd_name
, (struct packet
*)0,
4786 (struct lease
*)0, client
,
4787 client
-> sent_options
,
4788 (struct option_state
*)0,
4789 &global_scope
, oc
, MDL
))
4790 return ISC_R_SUCCESS
;
4793 * Construct the DHCID value for use in the DDNS update process
4794 * We have the newer standard version and the older interim version
4795 * chosen by the '-I' option. The interim version is left as is
4796 * for backwards compatibility. The standard version is based on
4797 * RFC 4701 section 3.3
4802 memset(&client_identifier
, 0, sizeof(client_identifier
));
4804 if (std_dhcid
== 1) {
4805 /* standard style */
4806 ddns_cb
->dhcid_class
= dns_rdatatype_dhcid
;
4810 ddns_cb
->dhcid_class
= dns_rdatatype_txt
;
4811 /* for backwards compatibility */
4812 ddns_v4_type
= DHO_DHCP_CLIENT_IDENTIFIER
;
4814 if (client
->active_lease
!= NULL
) {
4815 /* V6 request, get the client identifier, then
4816 * construct the dhcid for either standard
4818 if (((oc
= lookup_option(&dhcpv6_universe
,
4819 client
->sent_options
,
4820 D6O_CLIENTID
)) != NULL
) &&
4821 evaluate_option_cache(&client_identifier
, NULL
,
4823 client
->sent_options
, NULL
,
4824 &global_scope
, oc
, MDL
)) {
4825 result
= get_dhcid(ddns_cb
, 2,
4826 client_identifier
.data
,
4827 client_identifier
.len
);
4828 data_string_forget(&client_identifier
, MDL
);
4830 log_fatal("Impossible condition at %s:%d.", MDL
);
4833 * V4 request, use the client id if there is one or the
4834 * mac address if there isn't. If we have a client id
4835 * we check to see if it is an embedded DUID.
4837 if (((oc
= lookup_option(&dhcp_universe
,
4838 client
->sent_options
,
4839 DHO_DHCP_CLIENT_IDENTIFIER
)) != NULL
) &&
4840 evaluate_option_cache(&client_identifier
, NULL
,
4842 client
->sent_options
, NULL
,
4843 &global_scope
, oc
, MDL
)) {
4844 if ((std_dhcid
== 1) && (duid_v4
== 1) &&
4845 (client_identifier
.data
[0] == 255)) {
4847 * This appears to be an embedded DUID,
4848 * extract it and treat it as such
4850 if (client_identifier
.len
<= 5)
4851 log_fatal("Impossible condition at %s:%d.",
4853 result
= get_dhcid(ddns_cb
, 2,
4854 client_identifier
.data
+ 5,
4855 client_identifier
.len
- 5);
4857 result
= get_dhcid(ddns_cb
, ddns_v4_type
,
4858 client_identifier
.data
,
4859 client_identifier
.len
);
4861 data_string_forget(&client_identifier
, MDL
);
4863 result
= get_dhcid(ddns_cb
, 0,
4864 client
->interface
->hw_address
.hbuf
,
4865 client
->interface
->hw_address
.hlen
);
4869 return ISC_R_SUCCESS
;
4875 if (ddns_cb
->fwd_name
.len
&& ddns_cb
->dhcid
.len
) {
4876 rcode
= ddns_modify_fwd(ddns_cb
, MDL
);
4878 rcode
= ISC_R_FAILURE
;
4881 * A success from the modify routine means we are performing
4882 * async processing, for which we use the timedout error message.
4884 if (rcode
== ISC_R_SUCCESS
) {
4885 rcode
= ISC_R_TIMEDOUT
;
4893 * Schedule the first update. They will continue to retry occasionally
4894 * until they no longer time out (or fail).
4897 dhclient_schedule_updates(struct client_state
*client
,
4901 dhcp_ddns_cb_t
*ddns_cb
;
4904 if (!client
->config
->do_forward_update
)
4907 /* cancel any outstanding ddns requests */
4908 if (client
->ddns_cb
!= NULL
) {
4909 ddns_cancel(client
->ddns_cb
, MDL
);
4910 client
->ddns_cb
= NULL
;
4913 ddns_cb
= ddns_cb_alloc(MDL
);
4915 if (ddns_cb
!= NULL
) {
4916 ddns_cb
->lease
= (void *)client
;
4917 ddns_cb
->address
= *addr
;
4918 ddns_cb
->timeout
= 1;
4921 * XXX: DNS TTL is a problem we need to solve properly.
4922 * Until that time, 300 is a placeholder default for
4923 * something that is less insane than a value scaled
4928 ddns_cb
->state
= DDNS_STATE_ADD_FW_NXDOMAIN
;
4929 ddns_cb
->cur_func
= client_dns_update_action
;
4930 ddns_cb
->flags
= DDNS_UPDATE_ADDR
| DDNS_INCLUDE_RRSET
;
4932 client
->ddns_cb
= ddns_cb
;
4933 tv
.tv_sec
= cur_tv
.tv_sec
+ offset
;
4934 tv
.tv_usec
= cur_tv
.tv_usec
;
4935 add_timeout(&tv
, client_dns_update_timeout
,
4936 ddns_cb
, NULL
, NULL
);
4938 log_error("Unable to allocate dns update state for %s",
4945 dhcpv4_client_assignments(void)
4947 struct servent
*ent
;
4949 if (path_dhclient_pid
== NULL
)
4950 path_dhclient_pid
= _PATH_DHCLIENT_PID
;
4951 if (path_dhclient_db
== NULL
)
4952 path_dhclient_db
= _PATH_DHCLIENT_DB
;
4954 /* Default to the DHCP/BOOTP port. */
4956 /* If we're faking a relay agent, and we're not using loopback,
4957 use the server port, not the client port. */
4958 if (mockup_relay
&& giaddr
.s_addr
!= htonl(INADDR_LOOPBACK
)) {
4959 local_port
= htons(67);
4961 ent
= getservbyname("dhcpc", "udp");
4963 ent
= getservbyname("bootpc", "udp");
4965 local_port
= htons(68);
4967 local_port
= ent
->s_port
;
4968 #ifndef __CYGWIN32__
4974 /* If we're faking a relay agent, and we're not using loopback,
4975 we're using the server port, not the client port. */
4976 if (mockup_relay
&& giaddr
.s_addr
!= htonl(INADDR_LOOPBACK
)) {
4977 remote_port
= local_port
;
4979 remote_port
= htons(ntohs(local_port
) - 1); /* XXX */
4983 * The following routines are used to check that certain
4984 * strings are reasonable before we pass them to the scripts.
4985 * This avoids some problems with scripts treating the strings
4986 * as commands - see ticket 23722
4987 * The domain checking code should be done as part of assembling
4988 * the string but we are doing it here for now due to time
4992 static int check_domain_name(const char *ptr
, size_t len
, int dots
)
4996 /* not empty or complete length not over 255 characters */
4997 if ((len
== 0) || (len
> 256))
5000 /* consists of [[:alnum:]-]+ labels separated by [.] */
5001 /* a [_] is against RFC but seems to be "widely used"... */
5002 for (p
=ptr
; (*p
!= 0) && (len
-- > 0); p
++) {
5003 if ((*p
== '-') || (*p
== '_')) {
5004 /* not allowed at begin or end of a label */
5005 if (((p
- ptr
) == 0) || (len
== 0) || (p
[1] == '.'))
5007 } else if (*p
== '.') {
5008 /* each label has to be 1-63 characters;
5009 we allow [.] at the end ('foo.bar.') */
5011 if ((d
<= 0) || (d
>= 64))
5013 ptr
= p
+ 1; /* jump to the next label */
5014 if ((dots
> 0) && (len
> 0))
5016 } else if (isalnum((unsigned char)*p
) == 0) {
5017 /* also numbers at the begin are fine */
5021 return(dots
? -1 : 0);
5024 static int check_domain_name_list(const char *ptr
, size_t len
, int dots
)
5027 int ret
= -1; /* at least one needed */
5029 if ((ptr
== NULL
) || (len
== 0))
5032 for (p
=ptr
; (*p
!= 0) && (len
> 0); p
++, len
--) {
5036 if (check_domain_name(ptr
, p
- ptr
, dots
) != 0)
5043 return(check_domain_name(ptr
, p
- ptr
, dots
));
5048 static int check_option_values(struct universe
*universe
,
5056 /* just reject options we want to protect, will be escaped anyway */
5057 if ((universe
== NULL
) || (universe
== &dhcp_universe
)) {
5059 case DHO_DOMAIN_NAME
:
5060 #ifdef ACCEPT_LIST_IN_DOMAIN_NAME
5061 return check_domain_name_list(ptr
, len
, 0);
5063 return check_domain_name(ptr
, len
, 0);
5066 case DHO_NIS_DOMAIN
:
5067 case DHO_NETBIOS_SCOPE
:
5068 return check_domain_name(ptr
, len
, 0);
5070 case DHO_DOMAIN_SEARCH
:
5071 return check_domain_name_list(ptr
, len
, 0);
5076 for (; (*ptr
!= 0) && (len
-- > 0); ptr
++) {
5077 if(!(isalnum((unsigned char)*ptr
) ||
5078 *ptr
== '#' || *ptr
== '%' ||
5079 *ptr
== '+' || *ptr
== '-' ||
5080 *ptr
== '_' || *ptr
== ':' ||
5081 *ptr
== '.' || *ptr
== ',' ||
5082 *ptr
== '@' || *ptr
== '~' ||
5083 *ptr
== '\\' || *ptr
== '/' ||
5084 *ptr
== '[' || *ptr
== ']' ||
5085 *ptr
== '=' || *ptr
== ' '))
5094 if (universe
== &dhcpv6_universe
) {
5096 case D6O_SIP_SERVERS_DNS
:
5097 case D6O_DOMAIN_SEARCH
:
5098 case D6O_NIS_DOMAIN_NAME
:
5099 case D6O_NISP_DOMAIN_NAME
:
5100 return check_domain_name_list(ptr
, len
, 0);
5110 add_reject(struct packet
*packet
) {
5111 struct iaddrmatchlist
*list
;
5113 list
= dmalloc(sizeof(struct iaddrmatchlist
), MDL
);
5115 log_fatal ("no memory for reject list!");
5118 * client_addr is misleading - it is set to source address in common
5121 list
->match
.addr
= packet
->client_addr
;
5122 /* Set mask to indicate host address. */
5123 list
->match
.mask
.len
= list
->match
.addr
.len
;
5124 memset(list
->match
.mask
.iabuf
, 0xff, sizeof(list
->match
.mask
.iabuf
));
5126 /* Append to reject list for the source interface. */
5127 list
->next
= packet
->interface
->client
->config
->reject_list
;
5128 packet
->interface
->client
->config
->reject_list
= list
;
5131 * We should inform user that we won't be accepting this server
5134 log_info("Server added to list of rejected servers.");
5137 /* Wrapper function around common ddns_cb_free function that ensures
5138 * we set the client_state pointer to the control block to NULL. */
5140 dhclient_ddns_cb_free(dhcp_ddns_cb_t
*ddns_cb
, char* file
, int line
) {
5142 struct client_state
*client
= (struct client_state
*)ddns_cb
->lease
;
5143 if (client
!= NULL
) {
5144 client
->ddns_cb
= NULL
;
5147 ddns_cb_free(ddns_cb
, file
, line
);
5151 #if defined(DHCPv6) && defined(DHCP4o6)
5153 * \brief Omapi I/O handler
5155 * The inter-process communication receive handler.
5157 * On the DHCPv6 side, the message is either a POLL (which is answered
5158 * by a START or a STOP) or a DHCPv4-QUERY (which is forwarded to
5159 * DHCPv4 over DHCPv6 servers by forw_dhcpv4_query()).
5161 * On the DHCPv4 side, the message is either a START, a STOP
5162 * (both for the DHCP4 over DHCPv6 state machine) or a DHCPv4-RESPONSE
5163 * (which is processed by recv_dhcpv4_response()).
5165 * \param h the OMAPI object
5166 * \return a result for I/O success or error (used by the I/O subsystem)
5168 isc_result_t
dhcpv4o6_handler(omapi_object_t
*h
) {
5170 char start_msg
[5] = { 'S', 'T', 'A', 'R', 'T' };
5171 char stop_msg
[4] = { 'S', 'T', 'O', 'P' };
5172 char poll_msg
[4] = { 'P', 'O', 'L', 'L' };
5173 struct data_string raw
;
5176 if (h
->type
!= dhcp4o6_type
)
5177 return DHCP_R_INVALIDARG
;
5179 cc
= recv(dhcp4o6_fd
, buf
, sizeof(buf
), 0);
5181 return ISC_R_UNEXPECTED
;
5183 if (local_family
== AF_INET6
) {
5185 (memcmp(buf
, poll_msg
, sizeof(poll_msg
)) == 0)) {
5186 log_info("RCV: POLL");
5187 if (dhcp4o6_state
< 0)
5188 cc
= send(dhcp4o6_fd
, stop_msg
,
5189 sizeof(stop_msg
), 0);
5191 cc
= send(dhcp4o6_fd
, start_msg
,
5192 sizeof(start_msg
), 0);
5194 log_error("dhcpv4o6_handler: send(): %m");
5195 return ISC_R_IOERROR
;
5198 if (cc
< DHCP_FIXED_NON_UDP
+ 8)
5199 return ISC_R_UNEXPECTED
;
5200 memset(&raw
, 0, sizeof(raw
));
5201 if (!buffer_allocate(&raw
.buffer
, cc
, MDL
)) {
5202 log_error("dhcpv4o6_handler: "
5203 "no memory buffer.");
5204 return ISC_R_NOMEMORY
;
5206 raw
.data
= raw
.buffer
->data
;
5208 memcpy(raw
.buffer
->data
, buf
, cc
);
5210 forw_dhcpv4_query(&raw
);
5212 data_string_forget(&raw
, MDL
);
5216 (memcmp(buf
, stop_msg
, sizeof(stop_msg
)) == 0)) {
5217 log_info("RCV: STOP");
5218 if (dhcp4o6_state
> 0) {
5222 } else if ((cc
== 5) &&
5223 (memcmp(buf
, start_msg
, sizeof(start_msg
)) == 0)) {
5224 log_info("RCV: START");
5225 if (dhcp4o6_state
== 0)
5226 cancel_timeout(dhcp4o6_poll
, NULL
);
5230 if (cc
< DHCP_FIXED_NON_UDP
+ 16)
5231 return ISC_R_UNEXPECTED
;
5232 memset(&raw
, 0, sizeof(raw
));
5233 if (!buffer_allocate(&raw
.buffer
, cc
, MDL
)) {
5234 log_error("dhcpv4o6_handler: "
5235 "no memory buffer.");
5236 return ISC_R_NOMEMORY
;
5238 raw
.data
= raw
.buffer
->data
;
5240 memcpy(raw
.buffer
->data
, buf
, cc
);
5242 recv_dhcpv4_response(&raw
);
5244 data_string_forget(&raw
, MDL
);
5248 return ISC_R_SUCCESS
;
5252 * \brief Poll the DHCPv6 client
5253 * (DHCPv4 client function)
5255 * A POLL message is sent to the DHCPv6 client periodically to check
5256 * if the DHCPv6 is ready (i.e., has a valid DHCPv4-over-DHCPv6 server
5259 static void dhcp4o6_poll(void *dummy
) {
5260 char msg
[4] = { 'P', 'O', 'L', 'L' };
5264 IGNORE_UNUSED(dummy
);
5266 if (dhcp4o6_state
< 0)
5271 cc
= send(dhcp4o6_fd
, msg
, sizeof(msg
), 0);
5273 log_error("dhcp4o6_poll: send(): %m");
5275 tv
.tv_sec
= cur_time
+ 60;
5276 tv
.tv_usec
= random() % 1000000;
5278 add_timeout(&tv
, dhcp4o6_poll
, NULL
, 0, 0);
5282 * \brief Resume pending operations
5283 * (DHCPv4 client function)
5285 * A START message was received from the DHCPv6 client so pending
5286 * operations (RELEASE or REBOOT) must be resumed.
5288 static void dhcp4o6_resume() {
5289 struct interface_info
*ip
;
5290 struct client_state
*client
;
5292 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
5293 for (client
= ip
->client
; client
!= NULL
;
5294 client
= client
->next
) {
5295 if (client
->pending
== P_RELEASE
)
5297 else if (client
->pending
== P_REBOOT
)
5298 state_reboot(client
);
5304 * \brief Send a START to the DHCPv4 client
5305 * (DHCPv6 client function)
5307 * First check if there is a valid DHCPv4-over-DHCPv6 server address option,
5308 * and when found go UP and on a transition from another state send
5309 * a START message to the DHCPv4 client.
5311 void dhcp4o6_start() {
5312 struct interface_info
*ip
;
5313 struct client_state
*client
;
5314 struct dhc6_lease
*lease
;
5315 struct option_cache
*oc
;
5316 struct data_string addrs
;
5317 char msg
[5] = { 'S', 'T', 'A', 'R', 'T' };
5320 memset(&addrs
, 0, sizeof(addrs
));
5321 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
5322 for (client
= ip
->client
; client
!= NULL
;
5323 client
= client
->next
) {
5324 if ((client
->state
!= S_BOUND
) &&
5325 (client
->state
!= S_RENEWING
) &&
5326 (client
->state
!= S_REBINDING
))
5328 lease
= client
->active_lease
;
5329 if ((lease
== NULL
) || lease
->released
)
5331 oc
= lookup_option(&dhcpv6_universe
,
5333 D6O_DHCP4_O_DHCP6_SERVER
);
5335 !evaluate_option_cache(&addrs
, NULL
, NULL
, NULL
,
5336 lease
->options
, NULL
,
5337 &global_scope
, oc
, MDL
))
5339 if ((addrs
.len
% 16) != 0) {
5340 data_string_forget(&addrs
, MDL
);
5343 data_string_forget(&addrs
, MDL
);
5347 log_info("dhcp4o6_start: failed");
5352 if (dhcp4o6_state
== 1)
5354 log_info("dhcp4o6_start: go to UP");
5357 cc
= send(dhcp4o6_fd
, msg
, sizeof(msg
), 0);
5359 log_info("dhcp4o6_start: send(): %m");
5363 * Send a STOP to the DHCPv4 client
5364 * (DHCPv6 client function)
5366 * Go DOWN and on a transition from another state send a STOP message
5367 * to the DHCPv4 client.
5369 static void dhcp4o6_stop() {
5370 char msg
[4] = { 'S', 'T', 'O', 'P' };
5373 if (dhcp4o6_state
== -1)
5376 log_info("dhcp4o6_stop: go to DOWN");
5379 cc
= send(dhcp4o6_fd
, msg
, sizeof(msg
), 0);
5381 log_error("dhcp4o6_stop: send(): %m");
5383 #endif /* DHCPv6 && DHCP4o6 */