6
* Copyright (c) 2004-2011 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.
40
#include <dns/result.h>
42
TIME default_lease_time = 43200; /* 12 hours... */
43
TIME max_lease_time = 86400; /* 24 hours... */
45
const char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
46
const char *path_dhclient_db = NULL;
47
const char *path_dhclient_pid = NULL;
48
static char path_dhclient_script_array[] = _PATH_DHCLIENT_SCRIPT;
49
char *path_dhclient_script = path_dhclient_script_array;
51
/* False (default) => we write and use a pid file */
52
isc_boolean_t no_pid_file = ISC_FALSE;
54
int dhcp_max_agent_option_packet_length = 0;
56
int interfaces_requested = 0;
58
struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
59
struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } };
60
struct in_addr inaddr_any;
61
struct sockaddr_in sockaddr_broadcast;
62
struct in_addr giaddr;
63
struct data_string default_duid;
66
/* ASSERT_STATE() does nothing now; it used to be
67
assert (state_is == state_shouldbe). */
68
#define ASSERT_STATE(state_is, state_shouldbe) {}
70
static const char copyright[] =
71
"Copyright 2004-2011 Internet Systems Consortium.";
72
static const char arr [] = "All rights reserved.";
73
static const char message [] = "Internet Systems Consortium DHCP Client";
74
static const char url [] =
75
"For info, please visit https://www.isc.org/software/dhcp/";
77
u_int16_t local_port = 0;
78
u_int16_t remote_port = 0;
80
struct string_list *client_env = NULL;
81
int client_env_count = 0;
86
int wanted_ia_na = -1; /* the absolute value is the real one. */
89
char *mockup_relay = NULL;
91
void run_stateless(int exit_mode);
93
static void usage(void);
95
static isc_result_t write_duid(struct data_string *duid);
96
static void add_reject(struct packet *packet);
98
static int check_domain_name(const char *ptr, size_t len, int dots);
99
static int check_domain_name_list(const char *ptr, size_t len, int dots);
100
static int check_option_values(struct universe *universe, unsigned int opt,
101
const char *ptr, size_t len);
104
main(int argc, char **argv) {
107
struct interface_info *ip;
108
struct client_state *client;
113
int release_mode = 0;
115
omapi_object_t *listener;
118
int no_dhclient_conf = 0;
119
int no_dhclient_db = 0;
120
int no_dhclient_pid = 0;
121
int no_dhclient_script = 0;
123
int local_family_set = 0;
127
/* Initialize client globals. */
128
memset(&default_duid, 0, sizeof(default_duid));
130
/* Make sure that file descriptors 0 (stdin), 1, (stdout), and
131
2 (stderr) are open. To do this, we assume that when we
132
open a file the lowest available file descriptor is used. */
133
fd = open("/dev/null", O_RDWR);
135
fd = open("/dev/null", O_RDWR);
137
fd = open("/dev/null", O_RDWR);
139
log_perror = 0; /* No sense logging to /dev/null. */
143
openlog("dhclient", LOG_NDELAY, LOG_DAEMON);
145
#if !(defined(DEBUG) || defined(__CYGWIN32__))
146
setlogmask(LOG_UPTO(LOG_INFO));
149
/* Set up the isc and dns library managers */
150
status = dhcp_context_create();
151
if (status != ISC_R_SUCCESS)
152
log_fatal("Can't initialize context: %s",
153
isc_result_totext(status));
155
/* Set up the OMAPI. */
156
status = omapi_init();
157
if (status != ISC_R_SUCCESS)
158
log_fatal("Can't initialize OMAPI: %s",
159
isc_result_totext(status));
161
/* Set up the OMAPI wrappers for various server database internal
163
dhcp_common_objects_setup();
165
dhcp_interface_discovery_hook = dhclient_interface_discovery_hook;
166
dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook;
167
dhcp_interface_startup_hook = dhclient_interface_startup_hook;
169
for (i = 1; i < argc; i++) {
170
if (!strcmp(argv[i], "-r")) {
174
} else if (!strcmp(argv[i], "-4")) {
175
if (local_family_set && local_family != AF_INET)
176
log_fatal("Client can only do v4 or v6, not "
178
local_family_set = 1;
179
local_family = AF_INET;
180
} else if (!strcmp(argv[i], "-6")) {
181
if (local_family_set && local_family != AF_INET6)
182
log_fatal("Client can only do v4 or v6, not "
184
local_family_set = 1;
185
local_family = AF_INET6;
187
} else if (!strcmp(argv[i], "-x")) { /* eXit, no release */
191
} else if (!strcmp(argv[i], "-p")) {
194
local_port = validate_port(argv[i]);
195
log_debug("binding to user-specified port %d",
197
} else if (!strcmp(argv[i], "-d")) {
200
} else if (!strcmp(argv[i], "-pf")) {
203
path_dhclient_pid = argv[i];
205
} else if (!strcmp(argv[i], "--no-pid")) {
206
no_pid_file = ISC_TRUE;
207
} else if (!strcmp(argv[i], "-cf")) {
210
path_dhclient_conf = argv[i];
211
no_dhclient_conf = 1;
212
} else if (!strcmp(argv[i], "-lf")) {
215
path_dhclient_db = argv[i];
217
} else if (!strcmp(argv[i], "-sf")) {
220
path_dhclient_script = argv[i];
221
no_dhclient_script = 1;
222
} else if (!strcmp(argv[i], "-1")) {
224
} else if (!strcmp(argv[i], "-q")) {
226
} else if (!strcmp(argv[i], "-s")) {
230
} else if (!strcmp(argv[i], "-g")) {
233
mockup_relay = argv[i];
234
} else if (!strcmp(argv[i], "-nw")) {
236
} else if (!strcmp(argv[i], "-n")) {
237
/* do not start up any interfaces */
238
interfaces_requested = -1;
239
} else if (!strcmp(argv[i], "-w")) {
240
/* do not exit if there are no broadcast interfaces. */
242
} else if (!strcmp(argv[i], "-e")) {
243
struct string_list *tmp;
246
tmp = dmalloc(strlen(argv[i]) + sizeof *tmp, MDL);
248
log_fatal("No memory for %s", argv[i]);
249
strcpy(tmp->string, argv[i]);
250
tmp->next = client_env;
254
} else if (!strcmp(argv[i], "-S")) {
255
if (local_family_set && (local_family == AF_INET)) {
258
local_family_set = 1;
259
local_family = AF_INET6;
262
} else if (!strcmp(argv[i], "-N")) {
263
if (local_family_set && (local_family == AF_INET)) {
266
local_family_set = 1;
267
local_family = AF_INET6;
268
if (wanted_ia_na < 0) {
272
} else if (!strcmp(argv[i], "-T")) {
273
if (local_family_set && (local_family == AF_INET)) {
276
local_family_set = 1;
277
local_family = AF_INET6;
278
if (wanted_ia_na < 0) {
282
} else if (!strcmp(argv[i], "-P")) {
283
if (local_family_set && (local_family == AF_INET)) {
286
local_family_set = 1;
287
local_family = AF_INET6;
288
if (wanted_ia_na < 0) {
292
} else if (!strcmp(argv[i], "-D")) {
293
if (local_family_set && (local_family == AF_INET)) {
296
local_family_set = 1;
297
local_family = AF_INET6;
300
if (!strcasecmp(argv[i], "LL")) {
302
} else if (!strcasecmp(argv[i], "LLT")) {
303
duid_type = DUID_LLT;
308
} else if (!strcmp(argv[i], "-v")) {
310
} else if (!strcmp(argv[i], "--version")) {
311
log_info("isc-dhclient-%s", PACKAGE_VERSION);
313
} else if (argv[i][0] == '-') {
315
} else if (interfaces_requested < 0) {
318
struct interface_info *tmp = NULL;
320
status = interface_allocate(&tmp, MDL);
321
if (status != ISC_R_SUCCESS)
322
log_fatal("Can't record interface %s:%s",
323
argv[i], isc_result_totext(status));
324
if (strlen(argv[i]) >= sizeof(tmp->name))
325
log_fatal("%s: interface name too long (is %ld)",
326
argv[i], (long)strlen(argv[i]));
327
strcpy(tmp->name, argv[i]);
329
interface_reference(&tmp->next,
331
interface_dereference(&interfaces, MDL);
333
interface_reference(&interfaces, tmp, MDL);
334
tmp->flags = INTERFACE_REQUESTED;
335
interfaces_requested++;
339
if (wanted_ia_na < 0) {
343
/* Support only one (requested) interface for Prefix Delegation. */
344
if (wanted_ia_pd && (interfaces_requested != 1)) {
348
if (!no_dhclient_conf && (s = getenv("PATH_DHCLIENT_CONF"))) {
349
path_dhclient_conf = s;
351
if (!no_dhclient_db && (s = getenv("PATH_DHCLIENT_DB"))) {
352
path_dhclient_db = s;
354
if (!no_dhclient_pid && (s = getenv("PATH_DHCLIENT_PID"))) {
355
path_dhclient_pid = s;
357
if (!no_dhclient_script && (s = getenv("PATH_DHCLIENT_SCRIPT"))) {
358
path_dhclient_script = s;
361
/* Set up the initial dhcp option universe. */
362
initialize_common_option_spaces();
364
/* Assign v4 or v6 specific running parameters. */
365
if (local_family == AF_INET)
366
dhcpv4_client_assignments();
368
else if (local_family == AF_INET6)
369
dhcpv6_client_assignments();
372
log_fatal("Impossible condition at %s:%d.", MDL);
375
* convert relative path names to absolute, for files that need
376
* to be reopened after chdir() has been called
378
if (path_dhclient_db[0] != '/') {
379
char *path = dmalloc(PATH_MAX, MDL);
381
log_fatal("No memory for filename\n");
382
path_dhclient_db = realpath(path_dhclient_db, path);
383
if (path_dhclient_db == NULL)
384
log_fatal("%s: %s", path, strerror(errno));
387
if (path_dhclient_script[0] != '/') {
388
char *path = dmalloc(PATH_MAX, MDL);
390
log_fatal("No memory for filename\n");
391
path_dhclient_script = realpath(path_dhclient_script, path);
392
if (path_dhclient_script == NULL)
393
log_fatal("%s: %s", path, strerror(errno));
397
* See if we should kill off any currently running client
398
* we don't try to kill it off if the user told us not
399
* to write a pid file - we assume they are controlling
400
* the process in some other fashion.
402
if ((release_mode || exit_mode) && (no_pid_file == ISC_FALSE)) {
409
if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) {
410
e = fscanf(pidfd, "%ld\n", &temp);
411
oldpid = (pid_t)temp;
413
if (e != 0 && e != EOF) {
415
kill(oldpid, SIGTERM);
422
log_info("%s %s", message, PACKAGE_VERSION);
429
quiet_interface_discovery = 1;
432
/* If we're given a relay agent address to insert, for testing
433
purposes, figure out what it is. */
435
if (!inet_aton(mockup_relay, &giaddr)) {
437
he = gethostbyname(mockup_relay);
439
memcpy(&giaddr, he->h_addr_list[0],
442
log_fatal("%s: no such host", mockup_relay);
447
/* Get the current time... */
448
gettimeofday(&cur_tv, NULL);
450
sockaddr_broadcast.sin_family = AF_INET;
451
sockaddr_broadcast.sin_port = remote_port;
453
if (!inet_aton(server, &sockaddr_broadcast.sin_addr)) {
455
he = gethostbyname(server);
457
memcpy(&sockaddr_broadcast.sin_addr,
459
sizeof sockaddr_broadcast.sin_addr);
461
sockaddr_broadcast.sin_addr.s_addr =
465
sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
468
inaddr_any.s_addr = INADDR_ANY;
470
/* Stateless special case. */
472
if (release_mode || (wanted_ia_na > 0) ||
473
wanted_ia_ta || wanted_ia_pd ||
474
(interfaces_requested != 1)) {
477
run_stateless(exit_mode);
481
/* Discover all the network interfaces. */
482
discover_interfaces(DISCOVER_UNCONFIGURED);
484
/* Parse the dhclient.conf file. */
487
/* Parse the lease database. */
488
read_client_leases();
490
/* Rewrite the lease database... */
491
rewrite_client_leases();
494
/* config_counter(&snd_counter, &rcv_counter); */
497
* If no broadcast interfaces were discovered, call the script
502
* Call dhclient-script with the NBI flag,
503
* in case somebody cares.
505
script_init(NULL, "NBI", NULL);
509
* If we haven't been asked to persist, waiting for new
510
* interfaces, then just exit.
513
/* Nothing more to do. */
514
log_info("No broadcast interfaces found - exiting.");
517
} else if (!release_mode && !exit_mode) {
518
/* Call the script with the list of interfaces. */
519
for (ip = interfaces; ip; ip = ip->next) {
521
* If interfaces were specified, don't configure
522
* interfaces that weren't specified!
524
if ((interfaces_requested > 0) &&
525
((ip->flags & (INTERFACE_REQUESTED |
526
INTERFACE_AUTOMATIC)) !=
527
INTERFACE_REQUESTED))
530
if (local_family == AF_INET6) {
531
script_init(ip->client, "PREINIT6", NULL);
533
script_init(ip->client, "PREINIT", NULL);
534
if (ip->client->alias != NULL)
535
script_write_params(ip->client,
539
script_go(ip->client);
543
/* At this point, all the interfaces that the script thinks
544
are relevant should be running, so now we once again call
545
discover_interfaces(), and this time ask it to actually set
546
up the interfaces. */
547
discover_interfaces(interfaces_requested != 0
551
/* Make up a seed for the random number generator from current
552
time plus the sum of the last four bytes of each
553
interface's hardware address interpreted as an integer.
554
Not much entropy, but we're booting, so we're not likely to
555
find anything better. */
557
for (ip = interfaces; ip; ip = ip->next) {
560
&ip->hw_address.hbuf[ip->hw_address.hlen -
561
sizeof seed], sizeof seed);
564
srandom(seed + cur_time + (unsigned)getpid());
566
/* Start a configuration state machine for each interface. */
568
if (local_family == AF_INET6) {
569
/* Establish a default DUID. This may be moved to the
572
if (default_duid.len == 0) {
573
if (default_duid.buffer != NULL)
574
data_string_forget(&default_duid, MDL);
576
form_duid(&default_duid, MDL);
577
write_duid(&default_duid);
580
for (ip = interfaces ; ip != NULL ; ip = ip->next) {
581
for (client = ip->client ; client != NULL ;
582
client = client->next) {
584
start_release6(client);
586
} else if (exit_mode) {
587
unconfigure6(client, "STOP6");
591
/* If we have a previous binding, Confirm
592
* that we can (or can't) still use it.
594
if ((client->active_lease != NULL) &&
595
!client->active_lease->released)
596
start_confirm6(client);
604
for (ip = interfaces ; ip ; ip = ip->next) {
605
ip->flags |= INTERFACE_RUNNING;
606
for (client = ip->client ; client ;
607
client = client->next) {
610
else if (release_mode)
613
client->state = S_INIT;
615
if (top_level_config.initial_delay>0)
618
if (top_level_config.
624
tv.tv_usec = random()
628
* distribution than just
631
add_timeout(&tv, state_reboot,
634
state_reboot(client);
647
if (local_family == AF_INET6) {
655
/* Start up a listener for the object management API protocol. */
656
if (top_level_config.omapi_port != -1) {
658
result = omapi_generic_new(&listener, MDL);
659
if (result != ISC_R_SUCCESS)
660
log_fatal("Can't allocate new generic object: %s\n",
661
isc_result_totext(result));
662
result = omapi_protocol_listen(listener,
664
top_level_config.omapi_port,
666
if (result != ISC_R_SUCCESS)
667
log_fatal("Can't start OMAPI protocol: %s",
668
isc_result_totext (result));
671
/* Set up the bootp packet handler... */
672
bootp_packet_handler = do_packet;
674
dhcpv6_packet_handler = do_packet6;
677
#if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
678
defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
679
dmalloc_cutoff_generation = dmalloc_generation;
680
dmalloc_longterm = dmalloc_outstanding;
681
dmalloc_outstanding = 0;
684
/* If we're not supposed to wait before getting the address,
689
/* If we're not going to daemonize, write the pid file
691
if (no_daemon || nowait)
692
write_client_pid_file();
694
/* Start dispatching packets and timeouts... */
703
log_info("%s %s", message, PACKAGE_VERSION);
709
log_fatal("Usage: dhclient "
711
"[-4|-6] [-SNTP1dvrx] [-nw] [-p <port>] [-D LL|LLT]\n"
713
"[-1dvrx] [-nw] [-p <port>]\n"
715
" [-s server-addr] [-cf config-file] "
717
" [-pf pid-file] [--no-pid] [-e VAR=val]\n"
718
" [-sf script-file] [interface]");
721
void run_stateless(int exit_mode)
724
struct client_state *client;
725
omapi_object_t *listener;
728
/* Discover the network interface. */
729
discover_interfaces(DISCOVER_REQUESTED);
734
/* Parse the dhclient.conf file. */
737
/* Parse the lease database. */
738
read_client_leases();
740
/* Establish a default DUID. */
741
if (default_duid.len == 0) {
742
if (default_duid.buffer != NULL)
743
data_string_forget(&default_duid, MDL);
745
form_duid(&default_duid, MDL);
748
/* Start a configuration state machine. */
749
for (client = interfaces->client ;
751
client = client->next) {
753
unconfigure6(client, "STOP6");
756
start_info_request6(client);
761
/* Start up a listener for the object management API protocol. */
762
if (top_level_config.omapi_port != -1) {
764
result = omapi_generic_new(&listener, MDL);
765
if (result != ISC_R_SUCCESS)
766
log_fatal("Can't allocate new generic object: %s\n",
767
isc_result_totext(result));
768
result = omapi_protocol_listen(listener,
770
top_level_config.omapi_port,
772
if (result != ISC_R_SUCCESS)
773
log_fatal("Can't start OMAPI protocol: %s",
774
isc_result_totext(result));
777
/* Set up the packet handler... */
778
dhcpv6_packet_handler = do_packet6;
780
#if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
781
defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
782
dmalloc_cutoff_generation = dmalloc_generation;
783
dmalloc_longterm = dmalloc_outstanding;
784
dmalloc_outstanding = 0;
787
/* If we're not supposed to wait before getting the address,
792
/* If we're not going to daemonize, write the pid file
794
if (no_daemon || nowait)
795
write_client_pid_file();
797
/* Start dispatching packets and timeouts... */
805
isc_result_t find_class (struct class **c,
806
const char *s, const char *file, int line)
811
int check_collection (packet, lease, collection)
812
struct packet *packet;
814
struct collection *collection;
819
void classify (packet, class)
820
struct packet *packet;
825
int unbill_class (lease, class)
832
int find_subnet (struct subnet **sp,
833
struct iaddr addr, const char *file, int line)
838
/* Individual States:
840
* Each routine is called from the dhclient_state_machine() in one of
842
* -> entering INIT state
843
* -> recvpacket_flag == 0: timeout in this state
844
* -> otherwise: received a packet in this state
846
* Return conditions as handled by dhclient_state_machine():
847
* Returns 1, sendpacket_flag = 1: send packet, reset timer.
848
* Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
849
* Returns 0: finish the nap which was interrupted for no good reason.
851
* Several per-interface variables are used to keep track of the process:
852
* active_lease: the lease that is being used on the interface
853
* (null pointer if not configured yet).
854
* offered_leases: leases corresponding to DHCPOFFER messages that have
855
* been sent to us by DHCP servers.
856
* acked_leases: leases corresponding to DHCPACK messages that have been
857
* sent to us by DHCP servers.
858
* sendpacket: DHCP packet we're trying to send.
859
* destination: IP address to send sendpacket to
860
* In addition, there are several relevant per-lease variables.
861
* T1_expiry, T2_expiry, lease_expiry: lease milestones
862
* In the active lease, these control the process of renewing the lease;
863
* In leases on the acked_leases list, this simply determines when we
864
* can no longer legitimately use the lease.
867
void state_reboot (cpp)
870
struct client_state *client = cpp;
872
/* If we don't remember an active lease, go straight to INIT. */
873
if (!client -> active ||
874
client -> active -> is_bootp ||
875
client -> active -> expiry <= cur_time) {
880
/* We are in the rebooting state. */
881
client -> state = S_REBOOTING;
884
* make_request doesn't initialize xid because it normally comes
885
* from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
886
* so pick an xid now.
888
client -> xid = random ();
891
* Make a DHCPREQUEST packet, and set
892
* appropriate per-interface flags.
894
make_request (client, client -> active);
895
client -> destination = iaddr_broadcast;
896
client -> first_sending = cur_time;
897
client -> interval = client -> config -> initial_interval;
899
/* Zap the medium list... */
900
client -> medium = NULL;
902
/* Send out the first DHCPREQUEST packet. */
903
send_request (client);
906
/* Called when a lease has completely expired and we've been unable to
909
void state_init (cpp)
912
struct client_state *client = cpp;
914
ASSERT_STATE(state, S_INIT);
916
/* Make a DHCPDISCOVER packet, and set appropriate per-interface
918
make_discover (client, client -> active);
919
client -> xid = client -> packet.xid;
920
client -> destination = iaddr_broadcast;
921
client -> state = S_SELECTING;
922
client -> first_sending = cur_time;
923
client -> interval = client -> config -> initial_interval;
925
/* Add an immediate timeout to cause the first DHCPDISCOVER packet
927
send_discover (client);
931
* state_selecting is called when one or more DHCPOFFER packets have been
932
* received and a configurable period of time has passed.
935
void state_selecting (cpp)
938
struct client_state *client = cpp;
939
struct client_lease *lp, *next, *picked;
942
ASSERT_STATE(state, S_SELECTING);
945
* Cancel state_selecting and send_discover timeouts, since either
946
* one could have got us here.
948
cancel_timeout (state_selecting, client);
949
cancel_timeout (send_discover, client);
952
* We have received one or more DHCPOFFER packets. Currently,
953
* the only criterion by which we judge leases is whether or
954
* not we get a response when we arp for them.
957
for (lp = client -> offered_leases; lp; lp = next) {
961
* Check to see if we got an ARPREPLY for the address
962
* in this particular lease.
966
picked -> next = NULL;
968
destroy_client_lease (lp);
971
client -> offered_leases = NULL;
974
* If we just tossed all the leases we were offered, go back
978
client -> state = S_INIT;
983
/* If it was a BOOTREPLY, we can just take the address right now. */
984
if (picked -> is_bootp) {
985
client -> new = picked;
987
/* Make up some lease expiry times
988
XXX these should be configurable. */
989
client -> new -> expiry = cur_time + 12000;
990
client -> new -> renewal += cur_time + 8000;
991
client -> new -> rebind += cur_time + 10000;
993
client -> state = S_REQUESTING;
995
/* Bind to the address we received. */
1000
/* Go to the REQUESTING state. */
1001
client -> destination = iaddr_broadcast;
1002
client -> state = S_REQUESTING;
1003
client -> first_sending = cur_time;
1004
client -> interval = client -> config -> initial_interval;
1006
/* Make a DHCPREQUEST packet from the lease we picked. */
1007
make_request (client, picked);
1008
client -> xid = client -> packet.xid;
1010
/* Toss the lease we picked - we'll get it back in a DHCPACK. */
1011
destroy_client_lease (picked);
1013
/* Add an immediate timeout to send the first DHCPREQUEST packet. */
1014
send_request (client);
1017
/* state_requesting is called when we receive a DHCPACK message after
1018
having sent out one or more DHCPREQUEST packets. */
1020
void dhcpack (packet)
1021
struct packet *packet;
1023
struct interface_info *ip = packet -> interface;
1024
struct client_state *client;
1025
struct client_lease *lease;
1026
struct option_cache *oc;
1027
struct data_string ds;
1029
/* If we're not receptive to an offer right now, or if the offer
1030
has an unrecognizable transaction id, then just drop it. */
1031
for (client = ip -> client; client; client = client -> next) {
1032
if (client -> xid == packet -> raw -> xid)
1036
(packet -> interface -> hw_address.hlen - 1 !=
1037
packet -> raw -> hlen) ||
1038
(memcmp (&packet -> interface -> hw_address.hbuf [1],
1039
packet -> raw -> chaddr, packet -> raw -> hlen))) {
1041
log_debug ("DHCPACK in wrong transaction.");
1046
if (client -> state != S_REBOOTING &&
1047
client -> state != S_REQUESTING &&
1048
client -> state != S_RENEWING &&
1049
client -> state != S_REBINDING) {
1051
log_debug ("DHCPACK in wrong state.");
1056
log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
1058
lease = packet_to_lease (packet, client);
1060
log_info ("packet_to_lease failed.");
1064
client -> new = lease;
1066
/* Stop resending DHCPREQUEST. */
1067
cancel_timeout (send_request, client);
1069
/* Figure out the lease time. */
1070
oc = lookup_option (&dhcp_universe, client -> new -> options,
1071
DHO_DHCP_LEASE_TIME);
1072
memset (&ds, 0, sizeof ds);
1074
evaluate_option_cache (&ds, packet, (struct lease *)0, client,
1075
packet -> options, client -> new -> options,
1076
&global_scope, oc, MDL)) {
1078
client -> new -> expiry = getULong (ds.data);
1080
client -> new -> expiry = 0;
1081
data_string_forget (&ds, MDL);
1083
client -> new -> expiry = 0;
1085
if (client->new->expiry == 0) {
1088
log_error ("no expiry time on offered lease.");
1090
/* Quench this (broken) server. Return to INIT to reselect. */
1093
/* 1/2 second delay to restart at INIT. */
1094
tv.tv_sec = cur_tv.tv_sec;
1095
tv.tv_usec = cur_tv.tv_usec + 500000;
1097
if (tv.tv_usec >= 1000000) {
1099
tv.tv_usec -= 1000000;
1102
add_timeout(&tv, state_init, client, 0, 0);
1107
* A number that looks negative here is really just very large,
1108
* because the lease expiry offset is unsigned.
1110
if (client->new->expiry < 0)
1111
client->new->expiry = TIME_MAX;
1113
/* Take the server-provided renewal time if there is one. */
1114
oc = lookup_option (&dhcp_universe, client -> new -> options,
1115
DHO_DHCP_RENEWAL_TIME);
1117
evaluate_option_cache (&ds, packet, (struct lease *)0, client,
1118
packet -> options, client -> new -> options,
1119
&global_scope, oc, MDL)) {
1121
client -> new -> renewal = getULong (ds.data);
1123
client -> new -> renewal = 0;
1124
data_string_forget (&ds, MDL);
1126
client -> new -> renewal = 0;
1128
/* If it wasn't specified by the server, calculate it. */
1129
if (!client -> new -> renewal)
1130
client -> new -> renewal = client -> new -> expiry / 2 + 1;
1132
if (client -> new -> renewal <= 0)
1133
client -> new -> renewal = TIME_MAX;
1135
/* Now introduce some randomness to the renewal time: */
1136
if (client->new->renewal <= ((TIME_MAX / 3) - 3))
1137
client->new->renewal = (((client->new->renewal * 3) + 3) / 4) +
1138
(((random() % client->new->renewal) + 3) / 4);
1140
/* Same deal with the rebind time. */
1141
oc = lookup_option (&dhcp_universe, client -> new -> options,
1142
DHO_DHCP_REBINDING_TIME);
1144
evaluate_option_cache (&ds, packet, (struct lease *)0, client,
1145
packet -> options, client -> new -> options,
1146
&global_scope, oc, MDL)) {
1148
client -> new -> rebind = getULong (ds.data);
1150
client -> new -> rebind = 0;
1151
data_string_forget (&ds, MDL);
1153
client -> new -> rebind = 0;
1155
if (client -> new -> rebind <= 0) {
1156
if (client -> new -> expiry <= TIME_MAX / 7)
1157
client -> new -> rebind =
1158
client -> new -> expiry * 7 / 8;
1160
client -> new -> rebind =
1161
client -> new -> expiry / 8 * 7;
1164
/* Make sure our randomness didn't run the renewal time past the
1166
if (client -> new -> renewal > client -> new -> rebind) {
1167
if (client -> new -> rebind <= TIME_MAX / 3)
1168
client -> new -> renewal =
1169
client -> new -> rebind * 3 / 4;
1171
client -> new -> renewal =
1172
client -> new -> rebind / 4 * 3;
1175
client -> new -> expiry += cur_time;
1176
/* Lease lengths can never be negative. */
1177
if (client -> new -> expiry < cur_time)
1178
client -> new -> expiry = TIME_MAX;
1179
client -> new -> renewal += cur_time;
1180
if (client -> new -> renewal < cur_time)
1181
client -> new -> renewal = TIME_MAX;
1182
client -> new -> rebind += cur_time;
1183
if (client -> new -> rebind < cur_time)
1184
client -> new -> rebind = TIME_MAX;
1186
bind_lease (client);
1189
void bind_lease (client)
1190
struct client_state *client;
1194
/* Remember the medium. */
1195
client -> new -> medium = client -> medium;
1197
/* Run the client script with the new parameters. */
1198
script_init (client, (client -> state == S_REQUESTING
1200
: (client -> state == S_RENEWING
1202
: (client -> state == S_REBOOTING
1203
? "REBOOT" : "REBIND"))),
1204
client -> new -> medium);
1205
if (client -> active && client -> state != S_REBOOTING)
1206
script_write_params (client, "old_", client -> active);
1207
script_write_params (client, "new_", client -> new);
1208
if (client -> alias)
1209
script_write_params (client, "alias_", client -> alias);
1211
/* If the BOUND/RENEW code detects another machine using the
1212
offered address, it exits nonzero. We need to send a
1213
DHCPDECLINE and toss the lease. */
1214
if (script_go (client)) {
1215
make_decline (client, client -> new);
1216
send_decline (client);
1217
destroy_client_lease (client -> new);
1218
client -> new = (struct client_lease *)0;
1219
state_init (client);
1223
/* Write out the new lease if it has been long enough. */
1224
if (!client->last_write ||
1225
(cur_time - client->last_write) >= MIN_LEASE_WRITE)
1226
write_client_lease(client, client->new, 0, 0);
1228
/* Replace the old active lease with the new one. */
1229
if (client -> active)
1230
destroy_client_lease (client -> active);
1231
client -> active = client -> new;
1232
client -> new = (struct client_lease *)0;
1234
/* Set up a timeout to start the renewal process. */
1235
tv.tv_sec = client->active->renewal;
1236
tv.tv_usec = ((client->active->renewal - cur_tv.tv_sec) > 1) ?
1237
random() % 1000000 : cur_tv.tv_usec;
1238
add_timeout(&tv, state_bound, client, 0, 0);
1240
log_info ("bound to %s -- renewal in %ld seconds.",
1241
piaddr (client -> active -> address),
1242
(long)(client -> active -> renewal - cur_time));
1243
client -> state = S_BOUND;
1244
reinitialize_interfaces ();
1246
#if defined (NSUPDATE)
1247
if (client->config->do_forward_update)
1248
dhclient_schedule_updates(client, &client->active->address, 1);
1252
/* state_bound is called when we've successfully bound to a particular
1253
lease, but the renewal time on that lease has expired. We are
1254
expected to unicast a DHCPREQUEST to the server that gave us our
1257
void state_bound (cpp)
1260
struct client_state *client = cpp;
1261
struct option_cache *oc;
1262
struct data_string ds;
1264
ASSERT_STATE(state, S_BOUND);
1266
/* T1 has expired. */
1267
make_request (client, client -> active);
1268
client -> xid = client -> packet.xid;
1270
memset (&ds, 0, sizeof ds);
1271
oc = lookup_option (&dhcp_universe, client -> active -> options,
1272
DHO_DHCP_SERVER_IDENTIFIER);
1274
evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0,
1275
client, (struct option_state *)0,
1276
client -> active -> options,
1277
&global_scope, oc, MDL)) {
1279
memcpy (client -> destination.iabuf, ds.data, 4);
1280
client -> destination.len = 4;
1282
client -> destination = iaddr_broadcast;
1284
data_string_forget (&ds, MDL);
1286
client -> destination = iaddr_broadcast;
1288
client -> first_sending = cur_time;
1289
client -> interval = client -> config -> initial_interval;
1290
client -> state = S_RENEWING;
1292
/* Send the first packet immediately. */
1293
send_request (client);
1296
/* state_stop is called when we've been told to shut down. We unconfigure
1297
the interfaces, and then stop operating until told otherwise. */
1299
void state_stop (cpp)
1302
struct client_state *client = cpp;
1304
/* Cancel all timeouts. */
1305
cancel_timeout(state_selecting, client);
1306
cancel_timeout(send_discover, client);
1307
cancel_timeout(send_request, client);
1308
cancel_timeout(state_bound, client);
1310
/* If we have an address, unconfigure it. */
1311
if (client->active) {
1312
script_init(client, "STOP", client->active->medium);
1313
script_write_params(client, "old_", client->active);
1315
script_write_params(client, "alias_", client->alias);
1320
int commit_leases ()
1325
int write_lease (lease)
1326
struct lease *lease;
1331
int write_host (host)
1332
struct host_decl *host;
1337
void db_startup (testp)
1343
struct packet *packet;
1345
struct iaddrmatchlist *ap;
1349
if (packet -> raw -> op != BOOTREPLY)
1352
/* If there's a reject list, make sure this packet's sender isn't
1354
for (ap = packet -> interface -> client -> config -> reject_list;
1355
ap; ap = ap -> next) {
1356
if (addr_match(&packet->client_addr, &ap->match)) {
1358
/* piaddr() returns its result in a static
1359
buffer sized 4*16 (see common/inet.c). */
1361
strcpy(addrbuf, piaddr(ap->match.addr));
1362
strcpy(maskbuf, piaddr(ap->match.mask));
1364
log_info("BOOTREPLY from %s rejected by rule %s "
1365
"mask %s.", piaddr(packet->client_addr),
1376
struct packet *packet;
1378
struct iaddrmatchlist *ap;
1379
void (*handler) (struct packet *);
1384
switch (packet -> packet_type) {
1386
handler = dhcpoffer;
1404
/* If there's a reject list, make sure this packet's sender isn't
1406
for (ap = packet -> interface -> client -> config -> reject_list;
1407
ap; ap = ap -> next) {
1408
if (addr_match(&packet->client_addr, &ap->match)) {
1410
/* piaddr() returns its result in a static
1411
buffer sized 4*16 (see common/inet.c). */
1413
strcpy(addrbuf, piaddr(ap->match.addr));
1414
strcpy(maskbuf, piaddr(ap->match.mask));
1416
log_info("%s from %s rejected by rule %s mask %s.",
1417
type, piaddr(packet->client_addr),
1422
(*handler) (packet);
1427
dhcpv6(struct packet *packet) {
1428
struct iaddrmatchlist *ap;
1429
struct client_state *client;
1430
char addrbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")];
1432
/* Silently drop bogus messages. */
1433
if (packet->dhcpv6_msg_type >= dhcpv6_type_name_max)
1436
/* Discard, with log, packets from quenched sources. */
1437
for (ap = packet->interface->client->config->reject_list ;
1438
ap ; ap = ap->next) {
1439
if (addr_match(&packet->client_addr, &ap->match)) {
1440
strcpy(addrbuf, piaddr(packet->client_addr));
1441
log_info("%s from %s rejected by rule %s",
1442
dhcpv6_type_names[packet->dhcpv6_msg_type],
1444
piaddrmask(&ap->match.addr, &ap->match.mask));
1449
/* Screen out nonsensical messages. */
1450
switch(packet->dhcpv6_msg_type) {
1451
case DHCPV6_ADVERTISE:
1452
case DHCPV6_RECONFIGURE:
1457
log_info("RCV: %s message on %s from %s.",
1458
dhcpv6_type_names[packet->dhcpv6_msg_type],
1459
packet->interface->name, piaddr(packet->client_addr));
1466
/* Find a client state that matches the incoming XID. */
1467
for (client = packet->interface->client ; client ;
1468
client = client->next) {
1469
if (memcmp(&client->dhcpv6_transaction_id,
1470
packet->dhcpv6_transaction_id, 3) == 0) {
1471
client->v6_handler(packet, client);
1476
/* XXX: temporary log for debugging */
1477
log_info("Packet received, but nothing done with it.");
1481
void dhcpoffer (packet)
1482
struct packet *packet;
1484
struct interface_info *ip = packet -> interface;
1485
struct client_state *client;
1486
struct client_lease *lease, *lp;
1487
struct option **req;
1490
const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
1495
dump_packet (packet);
1498
/* Find a client state that matches the xid... */
1499
for (client = ip -> client; client; client = client -> next)
1500
if (client -> xid == packet -> raw -> xid)
1503
/* If we're not receptive to an offer right now, or if the offer
1504
has an unrecognizable transaction id, then just drop it. */
1506
client -> state != S_SELECTING ||
1507
(packet -> interface -> hw_address.hlen - 1 !=
1508
packet -> raw -> hlen) ||
1509
(memcmp (&packet -> interface -> hw_address.hbuf [1],
1510
packet -> raw -> chaddr, packet -> raw -> hlen))) {
1512
log_debug ("%s in wrong transaction.", name);
1517
sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr));
1520
/* If this lease doesn't supply the minimum required DHCPv4 parameters,
1523
req = client->config->required_options;
1525
for (i = 0 ; req[i] != NULL ; i++) {
1526
if ((req[i]->universe == &dhcp_universe) &&
1527
!lookup_option(&dhcp_universe, packet->options,
1529
struct option *option = NULL;
1530
unsigned code = req[i]->code;
1532
option_code_hash_lookup(&option,
1533
dhcp_universe.code_hash,
1537
log_info("%s: no %s option.", obuf,
1540
log_info("%s: no unknown-%u option.",
1543
option_dereference(&option, MDL);
1550
/* If we've already seen this lease, don't record it again. */
1551
for (lease = client -> offered_leases; lease; lease = lease -> next) {
1552
if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
1553
!memcmp (lease -> address.iabuf,
1554
&packet -> raw -> yiaddr, lease -> address.len)) {
1555
log_debug ("%s: already seen.", obuf);
1560
lease = packet_to_lease (packet, client);
1562
log_info ("%s: packet_to_lease failed.", obuf);
1566
/* If this lease was acquired through a BOOTREPLY, record that
1568
if (!packet -> options_valid || !packet -> packet_type)
1569
lease -> is_bootp = 1;
1571
/* Record the medium under which this lease was offered. */
1572
lease -> medium = client -> medium;
1574
/* Figure out when we're supposed to stop selecting. */
1575
stop_selecting = (client -> first_sending +
1576
client -> config -> select_interval);
1578
/* If this is the lease we asked for, put it at the head of the
1579
list, and don't mess with the arp request timeout. */
1580
if (lease -> address.len == client -> requested_address.len &&
1581
!memcmp (lease -> address.iabuf,
1582
client -> requested_address.iabuf,
1583
client -> requested_address.len)) {
1584
lease -> next = client -> offered_leases;
1585
client -> offered_leases = lease;
1587
/* Put the lease at the end of the list. */
1588
lease -> next = (struct client_lease *)0;
1589
if (!client -> offered_leases)
1590
client -> offered_leases = lease;
1592
for (lp = client -> offered_leases; lp -> next;
1599
/* If the selecting interval has expired, go immediately to
1600
state_selecting(). Otherwise, time out into
1601
state_selecting at the select interval. */
1602
if (stop_selecting <= cur_tv.tv_sec)
1603
state_selecting (client);
1605
tv.tv_sec = stop_selecting;
1606
tv.tv_usec = cur_tv.tv_usec;
1607
add_timeout(&tv, state_selecting, client, 0, 0);
1608
cancel_timeout(send_discover, client);
1610
log_info("%s", obuf);
1613
/* Allocate a client_lease structure and initialize it from the parameters
1614
in the specified packet. */
1616
struct client_lease *packet_to_lease (packet, client)
1617
struct packet *packet;
1618
struct client_state *client;
1620
struct client_lease *lease;
1622
struct option_cache *oc;
1623
struct option *option = NULL;
1624
struct data_string data;
1626
lease = (struct client_lease *)new_client_lease (MDL);
1629
log_error ("packet_to_lease: no memory to record lease.\n");
1630
return (struct client_lease *)0;
1633
memset (lease, 0, sizeof *lease);
1635
/* Copy the lease options. */
1636
option_state_reference (&lease -> options, packet -> options, MDL);
1638
lease -> address.len = sizeof (packet -> raw -> yiaddr);
1639
memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr,
1640
lease -> address.len);
1642
memset (&data, 0, sizeof data);
1644
if (client -> config -> vendor_space_name) {
1645
i = DHO_VENDOR_ENCAPSULATED_OPTIONS;
1647
/* See if there was a vendor encapsulation option. */
1648
oc = lookup_option (&dhcp_universe, lease -> options, i);
1650
client -> config -> vendor_space_name &&
1651
evaluate_option_cache (&data, packet,
1652
(struct lease *)0, client,
1653
packet -> options, lease -> options,
1654
&global_scope, oc, MDL)) {
1656
if (!option_code_hash_lookup(&option,
1657
dhcp_universe.code_hash,
1659
log_fatal("Unable to find VENDOR "
1660
"option (%s:%d).", MDL);
1661
parse_encapsulated_suboptions
1662
(packet -> options, option,
1663
data.data, data.len, &dhcp_universe,
1664
client -> config -> vendor_space_name
1667
option_dereference(&option, MDL);
1669
data_string_forget (&data, MDL);
1674
/* Figure out the overload flag. */
1675
oc = lookup_option (&dhcp_universe, lease -> options,
1676
DHO_DHCP_OPTION_OVERLOAD);
1678
evaluate_option_cache (&data, packet, (struct lease *)0, client,
1679
packet -> options, lease -> options,
1680
&global_scope, oc, MDL)) {
1685
data_string_forget (&data, MDL);
1689
/* If the server name was filled out, copy it. */
1690
if (!(i & 2) && packet -> raw -> sname [0]) {
1692
/* Don't count on the NUL terminator. */
1693
for (len = 0; len < DHCP_SNAME_LEN; len++)
1694
if (!packet -> raw -> sname [len])
1696
lease -> server_name = dmalloc (len + 1, MDL);
1697
if (!lease -> server_name) {
1698
log_error ("dhcpoffer: no memory for server name.\n");
1699
destroy_client_lease (lease);
1700
return (struct client_lease *)0;
1702
memcpy (lease -> server_name,
1703
packet -> raw -> sname, len);
1704
lease -> server_name [len] = 0;
1708
/* Ditto for the filename. */
1709
if (!(i & 1) && packet -> raw -> file [0]) {
1711
/* Don't count on the NUL terminator. */
1712
for (len = 0; len < DHCP_FILE_LEN; len++)
1713
if (!packet -> raw -> file [len])
1715
lease -> filename = dmalloc (len + 1, MDL);
1716
if (!lease -> filename) {
1717
log_error ("dhcpoffer: no memory for filename.\n");
1718
destroy_client_lease (lease);
1719
return (struct client_lease *)0;
1721
memcpy (lease -> filename,
1722
packet -> raw -> file, len);
1723
lease -> filename [len] = 0;
1727
execute_statements_in_scope ((struct binding_value **)0,
1728
(struct packet *)packet,
1729
(struct lease *)0, client,
1730
lease -> options, lease -> options,
1732
client -> config -> on_receipt,
1738
void dhcpnak (packet)
1739
struct packet *packet;
1741
struct interface_info *ip = packet -> interface;
1742
struct client_state *client;
1744
/* Find a client state that matches the xid... */
1745
for (client = ip -> client; client; client = client -> next)
1746
if (client -> xid == packet -> raw -> xid)
1749
/* If we're not receptive to an offer right now, or if the offer
1750
has an unrecognizable transaction id, then just drop it. */
1752
(packet -> interface -> hw_address.hlen - 1 !=
1753
packet -> raw -> hlen) ||
1754
(memcmp (&packet -> interface -> hw_address.hbuf [1],
1755
packet -> raw -> chaddr, packet -> raw -> hlen))) {
1757
log_debug ("DHCPNAK in wrong transaction.");
1762
if (client -> state != S_REBOOTING &&
1763
client -> state != S_REQUESTING &&
1764
client -> state != S_RENEWING &&
1765
client -> state != S_REBINDING) {
1767
log_debug ("DHCPNAK in wrong state.");
1772
log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
1774
if (!client -> active) {
1776
log_info ("DHCPNAK with no active lease.\n");
1781
/* If we get a DHCPNAK, we use the EXPIRE dhclient-script state
1782
* to indicate that we want all old bindings to be removed. (It
1783
* is possible that we may get a NAK while in the RENEW state,
1784
* so we might have bindings active at that time)
1786
script_init(client, "EXPIRE", NULL);
1787
script_write_params(client, "old_", client->active);
1789
script_write_params(client, "alias_", client->alias);
1792
destroy_client_lease (client -> active);
1793
client -> active = (struct client_lease *)0;
1795
/* Stop sending DHCPREQUEST packets... */
1796
cancel_timeout (send_request, client);
1798
/* On some scripts, 'EXPIRE' causes the interface to be ifconfig'd
1799
* down (this expunges any routes and arp cache). This makes the
1800
* interface unusable by state_init(), which we call next. So, we
1801
* need to 'PREINIT' the interface to bring it back up.
1803
script_init(client, "PREINIT", NULL);
1805
script_write_params(client, "alias_", client->alias);
1808
client -> state = S_INIT;
1809
state_init (client);
1812
/* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1813
one after the right interval has expired. If we don't get an offer by
1814
the time we reach the panic interval, call the panic function. */
1816
void send_discover (cpp)
1819
struct client_state *client = cpp;
1826
/* Figure out how long it's been since we started transmitting. */
1827
interval = cur_time - client -> first_sending;
1829
/* If we're past the panic timeout, call the script and tell it
1830
we haven't found anything for this interface yet. */
1831
if (interval > client -> config -> timeout) {
1832
state_panic (client);
1836
/* If we're selecting media, try the whole list before doing
1837
the exponential backoff, but if we've already received an
1838
offer, stop looping, because we obviously have it right. */
1839
if (!client -> offered_leases &&
1840
client -> config -> media) {
1843
if (client -> medium) {
1844
client -> medium = client -> medium -> next;
1847
if (!client -> medium) {
1849
log_fatal ("No valid media types for %s!",
1850
client -> interface -> name);
1852
client -> config -> media;
1856
log_info ("Trying medium \"%s\" %d",
1857
client -> medium -> string, increase);
1858
script_init (client, "MEDIUM", client -> medium);
1859
if (script_go (client)) {
1865
/* If we're supposed to increase the interval, do so. If it's
1866
currently zero (i.e., we haven't sent any packets yet), set
1867
it to initial_interval; otherwise, add to it a random number
1868
between zero and two times itself. On average, this means
1869
that it will double with every transmission. */
1871
if (!client->interval)
1872
client->interval = client->config->initial_interval;
1874
client->interval += random() % (2 * client->interval);
1876
/* Don't backoff past cutoff. */
1877
if (client->interval > client->config->backoff_cutoff)
1878
client->interval = (client->config->backoff_cutoff / 2)
1879
+ (random() % client->config->backoff_cutoff);
1880
} else if (!client->interval)
1881
client->interval = client->config->initial_interval;
1883
/* If the backoff would take us to the panic timeout, just use that
1885
if (cur_time + client -> interval >
1886
client -> first_sending + client -> config -> timeout)
1887
client -> interval =
1888
(client -> first_sending +
1889
client -> config -> timeout) - cur_time + 1;
1891
/* Record the number of seconds since we started sending. */
1892
if (interval < 65536)
1893
client -> packet.secs = htons (interval);
1895
client -> packet.secs = htons (65535);
1896
client -> secs = client -> packet.secs;
1898
log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
1899
client -> name ? client -> name : client -> interface -> name,
1900
inet_ntoa (sockaddr_broadcast.sin_addr),
1901
ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
1903
/* Send out a packet. */
1904
result = send_packet (client -> interface, (struct packet *)0,
1906
client -> packet_length,
1907
inaddr_any, &sockaddr_broadcast,
1908
(struct hardware *)0);
1911
* If we used 0 microseconds here, and there were other clients on the
1912
* same network with a synchronized local clock (ntp), and a similar
1913
* zero-microsecond-scheduler behavior, then we could be participating
1914
* in a sub-second DOS ttck.
1916
tv.tv_sec = cur_tv.tv_sec + client->interval;
1917
tv.tv_usec = client->interval > 1 ? random() % 1000000 : cur_tv.tv_usec;
1918
add_timeout(&tv, send_discover, client, 0, 0);
1921
/* state_panic gets called if we haven't received any offers in a preset
1922
amount of time. When this happens, we try to use existing leases that
1923
haven't yet expired, and failing that, we call the client script and
1924
hope it can do something. */
1926
void state_panic (cpp)
1929
struct client_state *client = cpp;
1930
struct client_lease *loop;
1931
struct client_lease *lp;
1934
loop = lp = client -> active;
1936
log_info ("No DHCPOFFERS received.");
1938
/* We may not have an active lease, but we may have some
1939
predefined leases that we can try. */
1940
if (!client -> active && client -> leases)
1943
/* Run through the list of leases and see if one can be used. */
1944
while (client -> active) {
1945
if (client -> active -> expiry > cur_time) {
1946
log_info ("Trying recorded lease %s",
1947
piaddr (client -> active -> address));
1948
/* Run the client script with the existing
1950
script_init (client, "TIMEOUT",
1951
client -> active -> medium);
1952
script_write_params (client, "new_", client -> active);
1953
if (client -> alias)
1954
script_write_params (client, "alias_",
1957
/* If the old lease is still good and doesn't
1958
yet need renewal, go into BOUND state and
1959
timeout at the renewal time. */
1960
if (!script_go (client)) {
1961
if (cur_time < client -> active -> renewal) {
1962
client -> state = S_BOUND;
1963
log_info ("bound: renewal in %ld %s.",
1964
(long)(client -> active -> renewal -
1965
cur_time), "seconds");
1966
tv.tv_sec = client->active->renewal;
1967
tv.tv_usec = ((client->active->renewal -
1969
random() % 1000000 :
1971
add_timeout(&tv, state_bound, client, 0, 0);
1973
client -> state = S_BOUND;
1974
log_info ("bound: immediate renewal.");
1975
state_bound (client);
1977
reinitialize_interfaces ();
1983
/* If there are no other leases, give up. */
1984
if (!client -> leases) {
1985
client -> leases = client -> active;
1986
client -> active = (struct client_lease *)0;
1991
/* Otherwise, put the active lease at the end of the
1992
lease list, and try another lease.. */
1993
for (lp = client -> leases; lp -> next; lp = lp -> next)
1995
lp -> next = client -> active;
1997
lp -> next -> next = (struct client_lease *)0;
1999
client -> active = client -> leases;
2000
client -> leases = client -> leases -> next;
2002
/* If we already tried this lease, we've exhausted the
2003
set of leases, so we might as well give up for
2005
if (client -> active == loop)
2008
loop = client -> active;
2011
/* No leases were available, or what was available didn't work, so
2012
tell the shell script that we failed to allocate an address,
2013
and try again later. */
2016
log_info ("Unable to obtain a lease on first try.%s",
2021
log_info ("No working leases in persistent database - sleeping.");
2022
script_init (client, "FAIL", (struct string_list *)0);
2023
if (client -> alias)
2024
script_write_params (client, "alias_", client -> alias);
2026
client -> state = S_INIT;
2027
tv.tv_sec = cur_tv.tv_sec + ((client->config->retry_interval + 1) / 2 +
2028
(random() % client->config->retry_interval));
2029
tv.tv_usec = ((tv.tv_sec - cur_tv.tv_sec) > 1) ?
2030
random() % 1000000 : cur_tv.tv_usec;
2031
add_timeout(&tv, state_init, client, 0, 0);
2035
void send_request (cpp)
2038
struct client_state *client = cpp;
2042
struct sockaddr_in destination;
2043
struct in_addr from;
2046
/* Figure out how long it's been since we started transmitting. */
2047
interval = cur_time - client -> first_sending;
2049
/* If we're in the INIT-REBOOT or REQUESTING state and we're
2050
past the reboot timeout, go to INIT and see if we can
2051
DISCOVER an address... */
2052
/* XXX In the INIT-REBOOT state, if we don't get an ACK, it
2053
means either that we're on a network with no DHCP server,
2054
or that our server is down. In the latter case, assuming
2055
that there is a backup DHCP server, DHCPDISCOVER will get
2056
us a new address, but we could also have successfully
2057
reused our old address. In the former case, we're hosed
2058
anyway. This is not a win-prone situation. */
2059
if ((client -> state == S_REBOOTING ||
2060
client -> state == S_REQUESTING) &&
2061
interval > client -> config -> reboot_timeout) {
2063
client -> state = S_INIT;
2064
cancel_timeout (send_request, client);
2065
state_init (client);
2069
/* If we're in the reboot state, make sure the media is set up
2071
if (client -> state == S_REBOOTING &&
2072
!client -> medium &&
2073
client -> active -> medium ) {
2074
script_init (client, "MEDIUM", client -> active -> medium);
2076
/* If the medium we chose won't fly, go to INIT state. */
2077
if (script_go (client))
2080
/* Record the medium. */
2081
client -> medium = client -> active -> medium;
2084
/* If the lease has expired, relinquish the address and go back
2085
to the INIT state. */
2086
if (client -> state != S_REQUESTING &&
2087
cur_time > client -> active -> expiry) {
2088
/* Run the client script with the new parameters. */
2089
script_init (client, "EXPIRE", (struct string_list *)0);
2090
script_write_params (client, "old_", client -> active);
2091
if (client -> alias)
2092
script_write_params (client, "alias_",
2096
/* Now do a preinit on the interface so that we can
2097
discover a new address. */
2098
script_init (client, "PREINIT", (struct string_list *)0);
2099
if (client -> alias)
2100
script_write_params (client, "alias_",
2104
client -> state = S_INIT;
2105
state_init (client);
2109
/* Do the exponential backoff... */
2110
if (!client -> interval)
2111
client -> interval = client -> config -> initial_interval;
2113
client -> interval += ((random () >> 2) %
2114
(2 * client -> interval));
2117
/* Don't backoff past cutoff. */
2118
if (client -> interval >
2119
client -> config -> backoff_cutoff)
2120
client -> interval =
2121
((client -> config -> backoff_cutoff / 2)
2122
+ ((random () >> 2) %
2123
client -> config -> backoff_cutoff));
2125
/* If the backoff would take us to the expiry time, just set the
2126
timeout to the expiry time. */
2127
if (client -> state != S_REQUESTING &&
2128
cur_time + client -> interval > client -> active -> expiry)
2129
client -> interval =
2130
client -> active -> expiry - cur_time + 1;
2132
/* If the lease T2 time has elapsed, or if we're not yet bound,
2133
broadcast the DHCPREQUEST rather than unicasting. */
2134
if (client -> state == S_REQUESTING ||
2135
client -> state == S_REBOOTING ||
2136
cur_time > client -> active -> rebind)
2137
destination.sin_addr = sockaddr_broadcast.sin_addr;
2139
memcpy (&destination.sin_addr.s_addr,
2140
client -> destination.iabuf,
2141
sizeof destination.sin_addr.s_addr);
2142
destination.sin_port = remote_port;
2143
destination.sin_family = AF_INET;
2145
destination.sin_len = sizeof destination;
2148
if (client -> state == S_RENEWING ||
2149
client -> state == S_REBINDING)
2150
memcpy (&from, client -> active -> address.iabuf,
2153
from.s_addr = INADDR_ANY;
2155
/* Record the number of seconds since we started sending. */
2156
if (client -> state == S_REQUESTING)
2157
client -> packet.secs = client -> secs;
2159
if (interval < 65536)
2160
client -> packet.secs = htons (interval);
2162
client -> packet.secs = htons (65535);
2165
log_info ("DHCPREQUEST on %s to %s port %d",
2166
client -> name ? client -> name : client -> interface -> name,
2167
inet_ntoa (destination.sin_addr),
2168
ntohs (destination.sin_port));
2170
if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
2172
result = send_packet (fallback_interface,
2175
client -> packet_length,
2177
(struct hardware *)0);
2179
/* Send out a packet. */
2180
result = send_packet (client -> interface, (struct packet *)0,
2182
client -> packet_length,
2184
(struct hardware *)0);
2186
tv.tv_sec = cur_tv.tv_sec + client->interval;
2187
tv.tv_usec = ((tv.tv_sec - cur_tv.tv_sec) > 1) ?
2188
random() % 1000000 : cur_tv.tv_usec;
2189
add_timeout(&tv, send_request, client, 0, 0);
2192
void send_decline (cpp)
2195
struct client_state *client = cpp;
2199
log_info ("DHCPDECLINE on %s to %s port %d",
2200
client -> name ? client -> name : client -> interface -> name,
2201
inet_ntoa (sockaddr_broadcast.sin_addr),
2202
ntohs (sockaddr_broadcast.sin_port));
2204
/* Send out a packet. */
2205
result = send_packet (client -> interface, (struct packet *)0,
2207
client -> packet_length,
2208
inaddr_any, &sockaddr_broadcast,
2209
(struct hardware *)0);
2212
void send_release (cpp)
2215
struct client_state *client = cpp;
2218
struct sockaddr_in destination;
2219
struct in_addr from;
2221
memcpy (&from, client -> active -> address.iabuf,
2223
memcpy (&destination.sin_addr.s_addr,
2224
client -> destination.iabuf,
2225
sizeof destination.sin_addr.s_addr);
2226
destination.sin_port = remote_port;
2227
destination.sin_family = AF_INET;
2229
destination.sin_len = sizeof destination;
2232
/* Set the lease to end now, so that we don't accidentally
2233
reuse it if we restart before the old expiry time. */
2234
client -> active -> expiry =
2235
client -> active -> renewal =
2236
client -> active -> rebind = cur_time;
2237
if (!write_client_lease (client, client -> active, 1, 1)) {
2238
log_error ("Can't release lease: lease write failed.");
2242
log_info ("DHCPRELEASE on %s to %s port %d",
2243
client -> name ? client -> name : client -> interface -> name,
2244
inet_ntoa (destination.sin_addr),
2245
ntohs (destination.sin_port));
2247
if (fallback_interface)
2248
result = send_packet (fallback_interface,
2251
client -> packet_length,
2253
(struct hardware *)0);
2255
/* Send out a packet. */
2256
result = send_packet (client -> interface, (struct packet *)0,
2258
client -> packet_length,
2260
(struct hardware *)0);
2264
make_client_options(struct client_state *client, struct client_lease *lease,
2265
u_int8_t *type, struct option_cache *sid,
2266
struct iaddr *rip, struct option **prl,
2267
struct option_state **op)
2270
struct option_cache *oc;
2271
struct option *option = NULL;
2272
struct buffer *bp = (struct buffer *)0;
2274
/* If there are any leftover options, get rid of them. */
2276
option_state_dereference (op, MDL);
2278
/* Allocate space for options. */
2279
option_state_allocate (op, MDL);
2281
/* Send the server identifier if provided. */
2283
save_option (&dhcp_universe, *op, sid);
2285
oc = (struct option_cache *)0;
2287
/* Send the requested address if provided. */
2289
client -> requested_address = *rip;
2290
i = DHO_DHCP_REQUESTED_ADDRESS;
2291
if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash,
2293
make_const_option_cache(&oc, NULL, rip->iabuf, rip->len,
2295
log_error ("can't make requested address cache.");
2297
save_option (&dhcp_universe, *op, oc);
2298
option_cache_dereference (&oc, MDL);
2300
option_dereference(&option, MDL);
2302
client -> requested_address.len = 0;
2305
i = DHO_DHCP_MESSAGE_TYPE;
2306
if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash, &i, 0,
2308
make_const_option_cache(&oc, NULL, type, 1, option, MDL)))
2309
log_error ("can't make message type.");
2311
save_option (&dhcp_universe, *op, oc);
2312
option_cache_dereference (&oc, MDL);
2314
option_dereference(&option, MDL);
2319
/* Probe the length of the list. */
2321
for (i = 0 ; prl[i] != NULL ; i++)
2322
if (prl[i]->universe == &dhcp_universe)
2325
if (!buffer_allocate (&bp, len, MDL))
2326
log_error ("can't make parameter list buffer.");
2328
unsigned code = DHO_DHCP_PARAMETER_REQUEST_LIST;
2331
for (i = 0 ; prl[i] != NULL ; i++)
2332
if (prl[i]->universe == &dhcp_universe)
2333
bp->data[len++] = prl[i]->code;
2335
if (!(option_code_hash_lookup(&option,
2336
dhcp_universe.code_hash,
2338
make_const_option_cache(&oc, &bp, NULL, len,
2340
log_error ("can't make option cache");
2342
save_option (&dhcp_universe, *op, oc);
2343
option_cache_dereference (&oc, MDL);
2345
option_dereference(&option, MDL);
2349
/* Run statements that need to be run on transmission. */
2350
if (client -> config -> on_transmission)
2351
execute_statements_in_scope
2352
((struct binding_value **)0,
2353
(struct packet *)0, (struct lease *)0, client,
2354
(lease ? lease -> options : (struct option_state *)0),
2356
client -> config -> on_transmission,
2360
void make_discover (client, lease)
2361
struct client_state *client;
2362
struct client_lease *lease;
2364
unsigned char discover = DHCPDISCOVER;
2365
struct option_state *options = (struct option_state *)0;
2367
memset (&client -> packet, 0, sizeof (client -> packet));
2369
make_client_options (client,
2370
lease, &discover, (struct option_cache *)0,
2371
lease ? &lease -> address : (struct iaddr *)0,
2372
client -> config -> requested_options,
2375
/* Set up the option buffer... */
2376
client -> packet_length =
2377
cons_options ((struct packet *)0, &client -> packet,
2378
(struct lease *)0, client,
2379
/* maximum packet size */1500,
2380
(struct option_state *)0,
2382
/* scope */ &global_scope,
2386
(struct data_string *)0,
2387
client -> config -> vendor_space_name);
2389
option_state_dereference (&options, MDL);
2390
if (client -> packet_length < BOOTP_MIN_LEN)
2391
client -> packet_length = BOOTP_MIN_LEN;
2393
client -> packet.op = BOOTREQUEST;
2394
client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2395
client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2396
client -> packet.hops = 0;
2397
client -> packet.xid = random ();
2398
client -> packet.secs = 0; /* filled in by send_discover. */
2400
if (can_receive_unicast_unconfigured (client -> interface))
2401
client -> packet.flags = 0;
2403
client -> packet.flags = htons (BOOTP_BROADCAST);
2405
memset (&(client -> packet.ciaddr),
2406
0, sizeof client -> packet.ciaddr);
2407
memset (&(client -> packet.yiaddr),
2408
0, sizeof client -> packet.yiaddr);
2409
memset (&(client -> packet.siaddr),
2410
0, sizeof client -> packet.siaddr);
2411
client -> packet.giaddr = giaddr;
2412
if (client -> interface -> hw_address.hlen > 0)
2413
memcpy (client -> packet.chaddr,
2414
&client -> interface -> hw_address.hbuf [1],
2415
(unsigned)(client -> interface -> hw_address.hlen - 1));
2418
dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2423
void make_request (client, lease)
2424
struct client_state *client;
2425
struct client_lease *lease;
2427
unsigned char request = DHCPREQUEST;
2428
struct option_cache *oc;
2430
memset (&client -> packet, 0, sizeof (client -> packet));
2432
if (client -> state == S_REQUESTING)
2433
oc = lookup_option (&dhcp_universe, lease -> options,
2434
DHO_DHCP_SERVER_IDENTIFIER);
2436
oc = (struct option_cache *)0;
2438
if (client -> sent_options)
2439
option_state_dereference (&client -> sent_options, MDL);
2441
make_client_options (client, lease, &request, oc,
2442
((client -> state == S_REQUESTING ||
2443
client -> state == S_REBOOTING)
2445
: (struct iaddr *)0),
2446
client -> config -> requested_options,
2447
&client -> sent_options);
2449
/* Set up the option buffer... */
2450
client -> packet_length =
2451
cons_options ((struct packet *)0, &client -> packet,
2452
(struct lease *)0, client,
2453
/* maximum packet size */1500,
2454
(struct option_state *)0,
2455
client -> sent_options,
2456
/* scope */ &global_scope,
2460
(struct data_string *)0,
2461
client -> config -> vendor_space_name);
2463
if (client -> packet_length < BOOTP_MIN_LEN)
2464
client -> packet_length = BOOTP_MIN_LEN;
2466
client -> packet.op = BOOTREQUEST;
2467
client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2468
client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2469
client -> packet.hops = 0;
2470
client -> packet.xid = client -> xid;
2471
client -> packet.secs = 0; /* Filled in by send_request. */
2473
/* If we own the address we're requesting, put it in ciaddr;
2474
otherwise set ciaddr to zero. */
2475
if (client -> state == S_BOUND ||
2476
client -> state == S_RENEWING ||
2477
client -> state == S_REBINDING) {
2478
memcpy (&client -> packet.ciaddr,
2479
lease -> address.iabuf, lease -> address.len);
2480
client -> packet.flags = 0;
2482
memset (&client -> packet.ciaddr, 0,
2483
sizeof client -> packet.ciaddr);
2484
if (can_receive_unicast_unconfigured (client -> interface))
2485
client -> packet.flags = 0;
2487
client -> packet.flags = htons (BOOTP_BROADCAST);
2490
memset (&client -> packet.yiaddr, 0,
2491
sizeof client -> packet.yiaddr);
2492
memset (&client -> packet.siaddr, 0,
2493
sizeof client -> packet.siaddr);
2494
if (client -> state != S_BOUND &&
2495
client -> state != S_RENEWING)
2496
client -> packet.giaddr = giaddr;
2498
memset (&client -> packet.giaddr, 0,
2499
sizeof client -> packet.giaddr);
2500
if (client -> interface -> hw_address.hlen > 0)
2501
memcpy (client -> packet.chaddr,
2502
&client -> interface -> hw_address.hbuf [1],
2503
(unsigned)(client -> interface -> hw_address.hlen - 1));
2506
dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2510
void make_decline (client, lease)
2511
struct client_state *client;
2512
struct client_lease *lease;
2514
unsigned char decline = DHCPDECLINE;
2515
struct option_cache *oc;
2517
struct option_state *options = (struct option_state *)0;
2519
/* Create the options cache. */
2520
oc = lookup_option (&dhcp_universe, lease -> options,
2521
DHO_DHCP_SERVER_IDENTIFIER);
2522
make_client_options(client, lease, &decline, oc, &lease->address,
2525
/* Consume the options cache into the option buffer. */
2526
memset (&client -> packet, 0, sizeof (client -> packet));
2527
client -> packet_length =
2528
cons_options ((struct packet *)0, &client -> packet,
2529
(struct lease *)0, client, 0,
2530
(struct option_state *)0, options,
2531
&global_scope, 0, 0, 0, (struct data_string *)0,
2532
client -> config -> vendor_space_name);
2534
/* Destroy the options cache. */
2535
option_state_dereference (&options, MDL);
2537
if (client -> packet_length < BOOTP_MIN_LEN)
2538
client -> packet_length = BOOTP_MIN_LEN;
2540
client -> packet.op = BOOTREQUEST;
2541
client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2542
client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2543
client -> packet.hops = 0;
2544
client -> packet.xid = client -> xid;
2545
client -> packet.secs = 0; /* Filled in by send_request. */
2546
if (can_receive_unicast_unconfigured (client -> interface))
2547
client -> packet.flags = 0;
2549
client -> packet.flags = htons (BOOTP_BROADCAST);
2551
/* ciaddr must always be zero. */
2552
memset (&client -> packet.ciaddr, 0,
2553
sizeof client -> packet.ciaddr);
2554
memset (&client -> packet.yiaddr, 0,
2555
sizeof client -> packet.yiaddr);
2556
memset (&client -> packet.siaddr, 0,
2557
sizeof client -> packet.siaddr);
2558
client -> packet.giaddr = giaddr;
2559
memcpy (client -> packet.chaddr,
2560
&client -> interface -> hw_address.hbuf [1],
2561
client -> interface -> hw_address.hlen);
2564
dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2568
void make_release (client, lease)
2569
struct client_state *client;
2570
struct client_lease *lease;
2572
unsigned char request = DHCPRELEASE;
2573
struct option_cache *oc;
2575
struct option_state *options = (struct option_state *)0;
2577
memset (&client -> packet, 0, sizeof (client -> packet));
2579
oc = lookup_option (&dhcp_universe, lease -> options,
2580
DHO_DHCP_SERVER_IDENTIFIER);
2581
make_client_options(client, lease, &request, oc, NULL, NULL, &options);
2583
/* Set up the option buffer... */
2584
client -> packet_length =
2585
cons_options ((struct packet *)0, &client -> packet,
2586
(struct lease *)0, client,
2587
/* maximum packet size */1500,
2588
(struct option_state *)0,
2590
/* scope */ &global_scope,
2594
(struct data_string *)0,
2595
client -> config -> vendor_space_name);
2597
if (client -> packet_length < BOOTP_MIN_LEN)
2598
client -> packet_length = BOOTP_MIN_LEN;
2599
option_state_dereference (&options, MDL);
2601
client -> packet.op = BOOTREQUEST;
2602
client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2603
client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2604
client -> packet.hops = 0;
2605
client -> packet.xid = random ();
2606
client -> packet.secs = 0;
2607
client -> packet.flags = 0;
2608
memcpy (&client -> packet.ciaddr,
2609
lease -> address.iabuf, lease -> address.len);
2610
memset (&client -> packet.yiaddr, 0,
2611
sizeof client -> packet.yiaddr);
2612
memset (&client -> packet.siaddr, 0,
2613
sizeof client -> packet.siaddr);
2614
client -> packet.giaddr = giaddr;
2615
memcpy (client -> packet.chaddr,
2616
&client -> interface -> hw_address.hbuf [1],
2617
client -> interface -> hw_address.hlen);
2620
dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2624
void destroy_client_lease (lease)
2625
struct client_lease *lease;
2627
if (lease -> server_name)
2628
dfree (lease -> server_name, MDL);
2629
if (lease -> filename)
2630
dfree (lease -> filename, MDL);
2631
option_state_dereference (&lease -> options, MDL);
2632
free_client_lease (lease, MDL);
2635
FILE *leaseFile = NULL;
2636
int leases_written = 0;
2638
void rewrite_client_leases ()
2640
struct interface_info *ip;
2641
struct client_state *client;
2642
struct client_lease *lp;
2644
if (leaseFile != NULL)
2646
leaseFile = fopen (path_dhclient_db, "w");
2647
if (leaseFile == NULL) {
2648
log_error ("can't create %s: %m", path_dhclient_db);
2652
/* If there is a default duid, write it out. */
2653
if (default_duid.len != 0)
2654
write_duid(&default_duid);
2656
/* Write out all the leases attached to configured interfaces that
2658
for (ip = interfaces; ip; ip = ip -> next) {
2659
for (client = ip -> client; client; client = client -> next) {
2660
for (lp = client -> leases; lp; lp = lp -> next) {
2661
write_client_lease (client, lp, 1, 0);
2663
if (client -> active)
2664
write_client_lease (client,
2665
client -> active, 1, 0);
2667
if (client->active_lease != NULL)
2668
write_client6_lease(client,
2669
client->active_lease,
2672
/* Reset last_write after rewrites. */
2673
client->last_write = 0;
2677
/* Write out any leases that are attached to interfaces that aren't
2678
currently configured. */
2679
for (ip = dummy_interfaces; ip; ip = ip -> next) {
2680
for (client = ip -> client; client; client = client -> next) {
2681
for (lp = client -> leases; lp; lp = lp -> next) {
2682
write_client_lease (client, lp, 1, 0);
2684
if (client -> active)
2685
write_client_lease (client,
2686
client -> active, 1, 0);
2688
if (client->active_lease != NULL)
2689
write_client6_lease(client,
2690
client->active_lease,
2693
/* Reset last_write after rewrites. */
2694
client->last_write = 0;
2700
void write_lease_option (struct option_cache *oc,
2701
struct packet *packet, struct lease *lease,
2702
struct client_state *client_state,
2703
struct option_state *in_options,
2704
struct option_state *cfg_options,
2705
struct binding_scope **scope,
2706
struct universe *u, void *stuff)
2708
const char *name, *dot;
2709
struct data_string ds;
2710
char *preamble = stuff;
2712
memset (&ds, 0, sizeof ds);
2714
if (u != &dhcp_universe) {
2721
if (evaluate_option_cache (&ds, packet, lease, client_state,
2722
in_options, cfg_options, scope, oc, MDL)) {
2723
fprintf(leaseFile, "%soption %s%s%s %s;\n", preamble,
2724
name, dot, oc->option->name,
2725
pretty_print_option(oc->option, ds.data, ds.len,
2727
data_string_forget (&ds, MDL);
2731
/* Write an option cache to the lease store. */
2733
write_options(struct client_state *client, struct option_state *options,
2734
const char *preamble)
2738
for (i = 0; i < options->universe_count; i++) {
2739
option_space_foreach(NULL, NULL, client, NULL, options,
2740
&global_scope, universes[i],
2741
(char *)preamble, write_lease_option);
2745
/* Write the default DUID to the lease store. */
2747
write_duid(struct data_string *duid)
2752
if ((duid == NULL) || (duid->len <= 2))
2753
return DHCP_R_INVALIDARG;
2755
if (leaseFile == NULL) { /* XXX? */
2756
leaseFile = fopen(path_dhclient_db, "w");
2757
if (leaseFile == NULL) {
2758
log_error("can't create %s: %m", path_dhclient_db);
2759
return ISC_R_IOERROR;
2763
/* It would make more sense to write this as a hex string,
2764
* but our function to do that (print_hex_n) uses a fixed
2765
* length buffer...and we can't guarantee a duid would be
2766
* less than the fixed length.
2768
str = quotify_buf(duid->data, duid->len, MDL);
2770
return ISC_R_NOMEMORY;
2772
stat = fprintf(leaseFile, "default-duid \"%s\";\n", str);
2775
return ISC_R_IOERROR;
2777
if (fflush(leaseFile) != 0)
2778
return ISC_R_IOERROR;
2780
return ISC_R_SUCCESS;
2783
/* Write a DHCPv6 lease to the store. */
2785
write_client6_lease(struct client_state *client, struct dhc6_lease *lease,
2786
int rewrite, int sync)
2789
struct dhc6_addr *addr;
2793
/* This should include the current lease. */
2794
if (!rewrite && (leases_written++ > 20)) {
2795
rewrite_client_leases();
2797
return ISC_R_SUCCESS;
2800
if (client == NULL || lease == NULL)
2801
return DHCP_R_INVALIDARG;
2803
if (leaseFile == NULL) { /* XXX? */
2804
leaseFile = fopen(path_dhclient_db, "w");
2805
if (leaseFile == NULL) {
2806
log_error("can't create %s: %m", path_dhclient_db);
2807
return ISC_R_IOERROR;
2811
stat = fprintf(leaseFile, "lease6 {\n");
2813
return ISC_R_IOERROR;
2815
stat = fprintf(leaseFile, " interface \"%s\";\n",
2816
client->interface->name);
2818
return ISC_R_IOERROR;
2820
for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
2821
switch (ia->ia_type) {
2833
stat = fprintf(leaseFile, " %s %s {\n",
2834
ianame, print_hex_1(4, ia->iaid, 12));
2836
return ISC_R_IOERROR;
2838
if (ia->ia_type != D6O_IA_TA)
2839
stat = fprintf(leaseFile, " starts %d;\n"
2842
(int)ia->starts, ia->renew, ia->rebind);
2844
stat = fprintf(leaseFile, " starts %d;\n",
2847
return ISC_R_IOERROR;
2849
for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
2850
if (ia->ia_type != D6O_IA_PD)
2851
stat = fprintf(leaseFile,
2853
piaddr(addr->address));
2855
stat = fprintf(leaseFile,
2856
" iaprefix %s/%d {\n",
2857
piaddr(addr->address),
2860
return ISC_R_IOERROR;
2862
stat = fprintf(leaseFile, " starts %d;\n"
2863
" preferred-life %u;\n"
2865
(int)addr->starts, addr->preferred_life,
2868
return ISC_R_IOERROR;
2870
if (addr->options != NULL)
2871
write_options(client, addr->options, " ");
2873
stat = fprintf(leaseFile, " }\n");
2875
return ISC_R_IOERROR;
2878
if (ia->options != NULL)
2879
write_options(client, ia->options, " ");
2881
stat = fprintf(leaseFile, " }\n");
2883
return ISC_R_IOERROR;
2886
if (lease->released) {
2887
stat = fprintf(leaseFile, " released;\n");
2889
return ISC_R_IOERROR;
2892
if (lease->options != NULL)
2893
write_options(client, lease->options, " ");
2895
stat = fprintf(leaseFile, "}\n");
2897
return ISC_R_IOERROR;
2899
if (fflush(leaseFile) != 0)
2900
return ISC_R_IOERROR;
2903
if (fsync(fileno(leaseFile)) < 0) {
2904
log_error("write_client_lease: fsync(): %m");
2905
return ISC_R_IOERROR;
2909
return ISC_R_SUCCESS;
2912
int write_client_lease (client, lease, rewrite, makesure)
2913
struct client_state *client;
2914
struct client_lease *lease;
2918
struct data_string ds;
2924
if (leases_written++ > 20) {
2925
rewrite_client_leases ();
2930
/* If the lease came from the config file, we don't need to stash
2931
a copy in the lease database. */
2932
if (lease -> is_static)
2935
if (leaseFile == NULL) { /* XXX */
2936
leaseFile = fopen (path_dhclient_db, "w");
2937
if (leaseFile == NULL) {
2938
log_error ("can't create %s: %m", path_dhclient_db);
2944
fprintf (leaseFile, "lease {\n");
2945
if (lease -> is_bootp) {
2946
fprintf (leaseFile, " bootp;\n");
2952
fprintf (leaseFile, " interface \"%s\";\n",
2953
client -> interface -> name);
2958
if (client -> name) {
2959
fprintf (leaseFile, " name \"%s\";\n", client -> name);
2965
fprintf (leaseFile, " fixed-address %s;\n",
2966
piaddr (lease -> address));
2971
if (lease -> filename) {
2972
s = quotify_string (lease -> filename, MDL);
2974
fprintf (leaseFile, " filename \"%s\";\n", s);
2984
if (lease->server_name != NULL) {
2985
s = quotify_string(lease->server_name, MDL);
2987
fprintf(leaseFile, " server-name \"%s\";\n", s);
2996
if (lease -> medium) {
2997
s = quotify_string (lease -> medium -> string, MDL);
2999
fprintf (leaseFile, " medium \"%s\";\n", s);
3013
memset (&ds, 0, sizeof ds);
3015
write_options(client, lease->options, " ");
3017
tval = print_time(lease->renewal);
3019
fprintf(leaseFile, " renew %s\n", tval) < 0)
3022
tval = print_time(lease->rebind);
3024
fprintf(leaseFile, " rebind %s\n", tval) < 0)
3027
tval = print_time(lease->expiry);
3029
fprintf(leaseFile, " expire %s\n", tval) < 0)
3032
if (fprintf(leaseFile, "}\n") < 0)
3035
if (fflush(leaseFile) != 0)
3038
client->last_write = cur_time;
3040
if (!errors && makesure) {
3041
if (fsync (fileno (leaseFile)) < 0) {
3042
log_info ("write_client_lease: %m");
3047
return errors ? 0 : 1;
3050
/* Variables holding name of script and file pointer for writing to
3051
script. Needless to say, this is not reentrant - only one script
3052
can be invoked at a time. */
3053
char scriptName [256];
3056
void script_init (client, reason, medium)
3057
struct client_state *client;
3059
struct string_list *medium;
3061
struct string_list *sl, *next;
3064
for (sl = client -> env; sl; sl = next) {
3068
client -> env = (struct string_list *)0;
3071
if (client -> interface) {
3072
client_envadd (client, "", "interface", "%s",
3073
client -> interface -> name);
3076
client_envadd (client,
3077
"", "client", "%s", client -> name);
3079
client_envadd (client,
3080
"", "medium", "%s", medium -> string);
3082
client_envadd (client, "", "reason", "%s", reason);
3083
client_envadd (client, "", "pid", "%ld", (long int)getpid ());
3087
void client_option_envadd (struct option_cache *oc,
3088
struct packet *packet, struct lease *lease,
3089
struct client_state *client_state,
3090
struct option_state *in_options,
3091
struct option_state *cfg_options,
3092
struct binding_scope **scope,
3093
struct universe *u, void *stuff)
3095
struct envadd_state *es = stuff;
3096
struct data_string data;
3097
memset (&data, 0, sizeof data);
3099
if (evaluate_option_cache (&data, packet, lease, client_state,
3100
in_options, cfg_options, scope, oc, MDL)) {
3103
if (dhcp_option_ev_name (name, sizeof name,
3107
value = pretty_print_option(oc->option,
3110
length = strlen(value);
3112
if (check_option_values(oc->option->universe,
3114
value, length) == 0) {
3115
client_envadd(es->client, es->prefix,
3118
log_error("suspect value in %s "
3119
"option - discarded",
3122
data_string_forget (&data, MDL);
3128
void script_write_params (client, prefix, lease)
3129
struct client_state *client;
3131
struct client_lease *lease;
3134
struct data_string data;
3135
struct option_cache *oc;
3136
struct envadd_state es;
3141
client_envadd (client,
3142
prefix, "ip_address", "%s", piaddr (lease -> address));
3144
/* For the benefit of Linux (and operating systems which may
3145
have similar needs), compute the network address based on
3146
the supplied ip address and netmask, if provided. Also
3147
compute the broadcast address (the host address all ones
3148
broadcast address, not the host address all zeroes
3149
broadcast address). */
3151
memset (&data, 0, sizeof data);
3152
oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK);
3153
if (oc && evaluate_option_cache (&data, (struct packet *)0,
3154
(struct lease *)0, client,
3155
(struct option_state *)0,
3157
&global_scope, oc, MDL)) {
3159
struct iaddr netmask, subnet, broadcast;
3162
* No matter the length of the subnet-mask option,
3163
* use only the first four octets. Note that
3164
* subnet-mask options longer than 4 octets are not
3165
* in conformance with RFC 2132, but servers with this
3168
memcpy(netmask.iabuf, data.data, 4);
3170
data_string_forget (&data, MDL);
3172
subnet = subnet_number (lease -> address, netmask);
3174
client_envadd (client, prefix, "network_number",
3175
"%s", piaddr (subnet));
3177
oc = lookup_option (&dhcp_universe,
3179
DHO_BROADCAST_ADDRESS);
3181
!(evaluate_option_cache
3182
(&data, (struct packet *)0,
3183
(struct lease *)0, client,
3184
(struct option_state *)0,
3186
&global_scope, oc, MDL))) {
3187
broadcast = broadcast_addr (subnet, netmask);
3188
if (broadcast.len) {
3189
client_envadd (client,
3190
prefix, "broadcast_address",
3191
"%s", piaddr (broadcast));
3196
data_string_forget (&data, MDL);
3199
if (lease->filename) {
3200
if (check_option_values(NULL, DHO_ROOT_PATH,
3202
strlen(lease->filename)) == 0) {
3203
client_envadd(client, prefix, "filename",
3204
"%s", lease->filename);
3206
log_error("suspect value in %s "
3207
"option - discarded",
3212
if (lease->server_name) {
3213
if (check_option_values(NULL, DHO_HOST_NAME,
3215
strlen(lease->server_name)) == 0 ) {
3216
client_envadd (client, prefix, "server_name",
3217
"%s", lease->server_name);
3219
log_error("suspect value in %s "
3220
"option - discarded",
3221
lease->server_name);
3226
for (i = 0; i < lease -> options -> universe_count; i++) {
3227
option_space_foreach ((struct packet *)0, (struct lease *)0,
3228
client, (struct option_state *)0,
3229
lease -> options, &global_scope,
3231
&es, client_option_envadd);
3233
client_envadd (client, prefix, "expiry", "%d", (int)(lease -> expiry));
3236
int script_go (client)
3237
struct client_state *client;
3242
char reason [] = "REASON=NBI";
3243
static char client_path [] = CLIENT_PATH;
3245
struct string_list *sp, *next;
3246
int pid, wpid, wstatus;
3249
scriptName = client -> config -> script_name;
3251
scriptName = top_level_config.script_name;
3253
envp = dmalloc (((client ? client -> envc : 2) +
3254
client_env_count + 2) * sizeof (char *), MDL);
3256
log_error ("No memory for client script environment.");
3260
/* Copy out the environment specified on the command line,
3262
for (sp = client_env; sp; sp = sp -> next) {
3263
envp [i++] = sp -> string;
3265
/* Copy out the environment specified by dhclient. */
3267
for (sp = client -> env; sp; sp = sp -> next) {
3268
envp [i++] = sp -> string;
3271
envp [i++] = reason;
3274
envp [i++] = client_path;
3275
envp [i] = (char *)0;
3277
argv [0] = scriptName;
3278
argv [1] = (char *)0;
3282
log_error ("fork: %m");
3286
wpid = wait (&wstatus);
3287
} while (wpid != pid && wpid > 0);
3289
log_error ("wait: %m");
3293
/* We don't want to pass an open file descriptor for
3294
* dhclient.leases when executing dhclient-script.
3296
if (leaseFile != NULL)
3298
execve (scriptName, argv, envp);
3299
log_error ("execve (%s, ...): %m", scriptName);
3304
for (sp = client -> env; sp; sp = next) {
3308
client -> env = (struct string_list *)0;
3312
gettimeofday(&cur_tv, NULL);
3313
return (WIFEXITED (wstatus) ?
3314
WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
3317
void client_envadd (struct client_state *client,
3318
const char *prefix, const char *name, const char *fmt, ...)
3323
struct string_list *val;
3326
va_start (list, fmt);
3327
len = vsnprintf (spbuf, sizeof spbuf, fmt, list);
3330
val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ +
3331
len + sizeof *val, MDL);
3339
if (len >= sizeof spbuf) {
3340
va_start (list, fmt);
3341
vsnprintf (s, len + 1, fmt, list);
3345
val -> next = client -> env;
3346
client -> env = val;
3350
int dhcp_option_ev_name (buf, buflen, option)
3353
struct option *option;
3359
if (option -> universe != &dhcp_universe) {
3360
s = option -> universe -> name;
3369
if (j + 1 == buflen)
3379
if (j + 1 == buflen)
3392
static int state = 0;
3395
/* Don't become a daemon if the user requested otherwise. */
3397
write_client_pid_file ();
3401
/* Only do it once. */
3406
/* Stop logging to stderr... */
3409
/* Become a daemon... */
3410
if ((pid = fork ()) < 0)
3411
log_fatal ("Can't fork daemon: %m");
3414
/* Become session leader and get pid... */
3417
/* Close standard I/O descriptors. */
3422
/* Reopen them on /dev/null. */
3423
open("/dev/null", O_RDWR);
3424
open("/dev/null", O_RDWR);
3425
open("/dev/null", O_RDWR);
3427
write_client_pid_file ();
3429
IGNORE_RET (chdir("/"));
3432
void write_client_pid_file ()
3437
/* nothing to do if the user doesn't want a pid file */
3438
if (no_pid_file == ISC_TRUE) {
3442
pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
3445
log_error ("Can't create %s: %m", path_dhclient_pid);
3449
pf = fdopen (pfdesc, "w");
3452
log_error ("Can't fdopen %s: %m", path_dhclient_pid);
3454
fprintf (pf, "%ld\n", (long)getpid ());
3459
void client_location_changed ()
3461
struct interface_info *ip;
3462
struct client_state *client;
3464
for (ip = interfaces; ip; ip = ip -> next) {
3465
for (client = ip -> client; client; client = client -> next) {
3466
switch (client -> state) {
3468
cancel_timeout (send_discover, client);
3472
cancel_timeout (state_bound, client);
3478
cancel_timeout (send_request, client);
3486
client -> state = S_INIT;
3487
state_reboot (client);
3492
void do_release(client)
3493
struct client_state *client;
3495
struct data_string ds;
3496
struct option_cache *oc;
3498
/* Pick a random xid. */
3499
client -> xid = random ();
3501
/* is there even a lease to release? */
3502
if (client -> active) {
3503
/* Make a DHCPRELEASE packet, and set appropriate per-interface
3505
make_release (client, client -> active);
3507
memset (&ds, 0, sizeof ds);
3508
oc = lookup_option (&dhcp_universe,
3509
client -> active -> options,
3510
DHO_DHCP_SERVER_IDENTIFIER);
3512
evaluate_option_cache (&ds, (struct packet *)0,
3513
(struct lease *)0, client,
3514
(struct option_state *)0,
3515
client -> active -> options,
3516
&global_scope, oc, MDL)) {
3518
memcpy (client -> destination.iabuf,
3520
client -> destination.len = 4;
3522
client -> destination = iaddr_broadcast;
3524
data_string_forget (&ds, MDL);
3526
client -> destination = iaddr_broadcast;
3527
client -> first_sending = cur_time;
3528
client -> interval = client -> config -> initial_interval;
3530
/* Zap the medium list... */
3531
client -> medium = (struct string_list *)0;
3533
/* Send out the first and only DHCPRELEASE packet. */
3534
send_release (client);
3536
/* Do the client script RELEASE operation. */
3537
script_init (client,
3538
"RELEASE", (struct string_list *)0);
3539
if (client -> alias)
3540
script_write_params (client, "alias_",
3542
script_write_params (client, "old_", client -> active);
3546
/* Cancel any timeouts. */
3547
cancel_timeout (state_bound, client);
3548
cancel_timeout (send_discover, client);
3549
cancel_timeout (state_init, client);
3550
cancel_timeout (send_request, client);
3551
cancel_timeout (state_reboot, client);
3552
client -> state = S_STOPPED;
3555
int dhclient_interface_shutdown_hook (struct interface_info *interface)
3557
do_release (interface -> client);
3562
int dhclient_interface_discovery_hook (struct interface_info *tmp)
3564
struct interface_info *last, *ip;
3565
/* See if we can find the client from dummy_interfaces */
3567
for (ip = dummy_interfaces; ip; ip = ip -> next) {
3568
if (!strcmp (ip -> name, tmp -> name)) {
3569
/* Remove from dummy_interfaces */
3571
ip = (struct interface_info *)0;
3572
interface_reference (&ip, last -> next, MDL);
3573
interface_dereference (&last -> next, MDL);
3575
interface_reference (&last -> next,
3577
interface_dereference (&ip -> next,
3581
ip = (struct interface_info *)0;
3582
interface_reference (&ip,
3583
dummy_interfaces, MDL);
3584
interface_dereference (&dummy_interfaces, MDL);
3586
interface_reference (&dummy_interfaces,
3588
interface_dereference (&ip -> next,
3592
/* Copy "client" to tmp */
3594
tmp -> client = ip -> client;
3595
tmp -> client -> interface = tmp;
3597
interface_dereference (&ip, MDL);
3605
isc_result_t dhclient_interface_startup_hook (struct interface_info *interface)
3607
struct interface_info *ip;
3608
struct client_state *client;
3610
/* This code needs some rethinking. It doesn't test against
3611
a signal name, and it just kind of bulls into doing something
3612
that may or may not be appropriate. */
3615
interface_reference (&interface -> next, interfaces, MDL);
3616
interface_dereference (&interfaces, MDL);
3618
interface_reference (&interfaces, interface, MDL);
3620
discover_interfaces (DISCOVER_UNCONFIGURED);
3622
for (ip = interfaces; ip; ip = ip -> next) {
3623
/* If interfaces were specified, don't configure
3624
interfaces that weren't specified! */
3625
if (ip -> flags & INTERFACE_RUNNING ||
3626
(ip -> flags & (INTERFACE_REQUESTED |
3627
INTERFACE_AUTOMATIC)) !=
3628
INTERFACE_REQUESTED)
3630
script_init (ip -> client,
3631
"PREINIT", (struct string_list *)0);
3632
if (ip -> client -> alias)
3633
script_write_params (ip -> client, "alias_",
3634
ip -> client -> alias);
3635
script_go (ip -> client);
3638
discover_interfaces (interfaces_requested != 0
3639
? DISCOVER_REQUESTED
3640
: DISCOVER_RUNNING);
3642
for (ip = interfaces; ip; ip = ip -> next) {
3643
if (ip -> flags & INTERFACE_RUNNING)
3645
ip -> flags |= INTERFACE_RUNNING;
3646
for (client = ip->client ; client ; client = client->next) {
3647
client->state = S_INIT;
3648
state_reboot(client);
3651
return ISC_R_SUCCESS;
3654
/* The client should never receive a relay agent information option,
3655
so if it does, log it and discard it. */
3657
int parse_agent_information_option (packet, len, data)
3658
struct packet *packet;
3665
/* The client never sends relay agent information options. */
3667
unsigned cons_agent_information_options (cfg_options, outpacket,
3669
struct option_state *cfg_options;
3670
struct dhcp_packet *outpacket;
3677
static void shutdown_exit (void *foo)
3682
#if defined (NSUPDATE)
3684
* If the first query fails, the updater MUST NOT delete the DNS name. It
3685
* may be that the host whose lease on the server has expired has moved
3686
* to another network and obtained a lease from a different server,
3687
* which has caused the client's A RR to be replaced. It may also be
3688
* that some other client has been configured with a name that matches
3689
* the name of the DHCP client, and the policy was that the last client
3690
* to specify the name would get the name. In this case, the DHCID RR
3691
* will no longer match the updater's notion of the client-identity of
3692
* the host pointed to by the DNS name.
3693
* -- "Interaction between DHCP and DNS"
3696
/* The first and second stages are pretty similar so we combine them */
3698
client_dns_remove_action(dhcp_ddns_cb_t *ddns_cb,
3699
isc_result_t eresult)
3702
isc_result_t result;
3704
if ((eresult == ISC_R_SUCCESS) &&
3705
(ddns_cb->state == DDNS_STATE_REM_FW_YXDHCID)) {
3706
/* Do the second stage of the FWD removal */
3707
ddns_cb->state = DDNS_STATE_REM_FW_NXRR;
3709
result = ddns_modify_fwd(ddns_cb);
3710
if (result == ISC_R_SUCCESS) {
3715
/* If we are done or have an error clean up */
3716
ddns_cb_free(ddns_cb, MDL);
3721
client_dns_remove(struct client_state *client,
3724
dhcp_ddns_cb_t *ddns_cb;
3725
isc_result_t result;
3727
/* if we have an old ddns request for this client, cancel it */
3728
if (client->ddns_cb != NULL) {
3729
ddns_cancel(client->ddns_cb);
3730
client->ddns_cb = NULL;
3733
ddns_cb = ddns_cb_alloc(MDL);
3734
if (ddns_cb != NULL) {
3735
ddns_cb->address = *addr;
3736
ddns_cb->timeout = 0;
3738
ddns_cb->state = DDNS_STATE_REM_FW_YXDHCID;
3739
ddns_cb->flags = DDNS_UPDATE_ADDR;
3740
ddns_cb->cur_func = client_dns_remove_action;
3742
result = client_dns_update(client, ddns_cb);
3744
if (result != ISC_R_TIMEDOUT) {
3745
ddns_cb_free(ddns_cb, MDL);
3751
isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
3752
control_object_state_t newstate)
3754
struct interface_info *ip;
3755
struct client_state *client;
3758
/* Do the right thing for each interface. */
3759
for (ip = interfaces; ip; ip = ip -> next) {
3760
for (client = ip -> client; client; client = client -> next) {
3762
case server_startup:
3763
return ISC_R_SUCCESS;
3765
case server_running:
3766
return ISC_R_SUCCESS;
3768
case server_shutdown:
3769
if (client -> active &&
3770
client -> active -> expiry > cur_time) {
3771
#if defined (NSUPDATE)
3772
if (client->config->do_forward_update) {
3773
client_dns_remove(client,
3774
&client->active->address);
3777
do_release (client);
3781
case server_hibernate:
3782
state_stop (client);
3786
state_reboot (client);
3792
if (newstate == server_shutdown) {
3793
tv.tv_sec = cur_tv.tv_sec;
3794
tv.tv_usec = cur_tv.tv_usec + 1;
3795
add_timeout(&tv, shutdown_exit, 0, 0, 0);
3797
return ISC_R_SUCCESS;
3800
#if defined (NSUPDATE)
3802
* Called after a timeout if the DNS update failed on the previous try.
3803
* Starts the retry process. If the retry times out it will schedule
3804
* this routine to run again after a 10x wait.
3807
client_dns_update_timeout (void *cp)
3809
dhcp_ddns_cb_t *ddns_cb = (dhcp_ddns_cb_t *)cp;
3810
struct client_state *client = (struct client_state *)ddns_cb->lease;
3811
isc_result_t status = ISC_R_FAILURE;
3813
if ((client != NULL) &&
3814
((client->active != NULL) ||
3815
(client->active_lease != NULL)))
3816
status = client_dns_update(client, ddns_cb);
3819
* A status of timedout indicates that we started the update and
3820
* have released control of the control block. Any other status
3821
* indicates that we should clean up the control block. We either
3822
* got a success which indicates that we didn't really need to
3823
* send an update or some other error in which case we weren't able
3824
* to start the update process. In both cases we still own
3825
* the control block and should free it.
3827
if (status != ISC_R_TIMEDOUT) {
3828
if (client != NULL) {
3829
client->ddns_cb = NULL;
3831
ddns_cb_free(ddns_cb, MDL);
3836
* If the first query succeeds, the updater can conclude that it
3837
* has added a new name whose only RRs are the A and DHCID RR records.
3838
* The A RR update is now complete (and a client updater is finished,
3839
* while a server might proceed to perform a PTR RR update).
3840
* -- "Interaction between DHCP and DNS"
3842
* If the second query succeeds, the updater can conclude that the current
3843
* client was the last client associated with the domain name, and that
3844
* the name now contains the updated A RR. The A RR update is now
3845
* complete (and a client updater is finished, while a server would
3846
* then proceed to perform a PTR RR update).
3847
* -- "Interaction between DHCP and DNS"
3849
* If the second query fails with NXRRSET, the updater must conclude
3850
* that the client's desired name is in use by another host. At this
3851
* juncture, the updater can decide (based on some administrative
3852
* configuration outside of the scope of this document) whether to let
3853
* the existing owner of the name keep that name, and to (possibly)
3854
* perform some name disambiguation operation on behalf of the current
3855
* client, or to replace the RRs on the name with RRs that represent
3856
* the current client. If the configured policy allows replacement of
3857
* existing records, the updater submits a query that deletes the
3858
* existing A RR and the existing DHCID RR, adding A and DHCID RRs that
3859
* represent the IP address and client-identity of the new client.
3860
* -- "Interaction between DHCP and DNS"
3863
/* The first and second stages are pretty similar so we combine them */
3865
client_dns_update_action(dhcp_ddns_cb_t *ddns_cb,
3866
isc_result_t eresult)
3868
isc_result_t result;
3874
/* Either we succeeded or broke in a bad way, clean up */
3879
* This is the only difference between the two stages,
3880
* check to see if it is the first stage, in which case
3881
* start the second stage
3883
if (ddns_cb->state == DDNS_STATE_ADD_FW_NXDOMAIN) {
3884
ddns_cb->state = DDNS_STATE_ADD_FW_YXDHCID;
3885
ddns_cb->cur_func = client_dns_update_action;
3887
result = ddns_modify_fwd(ddns_cb);
3888
if (result == ISC_R_SUCCESS) {
3894
case ISC_R_TIMEDOUT:
3896
* We got a timeout response from the DNS module. Schedule
3897
* another attempt for later. We forget the name, dhcid and
3898
* zone so if it gets changed we will get the new information.
3900
data_string_forget(&ddns_cb->fwd_name, MDL);
3901
data_string_forget(&ddns_cb->dhcid, MDL);
3902
if (ddns_cb->zone != NULL) {
3903
forget_zone((struct dns_zone **)&ddns_cb->zone);
3906
/* Reset to doing the first stage */
3907
ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN;
3908
ddns_cb->cur_func = client_dns_update_action;
3910
/* and update our timer */
3911
if (ddns_cb->timeout < 3600)
3912
ddns_cb->timeout *= 10;
3913
tv.tv_sec = cur_tv.tv_sec + ddns_cb->timeout;
3914
tv.tv_usec = cur_tv.tv_usec;
3915
add_timeout(&tv, client_dns_update_timeout,
3916
ddns_cb, NULL, NULL);
3920
ddns_cb_free(ddns_cb, MDL);
3924
/* See if we should do a DNS update, and if so, do it. */
3927
client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb)
3929
struct data_string client_identifier;
3930
struct option_cache *oc;
3935
/* If we didn't send an FQDN option, we certainly aren't going to
3936
be doing an update. */
3937
if (!client -> sent_options)
3938
return ISC_R_SUCCESS;
3940
/* If we don't have a lease, we can't do an update. */
3941
if ((client->active == NULL) && (client->active_lease == NULL))
3942
return ISC_R_SUCCESS;
3944
/* If we set the no client update flag, don't do the update. */
3945
if ((oc = lookup_option (&fqdn_universe, client -> sent_options,
3946
FQDN_NO_CLIENT_UPDATE)) &&
3947
evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
3948
(struct lease *)0, client,
3949
client -> sent_options,
3950
(struct option_state *)0,
3951
&global_scope, oc, MDL))
3952
return ISC_R_SUCCESS;
3954
/* If we set the "server, please update" flag, or didn't set it
3955
to false, don't do the update. */
3956
if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
3957
FQDN_SERVER_UPDATE)) ||
3958
evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
3959
(struct lease *)0, client,
3960
client -> sent_options,
3961
(struct option_state *)0,
3962
&global_scope, oc, MDL))
3963
return ISC_R_SUCCESS;
3965
/* If no FQDN option was supplied, don't do the update. */
3966
if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
3968
!evaluate_option_cache (&ddns_cb->fwd_name, (struct packet *)0,
3969
(struct lease *)0, client,
3970
client -> sent_options,
3971
(struct option_state *)0,
3972
&global_scope, oc, MDL))
3973
return ISC_R_SUCCESS;
3975
/* If this is a DHCPv6 client update, make a dhcid string out of
3976
* the DUID. If this is a DHCPv4 client update, choose either
3977
* the client identifier, if there is one, or the interface's
3981
memset(&client_identifier, 0, sizeof(client_identifier));
3982
if (client->active_lease != NULL) {
3984
lookup_option(&dhcpv6_universe, client->sent_options,
3985
D6O_CLIENTID)) != NULL) &&
3986
evaluate_option_cache(&client_identifier, NULL, NULL,
3987
client, client->sent_options, NULL,
3988
&global_scope, oc, MDL)) {
3989
/* RFC4701 defines type '2' as being for the DUID
3990
* field. We aren't using RFC4701 DHCID RR's yet,
3991
* but this is as good a value as any.
3993
result = get_dhcid(&ddns_cb->dhcid, 2,
3994
client_identifier.data,
3995
client_identifier.len);
3996
data_string_forget(&client_identifier, MDL);
3998
log_fatal("Impossible condition at %s:%d.", MDL);
4001
lookup_option(&dhcp_universe, client->sent_options,
4002
DHO_DHCP_CLIENT_IDENTIFIER)) != NULL) &&
4003
evaluate_option_cache(&client_identifier, NULL, NULL,
4004
client, client->sent_options, NULL,
4005
&global_scope, oc, MDL)) {
4006
result = get_dhcid(&ddns_cb->dhcid,
4007
DHO_DHCP_CLIENT_IDENTIFIER,
4008
client_identifier.data,
4009
client_identifier.len);
4010
data_string_forget(&client_identifier, MDL);
4012
result = get_dhcid(&ddns_cb->dhcid, 0,
4013
client->interface->hw_address.hbuf,
4014
client->interface->hw_address.hlen);
4017
return ISC_R_SUCCESS;
4023
if (ddns_cb->fwd_name.len && ddns_cb->dhcid.len) {
4024
rcode = ddns_modify_fwd(ddns_cb);
4026
rcode = ISC_R_FAILURE;
4029
* A success from the modify routine means we are performing
4030
* async processing, for which we use the timedout error message.
4032
if (rcode == ISC_R_SUCCESS) {
4033
rcode = ISC_R_TIMEDOUT;
4041
* Schedule the first update. They will continue to retry occasionally
4042
* until they no longer time out (or fail).
4045
dhclient_schedule_updates(struct client_state *client,
4049
dhcp_ddns_cb_t *ddns_cb;
4052
if (!client->config->do_forward_update)
4055
/* cancel any outstanding ddns requests */
4056
if (client->ddns_cb != NULL) {
4057
ddns_cancel(client->ddns_cb);
4058
client->ddns_cb = NULL;
4061
ddns_cb = ddns_cb_alloc(MDL);
4063
if (ddns_cb != NULL) {
4064
ddns_cb->lease = (void *)client;
4065
ddns_cb->address = *addr;
4066
ddns_cb->timeout = 1;
4069
* XXX: DNS TTL is a problem we need to solve properly.
4070
* Until that time, 300 is a placeholder default for
4071
* something that is less insane than a value scaled
4076
ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN;
4077
ddns_cb->cur_func = client_dns_update_action;
4078
ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_INCLUDE_RRSET;
4080
client->ddns_cb = ddns_cb;
4082
tv.tv_sec = cur_tv.tv_sec + offset;
4083
tv.tv_usec = cur_tv.tv_usec;
4084
add_timeout(&tv, client_dns_update_timeout,
4085
ddns_cb, NULL, NULL);
4087
log_error("Unable to allocate dns update state for %s",
4094
dhcpv4_client_assignments(void)
4096
struct servent *ent;
4098
if (path_dhclient_pid == NULL)
4099
path_dhclient_pid = _PATH_DHCLIENT_PID;
4100
if (path_dhclient_db == NULL)
4101
path_dhclient_db = _PATH_DHCLIENT_DB;
4103
/* Default to the DHCP/BOOTP port. */
4105
/* If we're faking a relay agent, and we're not using loopback,
4106
use the server port, not the client port. */
4107
if (mockup_relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
4108
local_port = htons(67);
4110
ent = getservbyname ("dhcpc", "udp");
4112
local_port = htons (68);
4114
local_port = ent -> s_port;
4115
#ifndef __CYGWIN32__
4121
/* If we're faking a relay agent, and we're not using loopback,
4122
we're using the server port, not the client port. */
4123
if (mockup_relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
4124
remote_port = local_port;
4126
remote_port = htons (ntohs (local_port) - 1); /* XXX */
4130
* The following routines are used to check that certain
4131
* strings are reasonable before we pass them to the scripts.
4132
* This avoids some problems with scripts treating the strings
4133
* as commands - see ticket 23722
4134
* The domain checking code should be done as part of assembling
4135
* the string but we are doing it here for now due to time
4139
static int check_domain_name(const char *ptr, size_t len, int dots)
4143
/* not empty or complete length not over 255 characters */
4144
if ((len == 0) || (len > 256))
4147
/* consists of [[:alnum:]-]+ labels separated by [.] */
4148
/* a [_] is against RFC but seems to be "widely used"... */
4149
for (p=ptr; (*p != 0) && (len-- > 0); p++) {
4150
if ((*p == '-') || (*p == '_')) {
4151
/* not allowed at begin or end of a label */
4152
if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
4154
} else if (*p == '.') {
4155
/* each label has to be 1-63 characters;
4156
we allow [.] at the end ('foo.bar.') */
4158
if ((d <= 0) || (d >= 64))
4160
ptr = p + 1; /* jump to the next label */
4161
if ((dots > 0) && (len > 0))
4163
} else if (isalnum((unsigned char)*p) == 0) {
4164
/* also numbers at the begin are fine */
4168
return(dots ? -1 : 0);
4171
static int check_domain_name_list(const char *ptr, size_t len, int dots)
4174
int ret = -1; /* at least one needed */
4176
if ((ptr == NULL) || (len == 0))
4179
for (p=ptr; (*p != 0) && (len > 0); p++, len--) {
4183
if (check_domain_name(ptr, p - ptr, dots) != 0)
4190
return(check_domain_name(ptr, p - ptr, dots));
4195
static int check_option_values(struct universe *universe,
4203
/* just reject options we want to protect, will be escaped anyway */
4204
if ((universe == NULL) || (universe == &dhcp_universe)) {
4206
case DHO_DOMAIN_NAME:
4207
#ifdef ACCEPT_LIST_IN_DOMAIN_NAME
4208
return check_domain_name_list(ptr, len, 0);
4210
return check_domain_name(ptr, len, 0);
4213
case DHO_NIS_DOMAIN:
4214
case DHO_NETBIOS_SCOPE:
4215
return check_domain_name(ptr, len, 0);
4217
case DHO_DOMAIN_SEARCH:
4218
return check_domain_name_list(ptr, len, 0);
4223
for (; (*ptr != 0) && (len-- > 0); ptr++) {
4224
if(!(isalnum((unsigned char)*ptr) ||
4225
*ptr == '#' || *ptr == '%' ||
4226
*ptr == '+' || *ptr == '-' ||
4227
*ptr == '_' || *ptr == ':' ||
4228
*ptr == '.' || *ptr == ',' ||
4229
*ptr == '@' || *ptr == '~' ||
4230
*ptr == '\\' || *ptr == '/' ||
4231
*ptr == '[' || *ptr == ']' ||
4232
*ptr == '=' || *ptr == ' '))
4241
if (universe == &dhcpv6_universe) {
4243
case D6O_SIP_SERVERS_DNS:
4244
case D6O_DOMAIN_SEARCH:
4245
case D6O_NIS_DOMAIN_NAME:
4246
case D6O_NISP_DOMAIN_NAME:
4247
return check_domain_name_list(ptr, len, 0);
4257
add_reject(struct packet *packet) {
4258
struct iaddrmatchlist *list;
4260
list = dmalloc(sizeof(struct iaddrmatchlist), MDL);
4262
log_fatal ("no memory for reject list!");
4265
* client_addr is misleading - it is set to source address in common
4268
list->match.addr = packet->client_addr;
4269
/* Set mask to indicate host address. */
4270
list->match.mask.len = list->match.addr.len;
4271
memset(list->match.mask.iabuf, 0xff, sizeof(list->match.mask.iabuf));
4273
/* Append to reject list for the source interface. */
4274
list->next = packet->interface->client->config->reject_list;
4275
packet->interface->client->config->reject_list = list;
4278
* We should inform user that we won't be accepting this server
4281
log_info("Server added to list of rejected servers.");