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