2 __RCSID("$NetBSD: arp.c,v 1.14 2015/07/09 10:15:34 roy Exp $");
5 * dhcpcd - DHCP client daemon
6 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
31 #include <sys/socket.h>
32 #include <sys/types.h>
34 #include <arpa/inet.h>
37 #include <netinet/in.h>
38 #include <netinet/if_ether.h>
55 #include "if-options.h"
59 (sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN))
62 arp_request(const struct interface
*ifp
, in_addr_t sip
, in_addr_t tip
)
64 uint8_t arp_buffer
[ARP_LEN
];
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
);
78 #define CHECK(fun, b, l) \
80 if (len + (l) > sizeof(arp_buffer)) \
85 } while (/* CONSTCOND */ 0)
86 #define APPEND(b, l) CHECK(memcpy, b, l)
87 #define ZERO(l) CHECK(memset, 0, l)
89 APPEND(&ar
, sizeof(ar
));
90 APPEND(ifp
->hwaddr
, ifp
->hwlen
);
91 APPEND(&sip
, sizeof(sip
));
93 APPEND(&tip
, sizeof(tip
));
94 return if_sendrawpacket(ifp
, ETHERTYPE_ARP
, arp_buffer
, len
);
102 arp_report_conflicted(const struct arp_state
*astate
, const struct arp_msg
*amsg
)
106 char buf
[HWADDR_LEN
* 3];
108 logger(astate
->iface
->ctx
, LOG_ERR
,
109 "%s: hardware address %s claims %s",
111 hwaddr_ntoa(amsg
->sha
, astate
->iface
->hwlen
,
113 inet_ntoa(astate
->failed
));
115 logger(astate
->iface
->ctx
, LOG_ERR
,
116 "%s: DAD detected %s",
117 astate
->iface
->name
, inet_ntoa(astate
->failed
));
121 arp_packet(void *arg
)
123 struct interface
*ifp
= arg
;
124 const struct interface
*ifn
;
125 uint8_t arp_buffer
[ARP_LEN
];
129 struct iarp_state
*state
;
130 struct arp_state
*astate
, *astaten
;
131 unsigned char *hw_s
, *hw_t
;
134 state
= ARP_STATE(ifp
);
136 while (!(flags
& RAW_EOF
)) {
137 bytes
= if_readrawpacket(ifp
, ETHERTYPE_ARP
,
138 arp_buffer
, sizeof(arp_buffer
), &flags
);
140 logger(ifp
->ctx
, LOG_ERR
,
141 "%s: arp if_readrawpacket: %m", ifp
->name
);
145 /* We must have a full ARP header */
146 if ((size_t)bytes
< sizeof(ar
))
148 memcpy(&ar
, arp_buffer
, sizeof(ar
));
149 /* Families must match */
150 if (ar
.ar_hrd
!= htons(ifp
->family
))
152 /* Protocol must be IP. */
153 if (ar
.ar_pro
!= htons(ETHERTYPE_IP
))
155 if (ar
.ar_pln
!= sizeof(arm
.sip
.s_addr
))
157 /* Only these types are recognised */
158 if (ar
.ar_op
!= htons(ARPOP_REPLY
) &&
159 ar
.ar_op
!= htons(ARPOP_REQUEST
))
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
)
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)
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
);
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
);
191 arp_open(struct interface
*ifp
)
193 struct iarp_state
*state
;
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
);
203 eloop_event_add(ifp
->ctx
->eloop
, state
->fd
,
204 arp_packet
, ifp
, NULL
, NULL
);
209 arp_announced(void *arg
)
211 struct arp_state
*astate
= arg
;
213 if (astate
->announced_cb
) {
214 astate
->announced_cb(astate
);
218 /* Nothing more to do, so free us */
223 arp_announce1(void *arg
)
225 struct arp_state
*astate
= arg
;
226 struct interface
*ifp
= astate
->iface
;
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
);
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
,
247 arp_announce(struct arp_state
*astate
)
250 arp_open(astate
->iface
);
252 arp_announce1(astate
);
256 arp_probed(void *arg
)
258 struct arp_state
*astate
= arg
;
260 astate
->probed_cb(astate
);
264 arp_probe1(void *arg
)
266 struct arp_state
*astate
= arg
;
267 struct interface
*ifp
= astate
->iface
;
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
);
275 eloop_timeout_add_tv(ifp
->ctx
->eloop
, &tv
, arp_probe1
, astate
);
277 tv
.tv_sec
= ANNOUNCE_WAIT
;
279 eloop_timeout_add_tv(ifp
->ctx
->eloop
, &tv
, arp_probed
, astate
);
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");
291 arp_probe(struct arp_state
*astate
)
294 arp_open(astate
->iface
);
296 logger(astate
->iface
->ctx
, LOG_DEBUG
, "%s: probing for %s",
297 astate
->iface
->name
, inet_ntoa(astate
->addr
));
302 arp_find(struct interface
*ifp
, const struct in_addr
*addr
)
304 struct iarp_state
*state
;
305 struct arp_state
*astate
;
307 if ((state
= ARP_STATE(ifp
)) == NULL
)
309 TAILQ_FOREACH(astate
, &state
->arp_states
, next
) {
310 if (astate
->addr
.s_addr
== addr
->s_addr
&& astate
->iface
== ifp
)
319 arp_new(struct interface
*ifp
, const struct in_addr
*addr
)
321 struct iarp_state
*state
;
322 struct arp_state
*astate
;
324 if ((state
= ARP_STATE(ifp
)) == NULL
) {
325 ifp
->if_data
[IF_DATA_ARP
] = malloc(sizeof(*state
));
326 state
= ARP_STATE(ifp
);
328 logger(ifp
->ctx
, LOG_ERR
, "%s: %m", __func__
);
332 TAILQ_INIT(&state
->arp_states
);
334 if (addr
&& (astate
= arp_find(ifp
, addr
)))
338 if ((astate
= calloc(1, sizeof(*astate
))) == NULL
) {
339 logger(ifp
->ctx
, LOG_ERR
, "%s: %s: %m", ifp
->name
, __func__
);
344 astate
->addr
= *addr
;
345 state
= ARP_STATE(ifp
);
346 TAILQ_INSERT_TAIL(&state
->arp_states
, astate
, next
);
351 arp_cancel(struct arp_state
*astate
)
354 eloop_timeout_delete(astate
->iface
->ctx
->eloop
, NULL
, astate
);
358 arp_free(struct arp_state
*astate
)
361 if (astate
!= NULL
) {
362 struct interface
*ifp
;
363 struct iarp_state
*state
;
366 eloop_timeout_delete(ifp
->ctx
->eloop
, NULL
, astate
);
367 state
= ARP_STATE(ifp
);
368 TAILQ_REMOVE(&state
->arp_states
, astate
, next
);
370 astate
->free_cb(astate
);
373 /* If there are no more ARP states, close the socket. */
374 if (state
->fd
!= -1 &&
375 TAILQ_FIRST(&state
->arp_states
) == NULL
)
377 eloop_event_delete(ifp
->ctx
->eloop
, state
->fd
);
380 ifp
->if_data
[IF_DATA_ARP
] = NULL
;
386 arp_free_but(struct arp_state
*astate
)
388 struct iarp_state
*state
;
389 struct arp_state
*p
, *n
;
391 state
= ARP_STATE(astate
->iface
);
392 TAILQ_FOREACH_SAFE(p
, &state
->arp_states
, next
, n
) {
399 arp_close(struct interface
*ifp
)
401 struct iarp_state
*state
;
402 struct arp_state
*astate
;
404 /* Freeing the last state will also free the main state,
405 * so test for both. */
407 if ((state
= ARP_STATE(ifp
)) == NULL
||
408 (astate
= TAILQ_FIRST(&state
->arp_states
)) == NULL
)
415 arp_handleifa(int cmd
, struct interface
*ifp
, const struct in_addr
*addr
,
418 #ifdef IN_IFF_DUPLICATED
419 struct iarp_state
*state
;
420 struct arp_state
*astate
, *asn
;
422 if (cmd
!= RTM_NEWADDR
|| (state
= ARP_STATE(ifp
)) == NULL
)
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
);