1e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/*
2e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * dhcpcd - DHCP client daemon
3a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * Copyright (c) 2006-2011 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 <errno.h>
29e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <signal.h>
30e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <stdlib.h>
31e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <string.h>
32e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <syslog.h>
33e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <unistd.h>
34e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
35e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "arp.h"
36e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "bind.h"
37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "common.h"
38e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "dhcpcd.h"
39e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "eloop.h"
40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "if-options.h"
41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "ipv4ll.h"
42e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "net.h"
43e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
44e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define ARP_LEN								      \
45e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	(sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN))
46e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
47e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic int
48e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtsend_arp(const struct interface *iface, int op, in_addr_t sip, in_addr_t tip)
49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{
50e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	uint8_t arp_buffer[ARP_LEN];
51e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct arphdr ar;
52e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	size_t len;
53e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	uint8_t *p;
54e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	int retval;
55e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
56e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	ar.ar_hrd = htons(iface->family);
57e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	ar.ar_pro = htons(ETHERTYPE_IP);
58e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	ar.ar_hln = iface->hwlen;
59e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	ar.ar_pln = sizeof(sip);
60e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	ar.ar_op = htons(op);
61e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	memcpy(arp_buffer, &ar, sizeof(ar));
62e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	p = arp_buffer + sizeof(ar);
63e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	memcpy(p, iface->hwaddr, iface->hwlen);
64e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	p += iface->hwlen;
65e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	memcpy(p, &sip, sizeof(sip));
66e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	p += sizeof(sip);
67e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	/* ARP requests should ignore this */
68e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	retval = iface->hwlen;
69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	while (retval--)
70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		*p++ = '\0';
71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	memcpy(p, &tip, sizeof(tip));
72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	p += sizeof(tip);
73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	len = p - arp_buffer;
74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	retval = send_raw_packet(iface, ETHERTYPE_ARP, arp_buffer, len);
75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	return retval;
76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}
77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic void
79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidthandle_arp_failure(struct interface *iface)
80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{
81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	/* If we failed without a magic cookie then we need to try
83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	 * and defend our IPv4LL address. */
84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if ((iface->state->offer != NULL &&
85e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		iface->state->offer->cookie != htonl(MAGIC_COOKIE)) ||
86e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	    (iface->state->new != NULL &&
87e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		iface->state->new->cookie != htonl(MAGIC_COOKIE)))
88e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	{
89e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		handle_ipv4ll_failure(iface);
90e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		return;
91e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
92e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
93e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	unlink(iface->leasefile);
94e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (!iface->state->lease.frominfo)
95e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		send_decline(iface);
96e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	close_sockets(iface);
97e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	delete_timeout(NULL, iface);
98e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (iface->state->lease.frominfo)
99e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		start_interface(iface);
100e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	else
101e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		add_timeout_sec(DHCP_ARP_FAIL, start_interface, iface);
102e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}
103e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
104e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic void
105e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidthandle_arp_packet(void *arg)
106e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{
107e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct interface *iface = arg;
108e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	uint8_t arp_buffer[ARP_LEN];
109e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct arphdr ar;
110e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	uint32_t reply_s;
111e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	uint32_t reply_t;
112e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	uint8_t *hw_s, *hw_t;
113e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	ssize_t bytes;
114e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct if_state *state = iface->state;
115e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct if_options *opts = state->options;
116e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	const char *hwaddr;
117e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct in_addr ina;
118e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
119e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	state->fail.s_addr = 0;
120e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	for(;;) {
121e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		bytes = get_raw_packet(iface, ETHERTYPE_ARP,
122a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		    arp_buffer, sizeof(arp_buffer), NULL);
123e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (bytes == 0 || bytes == -1)
124e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			return;
125e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* We must have a full ARP header */
126e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if ((size_t)bytes < sizeof(ar))
127e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			continue;
128e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		memcpy(&ar, arp_buffer, sizeof(ar));
129e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* Protocol must be IP. */
130e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (ar.ar_pro != htons(ETHERTYPE_IP))
131e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			continue;
132e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (ar.ar_pln != sizeof(reply_s))
133e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			continue;
134e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* Only these types are recognised */
135e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (ar.ar_op != htons(ARPOP_REPLY) &&
136e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    ar.ar_op != htons(ARPOP_REQUEST))
137e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			continue;
138e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
139e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* Get pointers to the hardware addreses */
140e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		hw_s = arp_buffer + sizeof(ar);
141e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		hw_t = hw_s + ar.ar_hln + ar.ar_pln;
142e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* Ensure we got all the data */
143e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if ((hw_t + ar.ar_hln + ar.ar_pln) - arp_buffer > bytes)
144e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			continue;
145e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* Ignore messages from ourself */
146e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (ar.ar_hln == iface->hwlen &&
147e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    memcmp(hw_s, iface->hwaddr, iface->hwlen) == 0)
148e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			continue;
149e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* Copy out the IP addresses */
150e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		memcpy(&reply_s, hw_s + ar.ar_hln, ar.ar_pln);
151e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		memcpy(&reply_t, hw_t + ar.ar_hln, ar.ar_pln);
152e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
153e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* Check for arping */
154e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (state->arping_index &&
155e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    state->arping_index <= opts->arping_len &&
156e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    (reply_s == opts->arping[state->arping_index - 1] ||
157e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			(reply_s == 0 &&
158e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    reply_t == opts->arping[state->arping_index - 1])))
159e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		{
160e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			ina.s_addr = reply_s;
161e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			hwaddr = hwaddr_ntoa((unsigned char *)hw_s,
162e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    (size_t)ar.ar_hln);
163e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			syslog(LOG_INFO,
164e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    "%s: found %s on hardware address %s",
165e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    iface->name, inet_ntoa(ina), hwaddr);
166e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			if (select_profile(iface, hwaddr) == -1 &&
167e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    errno == ENOENT)
168e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				select_profile(iface, inet_ntoa(ina));
169e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			close_sockets(iface);
170e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			delete_timeout(NULL, iface);
171e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			start_interface(iface);
172e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			return;
173e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		}
174e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
175e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* Check for conflict */
176e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (state->offer &&
177e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    (reply_s == state->offer->yiaddr ||
178e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			(reply_s == 0 && reply_t == state->offer->yiaddr)))
179e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			state->fail.s_addr = state->offer->yiaddr;
180e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
181e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* Handle IPv4LL conflicts */
182e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (IN_LINKLOCAL(htonl(iface->addr.s_addr)) &&
183e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    (reply_s == iface->addr.s_addr ||
184e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			(reply_s == 0 && reply_t == iface->addr.s_addr)))
185e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			state->fail.s_addr = iface->addr.s_addr;
186e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
187e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (state->fail.s_addr) {
188e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			syslog(LOG_ERR, "%s: hardware address %s claims %s",
189e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    iface->name,
190e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    hwaddr_ntoa((unsigned char *)hw_s,
191e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				(size_t)ar.ar_hln),
192e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    inet_ntoa(state->fail));
193e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			errno = EEXIST;
194e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			handle_arp_failure(iface);
195e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			return;
196e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		}
197e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
198e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}
199e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
200e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtvoid
201e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtsend_arp_announce(void *arg)
202e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{
203e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct interface *iface = arg;
204e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct if_state *state = iface->state;
205e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct timeval tv;
206e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
207a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	if (state->new == NULL)
208a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		return;
209e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (iface->arp_fd == -1) {
210e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		open_socket(iface, ETHERTYPE_ARP);
211e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		add_event(iface->arp_fd, handle_arp_packet, iface);
212e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
213e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (++state->claims < ANNOUNCE_NUM)
214e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		syslog(LOG_DEBUG,
215e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    "%s: sending ARP announce (%d of %d), "
216e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    "next in %d.00 seconds",
217e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    iface->name, state->claims, ANNOUNCE_NUM, ANNOUNCE_WAIT);
218e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	else
219e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		syslog(LOG_DEBUG,
220e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    "%s: sending ARP announce (%d of %d)",
221e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    iface->name, state->claims, ANNOUNCE_NUM);
222e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (send_arp(iface, ARPOP_REQUEST,
223e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		state->new->yiaddr, state->new->yiaddr) == -1)
224e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		syslog(LOG_ERR, "send_arp: %m");
225e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (state->claims < ANNOUNCE_NUM) {
226e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		add_timeout_sec(ANNOUNCE_WAIT, send_arp_announce, iface);
227e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		return;
228e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
229e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (state->new->cookie != htonl(MAGIC_COOKIE)) {
230e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		/* We should pretend to be at the end
231e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		 * of the DHCP negotation cycle unless we rebooted */
232e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (state->interval != 0)
233e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			state->interval = 64;
234e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		state->probes = 0;
235e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		state->claims = 0;
236e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		tv.tv_sec = state->interval - DHCP_RAND_MIN;
237e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		tv.tv_usec = arc4random() % (DHCP_RAND_MAX_U - DHCP_RAND_MIN_U);
238e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		timernorm(&tv);
239e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		add_timeout_tv(&tv, start_discover, iface);
240e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	} else {
241e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		delete_event(iface->arp_fd);
242e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		close(iface->arp_fd);
243e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		iface->arp_fd = -1;
244e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
245e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}
246e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
247e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtvoid
248e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtsend_arp_probe(void *arg)
249e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{
250e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct interface *iface = arg;
251e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct if_state *state = iface->state;
252e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct in_addr addr;
253e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	struct timeval tv;
254e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	int arping = 0;
255e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
256e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (state->arping_index < state->options->arping_len) {
257e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		addr.s_addr = state->options->arping[state->arping_index];
258e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		arping = 1;
259e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	} else if (state->offer) {
260e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (state->offer->yiaddr)
261e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			addr.s_addr = state->offer->yiaddr;
262e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		else
263e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			addr.s_addr = state->offer->ciaddr;
264e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	} else
265e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		addr.s_addr = iface->addr.s_addr;
266e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
267e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (iface->arp_fd == -1) {
268e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		open_socket(iface, ETHERTYPE_ARP);
269e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		add_event(iface->arp_fd, handle_arp_packet, iface);
270e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
271e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (state->probes == 0) {
272e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (arping)
273e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			syslog(LOG_INFO, "%s: searching for %s",
274e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    iface->name, inet_ntoa(addr));
275e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		else
276e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			syslog(LOG_INFO, "%s: checking for %s",
277e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			    iface->name, inet_ntoa(addr));
278e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
279e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (++state->probes < PROBE_NUM) {
280e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		tv.tv_sec = PROBE_MIN;
281e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		tv.tv_usec = arc4random() % (PROBE_MAX_U - PROBE_MIN_U);
282e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		timernorm(&tv);
283e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		add_timeout_tv(&tv, send_arp_probe, iface);
284e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	} else {
285e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		tv.tv_sec = ANNOUNCE_WAIT;
286e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		tv.tv_usec = 0;
287e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		if (arping) {
288e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			state->probes = 0;
289e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			if (++state->arping_index < state->options->arping_len)
290e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				add_timeout_tv(&tv, send_arp_probe, iface);
291e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			else
292e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt				add_timeout_tv(&tv, start_interface, iface);
293e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		} else
294e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt			add_timeout_tv(&tv, bind_interface, iface);
295e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	}
296e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	syslog(LOG_DEBUG,
297e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	    "%s: sending ARP probe (%d of %d), next in %0.2f seconds",
298e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	    iface->name, state->probes ? state->probes : PROBE_NUM, PROBE_NUM,
299e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	    timeval_to_double(&tv));
300e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	if (send_arp(iface, ARPOP_REQUEST, 0, addr.s_addr) == -1)
301e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		syslog(LOG_ERR, "send_arp: %m");
302e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}
303e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
304e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtvoid
305e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstart_arping(struct interface *iface)
306e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{
307e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	iface->state->probes = 0;
308e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	iface->state->arping_index = 0;
309e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt	send_arp_probe(iface);
310e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}
311