1/*	$OpenBSD: if_ether.c,v 1.267 2023/12/18 13:30:44 bluhm Exp $	*/
2/*	$NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $	*/
3
4/*
5 * Copyright (c) 1982, 1986, 1988, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 *	@(#)if_ether.c	8.1 (Berkeley) 6/10/93
33 */
34
35/*
36 * Ethernet address resolution protocol.
37 * TODO:
38 *	add "inuse/lock" bit (or ref. count) along with valid bit
39 */
40
41#include "carp.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/mbuf.h>
46#include <sys/socket.h>
47#include <sys/timeout.h>
48#include <sys/kernel.h>
49#include <sys/syslog.h>
50#include <sys/queue.h>
51#include <sys/pool.h>
52
53#include <net/if.h>
54#include <net/if_var.h>
55#include <net/if_dl.h>
56#include <net/route.h>
57#include <net/if_types.h>
58#include <net/netisr.h>
59
60#include <netinet/in.h>
61#include <netinet/in_var.h>
62#include <netinet/if_ether.h>
63#include <netinet/ip_var.h>
64#if NCARP > 0
65#include <netinet/ip_carp.h>
66#endif
67
68/*
69 *  Locks used to protect struct members in this file:
70 *	a	atomic operations
71 *	I	immutable after creation
72 *	K	kernel lock
73 *	m	arp mutex, needed when net lock is shared
74 *	N	net lock
75 */
76
77struct llinfo_arp {
78	LIST_ENTRY(llinfo_arp)	 la_list;	/* [mN] global arp_list */
79	struct rtentry		*la_rt;		/* [I] backpointer to rtentry */
80	struct mbuf_queue	 la_mq;		/* packet hold queue */
81	time_t			 la_refreshed;	/* when was refresh sent */
82	int			 la_asked;	/* number of queries sent */
83};
84#define LA_HOLD_QUEUE 10
85#define LA_HOLD_TOTAL 100
86
87/* timer values */
88int 	arpt_prune = (5 * 60);	/* [I] walk list every 5 minutes */
89int 	arpt_keep = (20 * 60);	/* [a] once resolved, cache for 20 minutes */
90int 	arpt_down = 20;	/* [a] once declared down, don't send for 20 secs */
91
92struct mbuf *arppullup(struct mbuf *m);
93void arpinvalidate(struct rtentry *);
94void arptfree(struct rtentry *);
95void arptimer(void *);
96struct rtentry *arplookup(struct in_addr *, int, int, unsigned int);
97void in_arpinput(struct ifnet *, struct mbuf *);
98void in_revarpinput(struct ifnet *, struct mbuf *);
99int arpcache(struct ifnet *, struct ether_arp *, struct rtentry *);
100void arpreply(struct ifnet *, struct mbuf *, struct in_addr *, uint8_t *,
101    unsigned int);
102
103struct niqueue arpinq = NIQUEUE_INITIALIZER(50, NETISR_ARP);
104
105/* llinfo_arp live time, rt_llinfo and RTF_LLINFO are protected by arp_mtx */
106struct mutex arp_mtx = MUTEX_INITIALIZER(IPL_SOFTNET);
107
108LIST_HEAD(, llinfo_arp) arp_list =
109    LIST_HEAD_INITIALIZER(arp_list);	/* [mN] list of llinfo_arp structures */
110struct	pool arp_pool;		/* [I] pool for llinfo_arp structures */
111int	arp_maxtries = 5;	/* [I] arp requests before set to rejected */
112unsigned int	la_hold_total;	/* [a] packets currently in the arp queue */
113
114#ifdef NFSCLIENT
115/* revarp state */
116struct in_addr revarp_myip, revarp_srvip;
117int revarp_finished;
118unsigned int revarp_ifidx;
119#endif /* NFSCLIENT */
120
121/*
122 * Timeout routine.  Age arp_tab entries periodically.
123 */
124void
125arptimer(void *arg)
126{
127	struct timeout *to = arg;
128	struct llinfo_arp *la, *nla;
129	time_t uptime;
130
131	NET_LOCK();
132	uptime = getuptime();
133	timeout_add_sec(to, arpt_prune);
134	/* Net lock is exclusive, no arp mutex needed for arp_list here. */
135	LIST_FOREACH_SAFE(la, &arp_list, la_list, nla) {
136		struct rtentry *rt = la->la_rt;
137
138		if (rt->rt_expire && rt->rt_expire < uptime)
139			arptfree(rt); /* timer has expired; clear */
140	}
141	NET_UNLOCK();
142}
143
144void
145arpinit(void)
146{
147	static struct timeout arptimer_to;
148
149	pool_init(&arp_pool, sizeof(struct llinfo_arp), 0,
150	    IPL_SOFTNET, 0, "arp", NULL);
151
152	timeout_set_flags(&arptimer_to, arptimer, &arptimer_to,
153	    KCLOCK_NONE, TIMEOUT_PROC | TIMEOUT_MPSAFE);
154	timeout_add_sec(&arptimer_to, arpt_prune);
155}
156
157void
158arp_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
159{
160	struct sockaddr *gate = rt->rt_gateway;
161	struct llinfo_arp *la;
162	time_t uptime;
163
164	NET_ASSERT_LOCKED();
165
166	if (ISSET(rt->rt_flags,
167	    RTF_GATEWAY|RTF_BROADCAST|RTF_MULTICAST|RTF_MPLS))
168		return;
169
170	uptime = getuptime();
171	switch (req) {
172	case RTM_ADD:
173		if (rt->rt_flags & RTF_CLONING) {
174			rt->rt_expire = 0;
175			break;
176		}
177		if ((rt->rt_flags & RTF_LOCAL) && rt->rt_llinfo == NULL)
178			rt->rt_expire = 0;
179		/*
180		 * Announce a new entry if requested or warn the user
181		 * if another station has this IP address.
182		 */
183		if (rt->rt_flags & (RTF_ANNOUNCE|RTF_LOCAL))
184			arprequest(ifp,
185			    &satosin(rt_key(rt))->sin_addr.s_addr,
186			    &satosin(rt_key(rt))->sin_addr.s_addr,
187			    (u_char *)LLADDR(satosdl(gate)));
188		/*FALLTHROUGH*/
189	case RTM_RESOLVE:
190		if (gate->sa_family != AF_LINK ||
191		    gate->sa_len < sizeof(struct sockaddr_dl)) {
192			log(LOG_DEBUG, "%s: bad gateway value: %s\n", __func__,
193			    ifp->if_xname);
194			break;
195		}
196		satosdl(gate)->sdl_type = ifp->if_type;
197		satosdl(gate)->sdl_index = ifp->if_index;
198		/*
199		 * Case 2:  This route may come from cloning, or a manual route
200		 * add with a LL address.
201		 */
202		la = pool_get(&arp_pool, PR_NOWAIT | PR_ZERO);
203		if (la == NULL) {
204			log(LOG_DEBUG, "%s: pool get failed\n", __func__);
205			break;
206		}
207
208		mtx_enter(&arp_mtx);
209		if (rt->rt_llinfo != NULL) {
210			/* we lost the race, another thread has entered it */
211			mtx_leave(&arp_mtx);
212			pool_put(&arp_pool, la);
213			break;
214		}
215		mq_init(&la->la_mq, LA_HOLD_QUEUE, IPL_SOFTNET);
216		rt->rt_llinfo = (caddr_t)la;
217		la->la_rt = rt;
218		rt->rt_flags |= RTF_LLINFO;
219		LIST_INSERT_HEAD(&arp_list, la, la_list);
220		if ((rt->rt_flags & RTF_LOCAL) == 0)
221			rt->rt_expire = uptime;
222		mtx_leave(&arp_mtx);
223
224		break;
225
226	case RTM_DELETE:
227		mtx_enter(&arp_mtx);
228		la = (struct llinfo_arp *)rt->rt_llinfo;
229		if (la == NULL) {
230			/* we lost the race, another thread has removed it */
231			mtx_leave(&arp_mtx);
232			break;
233		}
234		LIST_REMOVE(la, la_list);
235		rt->rt_llinfo = NULL;
236		rt->rt_flags &= ~RTF_LLINFO;
237		atomic_sub_int(&la_hold_total, mq_purge(&la->la_mq));
238		mtx_leave(&arp_mtx);
239
240		pool_put(&arp_pool, la);
241		break;
242
243	case RTM_INVALIDATE:
244		if (!ISSET(rt->rt_flags, RTF_LOCAL))
245			arpinvalidate(rt);
246		break;
247	}
248}
249
250/*
251 * Broadcast an ARP request. Caller specifies:
252 *	- arp header source ip address
253 *	- arp header target ip address
254 *	- arp header source ethernet address
255 */
256void
257arprequest(struct ifnet *ifp, u_int32_t *sip, u_int32_t *tip, u_int8_t *enaddr)
258{
259	struct mbuf *m;
260	struct ether_header *eh;
261	struct ether_arp *ea;
262	struct sockaddr sa;
263
264	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
265		return;
266	m->m_len = sizeof(*ea);
267	m->m_pkthdr.len = sizeof(*ea);
268	m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
269	m->m_pkthdr.pf.prio = ifp->if_llprio;
270	m_align(m, sizeof(*ea));
271	ea = mtod(m, struct ether_arp *);
272	eh = (struct ether_header *)sa.sa_data;
273	memset(ea, 0, sizeof(*ea));
274	memcpy(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost));
275	eh->ether_type = htons(ETHERTYPE_ARP);	/* if_output will not swap */
276	ea->arp_hrd = htons(ARPHRD_ETHER);
277	ea->arp_pro = htons(ETHERTYPE_IP);
278	ea->arp_hln = sizeof(ea->arp_sha);	/* hardware address length */
279	ea->arp_pln = sizeof(ea->arp_spa);	/* protocol address length */
280	ea->arp_op = htons(ARPOP_REQUEST);
281	memcpy(eh->ether_shost, enaddr, sizeof(eh->ether_shost));
282	memcpy(ea->arp_sha, enaddr, sizeof(ea->arp_sha));
283	memcpy(ea->arp_spa, sip, sizeof(ea->arp_spa));
284	memcpy(ea->arp_tpa, tip, sizeof(ea->arp_tpa));
285	sa.sa_family = pseudo_AF_HDRCMPLT;
286	sa.sa_len = sizeof(sa);
287	m->m_flags |= M_BCAST;
288	ifp->if_output(ifp, m, &sa, NULL);
289}
290
291void
292arpreply(struct ifnet *ifp, struct mbuf *m, struct in_addr *sip, uint8_t *eaddr,
293    unsigned int rdomain)
294{
295	struct ether_header *eh;
296	struct ether_arp *ea;
297	struct sockaddr sa;
298
299	m_resethdr(m);
300	m->m_pkthdr.ph_rtableid = rdomain;
301
302	ea = mtod(m, struct ether_arp *);
303	ea->arp_op = htons(ARPOP_REPLY);
304	ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
305
306	/* We're replying to a request. */
307	memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
308	memcpy(ea->arp_tpa, ea->arp_spa, sizeof(ea->arp_spa));
309
310	memcpy(ea->arp_sha, eaddr, sizeof(ea->arp_sha));
311	memcpy(ea->arp_spa, sip, sizeof(ea->arp_spa));
312
313	eh = (struct ether_header *)sa.sa_data;
314	memcpy(eh->ether_dhost, ea->arp_tha, sizeof(eh->ether_dhost));
315	memcpy(eh->ether_shost, eaddr, sizeof(eh->ether_shost));
316	eh->ether_type = htons(ETHERTYPE_ARP);
317	sa.sa_family = pseudo_AF_HDRCMPLT;
318	sa.sa_len = sizeof(sa);
319	ifp->if_output(ifp, m, &sa, NULL);
320}
321
322/*
323 * Resolve an IP address into an ethernet address.  If success,
324 * desten is filled in.  If there is no entry in arptab,
325 * set one up and broadcast a request for the IP address.
326 * Hold onto this mbuf and resend it once the address
327 * is finally resolved.  A return value of 0 indicates
328 * that desten has been filled in and the packet should be sent
329 * normally; A return value of EAGAIN indicates that the packet
330 * has been taken over here, either now or for later transmission.
331 * Any other return value indicates an error.
332 */
333int
334arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
335    struct sockaddr *dst, u_char *desten)
336{
337	struct arpcom *ac = (struct arpcom *)ifp;
338	struct llinfo_arp *la;
339	struct sockaddr_dl *sdl;
340	struct rtentry *rt = NULL;
341	char addr[INET_ADDRSTRLEN];
342	time_t uptime;
343	int refresh = 0, reject = 0;
344
345	if (m->m_flags & M_BCAST) {	/* broadcast */
346		memcpy(desten, etherbroadcastaddr, sizeof(etherbroadcastaddr));
347		return (0);
348	}
349	if (m->m_flags & M_MCAST) {	/* multicast */
350		ETHER_MAP_IP_MULTICAST(&satosin(dst)->sin_addr, desten);
351		return (0);
352	}
353
354	uptime = getuptime();
355	rt = rt_getll(rt0);
356
357	if (ISSET(rt->rt_flags, RTF_REJECT) &&
358	    (rt->rt_expire == 0 || rt->rt_expire > uptime)) {
359		m_freem(m);
360		return (rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
361	}
362
363	if (!ISSET(rt->rt_flags, RTF_LLINFO)) {
364		log(LOG_DEBUG, "%s: %s: route contains no arp information\n",
365		    __func__, inet_ntop(AF_INET, &satosin(rt_key(rt))->sin_addr,
366		    addr, sizeof(addr)));
367		goto bad;
368	}
369
370	sdl = satosdl(rt->rt_gateway);
371	if (sdl->sdl_alen > 0 && sdl->sdl_alen != ETHER_ADDR_LEN) {
372		log(LOG_DEBUG, "%s: %s: incorrect arp information\n", __func__,
373		    inet_ntop(AF_INET, &satosin(dst)->sin_addr,
374			addr, sizeof(addr)));
375		goto bad;
376	}
377
378
379	/*
380	 * Check the address family and length is valid, the address
381	 * is resolved; otherwise, try to resolve.
382	 */
383	if ((rt->rt_expire == 0 || rt->rt_expire > uptime) &&
384	    sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
385		memcpy(desten, LLADDR(sdl), sdl->sdl_alen);
386
387		/* refresh ARP entry when timeout gets close */
388		if (rt->rt_expire != 0 &&
389		    rt->rt_expire - arpt_keep / 8 < uptime) {
390
391			mtx_enter(&arp_mtx);
392			la = (struct llinfo_arp *)rt->rt_llinfo;
393			if (la != NULL) {
394				if (la->la_refreshed + 30 < uptime) {
395					la->la_refreshed = uptime;
396					refresh = 1;
397				}
398			}
399			mtx_leave(&arp_mtx);
400		}
401		if (refresh) {
402			arprequest(ifp,
403			    &satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr,
404			    &satosin(dst)->sin_addr.s_addr,
405			    ac->ac_enaddr);
406		}
407		return (0);
408	}
409
410	if (ifp->if_flags & (IFF_NOARP|IFF_STATICARP))
411		goto bad;
412
413	mtx_enter(&arp_mtx);
414	la = (struct llinfo_arp *)rt->rt_llinfo;
415	if (la == NULL) {
416		mtx_leave(&arp_mtx);
417		goto bad;
418	}
419
420	/*
421	 * There is an arptab entry, but no ethernet address
422	 * response yet. Insert mbuf in hold queue if below limit.
423	 * If above the limit free the queue without queuing the new packet.
424	 */
425	if (atomic_inc_int_nv(&la_hold_total) <= LA_HOLD_TOTAL) {
426		if (mq_push(&la->la_mq, m) != 0)
427			atomic_dec_int(&la_hold_total);
428	} else {
429		atomic_sub_int(&la_hold_total, mq_purge(&la->la_mq) + 1);
430		m_freem(m);
431	}
432
433	/*
434	 * Re-send the ARP request when appropriate.
435	 */
436#ifdef	DIAGNOSTIC
437	if (rt->rt_expire == 0) {
438		/* This should never happen. (Should it? -gwr) */
439		printf("%s: unresolved and rt_expire == 0\n", __func__);
440		/* Set expiration time to now (expired). */
441		rt->rt_expire = uptime;
442	}
443#endif
444	if (rt->rt_expire) {
445		reject = ~RTF_REJECT;
446		if (la->la_asked == 0 || rt->rt_expire != uptime) {
447			rt->rt_expire = uptime;
448			if (la->la_asked++ < arp_maxtries)
449				refresh = 1;
450			else {
451				reject = RTF_REJECT;
452				rt->rt_expire += arpt_down;
453				la->la_asked = 0;
454				la->la_refreshed = 0;
455				atomic_sub_int(&la_hold_total,
456				    mq_purge(&la->la_mq));
457			}
458		}
459	}
460	mtx_leave(&arp_mtx);
461
462	if (reject == RTF_REJECT && !ISSET(rt->rt_flags, RTF_REJECT)) {
463		KERNEL_LOCK();
464		SET(rt->rt_flags, RTF_REJECT);
465		KERNEL_UNLOCK();
466	}
467	if (reject == ~RTF_REJECT && ISSET(rt->rt_flags, RTF_REJECT)) {
468		KERNEL_LOCK();
469		CLR(rt->rt_flags, RTF_REJECT);
470		KERNEL_UNLOCK();
471	}
472	if (refresh)
473		arprequest(ifp, &satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr,
474		    &satosin(dst)->sin_addr.s_addr, ac->ac_enaddr);
475	return (EAGAIN);
476
477bad:
478	m_freem(m);
479	return (EINVAL);
480}
481
482struct mbuf *
483arppullup(struct mbuf *m)
484{
485	struct arphdr *ar;
486	int len;
487
488#ifdef DIAGNOSTIC
489	if ((m->m_flags & M_PKTHDR) == 0)
490		panic("arp without packet header");
491#endif
492
493	len = sizeof(struct arphdr);
494	if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
495		return NULL;
496
497	ar = mtod(m, struct arphdr *);
498	if (ntohs(ar->ar_hrd) != ARPHRD_ETHER ||
499	    ntohs(ar->ar_pro) != ETHERTYPE_IP ||
500	    ar->ar_hln != ETHER_ADDR_LEN ||
501	    ar->ar_pln != sizeof(struct in_addr)) {
502		m_freem(m);
503		return NULL;
504	}
505
506	len += 2 * (ar->ar_hln + ar->ar_pln);
507	if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
508		return NULL;
509
510	return m;
511}
512
513/*
514 * Common length and type checks are done here,
515 * then the protocol-specific routine is called.
516 */
517void
518arpinput(struct ifnet *ifp, struct mbuf *m)
519{
520	if ((m = arppullup(m)) == NULL)
521		return;
522	niq_enqueue(&arpinq, m);
523}
524
525void
526arpintr(void)
527{
528	struct mbuf_list ml;
529	struct mbuf *m;
530	struct ifnet *ifp;
531
532	niq_delist(&arpinq, &ml);
533
534	while ((m = ml_dequeue(&ml)) != NULL) {
535		ifp = if_get(m->m_pkthdr.ph_ifidx);
536
537		if (ifp != NULL)
538			in_arpinput(ifp, m);
539		else
540			m_freem(m);
541
542		if_put(ifp);
543	}
544}
545
546/*
547 * ARP for Internet protocols on Ethernet, RFC 826.
548 * In addition, a sanity check is performed on the sender
549 * protocol address, to catch impersonators.
550 */
551void
552in_arpinput(struct ifnet *ifp, struct mbuf *m)
553{
554	struct ether_arp *ea;
555	struct rtentry *rt = NULL;
556	struct sockaddr_in sin;
557	struct in_addr isaddr, itaddr;
558	char addr[INET_ADDRSTRLEN];
559	int op, target = 0;
560	unsigned int rdomain;
561
562	rdomain = rtable_l2(m->m_pkthdr.ph_rtableid);
563
564	ea = mtod(m, struct ether_arp *);
565	op = ntohs(ea->arp_op);
566	if ((op != ARPOP_REQUEST) && (op != ARPOP_REPLY))
567		goto out;
568
569	memcpy(&itaddr, ea->arp_tpa, sizeof(itaddr));
570	memcpy(&isaddr, ea->arp_spa, sizeof(isaddr));
571	memset(&sin, 0, sizeof(sin));
572	sin.sin_len = sizeof(sin);
573	sin.sin_family = AF_INET;
574
575	if (ETHER_IS_MULTICAST(ea->arp_sha) &&
576	    ETHER_IS_BROADCAST(ea->arp_sha)) {
577		inet_ntop(AF_INET, &isaddr, addr, sizeof(addr));
578		log(LOG_ERR, "arp: ether address is broadcast for IP address "
579		    "%s!\n", addr);
580		goto out;
581	}
582
583	if (!memcmp(ea->arp_sha, LLADDR(ifp->if_sadl), sizeof(ea->arp_sha)))
584		goto out;	/* it's from me, ignore it. */
585
586	/* Check target against our interface addresses. */
587	sin.sin_addr = itaddr;
588	rt = rtalloc(sintosa(&sin), 0, rdomain);
589	if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL) &&
590	    rt->rt_ifidx == ifp->if_index)
591		target = 1;
592	rtfree(rt);
593	rt = NULL;
594
595#if NCARP > 0
596	if (target && op == ARPOP_REQUEST && ifp->if_type == IFT_CARP &&
597	    !carp_iamatch(ifp))
598		goto out;
599#endif
600
601	/* Do we have an ARP cache for the sender? Create if we are target. */
602	rt = arplookup(&isaddr, target, 0, rdomain);
603
604	/* Check sender against our interface addresses. */
605	if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL) &&
606	    rt->rt_ifidx == ifp->if_index && isaddr.s_addr != INADDR_ANY) {
607		inet_ntop(AF_INET, &isaddr, addr, sizeof(addr));
608		log(LOG_ERR, "duplicate IP address %s sent from ethernet "
609		    "address %s\n", addr, ether_sprintf(ea->arp_sha));
610		itaddr = isaddr;
611	} else if (rt != NULL) {
612		if (arpcache(ifp, ea, rt))
613			goto out;
614	}
615
616	if (op == ARPOP_REQUEST) {
617		uint8_t *eaddr;
618
619		if (target) {
620			/* We already have all info for the reply */
621			eaddr = LLADDR(ifp->if_sadl);
622		} else {
623			rtfree(rt);
624			rt = arplookup(&itaddr, 0, SIN_PROXY, rdomain);
625			/*
626			 * Protect from possible duplicates, only owner
627			 * should respond
628			 */
629			if ((rt == NULL) || (rt->rt_ifidx != ifp->if_index))
630				goto out;
631			eaddr = LLADDR(satosdl(rt->rt_gateway));
632		}
633		arpreply(ifp, m, &itaddr, eaddr, rdomain);
634		rtfree(rt);
635		return;
636	}
637
638out:
639	rtfree(rt);
640	m_freem(m);
641}
642
643int
644arpcache(struct ifnet *ifp, struct ether_arp *ea, struct rtentry *rt)
645{
646	struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
647	struct sockaddr_dl *sdl = satosdl(rt->rt_gateway);
648	struct in_addr *spa = (struct in_addr *)ea->arp_spa;
649	char addr[INET_ADDRSTRLEN];
650	struct ifnet *rifp;
651	time_t uptime;
652	int changed = 0;
653
654	NET_ASSERT_LOCKED_EXCLUSIVE();
655	KASSERT(sdl != NULL);
656
657	/*
658	 * This can happen if the entry has been deleted by another CPU
659	 * after we found it.
660	 */
661	if (la == NULL)
662		return (0);
663
664	uptime = getuptime();
665	if (sdl->sdl_alen > 0) {
666		if (memcmp(ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) {
667			if (ISSET(rt->rt_flags, RTF_PERMANENT_ARP|RTF_LOCAL)) {
668				inet_ntop(AF_INET, spa, addr, sizeof(addr));
669				log(LOG_WARNING, "arp: attempt to overwrite "
670				   "permanent entry for %s by %s on %s\n", addr,
671				   ether_sprintf(ea->arp_sha), ifp->if_xname);
672				return (-1);
673			} else if (rt->rt_ifidx != ifp->if_index) {
674#if NCARP > 0
675				if (ifp->if_type != IFT_CARP)
676#endif
677				{
678					rifp = if_get(rt->rt_ifidx);
679					if (rifp == NULL)
680						return (-1);
681					inet_ntop(AF_INET, spa, addr,
682					    sizeof(addr));
683					log(LOG_WARNING, "arp: attempt to "
684					    "overwrite entry for %s on %s by "
685					    "%s on %s\n", addr, rifp->if_xname,
686					    ether_sprintf(ea->arp_sha),
687					    ifp->if_xname);
688					if_put(rifp);
689				}
690				return (-1);
691			} else {
692				inet_ntop(AF_INET, spa, addr, sizeof(addr));
693				log(LOG_INFO, "arp info overwritten for %s by "
694				    "%s on %s\n", addr,
695				    ether_sprintf(ea->arp_sha), ifp->if_xname);
696				rt->rt_expire = 1;/* no longer static */
697			}
698			changed = 1;
699		}
700	} else if (!if_isconnected(ifp, rt->rt_ifidx)) {
701		rifp = if_get(rt->rt_ifidx);
702		if (rifp == NULL)
703			return (-1);
704		inet_ntop(AF_INET, spa, addr, sizeof(addr));
705		log(LOG_WARNING, "arp: attempt to add entry for %s on %s by %s"
706		    " on %s\n", addr, rifp->if_xname,
707		    ether_sprintf(ea->arp_sha), ifp->if_xname);
708		if_put(rifp);
709		return (-1);
710	}
711	sdl->sdl_alen = sizeof(ea->arp_sha);
712	memcpy(LLADDR(sdl), ea->arp_sha, sizeof(ea->arp_sha));
713	if (rt->rt_expire)
714		rt->rt_expire = uptime + arpt_keep;
715	rt->rt_flags &= ~RTF_REJECT;
716
717	/* Notify userland that an ARP resolution has been done. */
718	if (la->la_asked || changed) {
719		rtm_send(rt, RTM_RESOLVE, 0, ifp->if_rdomain);
720	}
721
722	la->la_asked = 0;
723	la->la_refreshed = 0;
724	if_output_mq(ifp, &la->la_mq, &la_hold_total, rt_key(rt), rt);
725
726	return (0);
727}
728
729void
730arpinvalidate(struct rtentry *rt)
731{
732	struct llinfo_arp *la;
733	struct sockaddr_dl *sdl = satosdl(rt->rt_gateway);
734
735	mtx_enter(&arp_mtx);
736	la = (struct llinfo_arp *)rt->rt_llinfo;
737	if (la == NULL) {
738		mtx_leave(&arp_mtx);
739		return;
740	}
741	atomic_sub_int(&la_hold_total, mq_purge(&la->la_mq));
742	sdl->sdl_alen = 0;
743	la->la_asked = 0;
744	mtx_leave(&arp_mtx);
745}
746
747/*
748 * Free an arp entry.
749 */
750void
751arptfree(struct rtentry *rt)
752{
753	struct ifnet *ifp;
754
755	KASSERT(!ISSET(rt->rt_flags, RTF_LOCAL));
756	arpinvalidate(rt);
757
758	ifp = if_get(rt->rt_ifidx);
759	if (ifp == NULL)
760		return;
761	if (!ISSET(rt->rt_flags, RTF_STATIC|RTF_CACHED))
762		rtdeletemsg(rt, ifp, ifp->if_rdomain);
763	if_put(ifp);
764}
765
766/*
767 * Lookup or enter a new address in arptab.
768 */
769struct rtentry *
770arplookup(struct in_addr *inp, int create, int proxy, u_int tableid)
771{
772	struct rtentry *rt;
773	struct sockaddr_inarp sin;
774	int flags;
775
776	memset(&sin, 0, sizeof(sin));
777	sin.sin_len = sizeof(sin);
778	sin.sin_family = AF_INET;
779	sin.sin_addr.s_addr = inp->s_addr;
780	sin.sin_other = proxy ? SIN_PROXY : 0;
781	flags = (create) ? RT_RESOLVE : 0;
782
783	rt = rtalloc((struct sockaddr *)&sin, flags, tableid);
784	if (!rtisvalid(rt) || ISSET(rt->rt_flags, RTF_GATEWAY) ||
785	    !ISSET(rt->rt_flags, RTF_LLINFO) ||
786	    rt->rt_gateway->sa_family != AF_LINK) {
787		rtfree(rt);
788		return (NULL);
789	}
790
791	if (proxy && !ISSET(rt->rt_flags, RTF_ANNOUNCE)) {
792		while ((rt = rtable_iterate(rt)) != NULL) {
793			if (ISSET(rt->rt_flags, RTF_ANNOUNCE)) {
794				break;
795			}
796		}
797	}
798
799	return (rt);
800}
801
802/*
803 * Check whether we do proxy ARP for this address and we point to ourselves.
804 */
805int
806arpproxy(struct in_addr in, unsigned int rtableid)
807{
808	struct sockaddr_dl *sdl;
809	struct rtentry *rt;
810	struct ifnet *ifp;
811	int found = 0;
812
813	rt = arplookup(&in, 0, SIN_PROXY, rtableid);
814	if (!rtisvalid(rt)) {
815		rtfree(rt);
816		return (0);
817	}
818
819	/* Check that arp information are correct. */
820	sdl = satosdl(rt->rt_gateway);
821	if (sdl->sdl_alen != ETHER_ADDR_LEN) {
822		rtfree(rt);
823		return (0);
824	}
825
826	ifp = if_get(rt->rt_ifidx);
827	if (ifp == NULL) {
828		rtfree(rt);
829		return (0);
830	}
831
832	if (!memcmp(LLADDR(sdl), LLADDR(ifp->if_sadl), sdl->sdl_alen))
833		found = 1;
834
835	if_put(ifp);
836	rtfree(rt);
837	return (found);
838}
839
840/*
841 * Called from Ethernet interrupt handlers
842 * when ether packet type ETHERTYPE_REVARP
843 * is received.  Common length and type checks are done here,
844 * then the protocol-specific routine is called.
845 */
846void
847revarpinput(struct ifnet *ifp, struct mbuf *m)
848{
849	if ((m = arppullup(m)) == NULL)
850		return;
851	in_revarpinput(ifp, m);
852}
853
854/*
855 * RARP for Internet protocols on Ethernet.
856 * Algorithm is that given in RFC 903.
857 * We are only using for bootstrap purposes to get an ip address for one of
858 * our interfaces.  Thus we support no user-interface.
859 *
860 * Since the contents of the RARP reply are specific to the interface that
861 * sent the request, this code must ensure that they are properly associated.
862 *
863 * Note: also supports ARP via RARP packets, per the RFC.
864 */
865void
866in_revarpinput(struct ifnet *ifp, struct mbuf *m)
867{
868	struct ether_arp *ar;
869	int op;
870
871	ar = mtod(m, struct ether_arp *);
872	op = ntohs(ar->arp_op);
873	switch (op) {
874	case ARPOP_REQUEST:
875	case ARPOP_REPLY:	/* per RFC */
876		niq_enqueue(&arpinq, m);
877		return;
878	case ARPOP_REVREPLY:
879		break;
880	case ARPOP_REVREQUEST:	/* handled by rarpd(8) */
881	default:
882		goto out;
883	}
884#ifdef NFSCLIENT
885	if (revarp_ifidx == 0)
886		goto out;
887	if (revarp_ifidx != m->m_pkthdr.ph_ifidx) /* !same interface */
888		goto out;
889	if (revarp_finished)
890		goto wake;
891	if (memcmp(ar->arp_tha, LLADDR(ifp->if_sadl), sizeof(ar->arp_tha)))
892		goto out;
893	memcpy(&revarp_srvip, ar->arp_spa, sizeof(revarp_srvip));
894	memcpy(&revarp_myip, ar->arp_tpa, sizeof(revarp_myip));
895	revarp_finished = 1;
896wake:	/* Do wakeup every time in case it was missed. */
897	wakeup((caddr_t)&revarp_myip);
898#endif /* NFSCLIENT */
899
900out:
901	m_freem(m);
902}
903
904/*
905 * Send a RARP request for the ip address of the specified interface.
906 * The request should be RFC 903-compliant.
907 */
908void
909revarprequest(struct ifnet *ifp)
910{
911	struct sockaddr sa;
912	struct mbuf *m;
913	struct ether_header *eh;
914	struct ether_arp *ea;
915	struct arpcom *ac = (struct arpcom *)ifp;
916
917	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
918		return;
919	m->m_len = sizeof(*ea);
920	m->m_pkthdr.len = sizeof(*ea);
921	m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
922	m->m_pkthdr.pf.prio = ifp->if_llprio;
923	m_align(m, sizeof(*ea));
924	ea = mtod(m, struct ether_arp *);
925	eh = (struct ether_header *)sa.sa_data;
926	memset(ea, 0, sizeof(*ea));
927	memcpy(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost));
928	eh->ether_type = htons(ETHERTYPE_REVARP);
929	ea->arp_hrd = htons(ARPHRD_ETHER);
930	ea->arp_pro = htons(ETHERTYPE_IP);
931	ea->arp_hln = sizeof(ea->arp_sha);	/* hardware address length */
932	ea->arp_pln = sizeof(ea->arp_spa);	/* protocol address length */
933	ea->arp_op = htons(ARPOP_REVREQUEST);
934	memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(ea->arp_tha));
935	memcpy(ea->arp_sha, ac->ac_enaddr, sizeof(ea->arp_sha));
936	memcpy(ea->arp_tha, ac->ac_enaddr, sizeof(ea->arp_tha));
937	sa.sa_family = pseudo_AF_HDRCMPLT;
938	sa.sa_len = sizeof(sa);
939	m->m_flags |= M_BCAST;
940	ifp->if_output(ifp, m, &sa, NULL);
941}
942
943#ifdef NFSCLIENT
944/*
945 * RARP for the ip address of the specified interface, but also
946 * save the ip address of the server that sent the answer.
947 * Timeout if no response is received.
948 */
949int
950revarpwhoarewe(struct ifnet *ifp, struct in_addr *serv_in,
951    struct in_addr *clnt_in)
952{
953	int result, count = 20;
954
955	if (revarp_finished)
956		return EIO;
957
958	revarp_ifidx = ifp->if_index;
959	while (count--) {
960		revarprequest(ifp);
961		result = tsleep_nsec(&revarp_myip, PSOCK, "revarp",
962		    MSEC_TO_NSEC(500));
963		if (result != EWOULDBLOCK)
964			break;
965	}
966	revarp_ifidx = 0;
967	if (!revarp_finished)
968		return ENETUNREACH;
969
970	memcpy(serv_in, &revarp_srvip, sizeof(*serv_in));
971	memcpy(clnt_in, &revarp_myip, sizeof(*clnt_in));
972	return 0;
973}
974
975/* For compatibility: only saves interface address. */
976int
977revarpwhoami(struct in_addr *in, struct ifnet *ifp)
978{
979	struct in_addr server;
980	return (revarpwhoarewe(ifp, &server, in));
981}
982#endif /* NFSCLIENT */
983