xref: /openbsd-src/sys/netinet/if_ether.c (revision 2777ee89d0e541ec819d05abee114837837abbec)
1 /*	$OpenBSD: if_ether.c,v 1.205 2016/04/27 14:47:27 mpi 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 #if NCARP > 0
64 #include <netinet/ip_carp.h>
65 #endif
66 
67 struct llinfo_arp {
68 	LIST_ENTRY(llinfo_arp)	 la_list;
69 	struct rtentry		*la_rt;		/* backpointer to rtentry */
70 	long			 la_asked;	/* last time we QUERIED */
71 	struct mbuf_list	 la_ml;		/* packet hold queue */
72 };
73 #define LA_HOLD_QUEUE 10
74 #define LA_HOLD_TOTAL 100
75 
76 /* timer values */
77 int	arpt_prune = (5*60*1);	/* walk list every 5 minutes */
78 int	arpt_keep = (20*60);	/* once resolved, good for 20 more minutes */
79 int	arpt_down = 20;		/* once declared down, don't send for 20 secs */
80 
81 void arptfree(struct rtentry *);
82 void arptimer(void *);
83 struct rtentry *arplookup(u_int32_t, int, int, u_int);
84 void in_arpinput(struct mbuf *);
85 void in_revarpinput(struct mbuf *);
86 
87 LIST_HEAD(, llinfo_arp) arp_list;
88 struct	pool arp_pool;		/* pool for llinfo_arp structures */
89 int	arp_maxtries = 5;
90 int	arpinit_done;
91 int	la_hold_total;
92 
93 #ifdef NFSCLIENT
94 /* revarp state */
95 struct in_addr revarp_myip, revarp_srvip;
96 int revarp_finished;
97 unsigned int revarp_ifidx;
98 #endif /* NFSCLIENT */
99 
100 /*
101  * Timeout routine.  Age arp_tab entries periodically.
102  */
103 /* ARGSUSED */
104 void
105 arptimer(void *arg)
106 {
107 	struct timeout *to = (struct timeout *)arg;
108 	int s;
109 	struct llinfo_arp *la, *nla;
110 
111 	s = splsoftnet();
112 	timeout_add_sec(to, arpt_prune);
113 	LIST_FOREACH_SAFE(la, &arp_list, la_list, nla) {
114 		struct rtentry *rt = la->la_rt;
115 
116 		if (rt->rt_expire && rt->rt_expire <= time_second)
117 			arptfree(rt); /* timer has expired; clear */
118 	}
119 	splx(s);
120 }
121 
122 void
123 arp_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
124 {
125 	struct sockaddr *gate = rt->rt_gateway;
126 	struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
127 	struct ifaddr *ifa;
128 
129 	if (!arpinit_done) {
130 		static struct timeout arptimer_to;
131 
132 		arpinit_done = 1;
133 		pool_init(&arp_pool, sizeof(struct llinfo_arp), 0, 0, 0, "arp",
134 		    NULL);
135 		/*
136 		 * We generate expiration times from time.tv_sec
137 		 * so avoid accidently creating permanent routes.
138 		 */
139 		if (time_second == 0) {
140 			time_second++;
141 		}
142 
143 		timeout_set(&arptimer_to, arptimer, &arptimer_to);
144 		timeout_add_sec(&arptimer_to, 1);
145 	}
146 
147 	if (rt->rt_flags & (RTF_GATEWAY|RTF_BROADCAST))
148 		return;
149 
150 	switch (req) {
151 
152 	case RTM_ADD:
153 		if (rt->rt_flags & RTF_CLONING ||
154 		    ((rt->rt_flags & (RTF_LLINFO | RTF_LOCAL)) && !la)) {
155 			/*
156 			 * Give this route an expiration time, even though
157 			 * it's a "permanent" route, so that routes cloned
158 			 * from it do not need their expiration time set.
159 			 */
160 			rt->rt_expire = time_second;
161 			if ((rt->rt_flags & RTF_CLONING) != 0)
162 				break;
163 		}
164 		/*
165 		 * Announce a new entry if requested or warn the user
166 		 * if another station has this IP address.
167 		 */
168 		if (rt->rt_flags & (RTF_ANNOUNCE|RTF_LOCAL))
169 			arprequest(ifp,
170 			    &satosin(rt_key(rt))->sin_addr.s_addr,
171 			    &satosin(rt_key(rt))->sin_addr.s_addr,
172 			    (u_char *)LLADDR(satosdl(gate)));
173 		/*FALLTHROUGH*/
174 	case RTM_RESOLVE:
175 		if (gate->sa_family != AF_LINK ||
176 		    gate->sa_len < sizeof(struct sockaddr_dl)) {
177 			log(LOG_DEBUG, "%s: bad gateway value: %s\n", __func__,
178 			    ifp->if_xname);
179 			break;
180 		}
181 		satosdl(gate)->sdl_type = ifp->if_type;
182 		satosdl(gate)->sdl_index = ifp->if_index;
183 		if (la != 0)
184 			break; /* This happens on a route change */
185 		/*
186 		 * Case 2:  This route may come from cloning, or a manual route
187 		 * add with a LL address.
188 		 */
189 		la = pool_get(&arp_pool, PR_NOWAIT | PR_ZERO);
190 		rt->rt_llinfo = (caddr_t)la;
191 		if (la == NULL) {
192 			log(LOG_DEBUG, "%s: pool get failed\n", __func__);
193 			break;
194 		}
195 
196 		ml_init(&la->la_ml);
197 		la->la_rt = rt;
198 		rt->rt_flags |= RTF_LLINFO;
199 		LIST_INSERT_HEAD(&arp_list, la, la_list);
200 
201 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
202 			if ((ifa->ifa_addr->sa_family == AF_INET) &&
203 			    ifatoia(ifa)->ia_addr.sin_addr.s_addr ==
204 			    satosin(rt_key(rt))->sin_addr.s_addr)
205 				break;
206 		}
207 		if (ifa) {
208 			KASSERT(ifa == rt->rt_ifa);
209 			rt->rt_expire = 0;
210 		}
211 		break;
212 
213 	case RTM_DELETE:
214 		if (la == NULL)
215 			break;
216 		LIST_REMOVE(la, la_list);
217 		rt->rt_llinfo = 0;
218 		rt->rt_flags &= ~RTF_LLINFO;
219 		la_hold_total -= ml_purge(&la->la_ml);
220 		pool_put(&arp_pool, la);
221 	}
222 }
223 
224 /*
225  * Broadcast an ARP request. Caller specifies:
226  *	- arp header source ip address
227  *	- arp header target ip address
228  *	- arp header source ethernet address
229  */
230 void
231 arprequest(struct ifnet *ifp, u_int32_t *sip, u_int32_t *tip, u_int8_t *enaddr)
232 {
233 	struct mbuf *m;
234 	struct ether_header *eh;
235 	struct ether_arp *ea;
236 	struct sockaddr sa;
237 
238 	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
239 		return;
240 	m->m_len = sizeof(*ea);
241 	m->m_pkthdr.len = sizeof(*ea);
242 	m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
243 	MH_ALIGN(m, sizeof(*ea));
244 	ea = mtod(m, struct ether_arp *);
245 	eh = (struct ether_header *)sa.sa_data;
246 	memset(ea, 0, sizeof(*ea));
247 	memcpy(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost));
248 	eh->ether_type = htons(ETHERTYPE_ARP);	/* if_output will not swap */
249 	ea->arp_hrd = htons(ARPHRD_ETHER);
250 	ea->arp_pro = htons(ETHERTYPE_IP);
251 	ea->arp_hln = sizeof(ea->arp_sha);	/* hardware address length */
252 	ea->arp_pln = sizeof(ea->arp_spa);	/* protocol address length */
253 	ea->arp_op = htons(ARPOP_REQUEST);
254 	memcpy(eh->ether_shost, enaddr, sizeof(eh->ether_shost));
255 	memcpy(ea->arp_sha, enaddr, sizeof(ea->arp_sha));
256 	memcpy(ea->arp_spa, sip, sizeof(ea->arp_spa));
257 	memcpy(ea->arp_tpa, tip, sizeof(ea->arp_tpa));
258 	sa.sa_family = pseudo_AF_HDRCMPLT;
259 	sa.sa_len = sizeof(sa);
260 	m->m_flags |= M_BCAST;
261 	ifp->if_output(ifp, m, &sa, NULL);
262 }
263 
264 /*
265  * Resolve an IP address into an ethernet address.  If success,
266  * desten is filled in.  If there is no entry in arptab,
267  * set one up and broadcast a request for the IP address.
268  * Hold onto this mbuf and resend it once the address
269  * is finally resolved.  A return value of 0 indicates
270  * that desten has been filled in and the packet should be sent
271  * normally; A return value of EAGAIN indicates that the packet
272  * has been taken over here, either now or for later transmission.
273  * Any other return value indicates an error.
274  */
275 int
276 arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
277     struct sockaddr *dst, u_char *desten)
278 {
279 	struct arpcom *ac = (struct arpcom *)ifp;
280 	struct llinfo_arp *la = NULL;
281 	struct sockaddr_dl *sdl;
282 	struct rtentry *rt = NULL;
283 	struct mbuf *mh;
284 	char addr[INET_ADDRSTRLEN];
285 	int error, created = 0;
286 
287 	if (m->m_flags & M_BCAST) {	/* broadcast */
288 		memcpy(desten, etherbroadcastaddr, sizeof(etherbroadcastaddr));
289 		return (0);
290 	}
291 	if (m->m_flags & M_MCAST) {	/* multicast */
292 		ETHER_MAP_IP_MULTICAST(&satosin(dst)->sin_addr, desten);
293 		return (0);
294 	}
295 
296 	if (rt0 != NULL) {
297 		error = rt_checkgate(rt0, &rt);
298 		if (error) {
299 			m_freem(m);
300 			return (error);
301 		}
302 
303 		if ((rt->rt_flags & RTF_LLINFO) == 0) {
304 			log(LOG_DEBUG, "%s: %s: route contains no arp"
305 			    " information\n", __func__, inet_ntop(AF_INET,
306 				&satosin(rt_key(rt))->sin_addr, addr,
307 				sizeof(addr)));
308 			m_freem(m);
309 			return (EINVAL);
310 		}
311 
312 		la = (struct llinfo_arp *)rt->rt_llinfo;
313 		if (la == NULL)
314 			log(LOG_DEBUG, "%s: %s: route without link "
315 			    "local address\n", __func__, inet_ntop(AF_INET,
316 				&satosin(dst)->sin_addr, addr, sizeof(addr)));
317 	} else {
318 		rt = arplookup(satosin(dst)->sin_addr.s_addr, 1, 0,
319 		    ifp->if_rdomain);
320 		if (rt != NULL) {
321 		    	created = 1;
322 			la = ((struct llinfo_arp *)rt->rt_llinfo);
323 		}
324 		if (la == NULL)
325 			log(LOG_DEBUG, "%s: %s: can't allocate llinfo\n",
326 			    __func__,
327 			    inet_ntop(AF_INET, &satosin(dst)->sin_addr,
328 				addr, sizeof(addr)));
329 	}
330 	if (la == NULL || rt == NULL)
331 		goto bad;
332 	sdl = satosdl(rt->rt_gateway);
333 	if (sdl->sdl_alen > 0 && sdl->sdl_alen != ETHER_ADDR_LEN) {
334 		log(LOG_DEBUG, "%s: %s: incorrect arp information\n", __func__,
335 		    inet_ntop(AF_INET, &satosin(dst)->sin_addr,
336 			addr, sizeof(addr)));
337 		goto bad;
338 	}
339 	/*
340 	 * Check the address family and length is valid, the address
341 	 * is resolved; otherwise, try to resolve.
342 	 */
343 	if ((rt->rt_expire == 0 || rt->rt_expire > time_second) &&
344 	    sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
345 		memcpy(desten, LLADDR(sdl), sdl->sdl_alen);
346 		if (created)
347 			rtfree(rt);
348 		return (0);
349 	}
350 	if (ifp->if_flags & IFF_NOARP)
351 		goto bad;
352 
353 	/*
354 	 * There is an arptab entry, but no ethernet address
355 	 * response yet. Insert mbuf in hold queue if below limit
356 	 * if above the limit free the queue without queuing the new packet.
357 	 */
358 	if (la_hold_total < LA_HOLD_TOTAL && la_hold_total < nmbclust / 64) {
359 		if (ml_len(&la->la_ml) >= LA_HOLD_QUEUE) {
360 			mh = ml_dequeue(&la->la_ml);
361 			la_hold_total--;
362 			m_freem(mh);
363 		}
364 		ml_enqueue(&la->la_ml, m);
365 		la_hold_total++;
366 	} else {
367 		la_hold_total -= ml_purge(&la->la_ml);
368 		m_freem(m);
369 	}
370 
371 	/*
372 	 * Re-send the ARP request when appropriate.
373 	 */
374 #ifdef	DIAGNOSTIC
375 	if (rt->rt_expire == 0) {
376 		/* This should never happen. (Should it? -gwr) */
377 		printf("%s: unresolved and rt_expire == 0\n", __func__);
378 		/* Set expiration time to now (expired). */
379 		rt->rt_expire = time_second;
380 	}
381 #endif
382 	if (rt->rt_expire) {
383 		rt->rt_flags &= ~RTF_REJECT;
384 		if (la->la_asked == 0 || rt->rt_expire != time_second) {
385 			rt->rt_expire = time_second;
386 			if (la->la_asked++ < arp_maxtries)
387 				arprequest(ifp,
388 				    &satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr,
389 				    &satosin(dst)->sin_addr.s_addr,
390 				    ac->ac_enaddr);
391 			else {
392 				rt->rt_flags |= RTF_REJECT;
393 				rt->rt_expire += arpt_down;
394 				la->la_asked = 0;
395 				la_hold_total -= ml_purge(&la->la_ml);
396 			}
397 		}
398 	}
399 	if (created)
400 		rtfree(rt);
401 	return (EAGAIN);
402 
403 bad:
404 	m_freem(m);
405 	if (created)
406 		rtfree(rt);
407 	return (EINVAL);
408 }
409 
410 /*
411  * Common length and type checks are done here,
412  * then the protocol-specific routine is called.
413  */
414 void
415 arpinput(struct mbuf *m)
416 {
417 	struct arphdr *ar;
418 	int len;
419 
420 #ifdef DIAGNOSTIC
421 	if ((m->m_flags & M_PKTHDR) == 0)
422 		panic("arpintr");
423 #endif
424 
425 	len = sizeof(struct arphdr);
426 	if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
427 		return;
428 
429 	ar = mtod(m, struct arphdr *);
430 	if (ntohs(ar->ar_hrd) != ARPHRD_ETHER ||
431 	    ntohs(ar->ar_pro) != ETHERTYPE_IP) {
432 		m_freem(m);
433 		return;
434 	}
435 
436 	len += 2 * (ar->ar_hln + ar->ar_pln);
437 	if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
438 		return;
439 
440 	in_arpinput(m);
441 }
442 
443 /*
444  * ARP for Internet protocols on Ethernet, RFC 826.
445  * In addition, a sanity check is performed on the sender
446  * protocol address, to catch impersonators.
447  */
448 void
449 in_arpinput(struct mbuf *m)
450 {
451 	struct ether_arp *ea;
452 	struct ifnet *ifp;
453 	struct ether_header *eh;
454 	struct llinfo_arp *la = NULL;
455 	struct rtentry *rt = NULL;
456 	struct sockaddr_dl *sdl;
457 	struct sockaddr sa;
458 	struct sockaddr_in sin;
459 	struct in_addr isaddr, itaddr;
460 	struct mbuf *mh;
461 	uint8_t enaddr[ETHER_ADDR_LEN];
462 	char addr[INET_ADDRSTRLEN];
463 	int op, changed = 0, target = 0;
464 	unsigned int len, rdomain;
465 
466 	rdomain = rtable_l2(m->m_pkthdr.ph_rtableid);
467 
468 	ifp = if_get(m->m_pkthdr.ph_ifidx);
469 	if (ifp == NULL) {
470 		m_freem(m);
471 		return;
472 	}
473 	ea = mtod(m, struct ether_arp *);
474 	op = ntohs(ea->arp_op);
475 	if ((op != ARPOP_REQUEST) && (op != ARPOP_REPLY))
476 		goto out;
477 
478 	memcpy(&itaddr, ea->arp_tpa, sizeof(itaddr));
479 	memcpy(&isaddr, ea->arp_spa, sizeof(isaddr));
480 	memset(&sin, 0, sizeof(sin));
481 	sin.sin_len = sizeof(sin);
482 	sin.sin_family = AF_INET;
483 
484 	if (ETHER_IS_MULTICAST(&ea->arp_sha[0])) {
485 		if (!memcmp(ea->arp_sha, etherbroadcastaddr,
486 		    sizeof (ea->arp_sha))) {
487 			inet_ntop(AF_INET, &isaddr, addr, sizeof(addr));
488 			log(LOG_ERR, "arp: ether address is broadcast for "
489 			    "IP address %s!\n", addr);
490 			goto out;
491 		}
492 	}
493 
494 	memcpy(enaddr, LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
495 	if (!memcmp(ea->arp_sha, enaddr, sizeof(ea->arp_sha)))
496 		goto out;	/* it's from me, ignore it. */
497 
498 	/* Check target against our interface addresses. */
499 	sin.sin_addr = itaddr;
500 	rt = rtalloc(sintosa(&sin), 0, rdomain);
501 	if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL) &&
502 	    rt->rt_ifidx == ifp->if_index)
503 		target = 1;
504 	rtfree(rt);
505 	rt = NULL;
506 
507 #if NCARP > 0
508 	if (target && op == ARPOP_REQUEST && ifp->if_type == IFT_CARP &&
509 	    !carp_iamatch(ifp, enaddr))
510 		goto out;
511 #endif
512 
513 	/* Do we have an ARP cache for the sender?  Create if we are target. */
514 	rt = arplookup(isaddr.s_addr, target, 0, rdomain);
515 
516 	/* Check sender against our interface addresses. */
517 	if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL) &&
518 	    rt->rt_ifidx == ifp->if_index && isaddr.s_addr != INADDR_ANY) {
519 		inet_ntop(AF_INET, &isaddr, addr, sizeof(addr));
520 		log(LOG_ERR,
521 		   "duplicate IP address %s sent from ethernet address %s\n",
522 		   addr, ether_sprintf(ea->arp_sha));
523 		itaddr = isaddr;
524 	} else if (rt != NULL && (sdl = satosdl(rt->rt_gateway)) != NULL) {
525 		la = (struct llinfo_arp *)rt->rt_llinfo;
526 		if (sdl->sdl_alen) {
527 			if (memcmp(ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) {
528 				if (rt->rt_flags &
529 				    (RTF_PERMANENT_ARP|RTF_LOCAL)) {
530 					inet_ntop(AF_INET, &isaddr, addr,
531 					    sizeof(addr));
532 					log(LOG_WARNING, "arp: attempt to"
533 					   " overwrite permanent entry for %s"
534 					   " by %s on %s\n", addr,
535 					   ether_sprintf(ea->arp_sha),
536 					   ifp->if_xname);
537 					goto out;
538 				} else if (rt->rt_ifidx != ifp->if_index) {
539 #if NCARP > 0
540 					if (ifp->if_type != IFT_CARP)
541 #endif
542 					{
543 						struct ifnet *rifp = if_get(
544 						    rt->rt_ifidx);
545 						if (rifp == NULL)
546 							goto out;
547 						inet_ntop(AF_INET, &isaddr,
548 						    addr, sizeof(addr));
549 						log(LOG_WARNING, "arp: attempt"
550 						   " to overwrite entry for"
551 						   " %s on %s by %s on %s\n",
552 						   addr, rifp->if_xname,
553 						   ether_sprintf(ea->arp_sha),
554 						   ifp->if_xname);
555 						if_put(rifp);
556 					}
557 					goto out;
558 				} else {
559 					inet_ntop(AF_INET, &isaddr, addr,
560 					    sizeof(addr));
561 					log(LOG_INFO, "arp info overwritten for"
562 					   " %s by %s on %s\n", addr,
563 					   ether_sprintf(ea->arp_sha),
564 					   ifp->if_xname);
565 					rt->rt_expire = 1;/* no longer static */
566 				}
567 			changed = 1;
568 			}
569 		} else if (!if_isconnected(ifp, rt->rt_ifidx)) {
570 			struct ifnet *rifp = if_get(rt->rt_ifidx);
571 			if (rifp == NULL)
572 				goto out;
573 			inet_ntop(AF_INET, &isaddr, addr, sizeof(addr));
574 			log(LOG_WARNING,
575 			    "arp: attempt to add entry for %s "
576 			    "on %s by %s on %s\n", addr,
577 			    rifp->if_xname,
578 			    ether_sprintf(ea->arp_sha),
579 			    ifp->if_xname);
580 			if_put(rifp);
581 			goto out;
582 		}
583 		sdl->sdl_alen = sizeof(ea->arp_sha);
584 		memcpy(LLADDR(sdl), ea->arp_sha, sizeof(ea->arp_sha));
585 		if (rt->rt_expire)
586 			rt->rt_expire = time_second + arpt_keep;
587 		rt->rt_flags &= ~RTF_REJECT;
588 		/* Notify userland that an ARP resolution has been done. */
589 		if (la->la_asked || changed) {
590 			KERNEL_LOCK();
591 			rt_sendmsg(rt, RTM_RESOLVE, ifp->if_rdomain);
592 			KERNEL_UNLOCK();
593 		}
594 		la->la_asked = 0;
595 		while ((len = ml_len(&la->la_ml)) != 0) {
596 			mh = ml_dequeue(&la->la_ml);
597 			la_hold_total--;
598 
599 			ifp->if_output(ifp, mh, rt_key(rt), rt);
600 
601 			if (ml_len(&la->la_ml) == len) {
602 				/* mbuf is back in queue. Discard. */
603 				while ((mh = ml_dequeue(&la->la_ml)) != NULL) {
604 					la_hold_total--;
605 					m_freem(mh);
606 				}
607 				break;
608 			}
609 		}
610 	}
611 
612 	if (op != ARPOP_REQUEST) {
613 out:
614 		rtfree(rt);
615 		if_put(ifp);
616 		m_freem(m);
617 		return;
618 	}
619 
620 	rtfree(rt);
621 	if (target) {
622 		/* We are the target and already have all info for the reply */
623 		memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
624 		memcpy(ea->arp_sha, LLADDR(ifp->if_sadl), sizeof(ea->arp_sha));
625 	} else {
626 		rt = arplookup(itaddr.s_addr, 0, SIN_PROXY, rdomain);
627 		if (rt == NULL)
628 			goto out;
629 		/* protect from possible duplicates only owner should respond */
630 		if (rt->rt_ifidx != ifp->if_index)
631 			goto out;
632 		memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
633 		sdl = satosdl(rt->rt_gateway);
634 		memcpy(ea->arp_sha, LLADDR(sdl), sizeof(ea->arp_sha));
635 		rtfree(rt);
636 	}
637 
638 	memcpy(ea->arp_tpa, ea->arp_spa, sizeof(ea->arp_spa));
639 	memcpy(ea->arp_spa, &itaddr, sizeof(ea->arp_spa));
640 	ea->arp_op = htons(ARPOP_REPLY);
641 	ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
642 	eh = (struct ether_header *)sa.sa_data;
643 	memcpy(eh->ether_dhost, ea->arp_tha, sizeof(eh->ether_dhost));
644 	memcpy(eh->ether_shost, enaddr, sizeof(eh->ether_shost));
645 
646 	eh->ether_type = htons(ETHERTYPE_ARP);
647 	sa.sa_family = pseudo_AF_HDRCMPLT;
648 	sa.sa_len = sizeof(sa);
649 	ifp->if_output(ifp, m, &sa, NULL);
650 	if_put(ifp);
651 }
652 
653 /*
654  * Free an arp entry.
655  */
656 void
657 arptfree(struct rtentry *rt)
658 {
659 	struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
660 	struct sockaddr_dl *sdl = satosdl(rt->rt_gateway);
661 	struct ifnet *ifp;
662 
663 	ifp = if_get(rt->rt_ifidx);
664 	if ((sdl != NULL) && (sdl->sdl_family == AF_LINK)) {
665 		sdl->sdl_alen = 0;
666 		la->la_asked = 0;
667 	}
668 
669 	if (!ISSET(rt->rt_flags, RTF_STATIC))
670 		rtdeletemsg(rt, ifp, ifp->if_rdomain);
671 	if_put(ifp);
672 }
673 
674 /*
675  * Lookup or enter a new address in arptab.
676  */
677 struct rtentry *
678 arplookup(u_int32_t addr, int create, int proxy, u_int tableid)
679 {
680 	struct rtentry *rt;
681 	struct sockaddr_inarp sin;
682 	int flags;
683 
684 	memset(&sin, 0, sizeof(sin));
685 	sin.sin_len = sizeof(sin);
686 	sin.sin_family = AF_INET;
687 	sin.sin_addr.s_addr = addr;
688 	sin.sin_other = proxy ? SIN_PROXY : 0;
689 	flags = (create) ? RT_RESOLVE : 0;
690 
691 	rt = rtalloc((struct sockaddr *)&sin, flags, tableid);
692 	if (!rtisvalid(rt) || ISSET(rt->rt_flags, RTF_GATEWAY) ||
693 	    !ISSET(rt->rt_flags, RTF_LLINFO) ||
694 	    rt->rt_gateway->sa_family != AF_LINK) {
695 		rtfree(rt);
696 		return (NULL);
697 	}
698 
699 	if (proxy && !ISSET(rt->rt_flags, RTF_ANNOUNCE)) {
700 		struct rtentry *mrt = NULL;
701 #if defined(ART) && !defined(SMALL_KERNEL)
702 		mrt = rt;
703 		KERNEL_LOCK();
704 		while ((mrt = rtable_mpath_next(mrt)) != NULL) {
705 			if (ISSET(mrt->rt_flags, RTF_ANNOUNCE)) {
706 				rtref(mrt);
707 				break;
708 			}
709 		}
710 		KERNEL_UNLOCK();
711 #endif /* ART && !SMALL_KERNEL */
712 		rtfree(rt);
713 		return (mrt);
714 	}
715 
716 	return (rt);
717 }
718 
719 /*
720  * Check whether we do proxy ARP for this address and we point to ourselves.
721  */
722 int
723 arpproxy(struct in_addr in, unsigned int rtableid)
724 {
725 	struct sockaddr_dl *sdl;
726 	struct rtentry *rt;
727 	struct ifnet *ifp;
728 	int found = 0;
729 
730 	rt = arplookup(in.s_addr, 0, SIN_PROXY, rtableid);
731 	if (!rtisvalid(rt)) {
732 		rtfree(rt);
733 		return (0);
734 	}
735 
736 	/* Check that arp information are correct. */
737 	sdl = satosdl(rt->rt_gateway);
738 	if (sdl->sdl_alen != ETHER_ADDR_LEN) {
739 		rtfree(rt);
740 		return (0);
741 	}
742 
743 	ifp = if_get(rt->rt_ifidx);
744 	if (ifp == NULL) {
745 		rtfree(rt);
746 		return (0);
747 	}
748 
749 	if (!memcmp(LLADDR(sdl), LLADDR(ifp->if_sadl), sdl->sdl_alen))
750 		found = 1;
751 
752 	if_put(ifp);
753 	rtfree(rt);
754 	return (found);
755 }
756 
757 /*
758  * Called from Ethernet interrupt handlers
759  * when ether packet type ETHERTYPE_REVARP
760  * is received.  Common length and type checks are done here,
761  * then the protocol-specific routine is called.
762  */
763 void
764 revarpinput(struct mbuf *m)
765 {
766 	struct arphdr *ar;
767 
768 	if (m->m_len < sizeof(struct arphdr))
769 		goto out;
770 	ar = mtod(m, struct arphdr *);
771 	if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
772 		goto out;
773 	if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
774 		goto out;
775 	switch (ntohs(ar->ar_pro)) {
776 
777 	case ETHERTYPE_IP:
778 		in_revarpinput(m);
779 		return;
780 
781 	default:
782 		break;
783 	}
784 out:
785 	m_freem(m);
786 }
787 
788 /*
789  * RARP for Internet protocols on Ethernet.
790  * Algorithm is that given in RFC 903.
791  * We are only using for bootstrap purposes to get an ip address for one of
792  * our interfaces.  Thus we support no user-interface.
793  *
794  * Since the contents of the RARP reply are specific to the interface that
795  * sent the request, this code must ensure that they are properly associated.
796  *
797  * Note: also supports ARP via RARP packets, per the RFC.
798  */
799 void
800 in_revarpinput(struct mbuf *m)
801 {
802 	struct ifnet *ifp = NULL;
803 	struct ether_arp *ar;
804 	int op;
805 
806 	ar = mtod(m, struct ether_arp *);
807 	op = ntohs(ar->arp_op);
808 	switch (op) {
809 	case ARPOP_REQUEST:
810 	case ARPOP_REPLY:	/* per RFC */
811 		in_arpinput(m);
812 		return;
813 	case ARPOP_REVREPLY:
814 		break;
815 	case ARPOP_REVREQUEST:	/* handled by rarpd(8) */
816 	default:
817 		goto out;
818 	}
819 #ifdef NFSCLIENT
820 	if (revarp_ifidx == 0)
821 		goto out;
822 	if (revarp_ifidx != m->m_pkthdr.ph_ifidx) /* !same interface */
823 		goto out;
824 	if (revarp_finished)
825 		goto wake;
826 	ifp = if_get(revarp_ifidx);
827 	if (ifp == NULL)
828 		goto out;
829 	if (memcmp(ar->arp_tha, LLADDR(ifp->if_sadl), sizeof(ar->arp_tha)))
830 		goto out;
831 	memcpy(&revarp_srvip, ar->arp_spa, sizeof(revarp_srvip));
832 	memcpy(&revarp_myip, ar->arp_tpa, sizeof(revarp_myip));
833 	revarp_finished = 1;
834 wake:	/* Do wakeup every time in case it was missed. */
835 	wakeup((caddr_t)&revarp_myip);
836 #endif
837 
838 out:
839 	m_freem(m);
840 	if_put(ifp);
841 }
842 
843 /*
844  * Send a RARP request for the ip address of the specified interface.
845  * The request should be RFC 903-compliant.
846  */
847 void
848 revarprequest(struct ifnet *ifp)
849 {
850 	struct sockaddr sa;
851 	struct mbuf *m;
852 	struct ether_header *eh;
853 	struct ether_arp *ea;
854 	struct arpcom *ac = (struct arpcom *)ifp;
855 
856 	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
857 		return;
858 	m->m_len = sizeof(*ea);
859 	m->m_pkthdr.len = sizeof(*ea);
860 	MH_ALIGN(m, sizeof(*ea));
861 	ea = mtod(m, struct ether_arp *);
862 	eh = (struct ether_header *)sa.sa_data;
863 	memset(ea, 0, sizeof(*ea));
864 	memcpy(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost));
865 	eh->ether_type = htons(ETHERTYPE_REVARP);
866 	ea->arp_hrd = htons(ARPHRD_ETHER);
867 	ea->arp_pro = htons(ETHERTYPE_IP);
868 	ea->arp_hln = sizeof(ea->arp_sha);	/* hardware address length */
869 	ea->arp_pln = sizeof(ea->arp_spa);	/* protocol address length */
870 	ea->arp_op = htons(ARPOP_REVREQUEST);
871 	memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(ea->arp_tha));
872 	memcpy(ea->arp_sha, ac->ac_enaddr, sizeof(ea->arp_sha));
873 	memcpy(ea->arp_tha, ac->ac_enaddr, sizeof(ea->arp_tha));
874 	sa.sa_family = pseudo_AF_HDRCMPLT;
875 	sa.sa_len = sizeof(sa);
876 	m->m_flags |= M_BCAST;
877 	ifp->if_output(ifp, m, &sa, NULL);
878 }
879 
880 #ifdef NFSCLIENT
881 /*
882  * RARP for the ip address of the specified interface, but also
883  * save the ip address of the server that sent the answer.
884  * Timeout if no response is received.
885  */
886 int
887 revarpwhoarewe(struct ifnet *ifp, struct in_addr *serv_in,
888     struct in_addr *clnt_in)
889 {
890 	int result, count = 20;
891 
892 	if (revarp_finished)
893 		return EIO;
894 
895 	revarp_ifidx = ifp->if_index;
896 	while (count--) {
897 		revarprequest(ifp);
898 		result = tsleep((caddr_t)&revarp_myip, PSOCK, "revarp", hz/2);
899 		if (result != EWOULDBLOCK)
900 			break;
901 	}
902 	revarp_ifidx = 0;
903 	if (!revarp_finished)
904 		return ENETUNREACH;
905 
906 	memcpy(serv_in, &revarp_srvip, sizeof(*serv_in));
907 	memcpy(clnt_in, &revarp_myip, sizeof(*clnt_in));
908 	return 0;
909 }
910 
911 /* For compatibility: only saves interface address. */
912 int
913 revarpwhoami(struct in_addr *in, struct ifnet *ifp)
914 {
915 	struct in_addr server;
916 	return (revarpwhoarewe(ifp, &server, in));
917 }
918 #endif /* NFSCLIENT */
919