xref: /openbsd-src/sys/net/if_ethersubr.c (revision d4741794dd2f512d997014f8bd85fbb24d935059)
1 /*	$OpenBSD: if_ethersubr.c,v 1.241 2016/10/11 11:40:12 mikeb 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 
90 #include <net/if.h>
91 #include <net/netisr.h>
92 #include <net/route.h>
93 #include <net/if_llc.h>
94 #include <net/if_dl.h>
95 #include <net/if_media.h>
96 #include <net/if_types.h>
97 
98 #include <netinet/in.h>
99 #include <netinet/if_ether.h>
100 #include <netinet/ip_ipsp.h>
101 
102 #if NBPFILTER > 0
103 #include <net/bpf.h>
104 #endif
105 
106 #include "pppoe.h"
107 #if NPPPOE > 0
108 #include <net/if_pppoe.h>
109 #endif
110 
111 #ifdef INET6
112 #include <netinet6/in6_var.h>
113 #include <netinet6/nd6.h>
114 #endif
115 
116 #ifdef PIPEX
117 #include <net/pipex.h>
118 #endif
119 
120 #ifdef MPLS
121 #include <netmpls/mpls.h>
122 #endif /* MPLS */
123 
124 u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN] =
125     { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
126 u_int8_t etheranyaddr[ETHER_ADDR_LEN] =
127     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
128 #define senderr(e) { error = (e); goto bad;}
129 
130 int
131 ether_ioctl(struct ifnet *ifp, struct arpcom *arp, u_long cmd, caddr_t data)
132 {
133 	struct ifreq *ifr = (struct ifreq *)data;
134 	int error = 0;
135 
136 	switch (cmd) {
137 	case SIOCSIFADDR:
138 		break;
139 
140 	case SIOCSIFMTU:
141 		if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
142 			error = EINVAL;
143 		else
144 			ifp->if_mtu = ifr->ifr_mtu;
145 		break;
146 
147 	case SIOCADDMULTI:
148 	case SIOCDELMULTI:
149 		if (ifp->if_flags & IFF_MULTICAST) {
150 			error = (cmd == SIOCADDMULTI) ?
151 			    ether_addmulti(ifr, arp) :
152 			    ether_delmulti(ifr, arp);
153 		} else
154 			error = ENOTTY;
155 		break;
156 
157 	default:
158 		error = ENOTTY;
159 	}
160 
161 	return (error);
162 }
163 
164 
165 void
166 ether_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
167 {
168 	switch (rt_key(rt)->sa_family) {
169 	case AF_INET:
170 		arp_rtrequest(ifp, req, rt);
171 		break;
172 #ifdef INET6
173 	case AF_INET6:
174 		nd6_rtrequest(ifp, req, rt);
175 		break;
176 #endif
177 	default:
178 		break;
179 	}
180 }
181 /*
182  * Ethernet output routine.
183  * Encapsulate a packet of type family for the local net.
184  * Assumes that ifp is actually pointer to arpcom structure.
185  */
186 int
187 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
188     struct rtentry *rt)
189 {
190 	u_int16_t etype;
191 	u_char edst[ETHER_ADDR_LEN];
192 	u_char *esrc;
193 	struct mbuf *mcopy = NULL;
194 	struct ether_header *eh;
195 	struct arpcom *ac = (struct arpcom *)ifp;
196 	sa_family_t af = dst->sa_family;
197 	int error = 0;
198 
199 	KASSERT(rt != NULL || ISSET(m->m_flags, M_MCAST|M_BCAST) ||
200 		af == AF_UNSPEC || af == pseudo_AF_HDRCMPLT);
201 
202 #ifdef DIAGNOSTIC
203 	if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
204 		printf("%s: trying to send packet on wrong domain. "
205 		    "if %d vs. mbuf %d\n", ifp->if_xname,
206 		    ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid));
207 	}
208 #endif
209 
210 	esrc = ac->ac_enaddr;
211 
212 	if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
213 		senderr(ENETDOWN);
214 
215 	switch (af) {
216 	case AF_INET:
217 		error = arpresolve(ifp, rt, m, dst, edst);
218 		if (error)
219 			return (error == EAGAIN ? 0 : error);
220 		/* If broadcasting on a simplex interface, loopback a copy */
221 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
222 		    !m->m_pkthdr.pf.routed)
223 			mcopy = m_copym(m, 0, M_COPYALL, M_NOWAIT);
224 		etype = htons(ETHERTYPE_IP);
225 		break;
226 #ifdef INET6
227 	case AF_INET6:
228 		error = nd6_resolve(ifp, rt, m, dst, edst);
229 		if (error)
230 			return (error == EAGAIN ? 0 : error);
231 		etype = htons(ETHERTYPE_IPV6);
232 		break;
233 #endif
234 #ifdef MPLS
235        case AF_MPLS:
236 		if (rt)
237 			dst = rt_key(rt);
238 		else
239 			senderr(EHOSTUNREACH);
240 
241 		if (!ISSET(ifp->if_xflags, IFXF_MPLS))
242 			senderr(ENETUNREACH);
243 
244 		switch (dst->sa_family) {
245 			case AF_LINK:
246 				if (satosdl(dst)->sdl_alen < sizeof(edst))
247 					senderr(EHOSTUNREACH);
248 				memcpy(edst, LLADDR(satosdl(dst)),
249 				    sizeof(edst));
250 				break;
251 			case AF_INET:
252 			case AF_MPLS:
253 				error = arpresolve(ifp, rt, m, dst, edst);
254 				if (error)
255 					return (error == EAGAIN ? 0 : error);
256 				break;
257 			default:
258 				senderr(EHOSTUNREACH);
259 		}
260 		/* XXX handling for simplex devices in case of M/BCAST ?? */
261 		if (m->m_flags & (M_BCAST | M_MCAST))
262 			etype = htons(ETHERTYPE_MPLS_MCAST);
263 		else
264 			etype = htons(ETHERTYPE_MPLS);
265 		break;
266 #endif /* MPLS */
267 	case pseudo_AF_HDRCMPLT:
268 		eh = (struct ether_header *)dst->sa_data;
269 		esrc = eh->ether_shost;
270 		/* FALLTHROUGH */
271 
272 	case AF_UNSPEC:
273 		eh = (struct ether_header *)dst->sa_data;
274 		memcpy(edst, eh->ether_dhost, sizeof(edst));
275 		/* AF_UNSPEC doesn't swap the byte order of the ether_type. */
276 		etype = eh->ether_type;
277 		break;
278 
279 	default:
280 		printf("%s: can't handle af%d\n", ifp->if_xname,
281 			dst->sa_family);
282 		senderr(EAFNOSUPPORT);
283 	}
284 
285 	/* XXX Should we feed-back an unencrypted IPsec packet ? */
286 	if (mcopy)
287 		if_input_local(ifp, mcopy, dst->sa_family);
288 
289 	M_PREPEND(m, sizeof(struct ether_header) + ETHER_ALIGN, M_DONTWAIT);
290 	if (m == NULL)
291 		return (ENOBUFS);
292 	m_adj(m, ETHER_ALIGN);
293 	eh = mtod(m, struct ether_header *);
294 	eh->ether_type = etype;
295 	memcpy(eh->ether_dhost, edst, sizeof(eh->ether_dhost));
296 	memcpy(eh->ether_shost, esrc, sizeof(eh->ether_shost));
297 
298 	return (if_enqueue(ifp, m));
299 bad:
300 	m_freem(m);
301 	return (error);
302 }
303 
304 /*
305  * Process a received Ethernet packet;
306  * the packet is in the mbuf chain m without
307  * the ether header, which is provided separately.
308  */
309 int
310 ether_input(struct ifnet *ifp, struct mbuf *m, void *cookie)
311 {
312 	struct ether_header *eh;
313 	struct niqueue *inq;
314 	u_int16_t etype;
315 	int llcfound = 0;
316 	struct llc *l;
317 	struct arpcom *ac;
318 #if NPPPOE > 0
319 	struct ether_header *eh_tmp;
320 #endif
321 
322 	/* Drop short frames */
323 	if (m->m_len < ETHER_HDR_LEN)
324 		goto dropanyway;
325 
326 	ac = (struct arpcom *)ifp;
327 	eh = mtod(m, struct ether_header *);
328 	m_adj(m, ETHER_HDR_LEN);
329 
330 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
331 		/*
332 		 * If this is not a simplex interface, drop the packet
333 		 * if it came from us.
334 		 */
335 		if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
336 			if (memcmp(ac->ac_enaddr, eh->ether_shost,
337 			    ETHER_ADDR_LEN) == 0) {
338 				m_freem(m);
339 				return (1);
340 			}
341 		}
342 
343 		if (memcmp(etherbroadcastaddr, eh->ether_dhost,
344 		    sizeof(etherbroadcastaddr)) == 0)
345 			m->m_flags |= M_BCAST;
346 		else
347 			m->m_flags |= M_MCAST;
348 		ifp->if_imcasts++;
349 	}
350 
351 	/*
352 	 * HW vlan tagged packets that were not collected by vlan(4) must
353 	 * be dropped now.
354 	 */
355 	if (m->m_flags & M_VLANTAG) {
356 		m_freem(m);
357 		return (1);
358 	}
359 
360 	/*
361 	 * If packet is unicast, make sure it is for us.  Drop otherwise.
362 	 * This check is required in promiscous mode, and for some hypervisors
363 	 * where the MAC filter is 'best effort' only.
364 	 */
365 	if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
366 		if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN)) {
367 			m_freem(m);
368 			return (1);
369 		}
370 	}
371 
372 	etype = ntohs(eh->ether_type);
373 
374 decapsulate:
375 	switch (etype) {
376 	case ETHERTYPE_IP:
377 		inq = &ipintrq;
378 		break;
379 
380 	case ETHERTYPE_ARP:
381 		if (ifp->if_flags & IFF_NOARP)
382 			goto dropanyway;
383 		arpinput(ifp, m);
384 		return (1);
385 
386 	case ETHERTYPE_REVARP:
387 		if (ifp->if_flags & IFF_NOARP)
388 			goto dropanyway;
389 		revarpinput(ifp, m);
390 		return (1);
391 
392 #ifdef INET6
393 	/*
394 	 * Schedule IPv6 software interrupt for incoming IPv6 packet.
395 	 */
396 	case ETHERTYPE_IPV6:
397 		inq = &ip6intrq;
398 		break;
399 #endif /* INET6 */
400 #if NPPPOE > 0 || defined(PIPEX)
401 	case ETHERTYPE_PPPOEDISC:
402 	case ETHERTYPE_PPPOE:
403 		if (m->m_flags & (M_MCAST | M_BCAST))
404 			goto dropanyway;
405 		M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
406 		if (m == NULL)
407 			return (1);
408 
409 		eh_tmp = mtod(m, struct ether_header *);
410 		/*
411 		 * danger!
412 		 * eh_tmp and eh may overlap because eh
413 		 * is stolen from the mbuf above.
414 		 */
415 		memmove(eh_tmp, eh, sizeof(struct ether_header));
416 #ifdef PIPEX
417 		if (pipex_enable) {
418 			struct pipex_session *session;
419 
420 			KERNEL_LOCK();
421 			if ((session = pipex_pppoe_lookup_session(m)) != NULL) {
422 				pipex_pppoe_input(m, session);
423 				KERNEL_UNLOCK();
424 				return (1);
425 			}
426 			KERNEL_UNLOCK();
427 		}
428 #endif
429 		if (etype == ETHERTYPE_PPPOEDISC)
430 			inq = &pppoediscinq;
431 		else
432 			inq = &pppoeinq;
433 		break;
434 #endif
435 #ifdef MPLS
436 	case ETHERTYPE_MPLS:
437 	case ETHERTYPE_MPLS_MCAST:
438 		mpls_input(m);
439 		return (1);
440 #endif
441 	default:
442 		if (llcfound || etype > ETHERMTU ||
443 		    m->m_len < sizeof(struct llc))
444 			goto dropanyway;
445 		llcfound = 1;
446 		l = mtod(m, struct llc *);
447 		switch (l->llc_dsap) {
448 		case LLC_SNAP_LSAP:
449 			if (l->llc_control == LLC_UI &&
450 			    l->llc_dsap == LLC_SNAP_LSAP &&
451 			    l->llc_ssap == LLC_SNAP_LSAP) {
452 				/* SNAP */
453 				if (m->m_pkthdr.len > etype)
454 					m_adj(m, etype - m->m_pkthdr.len);
455 				m_adj(m, 6);
456 				M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
457 				if (m == NULL)
458 					return (1);
459 				*mtod(m, struct ether_header *) = *eh;
460 				goto decapsulate;
461 			}
462 		default:
463 			goto dropanyway;
464 		}
465 	}
466 
467 	niq_enqueue(inq, m);
468 	return (1);
469 dropanyway:
470 	m_freem(m);
471 	return (1);
472 }
473 
474 /*
475  * Convert Ethernet address to printable (loggable) representation.
476  */
477 static char digits[] = "0123456789abcdef";
478 char *
479 ether_sprintf(u_char *ap)
480 {
481 	int i;
482 	static char etherbuf[ETHER_ADDR_LEN * 3];
483 	char *cp = etherbuf;
484 
485 	for (i = 0; i < ETHER_ADDR_LEN; i++) {
486 		*cp++ = digits[*ap >> 4];
487 		*cp++ = digits[*ap++ & 0xf];
488 		*cp++ = ':';
489 	}
490 	*--cp = 0;
491 	return (etherbuf);
492 }
493 
494 /*
495  * Generate a (hopefully) acceptable MAC address, if asked.
496  */
497 void
498 ether_fakeaddr(struct ifnet *ifp)
499 {
500 	static int unit;
501 	int rng = arc4random();
502 
503 	/* Non-multicast; locally administered address */
504 	((struct arpcom *)ifp)->ac_enaddr[0] = 0xfe;
505 	((struct arpcom *)ifp)->ac_enaddr[1] = 0xe1;
506 	((struct arpcom *)ifp)->ac_enaddr[2] = 0xba;
507 	((struct arpcom *)ifp)->ac_enaddr[3] = 0xd0 | (unit++ & 0xf);
508 	((struct arpcom *)ifp)->ac_enaddr[4] = rng;
509 	((struct arpcom *)ifp)->ac_enaddr[5] = rng >> 8;
510 }
511 
512 /*
513  * Perform common duties while attaching to interface list
514  */
515 void
516 ether_ifattach(struct ifnet *ifp)
517 {
518 	struct arpcom *ac = (struct arpcom *)ifp;
519 
520 	/*
521 	 * Any interface which provides a MAC address which is obviously
522 	 * invalid gets whacked, so that users will notice.
523 	 */
524 	if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr))
525 		ether_fakeaddr(ifp);
526 
527 	ifp->if_type = IFT_ETHER;
528 	ifp->if_addrlen = ETHER_ADDR_LEN;
529 	ifp->if_hdrlen = ETHER_HDR_LEN;
530 	ifp->if_mtu = ETHERMTU;
531 	ifp->if_output = ether_output;
532 	ifp->if_rtrequest = ether_rtrequest;
533 
534 	if_ih_insert(ifp, ether_input, NULL);
535 
536 	if (ifp->if_hardmtu == 0)
537 		ifp->if_hardmtu = ETHERMTU;
538 
539 	if_alloc_sadl(ifp);
540 	memcpy(LLADDR(ifp->if_sadl), ac->ac_enaddr, ifp->if_addrlen);
541 	LIST_INIT(&ac->ac_multiaddrs);
542 #if NBPFILTER > 0
543 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN);
544 #endif
545 }
546 
547 void
548 ether_ifdetach(struct ifnet *ifp)
549 {
550 	struct arpcom *ac = (struct arpcom *)ifp;
551 	struct ether_multi *enm;
552 
553 	/* Undo pseudo-driver changes. */
554 	if_deactivate(ifp);
555 
556 	if_ih_remove(ifp, ether_input, NULL);
557 
558 	KASSERT(SRPL_EMPTY_LOCKED(&ifp->if_inputs));
559 
560 	for (enm = LIST_FIRST(&ac->ac_multiaddrs);
561 	    enm != NULL;
562 	    enm = LIST_FIRST(&ac->ac_multiaddrs)) {
563 		LIST_REMOVE(enm, enm_list);
564 		free(enm, M_IFMADDR, sizeof *enm);
565 	}
566 }
567 
568 #if 0
569 /*
570  * This is for reference.  We have table-driven versions of the
571  * crc32 generators, which are faster than the double-loop.
572  */
573 u_int32_t __pure
574 ether_crc32_le_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
575 {
576 	u_int32_t c, carry;
577 	size_t i, j;
578 
579 	for (i = 0; i < len; i++) {
580 		c = buf[i];
581 		for (j = 0; j < 8; j++) {
582 			carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
583 			crc >>= 1;
584 			c >>= 1;
585 			if (carry)
586 				crc = (crc ^ ETHER_CRC_POLY_LE);
587 		}
588 	}
589 
590 	return (crc);
591 }
592 
593 u_int32_t __pure
594 ether_crc32_be_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
595 {
596 	u_int32_t c, carry;
597 	size_t i, j;
598 
599 	for (i = 0; i < len; i++) {
600 		c = buf[i];
601 		for (j = 0; j < 8; j++) {
602 			carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
603 			crc <<= 1;
604 			c >>= 1;
605 			if (carry)
606 				crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
607 		}
608 	}
609 
610 	return (crc);
611 }
612 #else
613 u_int32_t __pure
614 ether_crc32_le_update(u_int32_t crc, const u_int8_t *buf, size_t len)
615 {
616 	static const u_int32_t crctab[] = {
617 		0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
618 		0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
619 		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
620 		0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
621 	};
622 	size_t i;
623 
624 	for (i = 0; i < len; i++) {
625 		crc ^= buf[i];
626 		crc = (crc >> 4) ^ crctab[crc & 0xf];
627 		crc = (crc >> 4) ^ crctab[crc & 0xf];
628 	}
629 
630 	return (crc);
631 }
632 
633 u_int32_t __pure
634 ether_crc32_be_update(u_int32_t crc, const u_int8_t *buf, size_t len)
635 {
636 	static const u_int8_t rev[] = {
637 		0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
638 		0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
639 	};
640 	static const u_int32_t crctab[] = {
641 		0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
642 		0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
643 		0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
644 		0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd
645 	};
646 	size_t i;
647 	u_int8_t data;
648 
649 	for (i = 0; i < len; i++) {
650 		data = buf[i];
651 		crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]];
652 		crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]];
653 	}
654 
655 	return (crc);
656 }
657 #endif
658 
659 u_int32_t
660 ether_crc32_le(const u_int8_t *buf, size_t len)
661 {
662 	return ether_crc32_le_update(0xffffffff, buf, len);
663 }
664 
665 u_int32_t
666 ether_crc32_be(const u_int8_t *buf, size_t len)
667 {
668 	return ether_crc32_be_update(0xffffffff, buf, len);
669 }
670 
671 u_char	ether_ipmulticast_min[ETHER_ADDR_LEN] =
672     { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
673 u_char	ether_ipmulticast_max[ETHER_ADDR_LEN] =
674     { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
675 
676 #ifdef INET6
677 u_char	ether_ip6multicast_min[ETHER_ADDR_LEN] =
678     { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
679 u_char	ether_ip6multicast_max[ETHER_ADDR_LEN] =
680     { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
681 #endif
682 
683 /*
684  * Convert a sockaddr into an Ethernet address or range of Ethernet
685  * addresses.
686  */
687 int
688 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
689     u_int8_t addrhi[ETHER_ADDR_LEN])
690 {
691 	struct sockaddr_in *sin;
692 #ifdef INET6
693 	struct sockaddr_in6 *sin6;
694 #endif /* INET6 */
695 
696 	switch (sa->sa_family) {
697 
698 	case AF_UNSPEC:
699 		memcpy(addrlo, sa->sa_data, ETHER_ADDR_LEN);
700 		memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
701 		break;
702 
703 	case AF_INET:
704 		sin = satosin(sa);
705 		if (sin->sin_addr.s_addr == INADDR_ANY) {
706 			/*
707 			 * An IP address of INADDR_ANY means listen to
708 			 * or stop listening to all of the Ethernet
709 			 * multicast addresses used for IP.
710 			 * (This is for the sake of IP multicast routers.)
711 			 */
712 			memcpy(addrlo, ether_ipmulticast_min, ETHER_ADDR_LEN);
713 			memcpy(addrhi, ether_ipmulticast_max, ETHER_ADDR_LEN);
714 		} else {
715 			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
716 			memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
717 		}
718 		break;
719 #ifdef INET6
720 	case AF_INET6:
721 		sin6 = satosin6(sa);
722 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
723 			/*
724 			 * An IP6 address of 0 means listen to or stop
725 			 * listening to all of the Ethernet multicast
726 			 * address used for IP6.
727 			 *
728 			 * (This might not be healthy, given IPv6's reliance on
729 			 * multicast for things like neighbor discovery.
730 			 * Perhaps initializing all-nodes, solicited nodes, and
731 			 * possibly all-routers for this interface afterwards
732 			 * is not a bad idea.)
733 			 */
734 
735 			memcpy(addrlo, ether_ip6multicast_min, ETHER_ADDR_LEN);
736 			memcpy(addrhi, ether_ip6multicast_max, ETHER_ADDR_LEN);
737 		} else {
738 			ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
739 			memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
740 		}
741 		break;
742 #endif
743 
744 	default:
745 		return (EAFNOSUPPORT);
746 	}
747 	return (0);
748 }
749 
750 /*
751  * Add an Ethernet multicast address or range of addresses to the list for a
752  * given interface.
753  */
754 int
755 ether_addmulti(struct ifreq *ifr, struct arpcom *ac)
756 {
757 	struct ether_multi *enm;
758 	u_char addrlo[ETHER_ADDR_LEN];
759 	u_char addrhi[ETHER_ADDR_LEN];
760 	int s = splnet(), error;
761 
762 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
763 	if (error != 0) {
764 		splx(s);
765 		return (error);
766 	}
767 
768 	/*
769 	 * Verify that we have valid Ethernet multicast addresses.
770 	 */
771 	if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
772 		splx(s);
773 		return (EINVAL);
774 	}
775 	/*
776 	 * See if the address range is already in the list.
777 	 */
778 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
779 	if (enm != NULL) {
780 		/*
781 		 * Found it; just increment the reference count.
782 		 */
783 		++enm->enm_refcount;
784 		splx(s);
785 		return (0);
786 	}
787 	/*
788 	 * New address or range; malloc a new multicast record
789 	 * and link it into the interface's multicast list.
790 	 */
791 	enm = malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
792 	if (enm == NULL) {
793 		splx(s);
794 		return (ENOBUFS);
795 	}
796 	memcpy(enm->enm_addrlo, addrlo, ETHER_ADDR_LEN);
797 	memcpy(enm->enm_addrhi, addrhi, ETHER_ADDR_LEN);
798 	enm->enm_refcount = 1;
799 	LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
800 	ac->ac_multicnt++;
801 	if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
802 		ac->ac_multirangecnt++;
803 	splx(s);
804 	/*
805 	 * Return ENETRESET to inform the driver that the list has changed
806 	 * and its reception filter should be adjusted accordingly.
807 	 */
808 	return (ENETRESET);
809 }
810 
811 /*
812  * Delete a multicast address record.
813  */
814 int
815 ether_delmulti(struct ifreq *ifr, struct arpcom *ac)
816 {
817 	struct ether_multi *enm;
818 	u_char addrlo[ETHER_ADDR_LEN];
819 	u_char addrhi[ETHER_ADDR_LEN];
820 	int s = splnet(), error;
821 
822 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
823 	if (error != 0) {
824 		splx(s);
825 		return (error);
826 	}
827 
828 	/*
829 	 * Look up the address in our list.
830 	 */
831 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
832 	if (enm == NULL) {
833 		splx(s);
834 		return (ENXIO);
835 	}
836 	if (--enm->enm_refcount != 0) {
837 		/*
838 		 * Still some claims to this record.
839 		 */
840 		splx(s);
841 		return (0);
842 	}
843 	/*
844 	 * No remaining claims to this record; unlink and free it.
845 	 */
846 	LIST_REMOVE(enm, enm_list);
847 	free(enm, M_IFMADDR, sizeof *enm);
848 	ac->ac_multicnt--;
849 	if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
850 		ac->ac_multirangecnt--;
851 	splx(s);
852 	/*
853 	 * Return ENETRESET to inform the driver that the list has changed
854 	 * and its reception filter should be adjusted accordingly.
855 	 */
856 	return (ENETRESET);
857 }
858