if_ether.c revision 1542
1/*
2 * Copyright (c) 1982, 1986, 1988, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *	@(#)if_ether.c	8.1 (Berkeley) 6/10/93
34 */
35
36/*
37 * Ethernet address resolution protocol.
38 * TODO:
39 *	add "inuse/lock" bit (or ref. count) along with valid bit
40 */
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/malloc.h>
45#include <sys/mbuf.h>
46#include <sys/socket.h>
47#include <sys/time.h>
48#include <sys/kernel.h>
49#include <sys/errno.h>
50#include <sys/ioctl.h>
51#include <sys/syslog.h>
52
53#include <net/if.h>
54#include <net/if_dl.h>
55#include <net/route.h>
56
57#include <netinet/in.h>
58#include <netinet/in_systm.h>
59#include <netinet/in_var.h>
60#include <netinet/ip.h>
61#include <netinet/if_ether.h>
62
63#define SIN(s) ((struct sockaddr_in *)s)
64#define SDL(s) ((struct sockaddr_dl *)s)
65#define SRP(s) ((struct sockaddr_inarp *)s)
66
67/*
68 * ARP trailer negotiation.  Trailer protocol is not IP specific,
69 * but ARP request/response use IP addresses.
70 */
71#define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
72
73
74/* timer values */
75int	arpt_prune = (5*60*1);	/* walk list every 5 minutes */
76int	arpt_keep = (20*60);	/* once resolved, good for 20 more minutes */
77int	arpt_down = 20;		/* once declared down, don't send for 20 secs */
78#define	rt_expire rt_rmx.rmx_expire
79
80static	void arprequest __P((struct arpcom *, u_long *, u_long *, u_char *));
81static	void arptfree __P((struct llinfo_arp *));
82static	void arptimer __P((void *));
83static	struct llinfo_arp *arplookup __P((u_long, int, int));
84static	void in_arpinput __P((struct mbuf *));
85
86extern	struct ifnet loif;
87extern	struct timeval time;
88struct	llinfo_arp llinfo_arp = {&llinfo_arp, &llinfo_arp};
89struct	ifqueue arpintrq = {0, 0, 0, 50};
90int	arp_inuse, arp_allocated, arp_intimer;
91int	arp_maxtries = 5;
92int	useloopback = 1;	/* use loopback interface for local traffic */
93int	arpinit_done = 0;
94
95/*
96 * Timeout routine.  Age arp_tab entries periodically.
97 */
98/* ARGSUSED */
99static void
100arptimer(ignored_arg)
101	void *ignored_arg;
102{
103	int s = splnet();
104	register struct llinfo_arp *la = llinfo_arp.la_next;
105
106	timeout(arptimer, (caddr_t)0, arpt_prune * hz);
107	while (la != &llinfo_arp) {
108		register struct rtentry *rt = la->la_rt;
109		la = la->la_next;
110		if (rt->rt_expire && rt->rt_expire <= time.tv_sec)
111			arptfree(la->la_prev); /* timer has expired, clear */
112	}
113	splx(s);
114}
115
116/*
117 * Parallel to llc_rtrequest.
118 */
119void
120arp_rtrequest(req, rt, sa)
121	int req;
122	register struct rtentry *rt;
123	struct sockaddr *sa;
124{
125	register struct sockaddr *gate = rt->rt_gateway;
126	register struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
127	static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
128
129	if (!arpinit_done) {
130		arpinit_done = 1;
131		timeout(arptimer, (caddr_t)0, hz);
132	}
133	if (rt->rt_flags & RTF_GATEWAY)
134		return;
135	switch (req) {
136
137	case RTM_ADD:
138		/*
139		 * XXX: If this is a manually added route to interface
140		 * such as older version of routed or gated might provide,
141		 * restore cloning bit.
142		 */
143		if ((rt->rt_flags & RTF_HOST) == 0 &&
144		    SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
145			rt->rt_flags |= RTF_CLONING;
146		if (rt->rt_flags & RTF_CLONING) {
147			/*
148			 * Case 1: This route should come from a route to iface.
149			 */
150			rt_setgate(rt, rt_key(rt),
151					(struct sockaddr *)&null_sdl);
152			gate = rt->rt_gateway;
153			SDL(gate)->sdl_type = rt->rt_ifp->if_type;
154			SDL(gate)->sdl_index = rt->rt_ifp->if_index;
155			rt->rt_expire = time.tv_sec;
156			break;
157		}
158		/* Announce a new entry if requested. */
159		if (rt->rt_flags & RTF_ANNOUNCE)
160			arprequest((struct arpcom *)rt->rt_ifp,
161			    &SIN(rt_key(rt))->sin_addr.s_addr,
162			    &SIN(rt_key(rt))->sin_addr.s_addr,
163			    (u_char *)LLADDR(SDL(gate)));
164		/*FALLTHROUGH*/
165	case RTM_RESOLVE:
166		if (gate->sa_family != AF_LINK ||
167		    gate->sa_len < sizeof(null_sdl)) {
168			log(LOG_DEBUG, "arp_rtrequest: bad gateway value");
169			break;
170		}
171		SDL(gate)->sdl_type = rt->rt_ifp->if_type;
172		SDL(gate)->sdl_index = rt->rt_ifp->if_index;
173		if (la != 0)
174			break; /* This happens on a route change */
175		/*
176		 * Case 2:  This route may come from cloning, or a manual route
177		 * add with a LL address.
178		 */
179		R_Malloc(la, struct llinfo_arp *, sizeof(*la));
180		rt->rt_llinfo = (caddr_t)la;
181		if (la == 0) {
182			log(LOG_DEBUG, "arp_rtrequest: malloc failed\n");
183			break;
184		}
185		arp_inuse++, arp_allocated++;
186		Bzero(la, sizeof(*la));
187		la->la_rt = rt;
188		rt->rt_flags |= RTF_LLINFO;
189		insque(la, &llinfo_arp);
190		if (SIN(rt_key(rt))->sin_addr.s_addr ==
191		    (IA_SIN(rt->rt_ifa))->sin_addr.s_addr) {
192		    /*
193		     * This test used to be
194		     *	if (loif.if_flags & IFF_UP)
195		     * It allowed local traffic to be forced
196		     * through the hardware by configuring the loopback down.
197		     * However, it causes problems during network configuration
198		     * for boards that can't receive packets they send.
199		     * It is now necessary to clear "useloopback" and remove
200		     * the route to force traffic out to the hardware.
201		     */
202			rt->rt_expire = 0;
203			Bcopy(((struct arpcom *)rt->rt_ifp)->ac_enaddr,
204				LLADDR(SDL(gate)), SDL(gate)->sdl_alen = 6);
205			if (useloopback)
206				rt->rt_ifp = &loif;
207
208		}
209		break;
210
211	case RTM_DELETE:
212		if (la == 0)
213			break;
214		arp_inuse--;
215		remque(la);
216		rt->rt_llinfo = 0;
217		rt->rt_flags &= ~RTF_LLINFO;
218		if (la->la_hold)
219			m_freem(la->la_hold);
220		Free((caddr_t)la);
221	}
222}
223
224/*
225 * Broadcast an ARP packet, asking who has addr on interface ac.
226 */
227void
228arpwhohas(ac, addr)
229	register struct arpcom *ac;
230	register struct in_addr *addr;
231{
232	arprequest(ac, &ac->ac_ipaddr.s_addr, &addr->s_addr, ac->ac_enaddr);
233}
234
235/*
236 * Broadcast an ARP request. Caller specifies:
237 *	- arp header source ip address
238 *	- arp header target ip address
239 *	- arp header source ethernet address
240 */
241static void
242arprequest(ac, sip, tip, enaddr)
243	register struct arpcom *ac;
244	register u_long *sip, *tip;
245	register u_char *enaddr;
246{
247	register struct mbuf *m;
248	register struct ether_header *eh;
249	register struct ether_arp *ea;
250	struct sockaddr sa;
251
252	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
253		return;
254	m->m_len = sizeof(*ea);
255	m->m_pkthdr.len = sizeof(*ea);
256	MH_ALIGN(m, sizeof(*ea));
257	ea = mtod(m, struct ether_arp *);
258	eh = (struct ether_header *)sa.sa_data;
259	bzero((caddr_t)ea, sizeof (*ea));
260	bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
261	    sizeof(eh->ether_dhost));
262	eh->ether_type = ETHERTYPE_ARP;		/* if_output will swap */
263	ea->arp_hrd = htons(ARPHRD_ETHER);
264	ea->arp_pro = htons(ETHERTYPE_IP);
265	ea->arp_hln = sizeof(ea->arp_sha);	/* hardware address length */
266	ea->arp_pln = sizeof(ea->arp_spa);	/* protocol address length */
267	ea->arp_op = htons(ARPOP_REQUEST);
268	bcopy((caddr_t)enaddr, (caddr_t)ea->arp_sha, sizeof(ea->arp_sha));
269	bcopy((caddr_t)sip, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));
270	bcopy((caddr_t)tip, (caddr_t)ea->arp_tpa, sizeof(ea->arp_tpa));
271	sa.sa_family = AF_UNSPEC;
272	sa.sa_len = sizeof(sa);
273	(*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
274}
275
276/*
277 * Resolve an IP address into an ethernet address.  If success,
278 * desten is filled in.  If there is no entry in arptab,
279 * set one up and broadcast a request for the IP address.
280 * Hold onto this mbuf and resend it once the address
281 * is finally resolved.  A return value of 1 indicates
282 * that desten has been filled in and the packet should be sent
283 * normally; a 0 return indicates that the packet has been
284 * taken over here, either now or for later transmission.
285 */
286int
287arpresolve(ac, rt, m, dst, desten)
288	register struct arpcom *ac;
289	register struct rtentry *rt;
290	struct mbuf *m;
291	register struct sockaddr *dst;
292	register u_char *desten;
293{
294	register struct llinfo_arp *la;
295	struct sockaddr_dl *sdl;
296
297	if (m->m_flags & M_BCAST) {	/* broadcast */
298		bcopy((caddr_t)etherbroadcastaddr, (caddr_t)desten,
299		    sizeof(etherbroadcastaddr));
300		return (1);
301	}
302	if (m->m_flags & M_MCAST) {	/* multicast */
303		ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
304		return(1);
305	}
306	if (rt)
307		la = (struct llinfo_arp *)rt->rt_llinfo;
308	else {
309		if (la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0))
310			rt = la->la_rt;
311	}
312	if (la == 0 || rt == 0) {
313		log(LOG_DEBUG, "arpresolve: can't allocate llinfo");
314		m_freem(m);
315		return (0);
316	}
317	sdl = SDL(rt->rt_gateway);
318	/*
319	 * Check the address family and length is valid, the address
320	 * is resolved; otherwise, try to resolve.
321	 */
322	if ((rt->rt_expire == 0 || rt->rt_expire > time.tv_sec) &&
323	    sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
324		bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
325		return 1;
326	}
327	/*
328	 * There is an arptab entry, but no ethernet address
329	 * response yet.  Replace the held mbuf with this
330	 * latest one.
331	 */
332	if (la->la_hold)
333		m_freem(la->la_hold);
334	la->la_hold = m;
335	if (rt->rt_expire) {
336		rt->rt_flags &= ~RTF_REJECT;
337		if (la->la_asked == 0 || rt->rt_expire != time.tv_sec) {
338			rt->rt_expire = time.tv_sec;
339			if (la->la_asked++ < arp_maxtries)
340				arpwhohas(ac, &(SIN(dst)->sin_addr));
341			else {
342				rt->rt_flags |= RTF_REJECT;
343				rt->rt_expire += arpt_down;
344				la->la_asked = 0;
345			}
346
347		}
348	}
349	return (0);
350}
351
352/*
353 * Common length and type checks are done here,
354 * then the protocol-specific routine is called.
355 */
356void
357arpintr()
358{
359	register struct mbuf *m;
360	register struct arphdr *ar;
361	int s;
362
363	while (arpintrq.ifq_head) {
364		s = splimp();
365		IF_DEQUEUE(&arpintrq, m);
366		splx(s);
367		if (m == 0 || (m->m_flags & M_PKTHDR) == 0)
368			panic("arpintr");
369		if (m->m_len >= sizeof(struct arphdr) &&
370		    (ar = mtod(m, struct arphdr *)) &&
371		    ntohs(ar->ar_hrd) == ARPHRD_ETHER &&
372		    m->m_len >=
373		      sizeof(struct arphdr) + 2 * ar->ar_hln + 2 * ar->ar_pln)
374
375			    switch (ntohs(ar->ar_pro)) {
376
377			    case ETHERTYPE_IP:
378			    case ETHERTYPE_IPTRAILERS:
379				    in_arpinput(m);
380				    continue;
381			    }
382		m_freem(m);
383	}
384}
385
386/*
387 * ARP for Internet protocols on 10 Mb/s Ethernet.
388 * Algorithm is that given in RFC 826.
389 * In addition, a sanity check is performed on the sender
390 * protocol address, to catch impersonators.
391 * We no longer handle negotiations for use of trailer protocol:
392 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent
393 * along with IP replies if we wanted trailers sent to us,
394 * and also sent them in response to IP replies.
395 * This allowed either end to announce the desire to receive
396 * trailer packets.
397 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
398 * but formerly didn't normally send requests.
399 */
400static void
401in_arpinput(m)
402	struct mbuf *m;
403{
404	register struct ether_arp *ea;
405	register struct arpcom *ac = (struct arpcom *)m->m_pkthdr.rcvif;
406	struct ether_header *eh;
407	register struct llinfo_arp *la = 0;
408	register struct rtentry *rt;
409	struct in_ifaddr *ia, *maybe_ia = 0;
410	struct sockaddr_dl *sdl;
411	struct sockaddr sa;
412	struct in_addr isaddr, itaddr, myaddr;
413	int op;
414
415	ea = mtod(m, struct ether_arp *);
416	op = ntohs(ea->arp_op);
417	bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr, sizeof (isaddr));
418	bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr, sizeof (itaddr));
419	for (ia = in_ifaddr; ia; ia = ia->ia_next)
420		if (ia->ia_ifp == &ac->ac_if) {
421			maybe_ia = ia;
422			if ((itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) ||
423			     (isaddr.s_addr == ia->ia_addr.sin_addr.s_addr))
424				break;
425		}
426	if (maybe_ia == 0)
427		goto out;
428	myaddr = ia ? ia->ia_addr.sin_addr : maybe_ia->ia_addr.sin_addr;
429	if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)ac->ac_enaddr,
430	    sizeof (ea->arp_sha)))
431		goto out;	/* it's from me, ignore it. */
432	if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr,
433	    sizeof (ea->arp_sha))) {
434		log(LOG_ERR,
435		    "arp: ether address is broadcast for IP address %x!\n",
436		    ntohl(isaddr.s_addr));
437		goto out;
438	}
439	if (isaddr.s_addr == myaddr.s_addr) {
440		log(LOG_ERR,
441		   "duplicate IP address %x!! sent from ethernet address: %s\n",
442		   ntohl(isaddr.s_addr), ether_sprintf(ea->arp_sha));
443		itaddr = myaddr;
444		goto reply;
445	}
446	la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);
447	if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
448		if (sdl->sdl_alen &&
449		    bcmp((caddr_t)ea->arp_sha, LLADDR(sdl), sdl->sdl_alen))
450			log(LOG_INFO, "arp info overwritten for %x by %s\n",
451			    isaddr.s_addr, ether_sprintf(ea->arp_sha));
452		bcopy((caddr_t)ea->arp_sha, LLADDR(sdl),
453			    sdl->sdl_alen = sizeof(ea->arp_sha));
454		if (rt->rt_expire)
455			rt->rt_expire = time.tv_sec + arpt_keep;
456		rt->rt_flags &= ~RTF_REJECT;
457		la->la_asked = 0;
458		if (la->la_hold) {
459			(*ac->ac_if.if_output)(&ac->ac_if, la->la_hold,
460				rt_key(rt), rt);
461			la->la_hold = 0;
462		}
463	}
464reply:
465	if (op != ARPOP_REQUEST) {
466	out:
467		m_freem(m);
468		return;
469	}
470	if (itaddr.s_addr == myaddr.s_addr) {
471		/* I am the target */
472		bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
473		    sizeof(ea->arp_sha));
474		bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
475		    sizeof(ea->arp_sha));
476	} else {
477		la = arplookup(itaddr.s_addr, 0, SIN_PROXY);
478		if (la == NULL)
479			goto out;
480		rt = la->la_rt;
481		bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
482		    sizeof(ea->arp_sha));
483		sdl = SDL(rt->rt_gateway);
484		bcopy(LLADDR(sdl), (caddr_t)ea->arp_sha, sizeof(ea->arp_sha));
485	}
486
487	bcopy((caddr_t)ea->arp_spa, (caddr_t)ea->arp_tpa, sizeof(ea->arp_spa));
488	bcopy((caddr_t)&itaddr, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));
489	ea->arp_op = htons(ARPOP_REPLY);
490	ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
491	eh = (struct ether_header *)sa.sa_data;
492	bcopy((caddr_t)ea->arp_tha, (caddr_t)eh->ether_dhost,
493	    sizeof(eh->ether_dhost));
494	eh->ether_type = ETHERTYPE_ARP;
495	sa.sa_family = AF_UNSPEC;
496	sa.sa_len = sizeof(sa);
497	(*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
498	return;
499}
500
501/*
502 * Free an arp entry.
503 */
504static void
505arptfree(la)
506	register struct llinfo_arp *la;
507{
508	register struct rtentry *rt = la->la_rt;
509	register struct sockaddr_dl *sdl;
510	if (rt == 0)
511		panic("arptfree");
512	if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&
513	    sdl->sdl_family == AF_LINK) {
514		sdl->sdl_alen = 0;
515		la->la_asked = 0;
516		rt->rt_flags &= ~RTF_REJECT;
517		return;
518	}
519	rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt),
520			0, (struct rtentry **)0);
521}
522/*
523 * Lookup or enter a new address in arptab.
524 */
525static struct llinfo_arp *
526arplookup(addr, create, proxy)
527	u_long addr;
528	int create, proxy;
529{
530	register struct rtentry *rt;
531	static struct sockaddr_inarp sin = {sizeof(sin), AF_INET };
532
533	sin.sin_addr.s_addr = addr;
534	sin.sin_other = proxy ? SIN_PROXY : 0;
535	rt = rtalloc1((struct sockaddr *)&sin, create);
536	if (rt == 0)
537		return (0);
538	rt->rt_refcnt--;
539	if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
540	    rt->rt_gateway->sa_family != AF_LINK) {
541		if (create)
542			log(LOG_DEBUG, "arptnew failed on %x\n", ntohl(addr));
543		return (0);
544	}
545	return ((struct llinfo_arp *)rt->rt_llinfo);
546}
547
548int
549arpioctl(cmd, data)
550	int cmd;
551	caddr_t data;
552{
553	return (EOPNOTSUPP);
554}
555