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