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