1 /*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
4 * All rights reserved
5
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include <sys/socket.h>
29 #include <sys/types.h>
30
31 #include <net/if.h>
32 #include <netinet/in.h>
33 #include <netinet/if_ether.h>
34
35 #include <errno.h>
36 #include <signal.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40
41 #define ELOOP_QUEUE 5
42 #include "config.h"
43 #include "arp.h"
44 #include "if.h"
45 #include "ipv4.h"
46 #include "common.h"
47 #include "dhcp.h"
48 #include "dhcpcd.h"
49 #include "eloop.h"
50 #include "if.h"
51 #include "if-options.h"
52 #include "ipv4ll.h"
53
54 #define ARP_LEN \
55 (sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN))
56
57 static ssize_t
arp_request(const struct interface * ifp,in_addr_t sip,in_addr_t tip,const uint8_t * dest_hw_addr)58 arp_request(const struct interface *ifp, in_addr_t sip, in_addr_t tip,
59 const uint8_t *dest_hw_addr)
60 {
61 uint8_t arp_buffer[ARP_LEN];
62 struct arphdr ar;
63 size_t len;
64 uint8_t *p;
65
66 ar.ar_hrd = htons(ifp->family);
67 ar.ar_pro = htons(ETHERTYPE_IP);
68 ar.ar_hln = ifp->hwlen;
69 ar.ar_pln = sizeof(sip);
70 ar.ar_op = htons(ARPOP_REQUEST);
71
72 p = arp_buffer;
73 len = 0;
74
75 #define CHECK(fun, b, l) \
76 do { \
77 if (len + (l) > sizeof(arp_buffer)) \
78 goto eexit; \
79 fun(p, (b), (l)); \
80 p += (l); \
81 len += (l); \
82 } while (/* CONSTCOND */ 0)
83 #define APPEND(b, l) CHECK(memcpy, b, l)
84 #define ZERO(l) CHECK(memset, 0, l)
85
86 APPEND(&ar, sizeof(ar));
87 APPEND(ifp->hwaddr, ifp->hwlen);
88 APPEND(&sip, sizeof(sip));
89 if (dest_hw_addr)
90 APPEND(dest_hw_addr, ifp->hwlen);
91 else
92 ZERO(ifp->hwlen);
93 APPEND(&tip, sizeof(tip));
94 return if_sendrawpacket(ifp, ETHERTYPE_ARP, arp_buffer, len,
95 dest_hw_addr);
96
97 eexit:
98 errno = ENOBUFS;
99 return -1;
100 }
101
102 void
arp_report_conflicted(const struct arp_state * astate,const struct arp_msg * amsg)103 arp_report_conflicted(const struct arp_state *astate, const struct arp_msg *amsg)
104 {
105
106 if (amsg) {
107 char buf[HWADDR_LEN * 3];
108
109 logger(astate->iface->ctx, LOG_ERR,
110 "%s: hardware address %s claims %s",
111 astate->iface->name,
112 hwaddr_ntoa(amsg->sha, astate->iface->hwlen,
113 buf, sizeof(buf)),
114 inet_ntoa(astate->failed));
115 } else
116 logger(astate->iface->ctx, LOG_ERR,
117 "%s: DAD detected %s",
118 astate->iface->name, inet_ntoa(astate->failed));
119 }
120
121 static void
arp_packet(void * arg)122 arp_packet(void *arg)
123 {
124 struct interface *ifp = arg;
125 const struct interface *ifn;
126 uint8_t arp_buffer[ARP_LEN];
127 struct arphdr ar;
128 struct arp_msg arm;
129 ssize_t bytes;
130 struct dhcp_state *state;
131 struct arp_state *astate, *astaten;
132 unsigned char *hw_s, *hw_t;
133 int flags;
134
135 state = D_STATE(ifp);
136 state->failed.s_addr = 0;
137 flags = 0;
138 while (!(flags & RAW_EOF)) {
139 bytes = if_readrawpacket(ifp, ETHERTYPE_ARP,
140 arp_buffer, sizeof(arp_buffer), &flags);
141 if (bytes == -1) {
142 logger(ifp->ctx, LOG_ERR,
143 "%s: arp if_readrawpacket: %m", ifp->name);
144 dhcp_close(ifp);
145 return;
146 }
147 /* We must have a full ARP header */
148 if ((size_t)bytes < sizeof(ar))
149 continue;
150 memcpy(&ar, arp_buffer, sizeof(ar));
151 /* Families must match */
152 if (ar.ar_hrd != htons(ifp->family))
153 continue;
154 /* Protocol must be IP. */
155 if (ar.ar_pro != htons(ETHERTYPE_IP))
156 continue;
157 if (ar.ar_pln != sizeof(arm.sip.s_addr))
158 continue;
159 /* Only these types are recognised */
160 if (ar.ar_op != htons(ARPOP_REPLY) &&
161 ar.ar_op != htons(ARPOP_REQUEST))
162 continue;
163
164 /* Get pointers to the hardware addreses */
165 hw_s = arp_buffer + sizeof(ar);
166 hw_t = hw_s + ar.ar_hln + ar.ar_pln;
167 /* Ensure we got all the data */
168 if ((hw_t + ar.ar_hln + ar.ar_pln) - arp_buffer > bytes)
169 continue;
170 /* Ignore messages from ourself */
171 TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
172 if (ar.ar_hln == ifn->hwlen &&
173 memcmp(hw_s, ifn->hwaddr, ifn->hwlen) == 0)
174 break;
175 }
176 if (ifn)
177 continue;
178 /* Copy out the HW and IP addresses */
179 memcpy(&arm.sha, hw_s, ar.ar_hln);
180 memcpy(&arm.sip.s_addr, hw_s + ar.ar_hln, ar.ar_pln);
181 memcpy(&arm.tha, hw_t, ar.ar_hln);
182 memcpy(&arm.tip.s_addr, hw_t + ar.ar_hln, ar.ar_pln);
183
184 /* Run the conflicts */
185 TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, astaten) {
186 if (astate->conflicted_cb)
187 astate->conflicted_cb(astate, &arm);
188 }
189 }
190 }
191
192 static void
arp_open(struct interface * ifp)193 arp_open(struct interface *ifp)
194 {
195 struct dhcp_state *state;
196
197 state = D_STATE(ifp);
198 if (state->arp_fd == -1) {
199 state->arp_fd = if_openrawsocket(ifp, ETHERTYPE_ARP);
200 if (state->arp_fd == -1) {
201 logger(ifp->ctx, LOG_ERR, "%s: %s: %m",
202 __func__, ifp->name);
203 return;
204 }
205 eloop_event_add(ifp->ctx->eloop, state->arp_fd,
206 arp_packet, ifp, NULL, NULL);
207 }
208 }
209
210 static void
arp_announced(void * arg)211 arp_announced(void *arg)
212 {
213 struct arp_state *astate = arg;
214
215 if (astate->announced_cb) {
216 astate->announced_cb(astate);
217 return;
218 }
219
220 /* Nothing more to do, so free us */
221 arp_free(astate);
222 }
223
224 static void
arp_announce1(void * arg)225 arp_announce1(void *arg)
226 {
227 struct arp_state *astate = arg;
228 struct interface *ifp = astate->iface;
229
230 if (++astate->claims < ANNOUNCE_NUM)
231 logger(ifp->ctx, LOG_DEBUG,
232 "%s: ARP announcing %s (%d of %d), "
233 "next in %d.0 seconds",
234 ifp->name, inet_ntoa(astate->addr),
235 astate->claims, ANNOUNCE_NUM, ANNOUNCE_WAIT);
236 else
237 logger(ifp->ctx, LOG_DEBUG,
238 "%s: ARP announcing %s (%d of %d)",
239 ifp->name, inet_ntoa(astate->addr),
240 astate->claims, ANNOUNCE_NUM);
241 if (arp_request(ifp, astate->addr.s_addr, astate->addr.s_addr,
242 NULL) == -1)
243 logger(ifp->ctx, LOG_ERR, "send_arp: %m");
244 eloop_timeout_add_sec(ifp->ctx->eloop, ANNOUNCE_WAIT,
245 astate->claims < ANNOUNCE_NUM ? arp_announce1 : arp_announced,
246 astate);
247 }
248
249 void
arp_announce(struct arp_state * astate)250 arp_announce(struct arp_state *astate)
251 {
252
253 arp_open(astate->iface);
254 astate->claims = 0;
255 arp_announce1(astate);
256 }
257
258 static void
arp_probed(void * arg)259 arp_probed(void *arg)
260 {
261 struct arp_state *astate = arg;
262
263 astate->probed_cb(astate);
264 }
265
266 static void
arp_probe1(void * arg)267 arp_probe1(void *arg)
268 {
269 struct arp_state *astate = arg;
270 struct interface *ifp = astate->iface;
271 struct timespec tv;
272 uint8_t *dest_hwaddr = NULL;
273
274 if (++astate->probes < PROBE_NUM) {
275 tv.tv_sec = PROBE_MIN;
276 tv.tv_nsec = (suseconds_t)arc4random_uniform(
277 (PROBE_MAX - PROBE_MIN) * NSEC_PER_SEC);
278 timespecnorm(&tv);
279 eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probe1, astate);
280 } else {
281 tv.tv_sec = ANNOUNCE_WAIT;
282 tv.tv_nsec = 0;
283 eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probed, astate);
284 }
285 logger(ifp->ctx, LOG_INFO,
286 "%s: ARP probing %s (%d of %d), next in %0.1f seconds",
287 ifp->name, inet_ntoa(astate->addr),
288 astate->probes ? astate->probes : PROBE_NUM, PROBE_NUM,
289 timespec_to_double(&tv));
290 if (astate->dest_hwlen == ifp->hwlen)
291 dest_hwaddr = astate->dest_hwaddr;
292 if (arp_request(ifp, astate->src_addr.s_addr,
293 astate->addr.s_addr, dest_hwaddr) == -1)
294 logger(ifp->ctx, LOG_ERR, "send_arp: %m");
295 }
296
297 void
arp_probe(struct arp_state * astate)298 arp_probe(struct arp_state *astate)
299 {
300
301 arp_open(astate->iface);
302 astate->probes = 0;
303 logger(astate->iface->ctx, LOG_DEBUG, "%s: probing for %s",
304 astate->iface->name, inet_ntoa(astate->addr));
305 arp_probe1(astate);
306 }
307
308 static struct arp_state *
arp_find(struct interface * ifp,const struct in_addr * addr)309 arp_find(struct interface *ifp, const struct in_addr *addr)
310 {
311 struct arp_state *astate;
312 struct dhcp_state *state;
313
314 state = D_STATE(ifp);
315 TAILQ_FOREACH(astate, &state->arp_states, next) {
316 if (astate->addr.s_addr == addr->s_addr && astate->iface == ifp)
317 return astate;
318 }
319 errno = ESRCH;
320 return NULL;
321 }
322
323 struct arp_state *
arp_new(struct interface * ifp,const struct in_addr * addr)324 arp_new(struct interface *ifp, const struct in_addr *addr)
325 {
326 struct arp_state *astate;
327 struct dhcp_state *state;
328
329 if (addr && (astate = arp_find(ifp, addr)))
330 return astate;
331
332 if ((astate = calloc(1, sizeof(*astate))) == NULL) {
333 logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
334 return NULL;
335 }
336 state = D_STATE(ifp);
337 astate->iface = ifp;
338 if (addr)
339 astate->addr = *addr;
340 TAILQ_INSERT_TAIL(&state->arp_states, astate, next);
341 return astate;
342 }
343
344 void
arp_cancel(struct arp_state * astate)345 arp_cancel(struct arp_state *astate)
346 {
347
348 eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate);
349 }
350
351 void
arp_free(struct arp_state * astate)352 arp_free(struct arp_state *astate)
353 {
354 struct dhcp_state *state;
355
356 if (astate) {
357 eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate);
358 state = D_STATE(astate->iface);
359 TAILQ_REMOVE(&state->arp_states, astate, next);
360 if (state->arp_ipv4ll == astate) {
361 ipv4ll_stop(astate->iface);
362 state->arp_ipv4ll = NULL;
363 }
364 free(astate);
365 }
366 }
367
368 void
arp_free_but(struct arp_state * astate)369 arp_free_but(struct arp_state *astate)
370 {
371 struct arp_state *p, *n;
372 struct dhcp_state *state;
373
374 state = D_STATE(astate->iface);
375 TAILQ_FOREACH_SAFE(p, &state->arp_states, next, n) {
376 if (p != astate)
377 arp_free(p);
378 }
379 }
380
381 void
arp_close(struct interface * ifp)382 arp_close(struct interface *ifp)
383 {
384 struct dhcp_state *state = D_STATE(ifp);
385 struct arp_state *astate;
386
387 if (state == NULL)
388 return;
389
390 if (state->arp_fd != -1) {
391 eloop_event_delete(ifp->ctx->eloop, state->arp_fd, 0);
392 close(state->arp_fd);
393 state->arp_fd = -1;
394 }
395
396 while ((astate = TAILQ_FIRST(&state->arp_states))) {
397 #ifndef __clang_analyzer__
398 /* clang guard needed for a more compex variant on this bug:
399 * http://llvm.org/bugs/show_bug.cgi?id=18222 */
400 arp_free(astate);
401 #endif
402 }
403 }
404
405 void
arp_handleifa(int cmd,struct interface * ifp,const struct in_addr * addr,int flags)406 arp_handleifa(int cmd, struct interface *ifp, const struct in_addr *addr,
407 int flags)
408 {
409 #ifdef IN_IFF_DUPLICATED
410 struct dhcp_state *state = D_STATE(ifp);
411 struct arp_state *astate, *asn;
412
413 if (cmd != RTM_NEWADDR || (state = D_STATE(ifp)) == NULL)
414 return;
415
416 TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, asn) {
417 if (astate->addr.s_addr == addr->s_addr) {
418 if (flags & IN_IFF_DUPLICATED) {
419 if (astate->conflicted_cb)
420 astate->conflicted_cb(astate, NULL);
421 } else if (!(flags & IN_IFF_NOTUSEABLE)) {
422 if (astate->probed_cb)
423 astate->probed_cb(astate);
424 }
425 }
426 }
427 #else
428 UNUSED(cmd);
429 UNUSED(ifp);
430 UNUSED(addr);
431 UNUSED(flags);
432 #endif
433 }
434