xref: /dragonfly/contrib/dhcpcd/src/arp.c (revision 6a6d63c5317abf314a78f8c8300ef73c2bc0c39e)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * dhcpcd - ARP handler
4  * Copyright (c) 2006-2023 Roy Marples <roy@marples.name>
5  * All rights reserved
6 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/socket.h>
30 #include <sys/types.h>
31 
32 #include <arpa/inet.h>
33 
34 #include <net/if.h>
35 #include <netinet/in.h>
36 #include <netinet/if_ether.h>
37 
38 #include <errno.h>
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <unistd.h>
43 
44 #define ELOOP_QUEUE ELOOP_ARP
45 #include "config.h"
46 #include "arp.h"
47 #include "bpf.h"
48 #include "ipv4.h"
49 #include "common.h"
50 #include "dhcpcd.h"
51 #include "eloop.h"
52 #include "if.h"
53 #include "if-options.h"
54 #include "ipv4ll.h"
55 #include "logerr.h"
56 #include "privsep.h"
57 
58 #if defined(ARP)
59 #define ARP_LEN                                                                           \
60           (FRAMEHDRLEN_MAX +                                                    \
61            sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN))
62 
63 /* ARP debugging can be quite noisy. Enable this for more noise! */
64 //#define ARP_DEBUG
65 
66 /* Assert the correct structure size for on wire */
67 __CTASSERT(sizeof(struct arphdr) == 8);
68 
69 static ssize_t
arp_request(const struct arp_state * astate,const struct in_addr * sip)70 arp_request(const struct arp_state *astate,
71     const struct in_addr *sip)
72 {
73           const struct interface *ifp = astate->iface;
74           const struct in_addr *tip = &astate->addr;
75           uint8_t arp_buffer[ARP_LEN];
76           struct arphdr ar;
77           size_t len;
78           uint8_t *p;
79 
80           ar.ar_hrd = htons(ifp->hwtype);
81           ar.ar_pro = htons(ETHERTYPE_IP);
82           ar.ar_hln = ifp->hwlen;
83           ar.ar_pln = sizeof(tip->s_addr);
84           ar.ar_op = htons(ARPOP_REQUEST);
85 
86           p = arp_buffer;
87           len = 0;
88 
89 #define CHECK(fun, b, l)                                                        \
90           do {                                                                            \
91                     if (len + (l) > sizeof(arp_buffer))                         \
92                               goto eexit;                                                 \
93                     fun(p, (b), (l));                                           \
94                     p += (l);                                                   \
95                     len += (l);                                                           \
96           } while (/* CONSTCOND */ 0)
97 #define APPEND(b, l)          CHECK(memcpy, b, l)
98 #define ZERO(l)               CHECK(memset, 0, l)
99 
100           APPEND(&ar, sizeof(ar));
101           APPEND(ifp->hwaddr, ifp->hwlen);
102           if (sip != NULL)
103                     APPEND(&sip->s_addr, sizeof(sip->s_addr));
104           else
105                     ZERO(sizeof(tip->s_addr));
106           ZERO(ifp->hwlen);
107           APPEND(&tip->s_addr, sizeof(tip->s_addr));
108 
109 #ifdef PRIVSEP
110           if (ifp->ctx->options & DHCPCD_PRIVSEP)
111                     return ps_bpf_sendarp(ifp, tip, arp_buffer, len);
112 #endif
113           /* Note that well formed ethernet will add extra padding
114            * to ensure that the packet is at least 60 bytes (64 including FCS). */
115           return bpf_send(astate->bpf, ETHERTYPE_ARP, arp_buffer, len);
116 
117 eexit:
118           errno = ENOBUFS;
119           return -1;
120 }
121 
122 static void
arp_report_conflicted(const struct arp_state * astate,const struct arp_msg * amsg)123 arp_report_conflicted(const struct arp_state *astate,
124     const struct arp_msg *amsg)
125 {
126           char abuf[HWADDR_LEN * 3];
127           char fbuf[HWADDR_LEN * 3];
128 
129           if (amsg == NULL) {
130                     logerrx("%s: DAD detected %s",
131                         astate->iface->name, inet_ntoa(astate->addr));
132                     return;
133           }
134 
135           hwaddr_ntoa(amsg->sha, astate->iface->hwlen, abuf, sizeof(abuf));
136           if (bpf_frame_header_len(astate->iface) == 0) {
137                     logwarnx("%s: %s claims %s",
138                         astate->iface->name, abuf, inet_ntoa(astate->addr));
139                     return;
140           }
141 
142           logwarnx("%s: %s(%s) claims %s",
143               astate->iface->name, abuf,
144               hwaddr_ntoa(amsg->fsha, astate->iface->hwlen, fbuf, sizeof(fbuf)),
145               inet_ntoa(astate->addr));
146 }
147 
148 static void
arp_found(struct arp_state * astate,const struct arp_msg * amsg)149 arp_found(struct arp_state *astate, const struct arp_msg *amsg)
150 {
151           struct interface *ifp;
152           struct ipv4_addr *ia;
153 #ifndef KERNEL_RFC5227
154           struct timespec now;
155 #endif
156 
157           arp_report_conflicted(astate, amsg);
158           ifp = astate->iface;
159 
160           /* If we haven't added the address we're doing a probe. */
161           ia = ipv4_iffindaddr(ifp, &astate->addr, NULL);
162           if (ia == NULL) {
163                     if (astate->found_cb != NULL)
164                               astate->found_cb(astate, amsg);
165                     return;
166           }
167 
168 #ifndef KERNEL_RFC5227
169           /* RFC 3927 Section 2.5 says a defence should
170            * broadcast an ARP announcement.
171            * Because the kernel will also unicast a reply to the
172            * hardware address which requested the IP address
173            * the other IPv4LL client will receieve two ARP
174            * messages.
175            * If another conflict happens within DEFEND_INTERVAL
176            * then we must drop our address and negotiate a new one.
177            * If DHCPCD_ARP_PERSISTDEFENCE is set, that enables
178            * RFC5227 section 2.4.c behaviour. Upon conflict
179            * detection, the host records the time that the
180            * conflicting ARP packet was received, and then
181            * broadcasts one single ARP Announcement. The host then
182            * continues to use the address normally. All further
183            * conflict notifications within the DEFEND_INTERVAL are
184            * ignored. */
185           clock_gettime(CLOCK_MONOTONIC, &now);
186           if (timespecisset(&astate->defend) &&
187               eloop_timespec_diff(&now, &astate->defend, NULL) < DEFEND_INTERVAL)
188           {
189                     logwarnx("%s: %d second defence failed for %s",
190                         ifp->name, DEFEND_INTERVAL, inet_ntoa(astate->addr));
191                     if (ifp->options->options & DHCPCD_ARP_PERSISTDEFENCE)
192                               return;
193           }
194           else if (arp_request(astate, &astate->addr) == -1)
195                     logerr(__func__);
196           else {
197                     logdebugx("%s: defended address %s",
198                         ifp->name, inet_ntoa(astate->addr));
199                     astate->defend = now;
200                     return;
201           }
202 #endif
203 
204           if (astate->defend_failed_cb != NULL)
205                     astate->defend_failed_cb(astate);
206 }
207 
208 static bool
arp_validate(const struct interface * ifp,struct arphdr * arp)209 arp_validate(const struct interface *ifp, struct arphdr *arp)
210 {
211 
212           /* Address type must match */
213           if (arp->ar_hrd != htons(ifp->hwtype))
214                     return false;
215 
216           /* Protocol must be IP. */
217           if (arp->ar_pro != htons(ETHERTYPE_IP))
218                     return false;
219 
220           /* lladdr length matches */
221           if (arp->ar_hln != ifp->hwlen)
222                     return false;
223 
224           /* Protocol length must match in_addr_t */
225           if (arp->ar_pln != sizeof(in_addr_t))
226                     return false;
227 
228           /* Only these types are recognised */
229           if (arp->ar_op != htons(ARPOP_REPLY) &&
230               arp->ar_op != htons(ARPOP_REQUEST))
231                     return false;
232 
233           return true;
234 }
235 
236 void
arp_packet(struct interface * ifp,uint8_t * data,size_t len,unsigned int bpf_flags)237 arp_packet(struct interface *ifp, uint8_t *data, size_t len,
238     unsigned int bpf_flags)
239 {
240           size_t fl = bpf_frame_header_len(ifp), falen;
241           const struct interface *ifn;
242           struct arphdr ar;
243           struct arp_msg arm;
244           const struct iarp_state *state;
245           struct arp_state *astate, *astaten;
246           uint8_t *hw_s, *hw_t;
247 #ifndef KERNEL_RFC5227
248           bool is_probe;
249 #endif /* KERNEL_RFC5227 */
250 
251           /* Copy the frame header source and destination out */
252           memset(&arm, 0, sizeof(arm));
253           if (fl != 0) {
254                     hw_s = bpf_frame_header_src(ifp, data, &falen);
255                     if (hw_s != NULL && falen <= sizeof(arm.fsha))
256                               memcpy(arm.fsha, hw_s, falen);
257                     hw_t = bpf_frame_header_dst(ifp, data, &falen);
258                     if (hw_t != NULL && falen <= sizeof(arm.ftha))
259                               memcpy(arm.ftha, hw_t, falen);
260 
261                     /* Skip past the frame header */
262                     data += fl;
263                     len -= fl;
264           }
265 
266           /* We must have a full ARP header */
267           if (len < sizeof(ar))
268                     return;
269           memcpy(&ar, data, sizeof(ar));
270 
271           if (!arp_validate(ifp, &ar)) {
272 #ifdef BPF_DEBUG
273                     logerrx("%s: ARP BPF validation failure", ifp->name);
274 #endif
275                     return;
276           }
277 
278           /* Get pointers to the hardware addresses */
279           hw_s = data + sizeof(ar);
280           hw_t = hw_s + ar.ar_hln + ar.ar_pln;
281           /* Ensure we got all the data */
282           if ((size_t)((hw_t + ar.ar_hln + ar.ar_pln) - data) > len)
283                     return;
284           /* Ignore messages from ourself */
285           TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
286                     if (ar.ar_hln == ifn->hwlen &&
287                         memcmp(hw_s, ifn->hwaddr, ifn->hwlen) == 0)
288                               break;
289           }
290           if (ifn) {
291 #ifdef ARP_DEBUG
292                     logdebugx("%s: ignoring ARP from self", ifp->name);
293 #endif
294                     return;
295           }
296           /* Copy out the HW and IP addresses */
297           memcpy(&arm.sha, hw_s, ar.ar_hln);
298           memcpy(&arm.sip.s_addr, hw_s + ar.ar_hln, ar.ar_pln);
299           memcpy(&arm.tha, hw_t, ar.ar_hln);
300           memcpy(&arm.tip.s_addr, hw_t + ar.ar_hln, ar.ar_pln);
301 
302 #ifndef KERNEL_RFC5227
303           /* During ARP probe the 'sender hardware address' MUST contain the hardware
304            * address of the interface sending the packet. RFC5227, 1.1 */
305           is_probe = ar.ar_op == htons(ARPOP_REQUEST) && IN_IS_ADDR_UNSPECIFIED(&arm.sip) &&
306               bpf_flags & BPF_BCAST;
307           if (is_probe && falen > 0 && (falen != ar.ar_hln ||
308               memcmp(&arm.sha, &arm.fsha, ar.ar_hln))) {
309                     char abuf[HWADDR_LEN * 3];
310                     char fbuf[HWADDR_LEN * 3];
311                     hwaddr_ntoa(&arm.sha, ar.ar_hln, abuf, sizeof(abuf));
312                     hwaddr_ntoa(&arm.fsha, falen, fbuf, sizeof(fbuf));
313                     logwarnx("%s: invalid ARP probe, sender hw address mismatch (%s, %s)",
314                         ifp->name, abuf, fbuf);
315                     return;
316           }
317 #endif /* KERNEL_RFC5227 */
318 
319           /* Match the ARP probe to our states.
320            * Ignore Unicast Poll, RFC1122. */
321           state = ARP_CSTATE(ifp);
322           if (state == NULL)
323                     return;
324           TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, astaten) {
325                     if (IN_ARE_ADDR_EQUAL(&arm.sip, &astate->addr) ||
326                         (IN_IS_ADDR_UNSPECIFIED(&arm.sip) &&
327                         IN_ARE_ADDR_EQUAL(&arm.tip, &astate->addr) &&
328                         bpf_flags & BPF_BCAST))
329                               arp_found(astate, &arm);
330           }
331 }
332 
333 static void
arp_read(void * arg,unsigned short events)334 arp_read(void *arg, unsigned short events)
335 {
336           struct arp_state *astate = arg;
337           struct bpf *bpf = astate->bpf;
338           struct interface *ifp = astate->iface;
339           uint8_t buf[ARP_LEN];
340           ssize_t bytes;
341           struct in_addr addr = astate->addr;
342 
343           if (events != ELE_READ)
344                     logerrx("%s: unexpected event 0x%04x", __func__, events);
345 
346           /* Some RAW mechanisms are generic file descriptors, not sockets.
347            * This means we have no kernel call to just get one packet,
348            * so we have to process the entire buffer. */
349           bpf->bpf_flags &= ~BPF_EOF;
350           while (!(bpf->bpf_flags & BPF_EOF)) {
351                     bytes = bpf_read(bpf, buf, sizeof(buf));
352                     if (bytes == -1) {
353                               logerr("%s: %s", __func__, ifp->name);
354                               arp_free(astate);
355                               return;
356                     }
357                     arp_packet(ifp, buf, (size_t)bytes, bpf->bpf_flags);
358                     /* Check we still have a state after processing. */
359                     if ((astate = arp_find(ifp, &addr)) == NULL)
360                               break;
361                     if ((bpf = astate->bpf) == NULL)
362                               break;
363           }
364 }
365 
366 static void
arp_probed(void * arg)367 arp_probed(void *arg)
368 {
369           struct arp_state *astate = arg;
370 
371           timespecclear(&astate->defend);
372           astate->not_found_cb(astate);
373 }
374 
375 static void
arp_probe1(void * arg)376 arp_probe1(void *arg)
377 {
378           struct arp_state *astate = arg;
379           struct interface *ifp = astate->iface;
380           unsigned int delay;
381 
382           if (++astate->probes < PROBE_NUM) {
383                     delay = (PROBE_MIN * MSEC_PER_SEC) +
384                         (arc4random_uniform(
385                         (PROBE_MAX - PROBE_MIN) * MSEC_PER_SEC));
386                     eloop_timeout_add_msec(ifp->ctx->eloop, delay, arp_probe1, astate);
387           } else {
388                     delay = ANNOUNCE_WAIT *       MSEC_PER_SEC;
389                     eloop_timeout_add_msec(ifp->ctx->eloop, delay, arp_probed, astate);
390           }
391           logdebugx("%s: ARP probing %s (%d of %d), next in %0.1f seconds",
392               ifp->name, inet_ntoa(astate->addr),
393               astate->probes ? astate->probes : PROBE_NUM, PROBE_NUM,
394               (float)delay / MSEC_PER_SEC);
395           if (arp_request(astate, NULL) == -1)
396                     logerr(__func__);
397 }
398 
399 void
arp_probe(struct arp_state * astate)400 arp_probe(struct arp_state *astate)
401 {
402 
403           astate->probes = 0;
404           logdebugx("%s: probing for %s",
405               astate->iface->name, inet_ntoa(astate->addr));
406           arp_probe1(astate);
407 }
408 #endif    /* ARP */
409 
410 struct arp_state *
arp_find(struct interface * ifp,const struct in_addr * addr)411 arp_find(struct interface *ifp, const struct in_addr *addr)
412 {
413           struct iarp_state *state;
414           struct arp_state *astate;
415 
416           if ((state = ARP_STATE(ifp)) == NULL)
417                     goto out;
418           TAILQ_FOREACH(astate, &state->arp_states, next) {
419                     if (astate->addr.s_addr == addr->s_addr && astate->iface == ifp)
420                               return astate;
421           }
422 out:
423           errno = ESRCH;
424           return NULL;
425 }
426 
427 static void
arp_announced(void * arg)428 arp_announced(void *arg)
429 {
430           struct arp_state *astate = arg;
431 
432           if (astate->announced_cb) {
433                     astate->announced_cb(astate);
434                     return;
435           }
436 
437           /* Keep the ARP state open to handle ongoing ACD. */
438 }
439 
440 static void
arp_announce1(void * arg)441 arp_announce1(void *arg)
442 {
443           struct arp_state *astate = arg;
444           struct interface *ifp = astate->iface;
445           struct ipv4_addr *ia;
446 
447           if (++astate->claims < ANNOUNCE_NUM)
448                     logdebugx("%s: ARP announcing %s (%d of %d), "
449                         "next in %d.0 seconds",
450                         ifp->name, inet_ntoa(astate->addr),
451                         astate->claims, ANNOUNCE_NUM, ANNOUNCE_WAIT);
452           else
453                     logdebugx("%s: ARP announcing %s (%d of %d)",
454                         ifp->name, inet_ntoa(astate->addr),
455                         astate->claims, ANNOUNCE_NUM);
456 
457           /* The kernel will send a Gratuitous ARP for newly added addresses.
458            * So we can avoid sending the same.
459            * Linux is special and doesn't send one. */
460           ia = ipv4_iffindaddr(ifp, &astate->addr, NULL);
461 #ifndef __linux__
462           if (astate->claims == 1 && ia != NULL && ia->flags & IPV4_AF_NEW)
463                     goto skip_request;
464 #endif
465 
466           if (arp_request(astate, &astate->addr) == -1)
467                     logerr(__func__);
468 
469 #ifndef __linux__
470 skip_request:
471 #endif
472           /* No longer a new address. */
473           if (ia != NULL)
474                     ia->flags |= ~IPV4_AF_NEW;
475 
476           eloop_timeout_add_sec(ifp->ctx->eloop, ANNOUNCE_WAIT,
477               astate->claims < ANNOUNCE_NUM ? arp_announce1 : arp_announced,
478               astate);
479 }
480 
481 static void
arp_announce(struct arp_state * astate)482 arp_announce(struct arp_state *astate)
483 {
484           struct iarp_state *state;
485           struct interface *ifp;
486           struct arp_state *a2;
487           int r;
488 
489           /* Cancel any other ARP announcements for this address. */
490           TAILQ_FOREACH(ifp, astate->iface->ctx->ifaces, next) {
491                     state = ARP_STATE(ifp);
492                     if (state == NULL)
493                               continue;
494                     TAILQ_FOREACH(a2, &state->arp_states, next) {
495                               if (astate == a2 ||
496                                   a2->addr.s_addr != astate->addr.s_addr)
497                                         continue;
498                               r = eloop_timeout_delete(a2->iface->ctx->eloop,
499                                   a2->claims < ANNOUNCE_NUM
500                                   ? arp_announce1 : arp_announced,
501                                   a2);
502                               if (r == -1)
503                                         logerr(__func__);
504                               else if (r != 0) {
505                                         logdebugx("%s: ARP announcement "
506                                             "of %s cancelled",
507                                             a2->iface->name,
508                                             inet_ntoa(a2->addr));
509                                         arp_announced(a2);
510                               }
511                     }
512           }
513 
514           astate->claims = 0;
515           arp_announce1(astate);
516 }
517 
518 struct arp_state *
arp_ifannounceaddr(struct interface * ifp,const struct in_addr * ia)519 arp_ifannounceaddr(struct interface *ifp, const struct in_addr *ia)
520 {
521           struct arp_state *astate;
522 
523           if (ifp->flags & IFF_NOARP || !(ifp->options->options & DHCPCD_ARP))
524                     return NULL;
525 
526           astate = arp_find(ifp, ia);
527           if (astate == NULL) {
528                     astate = arp_new(ifp, ia);
529                     if (astate == NULL)
530                               return NULL;
531                     astate->announced_cb = arp_free;
532           }
533           arp_announce(astate);
534           return astate;
535 }
536 
537 struct arp_state *
arp_announceaddr(struct dhcpcd_ctx * ctx,const struct in_addr * ia)538 arp_announceaddr(struct dhcpcd_ctx *ctx, const struct in_addr *ia)
539 {
540           struct interface *ifp, *iff = NULL;
541           struct ipv4_addr *iap;
542 
543           TAILQ_FOREACH(ifp, ctx->ifaces, next) {
544                     if (!ifp->active || !if_is_link_up(ifp))
545                               continue;
546                     iap = ipv4_iffindaddr(ifp, ia, NULL);
547                     if (iap == NULL)
548                               continue;
549 #ifdef IN_IFF_NOTUSEABLE
550                     if (iap->addr_flags & IN_IFF_NOTUSEABLE)
551                               continue;
552 #endif
553                     if (iff != NULL && iff->metric < ifp->metric)
554                               continue;
555                     iff = ifp;
556           }
557           if (iff == NULL)
558                     return NULL;
559 
560           return arp_ifannounceaddr(iff, ia);
561 }
562 
563 struct arp_state *
arp_new(struct interface * ifp,const struct in_addr * addr)564 arp_new(struct interface *ifp, const struct in_addr *addr)
565 {
566           struct iarp_state *state;
567           struct arp_state *astate;
568 
569           if ((state = ARP_STATE(ifp)) == NULL) {
570                     ifp->if_data[IF_DATA_ARP] = malloc(sizeof(*state));
571                     state = ARP_STATE(ifp);
572                     if (state == NULL) {
573                               logerr(__func__);
574                               return NULL;
575                     }
576                     TAILQ_INIT(&state->arp_states);
577           } else {
578                     if ((astate = arp_find(ifp, addr)) != NULL)
579                               return astate;
580           }
581 
582           if ((astate = calloc(1, sizeof(*astate))) == NULL) {
583                     logerr(__func__);
584                     return NULL;
585           }
586           astate->iface = ifp;
587           astate->addr = *addr;
588 
589 #ifdef PRIVSEP
590           if (IN_PRIVSEP(ifp->ctx)) {
591                     if (ps_bpf_openarp(ifp, addr) == -1) {
592                               logerr(__func__);
593                               free(astate);
594                               return NULL;
595                     }
596           } else
597 #endif
598           {
599                     astate->bpf = bpf_open(ifp, bpf_arp, addr);
600                     if (astate->bpf == NULL) {
601                               logerr(__func__);
602                               free(astate);
603                               return NULL;
604                     }
605                     if (eloop_event_add(ifp->ctx->eloop, astate->bpf->bpf_fd, ELE_READ,
606                         arp_read, astate) == -1)
607                               logerr("%s: eloop_event_add", __func__);
608           }
609 
610 
611           state = ARP_STATE(ifp);
612           TAILQ_INSERT_TAIL(&state->arp_states, astate, next);
613           return astate;
614 }
615 
616 void
arp_free(struct arp_state * astate)617 arp_free(struct arp_state *astate)
618 {
619           struct interface *ifp;
620           struct dhcpcd_ctx *ctx;
621           struct iarp_state *state;
622 
623           if (astate == NULL)
624                     return;
625 
626           ifp = astate->iface;
627           ctx = ifp->ctx;
628           eloop_timeout_delete(ctx->eloop, NULL, astate);
629 
630           state =   ARP_STATE(ifp);
631           TAILQ_REMOVE(&state->arp_states, astate, next);
632           if (astate->free_cb)
633                     astate->free_cb(astate);
634 
635 #ifdef PRIVSEP
636           if (IN_PRIVSEP(ctx) && ps_bpf_closearp(ifp, &astate->addr) == -1)
637                     logerr(__func__);
638 #endif
639           if (astate->bpf != NULL) {
640                     eloop_event_delete(ctx->eloop, astate->bpf->bpf_fd);
641                     bpf_close(astate->bpf);
642           }
643 
644           free(astate);
645 
646           if (TAILQ_FIRST(&state->arp_states) == NULL) {
647                     free(state);
648                     ifp->if_data[IF_DATA_ARP] = NULL;
649           }
650 }
651 
652 void
arp_freeaddr(struct interface * ifp,const struct in_addr * ia)653 arp_freeaddr(struct interface *ifp, const struct in_addr *ia)
654 {
655           struct arp_state *astate;
656 
657           astate = arp_find(ifp, ia);
658           arp_free(astate);
659 }
660 
661 void
arp_drop(struct interface * ifp)662 arp_drop(struct interface *ifp)
663 {
664           struct iarp_state *state;
665           struct arp_state *astate;
666 
667           while ((state = ARP_STATE(ifp)) != NULL &&
668               (astate = TAILQ_FIRST(&state->arp_states)) != NULL)
669                     arp_free(astate);
670 }
671