xref: /openbsd-src/sys/net/if_ethersubr.c (revision de8cc8edbc71bd3e3bc7fbffa27ba0e564c37d8b)
1 /*	$OpenBSD: if_ethersubr.c,v 1.271 2021/02/26 01:12:37 dlg Exp $	*/
2 /*	$NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $	*/
3 
4 /*
5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6  * 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 project 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 PROJECT 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 PROJECT 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 
33 /*
34  * Copyright (c) 1982, 1989, 1993
35  *	The Regents of the University of California.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. Neither the name of the University nor the names of its contributors
46  *    may be used to endorse or promote products derived from this software
47  *    without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59  * SUCH DAMAGE.
60  *
61  *	@(#)if_ethersubr.c	8.1 (Berkeley) 6/10/93
62  */
63 
64 /*
65 %%% portions-copyright-nrl-95
66 Portions of this software are Copyright 1995-1998 by Randall Atkinson,
67 Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
68 Reserved. All rights under this copyright have been assigned to the US
69 Naval Research Laboratory (NRL). The NRL Copyright Notice and License
70 Agreement Version 1.1 (January 17, 1995) applies to these portions of the
71 software.
72 You should have received a copy of the license with this software. If you
73 didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
74 */
75 
76 #include "bpfilter.h"
77 
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/kernel.h>
81 #include <sys/malloc.h>
82 #include <sys/mbuf.h>
83 #include <sys/protosw.h>
84 #include <sys/socket.h>
85 #include <sys/ioctl.h>
86 #include <sys/errno.h>
87 #include <sys/syslog.h>
88 #include <sys/timeout.h>
89 #include <sys/smr.h>
90 
91 #include <net/if.h>
92 #include <net/netisr.h>
93 #include <net/route.h>
94 #include <net/if_llc.h>
95 #include <net/if_dl.h>
96 #include <net/if_media.h>
97 #include <net/if_types.h>
98 
99 #include <netinet/in.h>
100 #include <netinet/if_ether.h>
101 #include <netinet/ip_ipsp.h>
102 
103 #if NBPFILTER > 0
104 #include <net/bpf.h>
105 #endif
106 
107 #include "vlan.h"
108 #if NVLAN > 0
109 #include <net/if_vlan_var.h>
110 #endif
111 
112 #include "carp.h"
113 #if NCARP > 0
114 #include <netinet/ip_carp.h>
115 #endif
116 
117 #include "pppoe.h"
118 #if NPPPOE > 0
119 #include <net/if_pppoe.h>
120 #endif
121 
122 #include "bpe.h"
123 #if NBPE > 0
124 #include <net/if_bpe.h>
125 #endif
126 
127 #ifdef INET6
128 #include <netinet6/in6_var.h>
129 #include <netinet6/nd6.h>
130 #endif
131 
132 #ifdef PIPEX
133 #include <net/pipex.h>
134 #endif
135 
136 #ifdef MPLS
137 #include <netmpls/mpls.h>
138 #endif /* MPLS */
139 
140 u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN] =
141     { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
142 u_int8_t etheranyaddr[ETHER_ADDR_LEN] =
143     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
144 #define senderr(e) { error = (e); goto bad;}
145 
146 int
147 ether_ioctl(struct ifnet *ifp, struct arpcom *arp, u_long cmd, caddr_t data)
148 {
149 	struct ifreq *ifr = (struct ifreq *)data;
150 	int error = 0;
151 
152 	switch (cmd) {
153 	case SIOCSIFADDR:
154 		break;
155 
156 	case SIOCSIFMTU:
157 		if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
158 			error = EINVAL;
159 		else
160 			ifp->if_mtu = ifr->ifr_mtu;
161 		break;
162 
163 	case SIOCADDMULTI:
164 	case SIOCDELMULTI:
165 		if (ifp->if_flags & IFF_MULTICAST) {
166 			error = (cmd == SIOCADDMULTI) ?
167 			    ether_addmulti(ifr, arp) :
168 			    ether_delmulti(ifr, arp);
169 		} else
170 			error = ENOTTY;
171 		break;
172 
173 	default:
174 		error = ENOTTY;
175 	}
176 
177 	return (error);
178 }
179 
180 
181 void
182 ether_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
183 {
184 	if (rt == NULL)
185 		return;
186 
187 	switch (rt_key(rt)->sa_family) {
188 	case AF_INET:
189 		arp_rtrequest(ifp, req, rt);
190 		break;
191 #ifdef INET6
192 	case AF_INET6:
193 		nd6_rtrequest(ifp, req, rt);
194 		break;
195 #endif
196 	default:
197 		break;
198 	}
199 }
200 
201 int
202 ether_resolve(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
203     struct rtentry *rt, struct ether_header *eh)
204 {
205 	struct arpcom *ac = (struct arpcom *)ifp;
206 	sa_family_t af = dst->sa_family;
207 	int error = 0;
208 
209 	if (!ISSET(ifp->if_flags, IFF_RUNNING))
210 		senderr(ENETDOWN);
211 
212 	KASSERT(rt != NULL || ISSET(m->m_flags, M_MCAST|M_BCAST) ||
213 		af == AF_UNSPEC || af == pseudo_AF_HDRCMPLT);
214 
215 #ifdef DIAGNOSTIC
216 	if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
217 		printf("%s: trying to send packet on wrong domain. "
218 		    "if %d vs. mbuf %d\n", ifp->if_xname,
219 		    ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid));
220 	}
221 #endif
222 
223 	switch (af) {
224 	case AF_INET:
225 		error = arpresolve(ifp, rt, m, dst, eh->ether_dhost);
226 		if (error)
227 			return (error);
228 		eh->ether_type = htons(ETHERTYPE_IP);
229 
230 		/*
231 		 * If broadcasting on a simplex interface, loopback a copy.
232 		 * The checksum must be calculated in software.  Keep the
233 		 * condition in sync with in_ifcap_cksum().
234 		 */
235 		if (ISSET(m->m_flags, M_BCAST) &&
236 		    ISSET(ifp->if_flags, IFF_SIMPLEX) &&
237 		    !m->m_pkthdr.pf.routed) {
238 			struct mbuf *mcopy;
239 
240 			/* XXX Should we input an unencrypted IPsec packet? */
241 			mcopy = m_copym(m, 0, M_COPYALL, M_NOWAIT);
242 			if (mcopy != NULL)
243 				if_input_local(ifp, mcopy, af);
244 		}
245 		break;
246 #ifdef INET6
247 	case AF_INET6:
248 		error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost);
249 		if (error)
250 			return (error);
251 		eh->ether_type = htons(ETHERTYPE_IPV6);
252 		break;
253 #endif
254 #ifdef MPLS
255 	case AF_MPLS:
256 		if (rt == NULL)
257 			senderr(EHOSTUNREACH);
258 
259 		if (!ISSET(ifp->if_xflags, IFXF_MPLS))
260 			senderr(ENETUNREACH);
261 
262 		dst = ISSET(rt->rt_flags, RTF_GATEWAY) ?
263 		    rt->rt_gateway : rt_key(rt);
264 
265 		switch (dst->sa_family) {
266 		case AF_LINK:
267 			if (satosdl(dst)->sdl_alen < sizeof(eh->ether_dhost))
268 				senderr(EHOSTUNREACH);
269 			memcpy(eh->ether_dhost, LLADDR(satosdl(dst)),
270 			    sizeof(eh->ether_dhost));
271 			break;
272 #ifdef INET6
273 		case AF_INET6:
274 			error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost);
275 			if (error)
276 				return (error);
277 			break;
278 #endif
279 		case AF_INET:
280 			error = arpresolve(ifp, rt, m, dst, eh->ether_dhost);
281 			if (error)
282 				return (error);
283 			break;
284 		default:
285 			senderr(EHOSTUNREACH);
286 		}
287 		/* XXX handling for simplex devices in case of M/BCAST ?? */
288 		if (m->m_flags & (M_BCAST | M_MCAST))
289 			eh->ether_type = htons(ETHERTYPE_MPLS_MCAST);
290 		else
291 			eh->ether_type = htons(ETHERTYPE_MPLS);
292 		break;
293 #endif /* MPLS */
294 	case pseudo_AF_HDRCMPLT:
295 		/* take the whole header from the sa */
296 		memcpy(eh, dst->sa_data, sizeof(*eh));
297 		return (0);
298 
299 	case AF_UNSPEC:
300 		/* take the dst and type from the sa, but get src below */
301 		memcpy(eh, dst->sa_data, sizeof(*eh));
302 		break;
303 
304 	default:
305 		printf("%s: can't handle af%d\n", ifp->if_xname, af);
306 		senderr(EAFNOSUPPORT);
307 	}
308 
309 	memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(eh->ether_shost));
310 
311 	return (0);
312 
313 bad:
314 	m_freem(m);
315 	return (error);
316 }
317 
318 struct mbuf*
319 ether_encap(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
320     struct rtentry *rt, int *errorp)
321 {
322 	struct ether_header eh;
323 	int error;
324 
325 	error = ether_resolve(ifp, m, dst, rt, &eh);
326 	switch (error) {
327 	case 0:
328 		break;
329 	case EAGAIN:
330 		error = 0;
331 	default:
332 		*errorp = error;
333 		return (NULL);
334 	}
335 
336 	m = m_prepend(m, ETHER_ALIGN + sizeof(eh), M_DONTWAIT);
337 	if (m == NULL) {
338 		*errorp = ENOBUFS;
339 		return (NULL);
340 	}
341 
342 	m_adj(m, ETHER_ALIGN);
343 	memcpy(mtod(m, struct ether_header *), &eh, sizeof(eh));
344 
345 	return (m);
346 }
347 
348 int
349 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
350     struct rtentry *rt)
351 {
352 	int error;
353 
354 	m = ether_encap(ifp, m, dst, rt, &error);
355 	if (m == NULL)
356 		return (error);
357 
358 	return (if_enqueue(ifp, m));
359 }
360 
361 /*
362  * Process a received Ethernet packet.
363  *
364  * Ethernet input has several "phases" of filtering packets to
365  * support virtual/pseudo interfaces before actual layer 3 protocol
366  * handling.
367  *
368  * First phase:
369  *
370  * The first phase supports drivers that aggregate multiple Ethernet
371  * ports into a single logical interface, ie, aggr(4) and trunk(4).
372  * These drivers intercept packets by swapping out the if_input handler
373  * on the "port" interfaces to steal the packets before they get here
374  * to ether_input().
375  */
376 void
377 ether_input(struct ifnet *ifp, struct mbuf *m)
378 {
379 	struct ether_header *eh;
380 	void (*input)(struct ifnet *, struct mbuf *);
381 	u_int16_t etype;
382 	struct arpcom *ac;
383 	const struct ether_brport *eb;
384 	unsigned int sdelim = 0;
385 
386 	/* Drop short frames */
387 	if (m->m_len < ETHER_HDR_LEN)
388 		goto dropanyway;
389 
390 	/*
391 	 * Second phase: service delimited packet filtering.
392 	 *
393 	 * Let vlan(4) and svlan(4) look at "service delimited"
394 	 * packets. If a virtual interface does not exist to take
395 	 * those packets, they're returned to ether_input() so a
396 	 * bridge can have a go at forwarding them.
397 	 */
398 
399 	eh = mtod(m, struct ether_header *);
400 	etype = ntohs(eh->ether_type);
401 
402 	if (ISSET(m->m_flags, M_VLANTAG) ||
403 	    etype == ETHERTYPE_VLAN || etype == ETHERTYPE_QINQ) {
404 #if NVLAN > 0
405 		m = vlan_input(ifp, m);
406 		if (m == NULL)
407 			return;
408 #endif /* NVLAN > 0 */
409 
410 		sdelim = 1;
411 	}
412 
413 	/*
414 	 * Third phase: bridge processing.
415 	 *
416 	 * Give the packet to a bridge interface, ie, bridge(4),
417 	 * switch(4), or tpmr(4), if it is configured. A bridge
418 	 * may take the packet and forward it to another port, or it
419 	 * may return it here to ether_input() to support local
420 	 * delivery to this port.
421 	 */
422 
423 	ac = (struct arpcom *)ifp;
424 
425 	smr_read_enter();
426 	eb = SMR_PTR_GET(&ac->ac_brport);
427 	if (eb != NULL) {
428 		m = (*eb->eb_input)(ifp, m, eb->eb_port);
429 		if (m == NULL) {
430 			smr_read_leave();
431 			return;
432 		}
433 	}
434 	smr_read_leave();
435 
436 	/*
437 	 * Fourth phase: drop service delimited packets.
438 	 *
439 	 * If the packet has a tag, and a bridge didn't want it,
440 	 * it's not for this port.
441 	 */
442 
443 	if (sdelim)
444 		goto dropanyway;
445 
446 	/*
447 	 * Fifth phase: destination address check.
448 	 *
449 	 * Is the packet specifically addressed to this port?
450 	 */
451 
452 	eh = mtod(m, struct ether_header *);
453 	if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) != 0) {
454 #if NCARP > 0
455 		/*
456 		 * If it's not for this port, it could be for carp(4).
457 		 */
458 		if (ifp->if_type != IFT_CARP &&
459 		    !SRPL_EMPTY_LOCKED(&ifp->if_carp)) {
460 			m = carp_input(ifp, m);
461 			if (m == NULL)
462 				return;
463 
464 			eh = mtod(m, struct ether_header *);
465 		}
466 #endif
467 
468 		/*
469 		 * If not, it must be multicast or broadcast to go further.
470 		 */
471 		if (!ETHER_IS_MULTICAST(eh->ether_dhost))
472 			goto dropanyway;
473 
474 		/*
475 		 * If this is not a simplex interface, drop the packet
476 		 * if it came from us.
477 		 */
478 		if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
479 			if (memcmp(ac->ac_enaddr, eh->ether_shost,
480 			    ETHER_ADDR_LEN) == 0)
481 				goto dropanyway;
482 		}
483 
484 		if (ETHER_IS_BROADCAST(eh->ether_dhost))
485 			m->m_flags |= M_BCAST;
486 		else
487 			m->m_flags |= M_MCAST;
488 		ifp->if_imcasts++;
489 	}
490 
491 	/*
492 	 * Sixth phase: protocol demux.
493 	 *
494 	 * At this point it is known that the packet is destined
495 	 * for layer 3 protocol handling on the local port.
496 	 */
497 
498 	switch (etype) {
499 	case ETHERTYPE_IP:
500 		input = ipv4_input;
501 		break;
502 
503 	case ETHERTYPE_ARP:
504 		if (ifp->if_flags & IFF_NOARP)
505 			goto dropanyway;
506 		input = arpinput;
507 		break;
508 
509 	case ETHERTYPE_REVARP:
510 		if (ifp->if_flags & IFF_NOARP)
511 			goto dropanyway;
512 		input = revarpinput;
513 		break;
514 
515 #ifdef INET6
516 	/*
517 	 * Schedule IPv6 software interrupt for incoming IPv6 packet.
518 	 */
519 	case ETHERTYPE_IPV6:
520 		input = ipv6_input;
521 		break;
522 #endif /* INET6 */
523 #if NPPPOE > 0 || defined(PIPEX)
524 	case ETHERTYPE_PPPOEDISC:
525 	case ETHERTYPE_PPPOE:
526 		if (m->m_flags & (M_MCAST | M_BCAST))
527 			goto dropanyway;
528 #ifdef PIPEX
529 		if (pipex_enable) {
530 			struct pipex_session *session;
531 
532 			if ((session = pipex_pppoe_lookup_session(m)) != NULL) {
533 				pipex_pppoe_input(m, session);
534 				return;
535 			}
536 		}
537 #endif
538 		if (etype == ETHERTYPE_PPPOEDISC)
539 			pppoe_disc_input(m);
540 		else
541 			pppoe_data_input(m);
542 		return;
543 #endif
544 #ifdef MPLS
545 	case ETHERTYPE_MPLS:
546 	case ETHERTYPE_MPLS_MCAST:
547 		input = mpls_input;
548 		break;
549 #endif
550 #if NBPE > 0
551 	case ETHERTYPE_PBB:
552 		bpe_input(ifp, m);
553 		return;
554 #endif
555 	default:
556 		goto dropanyway;
557 	}
558 
559 	m_adj(m, sizeof(*eh));
560 	(*input)(ifp, m);
561 	return;
562 dropanyway:
563 	m_freem(m);
564 	return;
565 }
566 
567 int
568 ether_brport_isset(struct ifnet *ifp)
569 {
570 	struct arpcom *ac = (struct arpcom *)ifp;
571 
572 	KERNEL_ASSERT_LOCKED();
573 	if (SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL)
574 		return (EBUSY);
575 
576 	return (0);
577 }
578 
579 void
580 ether_brport_set(struct ifnet *ifp, const struct ether_brport *eb)
581 {
582 	struct arpcom *ac = (struct arpcom *)ifp;
583 
584 	KERNEL_ASSERT_LOCKED();
585 	KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) == NULL,
586 	    "%s setting an already set brport", ifp->if_xname);
587 
588 	SMR_PTR_SET_LOCKED(&ac->ac_brport, eb);
589 }
590 
591 void
592 ether_brport_clr(struct ifnet *ifp)
593 {
594 	struct arpcom *ac = (struct arpcom *)ifp;
595 
596 	KERNEL_ASSERT_LOCKED();
597 	KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL,
598 	    "%s clearing an already clear brport", ifp->if_xname);
599 
600 	SMR_PTR_SET_LOCKED(&ac->ac_brport, NULL);
601 }
602 
603 const struct ether_brport *
604 ether_brport_get(struct ifnet *ifp)
605 {
606 	struct arpcom *ac = (struct arpcom *)ifp;
607 	SMR_ASSERT_CRITICAL();
608 	return (SMR_PTR_GET(&ac->ac_brport));
609 }
610 
611 const struct ether_brport *
612 ether_brport_get_locked(struct ifnet *ifp)
613 {
614 	struct arpcom *ac = (struct arpcom *)ifp;
615 	KERNEL_ASSERT_LOCKED();
616 	return (SMR_PTR_GET_LOCKED(&ac->ac_brport));
617 }
618 
619 /*
620  * Convert Ethernet address to printable (loggable) representation.
621  */
622 static char digits[] = "0123456789abcdef";
623 char *
624 ether_sprintf(u_char *ap)
625 {
626 	int i;
627 	static char etherbuf[ETHER_ADDR_LEN * 3];
628 	char *cp = etherbuf;
629 
630 	for (i = 0; i < ETHER_ADDR_LEN; i++) {
631 		*cp++ = digits[*ap >> 4];
632 		*cp++ = digits[*ap++ & 0xf];
633 		*cp++ = ':';
634 	}
635 	*--cp = 0;
636 	return (etherbuf);
637 }
638 
639 /*
640  * Generate a (hopefully) acceptable MAC address, if asked.
641  */
642 void
643 ether_fakeaddr(struct ifnet *ifp)
644 {
645 	static int unit;
646 	int rng = arc4random();
647 
648 	/* Non-multicast; locally administered address */
649 	((struct arpcom *)ifp)->ac_enaddr[0] = 0xfe;
650 	((struct arpcom *)ifp)->ac_enaddr[1] = 0xe1;
651 	((struct arpcom *)ifp)->ac_enaddr[2] = 0xba;
652 	((struct arpcom *)ifp)->ac_enaddr[3] = 0xd0 | (unit++ & 0xf);
653 	((struct arpcom *)ifp)->ac_enaddr[4] = rng;
654 	((struct arpcom *)ifp)->ac_enaddr[5] = rng >> 8;
655 }
656 
657 /*
658  * Perform common duties while attaching to interface list
659  */
660 void
661 ether_ifattach(struct ifnet *ifp)
662 {
663 	struct arpcom *ac = (struct arpcom *)ifp;
664 
665 	/*
666 	 * Any interface which provides a MAC address which is obviously
667 	 * invalid gets whacked, so that users will notice.
668 	 */
669 	if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr))
670 		ether_fakeaddr(ifp);
671 
672 	ifp->if_type = IFT_ETHER;
673 	ifp->if_addrlen = ETHER_ADDR_LEN;
674 	ifp->if_hdrlen = ETHER_HDR_LEN;
675 	ifp->if_mtu = ETHERMTU;
676 	ifp->if_input = ether_input;
677 	if (ifp->if_output == NULL)
678 		ifp->if_output = ether_output;
679 	ifp->if_rtrequest = ether_rtrequest;
680 
681 	if (ifp->if_hardmtu == 0)
682 		ifp->if_hardmtu = ETHERMTU;
683 
684 	if_alloc_sadl(ifp);
685 	memcpy(LLADDR(ifp->if_sadl), ac->ac_enaddr, ifp->if_addrlen);
686 	LIST_INIT(&ac->ac_multiaddrs);
687 #if NBPFILTER > 0
688 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN);
689 #endif
690 }
691 
692 void
693 ether_ifdetach(struct ifnet *ifp)
694 {
695 	struct arpcom *ac = (struct arpcom *)ifp;
696 	struct ether_multi *enm;
697 
698 	/* Undo pseudo-driver changes. */
699 	if_deactivate(ifp);
700 
701 	for (enm = LIST_FIRST(&ac->ac_multiaddrs);
702 	    enm != NULL;
703 	    enm = LIST_FIRST(&ac->ac_multiaddrs)) {
704 		LIST_REMOVE(enm, enm_list);
705 		free(enm, M_IFMADDR, sizeof *enm);
706 	}
707 }
708 
709 #if 0
710 /*
711  * This is for reference.  We have table-driven versions of the
712  * crc32 generators, which are faster than the double-loop.
713  */
714 u_int32_t __pure
715 ether_crc32_le_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
716 {
717 	u_int32_t c, carry;
718 	size_t i, j;
719 
720 	for (i = 0; i < len; i++) {
721 		c = buf[i];
722 		for (j = 0; j < 8; j++) {
723 			carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
724 			crc >>= 1;
725 			c >>= 1;
726 			if (carry)
727 				crc = (crc ^ ETHER_CRC_POLY_LE);
728 		}
729 	}
730 
731 	return (crc);
732 }
733 
734 u_int32_t __pure
735 ether_crc32_be_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
736 {
737 	u_int32_t c, carry;
738 	size_t i, j;
739 
740 	for (i = 0; i < len; i++) {
741 		c = buf[i];
742 		for (j = 0; j < 8; j++) {
743 			carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
744 			crc <<= 1;
745 			c >>= 1;
746 			if (carry)
747 				crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
748 		}
749 	}
750 
751 	return (crc);
752 }
753 #else
754 u_int32_t __pure
755 ether_crc32_le_update(u_int32_t crc, const u_int8_t *buf, size_t len)
756 {
757 	static const u_int32_t crctab[] = {
758 		0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
759 		0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
760 		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
761 		0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
762 	};
763 	size_t i;
764 
765 	for (i = 0; i < len; i++) {
766 		crc ^= buf[i];
767 		crc = (crc >> 4) ^ crctab[crc & 0xf];
768 		crc = (crc >> 4) ^ crctab[crc & 0xf];
769 	}
770 
771 	return (crc);
772 }
773 
774 u_int32_t __pure
775 ether_crc32_be_update(u_int32_t crc, const u_int8_t *buf, size_t len)
776 {
777 	static const u_int8_t rev[] = {
778 		0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
779 		0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
780 	};
781 	static const u_int32_t crctab[] = {
782 		0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
783 		0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
784 		0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
785 		0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd
786 	};
787 	size_t i;
788 	u_int8_t data;
789 
790 	for (i = 0; i < len; i++) {
791 		data = buf[i];
792 		crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]];
793 		crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]];
794 	}
795 
796 	return (crc);
797 }
798 #endif
799 
800 u_int32_t
801 ether_crc32_le(const u_int8_t *buf, size_t len)
802 {
803 	return ether_crc32_le_update(0xffffffff, buf, len);
804 }
805 
806 u_int32_t
807 ether_crc32_be(const u_int8_t *buf, size_t len)
808 {
809 	return ether_crc32_be_update(0xffffffff, buf, len);
810 }
811 
812 u_char	ether_ipmulticast_min[ETHER_ADDR_LEN] =
813     { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
814 u_char	ether_ipmulticast_max[ETHER_ADDR_LEN] =
815     { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
816 
817 #ifdef INET6
818 u_char	ether_ip6multicast_min[ETHER_ADDR_LEN] =
819     { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
820 u_char	ether_ip6multicast_max[ETHER_ADDR_LEN] =
821     { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
822 #endif
823 
824 /*
825  * Convert a sockaddr into an Ethernet address or range of Ethernet
826  * addresses.
827  */
828 int
829 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
830     u_int8_t addrhi[ETHER_ADDR_LEN])
831 {
832 	struct sockaddr_in *sin;
833 #ifdef INET6
834 	struct sockaddr_in6 *sin6;
835 #endif /* INET6 */
836 
837 	switch (sa->sa_family) {
838 
839 	case AF_UNSPEC:
840 		memcpy(addrlo, sa->sa_data, ETHER_ADDR_LEN);
841 		memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
842 		break;
843 
844 	case AF_INET:
845 		sin = satosin(sa);
846 		if (sin->sin_addr.s_addr == INADDR_ANY) {
847 			/*
848 			 * An IP address of INADDR_ANY means listen to
849 			 * or stop listening to all of the Ethernet
850 			 * multicast addresses used for IP.
851 			 * (This is for the sake of IP multicast routers.)
852 			 */
853 			memcpy(addrlo, ether_ipmulticast_min, ETHER_ADDR_LEN);
854 			memcpy(addrhi, ether_ipmulticast_max, ETHER_ADDR_LEN);
855 		} else {
856 			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
857 			memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
858 		}
859 		break;
860 #ifdef INET6
861 	case AF_INET6:
862 		sin6 = satosin6(sa);
863 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
864 			/*
865 			 * An IP6 address of 0 means listen to or stop
866 			 * listening to all of the Ethernet multicast
867 			 * address used for IP6.
868 			 *
869 			 * (This might not be healthy, given IPv6's reliance on
870 			 * multicast for things like neighbor discovery.
871 			 * Perhaps initializing all-nodes, solicited nodes, and
872 			 * possibly all-routers for this interface afterwards
873 			 * is not a bad idea.)
874 			 */
875 
876 			memcpy(addrlo, ether_ip6multicast_min, ETHER_ADDR_LEN);
877 			memcpy(addrhi, ether_ip6multicast_max, ETHER_ADDR_LEN);
878 		} else {
879 			ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
880 			memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
881 		}
882 		break;
883 #endif
884 
885 	default:
886 		return (EAFNOSUPPORT);
887 	}
888 	return (0);
889 }
890 
891 /*
892  * Add an Ethernet multicast address or range of addresses to the list for a
893  * given interface.
894  */
895 int
896 ether_addmulti(struct ifreq *ifr, struct arpcom *ac)
897 {
898 	struct ether_multi *enm;
899 	u_char addrlo[ETHER_ADDR_LEN];
900 	u_char addrhi[ETHER_ADDR_LEN];
901 	int s = splnet(), error;
902 
903 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
904 	if (error != 0) {
905 		splx(s);
906 		return (error);
907 	}
908 
909 	/*
910 	 * Verify that we have valid Ethernet multicast addresses.
911 	 */
912 	if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
913 		splx(s);
914 		return (EINVAL);
915 	}
916 	/*
917 	 * See if the address range is already in the list.
918 	 */
919 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
920 	if (enm != NULL) {
921 		/*
922 		 * Found it; just increment the reference count.
923 		 */
924 		++enm->enm_refcount;
925 		splx(s);
926 		return (0);
927 	}
928 	/*
929 	 * New address or range; malloc a new multicast record
930 	 * and link it into the interface's multicast list.
931 	 */
932 	enm = malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
933 	if (enm == NULL) {
934 		splx(s);
935 		return (ENOBUFS);
936 	}
937 	memcpy(enm->enm_addrlo, addrlo, ETHER_ADDR_LEN);
938 	memcpy(enm->enm_addrhi, addrhi, ETHER_ADDR_LEN);
939 	enm->enm_refcount = 1;
940 	LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
941 	ac->ac_multicnt++;
942 	if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
943 		ac->ac_multirangecnt++;
944 	splx(s);
945 	/*
946 	 * Return ENETRESET to inform the driver that the list has changed
947 	 * and its reception filter should be adjusted accordingly.
948 	 */
949 	return (ENETRESET);
950 }
951 
952 /*
953  * Delete a multicast address record.
954  */
955 int
956 ether_delmulti(struct ifreq *ifr, struct arpcom *ac)
957 {
958 	struct ether_multi *enm;
959 	u_char addrlo[ETHER_ADDR_LEN];
960 	u_char addrhi[ETHER_ADDR_LEN];
961 	int s = splnet(), error;
962 
963 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
964 	if (error != 0) {
965 		splx(s);
966 		return (error);
967 	}
968 
969 	/*
970 	 * Look up the address in our list.
971 	 */
972 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
973 	if (enm == NULL) {
974 		splx(s);
975 		return (ENXIO);
976 	}
977 	if (--enm->enm_refcount != 0) {
978 		/*
979 		 * Still some claims to this record.
980 		 */
981 		splx(s);
982 		return (0);
983 	}
984 	/*
985 	 * No remaining claims to this record; unlink and free it.
986 	 */
987 	LIST_REMOVE(enm, enm_list);
988 	free(enm, M_IFMADDR, sizeof *enm);
989 	ac->ac_multicnt--;
990 	if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
991 		ac->ac_multirangecnt--;
992 	splx(s);
993 	/*
994 	 * Return ENETRESET to inform the driver that the list has changed
995 	 * and its reception filter should be adjusted accordingly.
996 	 */
997 	return (ENETRESET);
998 }
999 
1000 uint64_t
1001 ether_addr_to_e64(const struct ether_addr *ea)
1002 {
1003 	uint64_t e64 = 0;
1004 	size_t i;
1005 
1006 	for (i = 0; i < nitems(ea->ether_addr_octet); i++) {
1007 		e64 <<= 8;
1008 		e64 |= ea->ether_addr_octet[i];
1009 	}
1010 
1011 	return (e64);
1012 }
1013 
1014 void
1015 ether_e64_to_addr(struct ether_addr *ea, uint64_t e64)
1016 {
1017 	size_t i = nitems(ea->ether_addr_octet);
1018 
1019 	do {
1020 		ea->ether_addr_octet[--i] = e64;
1021 		e64 >>= 8;
1022 	} while (i > 0);
1023 }
1024