1e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/*
2e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * dhcpcd - DHCP client daemon
3e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Copyright (c) 2006-2010 Roy Marples <roy@marples.name>
4e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * All rights reserved
5e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
6e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Redistribution and use in source and binary forms, with or without
7e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * modification, are permitted provided that the following conditions
8e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * are met:
9e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 1. Redistributions of source code must retain the above copyright
10e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *    notice, this list of conditions and the following disclaimer.
11e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 2. Redistributions in binary form must reproduce the above copyright
12e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *    notice, this list of conditions and the following disclaimer in the
13e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *    documentation and/or other materials provided with the distribution.
14e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *
15e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * SUCH DAMAGE.
26e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt */
27e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
28e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/param.h>
29e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/time.h>
30e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
31e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <fcntl.h>
32e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#ifdef BSD
33e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#  include <paths.h>
34e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif
35e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <signal.h>
36e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <stdlib.h>
37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <syslog.h>
38e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <unistd.h>
39e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "arp.h"
41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "bind.h"
42e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "common.h"
43e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "configure.h"
44e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "dhcpcd.h"
45e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "eloop.h"
46e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "if-options.h"
47e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "net.h"
48e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "signals.h"
49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
50e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#ifndef _PATH_DEVNULL
51e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#  define _PATH_DEVNULL "/dev/null"
52e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif
53e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
54e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* We do things after aquiring the lease, so ensure we have enough time for them */
55e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define DHCP_MIN_LEASE 20
56e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
57e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#ifndef THERE_IS_NO_FORK
58e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtpid_t
59e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtdaemonise(void)
60e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{
61e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	pid_t pid;
62e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	sigset_t full;
63e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	sigset_t old;
64e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	char buf = '\0';
65e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	int sidpipe[2], fd;
66e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
67e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (options & DHCPCD_DAEMONISED || !(options & DHCPCD_DAEMONISE))
68e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		return 0;
69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	sigfillset(&full);
70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	sigprocmask(SIG_SETMASK, &full, &old);
71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	/* Setup a signal pipe so parent knows when to exit. */
72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (pipe(sidpipe) == -1) {
73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		syslog(LOG_ERR, "pipe: %m");
74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		return -1;
75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	syslog(LOG_DEBUG, "forking to background");
77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	switch (pid = fork()) {
78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	case -1:
79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		syslog(LOG_ERR, "fork: %m");
80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		exit(EXIT_FAILURE);
81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* NOTREACHED */
82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	case 0:
83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		setsid();
84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* Notify parent it's safe to exit as we've detached. */
85e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		close(sidpipe[0]);
86e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (write(sidpipe[1], &buf, 1) == -1)
87e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			syslog(LOG_ERR, "failed to notify parent: %m");
88e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		close(sidpipe[1]);
89e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
90e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			dup2(fd, STDIN_FILENO);
91e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			dup2(fd, STDOUT_FILENO);
92e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			dup2(fd, STDERR_FILENO);
93e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			if (fd > STDERR_FILENO)
94e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				close(fd);
95e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		}
96e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		break;
97e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	default:
98e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		signal_reset();
99e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* Wait for child to detach */
100e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		close(sidpipe[1]);
101e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (read(sidpipe[0], &buf, 1) == -1)
102e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			syslog(LOG_ERR, "failed to read child: %m");
103e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		close(sidpipe[0]);
104e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		break;
105e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
106e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	/* Done with the fd now */
107e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (pid != 0) {
108e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		syslog(LOG_INFO, "forked to background, child pid %d",pid);
109e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		writepid(pidfd, pid);
110e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		close(pidfd);
111e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		pidfd = -1;
112e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		exit(EXIT_SUCCESS);
113e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
114e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	options |= DHCPCD_DAEMONISED;
115e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	sigprocmask(SIG_SETMASK, &old, NULL);
116e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	return pid;
117e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}
118e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif
119e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
120e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtvoid
121e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtbind_interface(void *arg)
122e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{
123e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct interface *iface = arg;
124e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct if_state *state = iface->state;
125e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct if_options *ifo = state->options;
126e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct dhcp_lease *lease = &state->lease;
127e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct timeval tv;
128e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
129e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	/* We're binding an address now - ensure that sockets are closed */
130e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	close_sockets(iface);
131e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	state->reason = NULL;
132e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	delete_timeout(handle_exit_timeout, NULL);
133e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (clock_monotonic)
134e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		get_monotonic(&lease->boundtime);
135e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	state->xid = 0;
136e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	free(state->old);
137e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	state->old = state->new;
138e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	state->new = state->offer;
139e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	state->offer = NULL;
140e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	get_lease(lease, state->new);
141e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (ifo->options & DHCPCD_STATIC) {
142e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		syslog(LOG_INFO, "%s: using static address %s",
143e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    iface->name, inet_ntoa(lease->addr));
144e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		lease->leasetime = ~0U;
145e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		lease->net.s_addr = ifo->req_mask.s_addr;
146e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		state->reason = "STATIC";
147e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	} else if (state->new->cookie != htonl(MAGIC_COOKIE)) {
148e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		syslog(LOG_INFO, "%s: using IPv4LL address %s",
149e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    iface->name, inet_ntoa(lease->addr));
150e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		lease->leasetime = ~0U;
151e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		state->reason = "IPV4LL";
152e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	} else if (ifo->options & DHCPCD_INFORM) {
153e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (ifo->req_addr.s_addr != 0)
154e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			lease->addr.s_addr = ifo->req_addr.s_addr;
155e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		else
156e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			lease->addr.s_addr = iface->addr.s_addr;
157e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		syslog(LOG_INFO, "%s: received approval for %s", iface->name,
158e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    inet_ntoa(lease->addr));
159e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		lease->leasetime = ~0U;
160e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		state->reason = "INFORM";
161e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	} else {
162e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (gettimeofday(&tv, NULL) == 0)
163e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			lease->leasedfrom = tv.tv_sec;
164e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		else if (lease->frominfo)
165e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			state->reason = "TIMEOUT";
166e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (lease->leasetime == ~0U) {
167e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			lease->renewaltime =
168e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    lease->rebindtime =
169e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    lease->leasetime;
170e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			syslog(LOG_INFO, "%s: leased %s for infinity",
171e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    iface->name, inet_ntoa(lease->addr));
172e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		} else {
173e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			if (lease->leasetime < DHCP_MIN_LEASE) {
174e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				syslog(LOG_WARNING,
175e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				    "%s: minimum lease is %d seconds",
176e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				    iface->name, DHCP_MIN_LEASE);
177e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				lease->leasetime = DHCP_MIN_LEASE;
178e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			}
179e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			if (lease->rebindtime == 0)
180e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				lease->rebindtime = lease->leasetime * T2;
181e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			else if (lease->rebindtime >= lease->leasetime) {
182e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				lease->rebindtime = lease->leasetime * T2;
183e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				syslog(LOG_ERR,
184e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				    "%s: rebind time greater than lease "
185e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				    "time, forcing to %u seconds",
186e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				    iface->name, lease->rebindtime);
187e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			}
188e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			if (lease->renewaltime == 0)
189e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				lease->renewaltime = lease->leasetime * T1;
190e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			else if (lease->renewaltime > lease->rebindtime) {
191e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				lease->renewaltime = lease->leasetime * T1;
192e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				syslog(LOG_ERR,
193e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				    "%s: renewal time greater than rebind "
194e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				    "time, forcing to %u seconds",
195e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				    iface->name, lease->renewaltime);
196e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			}
197e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			syslog(LOG_INFO,
198e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    "%s: leased %s for %u seconds", iface->name,
199e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    inet_ntoa(lease->addr), lease->leasetime);
200e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		}
201e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
202e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (options & DHCPCD_TEST) {
203e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		state->reason = "TEST";
204e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		run_script(iface);
205e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		exit(EXIT_SUCCESS);
206e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
207e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (state->reason == NULL) {
208e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (state->old) {
209e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			if (state->old->yiaddr == state->new->yiaddr &&
210e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    lease->server.s_addr)
211e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				state->reason = "RENEW";
212e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			else
213e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				state->reason = "REBIND";
214e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		} else if (state->state == DHS_REBOOT)
215e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			state->reason = "REBOOT";
216e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		else
217e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			state->reason = "BOUND";
218e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
219e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (lease->leasetime == ~0U)
220e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		lease->renewaltime = lease->rebindtime = lease->leasetime;
221e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	else {
222e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		add_timeout_sec(lease->renewaltime, start_renew, iface);
223e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		add_timeout_sec(lease->rebindtime, start_rebind, iface);
224e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		add_timeout_sec(lease->leasetime, start_expire, iface);
225e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
226e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	ifo->options &= ~ DHCPCD_CSR_WARNED;
227e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	configure(iface);
228e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	daemonise();
229e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	state->state = DHS_BOUND;
230e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (ifo->options & DHCPCD_ARP) {
231e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		state->claims = 0;
232e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		send_arp_announce(iface);
233e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
234e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}
235